diff --git a/src/modules/cards/tests/application/GetCollectionPageUseCase.test.ts b/src/modules/cards/tests/application/GetCollectionPageUseCase.test.ts index be21fcf3..e047c9b4 100644 --- a/src/modules/cards/tests/application/GetCollectionPageUseCase.test.ts +++ b/src/modules/cards/tests/application/GetCollectionPageUseCase.test.ts @@ -756,6 +756,7 @@ describe('GetCollectionPageUseCase', () => { .mockRejectedValue(new Error('Query failed')), getUrlCardView: jest.fn(), getLibrariesForCard: jest.fn(), + getLibrariesForUrl: jest.fn(), }; const errorUseCase = new GetCollectionPageUseCase( diff --git a/src/modules/cards/tests/application/GetMyUrlCardsUseCase.test.ts b/src/modules/cards/tests/application/GetMyUrlCardsUseCase.test.ts index 2ea338f4..7e22148d 100644 --- a/src/modules/cards/tests/application/GetMyUrlCardsUseCase.test.ts +++ b/src/modules/cards/tests/application/GetMyUrlCardsUseCase.test.ts @@ -627,6 +627,7 @@ describe('GetUrlCardsUseCase', () => { .fn() .mockRejectedValue(new Error('Database connection failed')), getLibrariesForCard: jest.fn(), + getLibrariesForUrl: jest.fn(), }; const errorUseCase = new GetUrlCardsUseCase( diff --git a/src/modules/cards/tests/application/GetUrlCardViewUseCase.test.ts b/src/modules/cards/tests/application/GetUrlCardViewUseCase.test.ts index f2e61cb5..4ffb16c9 100644 --- a/src/modules/cards/tests/application/GetUrlCardViewUseCase.test.ts +++ b/src/modules/cards/tests/application/GetUrlCardViewUseCase.test.ts @@ -475,6 +475,7 @@ describe('GetUrlCardViewUseCase', () => { .fn() .mockRejectedValue(new Error('Database connection failed')), getLibrariesForCard: jest.fn(), + getLibrariesForUrl: jest.fn(), }; const errorUseCase = new GetUrlCardViewUseCase(errorRepo, profileService); diff --git a/src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getLibrariesForUrl.integration.test.ts b/src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getLibrariesForUrl.integration.test.ts index a25659a3..2b667df4 100644 --- a/src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getLibrariesForUrl.integration.test.ts +++ b/src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getLibrariesForUrl.integration.test.ts @@ -395,146 +395,4 @@ describe('DrizzleCardQueryRepository - getLibrariesForUrl', () => { expect(result.hasMore).toBe(false); }); }); - - describe('complex scenarios', () => { - it('should handle multiple users with multiple cards for same URL', async () => { - const testUrl = 'https://example.com/complex-scenario'; - const url = URL.create(testUrl).unwrap(); - - // Curator1: 2 cards with same URL - const card1a = new CardBuilder() - .withCuratorId(curator1.value) - .withType(CardTypeEnum.URL) - .withUrl(url) - .buildOrThrow(); - - const card1b = new CardBuilder() - .withCuratorId(curator1.value) - .withType(CardTypeEnum.URL) - .withUrl(url) - .buildOrThrow(); - - // Curator2: 1 card with same URL - const card2 = new CardBuilder() - .withCuratorId(curator2.value) - .withType(CardTypeEnum.URL) - .withUrl(url) - .buildOrThrow(); - - // Curator3: 1 card with different URL (should not appear) - const differentUrl = URL.create('https://example.com/different').unwrap(); - const card3 = new CardBuilder() - .withCuratorId(curator3.value) - .withType(CardTypeEnum.URL) - .withUrl(differentUrl) - .buildOrThrow(); - - // Add all cards to their respective libraries - card1a.addToLibrary(curator1); - card1b.addToLibrary(curator1); - card2.addToLibrary(curator2); - card3.addToLibrary(curator3); - - await cardRepository.save(card1a); - await cardRepository.save(card1b); - await cardRepository.save(card2); - await cardRepository.save(card3); - - const result = await queryRepository.getLibrariesForUrl(testUrl, { - page: 1, - limit: 10, - sortBy: CardSortField.UPDATED_AT, - sortOrder: SortOrder.DESC, - }); - - // Should return 3 entries: 2 from curator1, 1 from curator2 - expect(result.items).toHaveLength(3); - expect(result.totalCount).toBe(3); - - // Check user distribution - const userIds = result.items.map((lib) => lib.userId); - const curator1Count = userIds.filter((id) => id === curator1.value).length; - const curator2Count = userIds.filter((id) => id === curator2.value).length; - const curator3Count = userIds.filter((id) => id === curator3.value).length; - - expect(curator1Count).toBe(2); - expect(curator2Count).toBe(1); - expect(curator3Count).toBe(0); // Different URL - - // Check card IDs - const cardIds = result.items.map((lib) => lib.cardId); - expect(cardIds).toContain(card1a.cardId.getStringValue()); - expect(cardIds).toContain(card1b.cardId.getStringValue()); - expect(cardIds).toContain(card2.cardId.getStringValue()); - expect(cardIds).not.toContain(card3.cardId.getStringValue()); - }); - - it('should handle URL normalization edge cases', async () => { - // Test with URLs that might be considered the same but are stored differently - const baseUrl = 'https://example.com/article'; - const urlWithTrailingSlash = 'https://example.com/article/'; - const urlWithQuery = 'https://example.com/article?utm_source=test'; - - const url1 = URL.create(baseUrl).unwrap(); - const url2 = URL.create(urlWithTrailingSlash).unwrap(); - const url3 = URL.create(urlWithQuery).unwrap(); - - const card1 = new CardBuilder() - .withCuratorId(curator1.value) - .withType(CardTypeEnum.URL) - .withUrl(url1) - .buildOrThrow(); - - const card2 = new CardBuilder() - .withCuratorId(curator2.value) - .withType(CardTypeEnum.URL) - .withUrl(url2) - .buildOrThrow(); - - const card3 = new CardBuilder() - .withCuratorId(curator3.value) - .withType(CardTypeEnum.URL) - .withUrl(url3) - .buildOrThrow(); - - card1.addToLibrary(curator1); - card2.addToLibrary(curator2); - card3.addToLibrary(curator3); - - await cardRepository.save(card1); - await cardRepository.save(card2); - await cardRepository.save(card3); - - // Query for exact base URL - const result = await queryRepository.getLibrariesForUrl(baseUrl, { - page: 1, - limit: 10, - sortBy: CardSortField.UPDATED_AT, - sortOrder: SortOrder.DESC, - }); - - // Should only return exact match - expect(result.items).toHaveLength(1); - expect(result.items[0]!.userId).toBe(curator1.value); - expect(result.items[0]!.cardId).toBe(card1.cardId.getStringValue()); - }); - }); - - describe('error handling', () => { - it('should handle database errors gracefully', async () => { - // Close the database connection to simulate an error - await db.$client.end(); - - const testUrl = 'https://example.com/error-test'; - - await expect( - queryRepository.getLibrariesForUrl(testUrl, { - page: 1, - limit: 10, - sortBy: CardSortField.UPDATED_AT, - sortOrder: SortOrder.DESC, - }), - ).rejects.toThrow(); - }); - }); });