From 552fb876d477e3bac098123818cc3f7b5cf4a8a8 Mon Sep 17 00:00:00 2001 From: Wesley Finck Date: Thu, 9 Oct 2025 12:36:05 -0700 Subject: [PATCH] refactor: Update tests to reflect single library constraint for URL cards Co-authored-by: aider (anthropic/claude-sonnet-4-5-20250929) --- ...y.getCardsInCollection.integration.test.ts | 13 +-- ...ository.getUrlCardView.integration.test.ts | 80 +++++---------- ...tory.getUrlCardsOfUser.integration.test.ts | 98 +++++++------------ 3 files changed, 64 insertions(+), 127 deletions(-) diff --git a/src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getCardsInCollection.integration.test.ts b/src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getCardsInCollection.integration.test.ts index 00a0ccb4..ae4094eb 100644 --- a/src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getCardsInCollection.integration.test.ts +++ b/src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getCardsInCollection.integration.test.ts @@ -476,7 +476,7 @@ describe('DrizzleCardQueryRepository - getCardsInCollection', () => { }); it('should handle sorting by library count in collection', async () => { - // Create URL cards with different library counts + // Create URL cards - each URL card can only be in its creator's library const url1 = URL.create('https://example.com/popular').unwrap(); const urlCard1 = new CardBuilder() .withCuratorId(curatorId.value) @@ -492,13 +492,9 @@ describe('DrizzleCardQueryRepository - getCardsInCollection', () => { await cardRepository.save(urlCard1); await cardRepository.save(urlCard2); - // Add cards to multiple users' libraries to create different library counts + // Add cards to creator's library - URL cards can only be in creator's library urlCard1.addToLibrary(curatorId); await cardRepository.save(urlCard1); - urlCard1.addToLibrary(otherCuratorId); - await cardRepository.save(urlCard1); - urlCard1.addToLibrary(thirdCuratorId); - await cardRepository.save(urlCard1); urlCard2.addToLibrary(curatorId); await cardRepository.save(urlCard2); @@ -532,8 +528,9 @@ describe('DrizzleCardQueryRepository - getCardsInCollection', () => { ); expect(result.items).toHaveLength(2); - expect(result.items[0]?.libraryCount).toBe(3); // urlCard1 - expect(result.items[1]?.libraryCount).toBe(1); // urlCard2 + // Both URL cards have library count of 1 (only in creator's library) + expect(result.items[0]?.libraryCount).toBe(1); + expect(result.items[1]?.libraryCount).toBe(1); }); it('should handle pagination for collection cards', async () => { diff --git a/src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getUrlCardView.integration.test.ts b/src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getUrlCardView.integration.test.ts index 80641aa7..8a62404a 100644 --- a/src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getUrlCardView.integration.test.ts +++ b/src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getUrlCardView.integration.test.ts @@ -162,9 +162,9 @@ describe('DrizzleCardQueryRepository - getUrlCardView', () => { expect(result?.cardContent.thumbnailUrl).toBeUndefined(); }); - it('should include users who have the card in their libraries', async () => { + it('should include creator in library when URL card is in their library', async () => { // Create URL card - const url = URL.create('https://example.com/shared-article').unwrap(); + const url = URL.create('https://example.com/creator-library').unwrap(); const urlCard = new CardBuilder() .withCuratorId(curatorId.value) .withUrlCard(url) @@ -172,27 +172,17 @@ describe('DrizzleCardQueryRepository - getUrlCardView', () => { await cardRepository.save(urlCard); - // Add card to multiple users' libraries + // Add card to creator's library (URL cards can only be in creator's library) urlCard.addToLibrary(curatorId); await cardRepository.save(urlCard); - urlCard.addToLibrary(otherCuratorId); - await cardRepository.save(urlCard); - - urlCard.addToLibrary(thirdCuratorId); - await cardRepository.save(urlCard); - const result = await queryRepository.getUrlCardView( urlCard.cardId.getStringValue(), ); expect(result).toBeDefined(); - expect(result?.libraries).toHaveLength(3); - - const userIds = result?.libraries.map((lib) => lib.userId).sort(); - expect(userIds).toEqual( - [curatorId.value, otherCuratorId.value, thirdCuratorId.value].sort(), - ); + expect(result?.libraries).toHaveLength(1); + expect(result?.libraries[0]?.userId).toBe(curatorId.value); }); it('should include collections that contain the card', async () => { @@ -266,7 +256,7 @@ describe('DrizzleCardQueryRepository - getUrlCardView', () => { expect(favoritesCollection?.authorId).toBe(otherCuratorId.value); }); - it('should handle card with both libraries and collections', async () => { + it('should handle card with both library and collections', async () => { // Create URL card with full metadata const url = URL.create('https://example.com/comprehensive').unwrap(); const urlMetadata = UrlMetadata.create({ @@ -285,13 +275,10 @@ describe('DrizzleCardQueryRepository - getUrlCardView', () => { await cardRepository.save(urlCard); - // Add to multiple libraries + // Add to creator's library (URL cards can only be in creator's library) urlCard.addToLibrary(curatorId); await cardRepository.save(urlCard); - urlCard.addToLibrary(otherCuratorId); - await cardRepository.save(urlCard); - // Create multiple collections const workCollection = Collection.create( { @@ -354,12 +341,9 @@ describe('DrizzleCardQueryRepository - getUrlCardView', () => { 'https://example.com/comprehensive.jpg', ); - // Check libraries - expect(result?.libraries).toHaveLength(2); - const libraryUserIds = result?.libraries.map((lib) => lib.userId).sort(); - expect(libraryUserIds).toEqual( - [curatorId.value, otherCuratorId.value].sort(), - ); + // Check libraries - URL cards can only be in creator's library + expect(result?.libraries).toHaveLength(1); + expect(result?.libraries[0]?.userId).toBe(curatorId.value); // Check collections expect(result?.collections).toHaveLength(3); @@ -492,7 +476,7 @@ describe('DrizzleCardQueryRepository - getUrlCardView', () => { expect(result?.libraries[0]?.userId).toBe(curatorId.value); }); - it('should handle large numbers of libraries and collections', async () => { + it('should handle multiple collections from different users', async () => { // Create URL card const url = URL.create('https://example.com/popular-article').unwrap(); const urlCard = new CardBuilder() @@ -502,13 +486,11 @@ describe('DrizzleCardQueryRepository - getUrlCardView', () => { await cardRepository.save(urlCard); - // Add to multiple libraries + // Add to creator's library urlCard.addToLibrary(curatorId); - urlCard.addToLibrary(otherCuratorId); - urlCard.addToLibrary(thirdCuratorId); await cardRepository.save(urlCard); - // Create multiple collections + // Create multiple collections from different users const collections = []; for (let i = 1; i <= 5; i++) { const collection = Collection.create( @@ -533,7 +515,8 @@ describe('DrizzleCardQueryRepository - getUrlCardView', () => { ); expect(result).toBeDefined(); - expect(result?.libraries).toHaveLength(3); + // URL cards can only be in creator's library + expect(result?.libraries).toHaveLength(1); expect(result?.collections).toHaveLength(5); // Verify all collections are present @@ -705,9 +688,9 @@ describe('DrizzleCardQueryRepository - getUrlCardView', () => { expect(result).toContain(curatorId.value); }); - it('should return multiple user IDs when card is in multiple libraries', async () => { + it('should return creator ID for URL card in creator library', async () => { // Create URL card - const url = URL.create('https://example.com/multiple-libraries').unwrap(); + const url = URL.create('https://example.com/creator-library').unwrap(); const urlCard = new CardBuilder() .withCuratorId(curatorId.value) .withUrlCard(url) @@ -715,24 +698,16 @@ describe('DrizzleCardQueryRepository - getUrlCardView', () => { await cardRepository.save(urlCard); - // Add to multiple users' libraries + // Add to creator's library (URL cards can only be in creator's library) urlCard.addToLibrary(curatorId); await cardRepository.save(urlCard); - urlCard.addToLibrary(otherCuratorId); - await cardRepository.save(urlCard); - - urlCard.addToLibrary(thirdCuratorId); - await cardRepository.save(urlCard); - const result = await queryRepository.getLibrariesForCard( urlCard.cardId.getStringValue(), ); - expect(result).toHaveLength(3); - expect(result.sort()).toEqual( - [curatorId.value, otherCuratorId.value, thirdCuratorId.value].sort(), - ); + expect(result).toHaveLength(1); + expect(result).toContain(curatorId.value); }); it('should return empty array for non-existent card', async () => { @@ -811,30 +786,21 @@ describe('DrizzleCardQueryRepository - getUrlCardView', () => { // Create URL card const url = URL.create('https://example.com/order-test').unwrap(); const urlCard = new CardBuilder() - .withCuratorId(curatorId.value) + .withCuratorId(thirdCuratorId.value) .withUrlCard(url) .buildOrThrow(); await cardRepository.save(urlCard); - // Add to libraries in specific order + // Add to creator's library (URL cards can only be in creator's library) urlCard.addToLibrary(thirdCuratorId); await cardRepository.save(urlCard); - urlCard.addToLibrary(curatorId); - await cardRepository.save(urlCard); - - urlCard.addToLibrary(otherCuratorId); - await cardRepository.save(urlCard); - const result = await queryRepository.getLibrariesForCard( urlCard.cardId.getStringValue(), ); - expect(result).toHaveLength(3); - // Should contain all three users regardless of order - expect(result).toContain(curatorId.value); - expect(result).toContain(otherCuratorId.value); + expect(result).toHaveLength(1); expect(result).toContain(thirdCuratorId.value); }); }); diff --git a/src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getUrlCardsOfUser.integration.test.ts b/src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getUrlCardsOfUser.integration.test.ts index 539be563..66ba11b4 100644 --- a/src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getUrlCardsOfUser.integration.test.ts +++ b/src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getUrlCardsOfUser.integration.test.ts @@ -282,27 +282,31 @@ describe('DrizzleCardQueryRepository - getUrlCardsOfUser', () => { ); }); - it('should handle multiple users with library memberships', async () => { - // Create URL card - const url = URL.create('https://example.com/shared-article').unwrap(); - const urlCard = new CardBuilder() + it('should only return URL cards in the specified user library', async () => { + // Create URL card for first user + const url1 = URL.create('https://example.com/user1-article').unwrap(); + const urlCard1 = new CardBuilder() .withCuratorId(curatorId.value) - .withUrlCard(url) + .withUrlCard(url1) .buildOrThrow(); - await cardRepository.save(urlCard); + await cardRepository.save(urlCard1); - // Add card to first user's library - urlCard.addToLibrary(curatorId); - await cardRepository.save(urlCard); + // Create URL card for second user + const url2 = URL.create('https://example.com/user2-article').unwrap(); + const urlCard2 = new CardBuilder() + .withCuratorId(otherCuratorId.value) + .withUrlCard(url2) + .buildOrThrow(); - // Add card to second user's library - urlCard.addToLibrary(otherCuratorId); - await cardRepository.save(urlCard); + await cardRepository.save(urlCard2); - // Add card to third user's library - urlCard.addToLibrary(thirdCuratorId); - await cardRepository.save(urlCard); + // Add cards to their respective creator's libraries + urlCard1.addToLibrary(curatorId); + await cardRepository.save(urlCard1); + + urlCard2.addToLibrary(otherCuratorId); + await cardRepository.save(urlCard2); // Query URL cards for first user const result1 = await queryRepository.getUrlCardsOfUser(curatorId.value, { @@ -323,26 +327,12 @@ describe('DrizzleCardQueryRepository - getUrlCardsOfUser', () => { }, ); - // Query URL cards for third user - const result3 = await queryRepository.getUrlCardsOfUser( - thirdCuratorId.value, - { - page: 1, - limit: 10, - sortBy: CardSortField.UPDATED_AT, - sortOrder: SortOrder.DESC, - }, - ); - - // All users should see the card + // Each user should only see their own URL card expect(result1.items).toHaveLength(1); - expect(result2.items).toHaveLength(1); - expect(result3.items).toHaveLength(1); + expect(result1.items[0]?.url).toBe(url1.value); - // Library count should be 3 for all users - expect(result1.items[0]?.libraryCount).toBe(3); - expect(result2.items[0]?.libraryCount).toBe(3); - expect(result3.items[0]?.libraryCount).toBe(3); + expect(result2.items).toHaveLength(1); + expect(result2.items[0]?.url).toBe(url2.value); }); it("should not return URL cards from other users' libraries", async () => { @@ -462,19 +452,13 @@ describe('DrizzleCardQueryRepository - getUrlCardsOfUser', () => { await collectionRepository.save(workCollection); await collectionRepository.save(personalCollection); - // Add both cards to user's library with multiple memberships using domain logic + // Add both cards to user's library - URL cards can only be in creator's library urlCard.addToLibrary(curatorId); await cardRepository.save(urlCard); noteCard.addToLibrary(curatorId); await cardRepository.save(noteCard); - urlCard.addToLibrary(otherCuratorId); - await cardRepository.save(urlCard); - - urlCard.addToLibrary(thirdCuratorId); - await cardRepository.save(urlCard); - // Query URL cards const result = await queryRepository.getUrlCardsOfUser(curatorId.value, { page: 1, @@ -498,8 +482,8 @@ describe('DrizzleCardQueryRepository - getUrlCardsOfUser', () => { 'https://example.com/complex.jpg', ); - // Check library count - expect(urlCardResult?.libraryCount).toBe(3); + // Check library count - URL cards can only be in one library (creator's) + expect(urlCardResult?.libraryCount).toBe(1); // Check connected note expect(urlCardResult?.note).toBeDefined(); @@ -527,20 +511,18 @@ describe('DrizzleCardQueryRepository - getUrlCardsOfUser', () => { describe('sorting', () => { beforeEach(async () => { // Create URL cards with different properties for sorting + // Each URL card is created by and belongs to curatorId const urls = [ { url: 'https://example.com/alpha', - libraryCount: 1, date: '2023-01-01', }, { url: 'https://example.com/beta', - libraryCount: 3, date: '2023-01-03', }, { url: 'https://example.com/gamma', - libraryCount: 2, date: '2023-01-02', }, ]; @@ -556,19 +538,9 @@ describe('DrizzleCardQueryRepository - getUrlCardsOfUser', () => { await cardRepository.save(urlCard); - // Add to library using domain logic - add multiple users to reach the desired library count + // Add to library using domain logic - URL cards can only be in creator's library urlCard.addToLibrary(curatorId); await cardRepository.save(urlCard); - - // Add additional users to reach the test library count - if (urlData.libraryCount > 1) { - urlCard.addToLibrary(otherCuratorId); - await cardRepository.save(urlCard); - } - if (urlData.libraryCount > 2) { - urlCard.addToLibrary(thirdCuratorId); - await cardRepository.save(urlCard); - } } }); @@ -581,9 +553,10 @@ describe('DrizzleCardQueryRepository - getUrlCardsOfUser', () => { }); expect(result.items).toHaveLength(3); - expect(result.items[0]?.libraryCount).toBe(3); // beta - expect(result.items[1]?.libraryCount).toBe(2); // gamma - expect(result.items[2]?.libraryCount).toBe(1); // alpha + // All URL cards have library count of 1 (only in creator's library) + expect(result.items[0]?.libraryCount).toBe(1); + expect(result.items[1]?.libraryCount).toBe(1); + expect(result.items[2]?.libraryCount).toBe(1); }); it('should sort by library count ascending', async () => { @@ -595,9 +568,10 @@ describe('DrizzleCardQueryRepository - getUrlCardsOfUser', () => { }); expect(result.items).toHaveLength(3); - expect(result.items[0]?.libraryCount).toBe(1); // alpha - expect(result.items[1]?.libraryCount).toBe(2); // gamma - expect(result.items[2]?.libraryCount).toBe(3); // beta + // All URL cards have library count of 1 (only in creator's library) + expect(result.items[0]?.libraryCount).toBe(1); + expect(result.items[1]?.libraryCount).toBe(1); + expect(result.items[2]?.libraryCount).toBe(1); }); it('should sort by updated date descending', async () => { -- 2.51.2