@@ -1070,6 +1070,152 @@ describe("HypercertOperationsImpl", () => {
10701070 } ) ,
10711071 ) ;
10721072 } ) ;
1073+
1074+ it ( "should create a collection with avatar and banner (Blob)" , async ( ) => {
1075+ const avatarBlob = new Blob ( [ "avatar" ] , { type : "image/png" } ) ;
1076+ const bannerBlob = new Blob ( [ "banner" ] , { type : "image/jpeg" } ) ;
1077+
1078+ // Mock blob upload
1079+ mockAgent . com . atproto . repo . uploadBlob . mockResolvedValueOnce ( {
1080+ success : true ,
1081+ data : {
1082+ blob : {
1083+ $type : "blob" ,
1084+ ref : { $link : "bafyrei-avatar" } ,
1085+ mimeType : "image/png" ,
1086+ size : 100 ,
1087+ } ,
1088+ } ,
1089+ } ) ;
1090+
1091+ mockAgent . com . atproto . repo . uploadBlob . mockResolvedValueOnce ( {
1092+ success : true ,
1093+ data : {
1094+ blob : {
1095+ $type : "blob" ,
1096+ ref : { $link : "bafyrei-banner" } ,
1097+ mimeType : "image/jpeg" ,
1098+ size : 200 ,
1099+ } ,
1100+ } ,
1101+ } ) ;
1102+
1103+ mockAgent . com . atproto . repo . createRecord . mockResolvedValue ( {
1104+ success : true ,
1105+ data : { uri : "at://did:plc:test/org.hypercerts.collection/branded" , cid : "branded-cid" } ,
1106+ } ) ;
1107+
1108+ const result = await hypercertOps . createCollection ( {
1109+ title : "Branded Collection" ,
1110+ avatar : avatarBlob ,
1111+ banner : bannerBlob ,
1112+ items : [ ] ,
1113+ } ) ;
1114+
1115+ expect ( result . uri ) . toContain ( "collection" ) ;
1116+ expect ( mockAgent . com . atproto . repo . uploadBlob ) . toHaveBeenCalledTimes ( 2 ) ;
1117+ expect ( mockAgent . com . atproto . repo . createRecord ) . toHaveBeenCalledWith (
1118+ expect . objectContaining ( {
1119+ record : expect . objectContaining ( {
1120+ title : "Branded Collection" ,
1121+ avatar : expect . objectContaining ( {
1122+ $type : "org.hypercerts.defs#smallImage" ,
1123+ } ) ,
1124+ banner : expect . objectContaining ( {
1125+ $type : "org.hypercerts.defs#largeImage" ,
1126+ } ) ,
1127+ } ) ,
1128+ } ) ,
1129+ ) ;
1130+ } ) ;
1131+
1132+ it ( "should create a collection with avatar and banner (URI strings)" , async ( ) => {
1133+ mockAgent . com . atproto . repo . createRecord . mockResolvedValue ( {
1134+ success : true ,
1135+ data : { uri : "at://did:plc:test/org.hypercerts.collection/uris" , cid : "uris-cid" } ,
1136+ } ) ;
1137+
1138+ const result = await hypercertOps . createCollection ( {
1139+ title : "Collection with URIs" ,
1140+ avatar : "https://example.com/avatar.png" ,
1141+ banner : "https://example.com/banner.jpg" ,
1142+ items : [ ] ,
1143+ } ) ;
1144+
1145+ expect ( result . uri ) . toContain ( "collection" ) ;
1146+ expect ( mockAgent . com . atproto . repo . createRecord ) . toHaveBeenCalledWith (
1147+ expect . objectContaining ( {
1148+ record : expect . objectContaining ( {
1149+ avatar : expect . objectContaining ( {
1150+ $type : "org.hypercerts.defs#uri" ,
1151+ uri : "https://example.com/avatar.png" ,
1152+ } ) ,
1153+ banner : expect . objectContaining ( {
1154+ $type : "org.hypercerts.defs#uri" ,
1155+ uri : "https://example.com/banner.jpg" ,
1156+ } ) ,
1157+ } ) ,
1158+ } ) ,
1159+ ) ;
1160+ } ) ;
1161+
1162+ it ( "should create a project with avatar and banner" , async ( ) => {
1163+ const logoBlob = new Blob ( [ "logo" ] , { type : "image/png" } ) ;
1164+ const headerBlob = new Blob ( [ "header" ] , { type : "image/jpeg" } ) ;
1165+
1166+ mockAgent . com . atproto . repo . uploadBlob . mockResolvedValueOnce ( {
1167+ success : true ,
1168+ data : {
1169+ blob : {
1170+ $type : "blob" ,
1171+ ref : { $link : "bafyrei-logo" } ,
1172+ mimeType : "image/png" ,
1173+ size : 150 ,
1174+ } ,
1175+ } ,
1176+ } ) ;
1177+
1178+ mockAgent . com . atproto . repo . uploadBlob . mockResolvedValueOnce ( {
1179+ success : true ,
1180+ data : {
1181+ blob : {
1182+ $type : "blob" ,
1183+ ref : { $link : "bafyrei-header" } ,
1184+ mimeType : "image/jpeg" ,
1185+ size : 250 ,
1186+ } ,
1187+ } ,
1188+ } ) ;
1189+
1190+ mockAgent . com . atproto . repo . createRecord . mockResolvedValue ( {
1191+ success : true ,
1192+ data : { uri : "at://did:plc:test/org.hypercerts.claim.collection/project123" , cid : "project-cid" } ,
1193+ } ) ;
1194+
1195+ const result = await hypercertOps . createProject ( {
1196+ title : "Climate Action Project" ,
1197+ avatar : logoBlob ,
1198+ banner : headerBlob ,
1199+ shortDescription : "Community climate initiative" ,
1200+ items : [ ] ,
1201+ } ) ;
1202+
1203+ expect ( result . uri ) . toContain ( "collection" ) ;
1204+ expect ( mockAgent . com . atproto . repo . createRecord ) . toHaveBeenCalledWith (
1205+ expect . objectContaining ( {
1206+ record : expect . objectContaining ( {
1207+ title : "Climate Action Project" ,
1208+ type : "project" ,
1209+ avatar : expect . objectContaining ( {
1210+ $type : "org.hypercerts.defs#smallImage" ,
1211+ } ) ,
1212+ banner : expect . objectContaining ( {
1213+ $type : "org.hypercerts.defs#largeImage" ,
1214+ } ) ,
1215+ } ) ,
1216+ } ) ,
1217+ ) ;
1218+ } ) ;
10731219 } ) ;
10741220
10751221 describe ( "getCollection" , ( ) => {
@@ -1265,6 +1411,8 @@ describe("HypercertOperationsImpl", () => {
12651411 } ) ;
12661412
12671413 expect ( result . uri ) . toBe ( "at://did:plc:test/org.hypercerts.collection/abc123" ) ;
1414+
1415+ // Verify that putRecord was called
12681416 expect ( mockAgent . com . atproto . repo . putRecord ) . toHaveBeenCalledWith (
12691417 expect . objectContaining ( {
12701418 record : expect . objectContaining ( {
@@ -1275,6 +1423,153 @@ describe("HypercertOperationsImpl", () => {
12751423 } ) ,
12761424 } ) ,
12771425 ) ;
1426+
1427+ // Explicitly verify that itemWeight was removed from both items
1428+ const putRecordCall = mockAgent . com . atproto . repo . putRecord . mock . calls [ 0 ] [ 0 ] ;
1429+ const updatedItems = putRecordCall . record . items ;
1430+ expect ( updatedItems [ 0 ] ) . not . toHaveProperty ( "itemWeight" ) ;
1431+ expect ( updatedItems [ 1 ] ) . not . toHaveProperty ( "itemWeight" ) ;
1432+ } ) ;
1433+
1434+ it ( "should update collection avatar and banner (Blob)" , async ( ) => {
1435+ const newAvatar = new Blob ( [ "new-avatar" ] , { type : "image/png" } ) ;
1436+ const newBanner = new Blob ( [ "new-banner" ] , { type : "image/jpeg" } ) ;
1437+
1438+ mockAgent . com . atproto . repo . uploadBlob . mockResolvedValueOnce ( {
1439+ success : true ,
1440+ data : {
1441+ blob : {
1442+ $type : "blob" ,
1443+ ref : { $link : "bafyrei-new-avatar" } ,
1444+ mimeType : "image/png" ,
1445+ size : 100 ,
1446+ } ,
1447+ } ,
1448+ } ) ;
1449+
1450+ mockAgent . com . atproto . repo . uploadBlob . mockResolvedValueOnce ( {
1451+ success : true ,
1452+ data : {
1453+ blob : {
1454+ $type : "blob" ,
1455+ ref : { $link : "bafyrei-new-banner" } ,
1456+ mimeType : "image/jpeg" ,
1457+ size : 200 ,
1458+ } ,
1459+ } ,
1460+ } ) ;
1461+
1462+ const result = await hypercertOps . updateCollection ( "at://did:plc:test/org.hypercerts.collection/abc123" , {
1463+ avatar : newAvatar ,
1464+ banner : newBanner ,
1465+ } ) ;
1466+
1467+ expect ( result . uri ) . toBe ( "at://did:plc:test/org.hypercerts.collection/abc123" ) ;
1468+ expect ( mockAgent . com . atproto . repo . uploadBlob ) . toHaveBeenCalledTimes ( 2 ) ;
1469+ expect ( mockAgent . com . atproto . repo . putRecord ) . toHaveBeenCalledWith (
1470+ expect . objectContaining ( {
1471+ record : expect . objectContaining ( {
1472+ avatar : expect . objectContaining ( {
1473+ $type : "org.hypercerts.defs#smallImage" ,
1474+ } ) ,
1475+ banner : expect . objectContaining ( {
1476+ $type : "org.hypercerts.defs#largeImage" ,
1477+ } ) ,
1478+ } ) ,
1479+ } ) ,
1480+ ) ;
1481+ } ) ;
1482+
1483+ it ( "should update collection avatar and banner (URI strings)" , async ( ) => {
1484+ const result = await hypercertOps . updateCollection ( "at://did:plc:test/org.hypercerts.collection/abc123" , {
1485+ avatar : "https://example.com/new-avatar.png" ,
1486+ banner : "https://example.com/new-banner.jpg" ,
1487+ } ) ;
1488+
1489+ expect ( result . uri ) . toBe ( "at://did:plc:test/org.hypercerts.collection/abc123" ) ;
1490+ expect ( mockAgent . com . atproto . repo . putRecord ) . toHaveBeenCalledWith (
1491+ expect . objectContaining ( {
1492+ record : expect . objectContaining ( {
1493+ avatar : expect . objectContaining ( {
1494+ $type : "org.hypercerts.defs#uri" ,
1495+ uri : "https://example.com/new-avatar.png" ,
1496+ } ) ,
1497+ banner : expect . objectContaining ( {
1498+ $type : "org.hypercerts.defs#uri" ,
1499+ uri : "https://example.com/new-banner.jpg" ,
1500+ } ) ,
1501+ } ) ,
1502+ } ) ,
1503+ ) ;
1504+ } ) ;
1505+
1506+ it ( "should remove avatar and banner when set to null" , async ( ) => {
1507+ // Setup: collection with avatar and banner
1508+ mockAgent . com . atproto . repo . getRecord . mockResolvedValue ( {
1509+ success : true ,
1510+ data : {
1511+ uri : "at://did:plc:test/org.hypercerts.collection/abc123" ,
1512+ cid : "old-cid" ,
1513+ value : {
1514+ $type : "org.hypercerts.collection" ,
1515+ title : "Collection" ,
1516+ items : [ ] ,
1517+ avatar : { $type : "org.hypercerts.defs#uri" , uri : "https://example.com/old-avatar.png" } ,
1518+ banner : { $type : "org.hypercerts.defs#uri" , uri : "https://example.com/old-banner.jpg" } ,
1519+ createdAt : "2024-01-01T00:00:00Z" ,
1520+ } ,
1521+ } ,
1522+ } ) ;
1523+
1524+ const result = await hypercertOps . updateCollection ( "at://did:plc:test/org.hypercerts.collection/abc123" , {
1525+ avatar : null ,
1526+ banner : null ,
1527+ } ) ;
1528+
1529+ expect ( result . uri ) . toBe ( "at://did:plc:test/org.hypercerts.collection/abc123" ) ;
1530+ expect ( mockAgent . com . atproto . repo . putRecord ) . toHaveBeenCalledWith (
1531+ expect . objectContaining ( {
1532+ record : expect . not . objectContaining ( {
1533+ avatar : expect . anything ( ) ,
1534+ banner : expect . anything ( ) ,
1535+ } ) ,
1536+ } ) ,
1537+ ) ;
1538+ } ) ;
1539+
1540+ it ( "should preserve avatar and banner when not updating them" , async ( ) => {
1541+ // Setup: collection with avatar and banner
1542+ mockAgent . com . atproto . repo . getRecord . mockResolvedValue ( {
1543+ success : true ,
1544+ data : {
1545+ uri : "at://did:plc:test/org.hypercerts.collection/abc123" ,
1546+ cid : "old-cid" ,
1547+ value : {
1548+ $type : "org.hypercerts.collection" ,
1549+ title : "Old Title" ,
1550+ items : [ ] ,
1551+ avatar : { $type : "org.hypercerts.defs#uri" , uri : "https://example.com/avatar.png" } ,
1552+ banner : { $type : "org.hypercerts.defs#uri" , uri : "https://example.com/banner.jpg" } ,
1553+ createdAt : "2024-01-01T00:00:00Z" ,
1554+ } ,
1555+ } ,
1556+ } ) ;
1557+
1558+ const result = await hypercertOps . updateCollection ( "at://did:plc:test/org.hypercerts.collection/abc123" , {
1559+ title : "New Title" ,
1560+ // Not updating avatar or banner
1561+ } ) ;
1562+
1563+ expect ( result . uri ) . toBe ( "at://did:plc:test/org.hypercerts.collection/abc123" ) ;
1564+ expect ( mockAgent . com . atproto . repo . putRecord ) . toHaveBeenCalledWith (
1565+ expect . objectContaining ( {
1566+ record : expect . objectContaining ( {
1567+ title : "New Title" ,
1568+ avatar : { $type : "org.hypercerts.defs#uri" , uri : "https://example.com/avatar.png" } ,
1569+ banner : { $type : "org.hypercerts.defs#uri" , uri : "https://example.com/banner.jpg" } ,
1570+ } ) ,
1571+ } ) ,
1572+ ) ;
12781573 } ) ;
12791574 } ) ;
12801575
0 commit comments