Constellation, Spacedust, Slingshot, UFOs: atproto crates and services for microcosm

Add tests for new get_many_to_many query handler

Changed files
+212
constellation
src
storage
+212
constellation/src/storage/mod.rs
··· 1564 1564 } 1565 1565 ); 1566 1566 }); 1567 + 1568 + test_each_storage!(get_m2m_empty, |storage| { 1569 + assert_eq!( 1570 + storage.get_many_to_many( 1571 + "a.com", 1572 + "a.b.c", 1573 + ".d.e", 1574 + ".f.g", 1575 + 10, 1576 + None, 1577 + &HashSet::new(), 1578 + &HashSet::new(), 1579 + )?, 1580 + PagedOrderedCollection { 1581 + items: vec![], 1582 + next: None, 1583 + } 1584 + ); 1585 + }); 1586 + 1587 + test_each_storage!(get_m2m_single, |storage| { 1588 + storage.push( 1589 + &ActionableEvent::CreateLinks { 1590 + record_id: RecordId { 1591 + did: "did:plc:asdf".into(), 1592 + collection: "app.t.c".into(), 1593 + rkey: "asdf".into(), 1594 + }, 1595 + links: vec![ 1596 + CollectedLink { 1597 + target: Link::Uri("a.com".into()), 1598 + path: ".abc.uri".into(), 1599 + }, 1600 + CollectedLink { 1601 + target: Link::Uri("b.com".into()), 1602 + path: ".def.uri".into(), 1603 + }, 1604 + CollectedLink { 1605 + target: Link::Uri("b.com".into()), 1606 + path: ".ghi.uri".into(), 1607 + }, 1608 + ], 1609 + }, 1610 + 0, 1611 + )?; 1612 + assert_eq!( 1613 + storage.get_many_to_many( 1614 + "a.com", 1615 + "app.t.c", 1616 + ".abc.uri", 1617 + ".def.uri", 1618 + 10, 1619 + None, 1620 + &HashSet::new(), 1621 + &HashSet::new(), 1622 + )?, 1623 + PagedOrderedCollection { 1624 + items: vec![( 1625 + "b.com".to_string(), 1626 + vec![RecordId { 1627 + did: "did:plc:asdf".into(), 1628 + collection: "app.t.c".into(), 1629 + rkey: "asdf".into(), 1630 + }] 1631 + )], 1632 + next: None, 1633 + } 1634 + ); 1635 + }); 1636 + 1637 + test_each_storage!(get_m2m_filters, |storage| { 1638 + storage.push( 1639 + &ActionableEvent::CreateLinks { 1640 + record_id: RecordId { 1641 + did: "did:plc:asdf".into(), 1642 + collection: "app.t.c".into(), 1643 + rkey: "asdf".into(), 1644 + }, 1645 + links: vec![ 1646 + CollectedLink { 1647 + target: Link::Uri("a.com".into()), 1648 + path: ".abc.uri".into(), 1649 + }, 1650 + CollectedLink { 1651 + target: Link::Uri("b.com".into()), 1652 + path: ".def.uri".into(), 1653 + }, 1654 + ], 1655 + }, 1656 + 0, 1657 + )?; 1658 + storage.push( 1659 + &ActionableEvent::CreateLinks { 1660 + record_id: RecordId { 1661 + did: "did:plc:asdf".into(), 1662 + collection: "app.t.c".into(), 1663 + rkey: "asdf2".into(), 1664 + }, 1665 + links: vec![ 1666 + CollectedLink { 1667 + target: Link::Uri("a.com".into()), 1668 + path: ".abc.uri".into(), 1669 + }, 1670 + CollectedLink { 1671 + target: Link::Uri("b.com".into()), 1672 + path: ".def.uri".into(), 1673 + }, 1674 + ], 1675 + }, 1676 + 1, 1677 + )?; 1678 + storage.push( 1679 + &ActionableEvent::CreateLinks { 1680 + record_id: RecordId { 1681 + did: "did:plc:fdsa".into(), 1682 + collection: "app.t.c".into(), 1683 + rkey: "fdsa".into(), 1684 + }, 1685 + links: vec![ 1686 + CollectedLink { 1687 + target: Link::Uri("a.com".into()), 1688 + path: ".abc.uri".into(), 1689 + }, 1690 + CollectedLink { 1691 + target: Link::Uri("c.com".into()), 1692 + path: ".def.uri".into(), 1693 + }, 1694 + ], 1695 + }, 1696 + 2, 1697 + )?; 1698 + storage.push( 1699 + &ActionableEvent::CreateLinks { 1700 + record_id: RecordId { 1701 + did: "did:plc:fdsa".into(), 1702 + collection: "app.t.c".into(), 1703 + rkey: "fdsa2".into(), 1704 + }, 1705 + links: vec![ 1706 + CollectedLink { 1707 + target: Link::Uri("a.com".into()), 1708 + path: ".abc.uri".into(), 1709 + }, 1710 + CollectedLink { 1711 + target: Link::Uri("c.com".into()), 1712 + path: ".def.uri".into(), 1713 + }, 1714 + ], 1715 + }, 1716 + 3, 1717 + )?; 1718 + 1719 + // Test without filters - should get all records grouped by secondary target 1720 + let result = storage.get_many_to_many( 1721 + "a.com", 1722 + "app.t.c", 1723 + ".abc.uri", 1724 + ".def.uri", 1725 + 10, 1726 + None, 1727 + &HashSet::new(), 1728 + &HashSet::new(), 1729 + )?; 1730 + assert_eq!(result.items.len(), 2); 1731 + assert_eq!(result.next, None); 1732 + // Find b.com group 1733 + let (b_target, b_records) = result.items.iter().find(|(target, _)| target == "b.com").unwrap(); 1734 + assert_eq!(b_target, "b.com"); 1735 + assert_eq!(b_records.len(), 2); 1736 + assert!(b_records.iter().any(|r| r.did.0 == "did:plc:asdf" && r.rkey == "asdf")); 1737 + assert!(b_records.iter().any(|r| r.did.0 == "did:plc:asdf" && r.rkey == "asdf2")); 1738 + // Find c.com group 1739 + let (c_target, c_records) = result.items.iter().find(|(target, _)| target == "c.com").unwrap(); 1740 + assert_eq!(c_target, "c.com"); 1741 + assert_eq!(c_records.len(), 2); 1742 + assert!(c_records.iter().any(|r| r.did.0 == "did:plc:fdsa" && r.rkey == "fdsa")); 1743 + assert!(c_records.iter().any(|r| r.did.0 == "did:plc:fdsa" && r.rkey == "fdsa2")); 1744 + 1745 + // Test with DID filter - should only get records from did:plc:fdsa 1746 + let result = storage.get_many_to_many( 1747 + "a.com", 1748 + "app.t.c", 1749 + ".abc.uri", 1750 + ".def.uri", 1751 + 10, 1752 + None, 1753 + &HashSet::from_iter([Did("did:plc:fdsa".to_string())]), 1754 + &HashSet::new(), 1755 + )?; 1756 + assert_eq!(result.items.len(), 1); 1757 + let (target, records) = &result.items[0]; 1758 + assert_eq!(target, "c.com"); 1759 + assert_eq!(records.len(), 2); 1760 + assert!(records.iter().all(|r| r.did.0 == "did:plc:fdsa")); 1761 + 1762 + // Test with target filter - should only get records linking to b.com 1763 + let result = storage.get_many_to_many( 1764 + "a.com", 1765 + "app.t.c", 1766 + ".abc.uri", 1767 + ".def.uri", 1768 + 10, 1769 + None, 1770 + &HashSet::new(), 1771 + &HashSet::from_iter(["b.com".to_string()]), 1772 + )?; 1773 + assert_eq!(result.items.len(), 1); 1774 + let (target, records) = &result.items[0]; 1775 + assert_eq!(target, "b.com"); 1776 + assert_eq!(records.len(), 2); 1777 + assert!(records.iter().all(|r| r.did.0 == "did:plc:asdf")); 1778 + }); 1567 1779 }