// Comprehensive test coverage for Repository layer import { IUserRepository } from '../src/Domain/IRepository/IUserRepository'; import { IDeckRepository } from '../src/Domain/IRepository/IDeckRepository'; import { IOrganizationRepository } from '../src/Domain/IRepository/IOrganizationRepository'; import { IContactRepository } from '../src/Domain/IRepository/IContactRepository'; import { UserAggregate, UserState } from '../src/Domain/User/UserAggregate'; import { DeckAggregate, Type as DeckType } from '../src/Domain/Deck/DeckAggregate'; import { OrganizationAggregate } from '../src/Domain/Organization/OrganizationAggregate'; import { ContactAggregate } from '../src/Domain/Contact/ContactAggregate'; import { createMockUser, createMockDeck, createMockOrganization, createMockContact, createMockUserRepository, createMockDeckRepository, createMockOrganizationRepository, createMockContactRepository } from './testUtils'; describe('Repository Layer - Comprehensive Coverage', () => { describe('IUserRepository Interface Coverage', () => { let mockUserRepository: jest.Mocked; beforeEach(() => { mockUserRepository = createMockUserRepository(); }); it('should implement all required methods', () => { expect(mockUserRepository.create).toBeDefined(); expect(mockUserRepository.findByPage).toBeDefined(); expect(mockUserRepository.findByPageIncludingDeleted).toBeDefined(); expect(mockUserRepository.findById).toBeDefined(); expect(mockUserRepository.findByIdIncludingDeleted).toBeDefined(); expect(mockUserRepository.findByUsername).toBeDefined(); expect(mockUserRepository.findByEmail).toBeDefined(); expect(mockUserRepository.findByToken).toBeDefined(); expect(mockUserRepository.search).toBeDefined(); expect(mockUserRepository.searchIncludingDeleted).toBeDefined(); expect(mockUserRepository.update).toBeDefined(); expect(mockUserRepository.delete).toBeDefined(); expect(mockUserRepository.softDelete).toBeDefined(); expect(mockUserRepository.deactivate).toBeDefined(); }); it('should handle user creation', async () => { const userData = { username: 'testuser', email: 'test@example.com' }; const mockUser = createMockUser(userData); mockUserRepository.create.mockResolvedValue(mockUser); const result = await mockUserRepository.create(userData); expect(result).toEqual(mockUser); expect(mockUserRepository.create).toHaveBeenCalledWith(userData); }); it('should handle paginated user retrieval', async () => { const mockUsers = [createMockUser(), createMockUser({ id: 'user2' })]; mockUserRepository.findByPage.mockResolvedValue({ users: mockUsers, totalCount: 2 }); const result = await mockUserRepository.findByPage(0, 10); expect(result.users).toHaveLength(2); expect(result.totalCount).toBe(2); }); it('should handle user search operations', async () => { const mockUsers = [createMockUser({ username: 'searchtest' })]; mockUserRepository.search.mockResolvedValue({ users: mockUsers, totalCount: 1 }); const result = await mockUserRepository.search('searchtest'); expect(result.users).toHaveLength(1); expect(result.users[0].username).toBe('searchtest'); }); it('should handle user state transitions', async () => { const mockUser = createMockUser({ state: UserState.VERIFIED_REGULAR }); mockUserRepository.deactivate.mockResolvedValue(mockUser); const result = await mockUserRepository.deactivate('user-id'); expect(result).toEqual(mockUser); }); }); describe('IDeckRepository Interface Coverage', () => { let mockDeckRepository: jest.Mocked; beforeEach(() => { mockDeckRepository = createMockDeckRepository(); }); it('should implement all required methods including new ones', () => { expect(mockDeckRepository.create).toBeDefined(); expect(mockDeckRepository.findByPage).toBeDefined(); expect(mockDeckRepository.findByPageIncludingDeleted).toBeDefined(); expect(mockDeckRepository.findById).toBeDefined(); expect(mockDeckRepository.findByIdIncludingDeleted).toBeDefined(); expect(mockDeckRepository.search).toBeDefined(); expect(mockDeckRepository.searchIncludingDeleted).toBeDefined(); expect(mockDeckRepository.update).toBeDefined(); expect(mockDeckRepository.delete).toBeDefined(); expect(mockDeckRepository.softDelete).toBeDefined(); expect(mockDeckRepository.countActiveByUserId).toBeDefined(); expect(mockDeckRepository.countOrganizationalByUserId).toBeDefined(); expect(mockDeckRepository.findFilteredDecks).toBeDefined(); }); it('should handle deck counting operations', async () => { mockDeckRepository.countActiveByUserId.mockResolvedValue(5); mockDeckRepository.countOrganizationalByUserId.mockResolvedValue(3); const activeCount = await mockDeckRepository.countActiveByUserId('user-id'); const orgCount = await mockDeckRepository.countOrganizationalByUserId('user-id'); expect(activeCount).toBe(5); expect(orgCount).toBe(3); }); it('should handle filtered deck retrieval', async () => { const mockDecks = [createMockDeck(), createMockDeck({ id: 'deck2' })]; mockDeckRepository.findFilteredDecks.mockResolvedValue({ decks: mockDecks, totalCount: 2 }); const result = await mockDeckRepository.findFilteredDecks('user-id', 'org-id', false, 0, 10); expect(result.decks).toHaveLength(2); expect(result.totalCount).toBe(2); }); it('should handle different deck types', async () => { const jokerDeck = createMockDeck({ type: DeckType.JOKER }); const luckDeck = createMockDeck({ type: DeckType.LUCK }); const questionDeck = createMockDeck({ type: DeckType.QUESTION }); mockDeckRepository.create.mockResolvedValueOnce(jokerDeck); mockDeckRepository.create.mockResolvedValueOnce(luckDeck); mockDeckRepository.create.mockResolvedValueOnce(questionDeck); const result1 = await mockDeckRepository.create({ type: DeckType.JOKER }); const result2 = await mockDeckRepository.create({ type: DeckType.LUCK }); const result3 = await mockDeckRepository.create({ type: DeckType.QUESTION }); expect(result1.type).toBe(DeckType.JOKER); expect(result2.type).toBe(DeckType.LUCK); expect(result3.type).toBe(DeckType.QUESTION); }); }); describe('IOrganizationRepository Interface Coverage', () => { let mockOrgRepository: jest.Mocked; beforeEach(() => { mockOrgRepository = createMockOrganizationRepository(); }); it('should implement all required methods', () => { expect(mockOrgRepository.create).toBeDefined(); expect(mockOrgRepository.findByPage).toBeDefined(); expect(mockOrgRepository.findByPageIncludingDeleted).toBeDefined(); expect(mockOrgRepository.findById).toBeDefined(); expect(mockOrgRepository.findByIdIncludingDeleted).toBeDefined(); expect(mockOrgRepository.search).toBeDefined(); expect(mockOrgRepository.searchIncludingDeleted).toBeDefined(); expect(mockOrgRepository.update).toBeDefined(); expect(mockOrgRepository.delete).toBeDefined(); expect(mockOrgRepository.softDelete).toBeDefined(); }); it('should handle organization CRUD operations', async () => { const orgData = { name: 'Test Org', contactemail: 'test@org.com' }; const mockOrg = createMockOrganization(orgData); mockOrgRepository.create.mockResolvedValue(mockOrg); mockOrgRepository.findById.mockResolvedValue(mockOrg); mockOrgRepository.update.mockResolvedValue(mockOrg); mockOrgRepository.softDelete.mockResolvedValue(mockOrg); const created = await mockOrgRepository.create(orgData); const found = await mockOrgRepository.findById('org-id'); const updated = await mockOrgRepository.update('org-id', { name: 'Updated Org' }); const deleted = await mockOrgRepository.softDelete('org-id'); expect(created.name).toBe('Test Org'); expect(found).toEqual(mockOrg); expect(updated).toEqual(mockOrg); expect(deleted).toEqual(mockOrg); }); }); describe('IContactRepository Interface Coverage', () => { let mockContactRepository: jest.Mocked; beforeEach(() => { mockContactRepository = createMockContactRepository(); }); it('should implement all required methods', () => { expect(mockContactRepository.create).toBeDefined(); expect(mockContactRepository.findById).toBeDefined(); expect(mockContactRepository.findByPage).toBeDefined(); expect(mockContactRepository.findByPageIncludingDeleted).toBeDefined(); expect(mockContactRepository.findByIdIncludingDeleted).toBeDefined(); expect(mockContactRepository.search).toBeDefined(); expect(mockContactRepository.searchIncludingDeleted).toBeDefined(); expect(mockContactRepository.update).toBeDefined(); expect(mockContactRepository.delete).toBeDefined(); expect(mockContactRepository.softDelete).toBeDefined(); }); it('should handle contact search operations', async () => { const mockContacts = [createMockContact({ email: 'test@example.com' })]; mockContactRepository.search.mockResolvedValue(mockContacts); mockContactRepository.searchIncludingDeleted.mockResolvedValue(mockContacts); const activeResults = await mockContactRepository.search('test'); const allResults = await mockContactRepository.searchIncludingDeleted('test'); expect(activeResults).toHaveLength(1); expect(allResults).toHaveLength(1); }); it('should handle contact lifecycle', async () => { const contactData = { email: 'user@example.com', message: 'Help Request' }; const mockContact = createMockContact(contactData); mockContactRepository.create.mockResolvedValue(mockContact); mockContactRepository.findById.mockResolvedValue(mockContact); mockContactRepository.findByIdIncludingDeleted.mockResolvedValue(mockContact); const created = await mockContactRepository.create(contactData); const found = await mockContactRepository.findById('contact-id'); const foundWithDeleted = await mockContactRepository.findByIdIncludingDeleted('contact-id'); expect(created.email).toBe('user@example.com'); expect(found).toEqual(mockContact); expect(foundWithDeleted).toEqual(mockContact); }); }); describe('Cross-Repository Integration Tests', () => { let userRepo: jest.Mocked; let deckRepo: jest.Mocked; let orgRepo: jest.Mocked; beforeEach(() => { userRepo = createMockUserRepository(); deckRepo = createMockDeckRepository(); orgRepo = createMockOrganizationRepository(); }); it('should simulate user-deck relationship operations', async () => { const mockUser = createMockUser({ id: 'user-123' }); const mockDecks = [ createMockDeck({ userid: 'user-123', name: 'Deck 1' }), createMockDeck({ userid: 'user-123', name: 'Deck 2' }) ]; userRepo.findById.mockResolvedValue(mockUser); deckRepo.findFilteredDecks.mockResolvedValue({ decks: mockDecks, totalCount: 2 }); deckRepo.countActiveByUserId.mockResolvedValue(2); const user = await userRepo.findById('user-123'); const userDecks = await deckRepo.findFilteredDecks('user-123'); const deckCount = await deckRepo.countActiveByUserId('user-123'); expect(user).toBeDefined(); expect(userDecks.decks).toHaveLength(2); expect(deckCount).toBe(2); expect(userDecks.decks.every(deck => deck.userid === 'user-123')).toBe(true); }); it('should simulate organization-user relationship operations', async () => { const mockOrg = createMockOrganization({ id: 'org-123', name: 'Test Organization' }); const mockUsers = [ createMockUser({ orgid: 'org-123' }), createMockUser({ orgid: 'org-123', id: 'user-2' }) ]; orgRepo.findById.mockResolvedValue(mockOrg); userRepo.findByPage.mockResolvedValue({ users: mockUsers, totalCount: 2 }); const org = await orgRepo.findById('org-123'); const orgUsers = await userRepo.findByPage(0, 10); expect(org).toBeDefined(); expect(orgUsers.users).toHaveLength(2); expect(orgUsers.users.every(user => user.orgid === 'org-123')).toBe(true); }); }); });