diff --git a/src/features/twitter/services/authorize-twitter-service.test.ts b/src/features/twitter/services/authorize-twitter-service.test.ts index b85c9cf..f48a18b 100644 --- a/src/features/twitter/services/authorize-twitter-service.test.ts +++ b/src/features/twitter/services/authorize-twitter-service.test.ts @@ -6,17 +6,49 @@ import type { TokenRepository } from '@/features/account/repositories/token-repo import type { Logger } from '@/shared/infra/logger/logger'; import { loggerMock } from '@/shared/test-helpers/mocks/logger.mock'; +import type { TwitterTokenResponse } from '../models/twitter-models'; import { AuthorizeTwitterService } from './authorize-twitter-service'; import type { TwitterService } from './twitter-service'; describe('[Service] Authorize Twitter', () => { let sut: AuthorizeTwitterService; - const mockLogger = mock(loggerMock); - const mockTwitterService = mock(); - const mockAccountRepository = mock(); - const mockTokenRepository = mock(); + let mockLogger: Logger; + let mockTwitterService: TwitterService; + let mockAccountRepository: AccountRepository; + let mockTokenRepository: TokenRepository; + const fakeAccount = { + avatarUrl: faker.image.avatar(), + createdAt: faker.date.past(), + favorite: faker.datatype.boolean(), + id: faker.string.uuid(), + name: faker.person.firstName(), + socialMediaId: faker.number.int(), + socialMediaUserId: faker.string.uuid(), + updatedAt: faker.date.recent(), + userId: faker.string.uuid(), + username: faker.internet.userName(), + }; beforeEach(() => { + mockLogger = mock(loggerMock); + + mockTwitterService = mock({ + getTwitterOAuthToken: vi.fn(), + getTwitterUser: vi.fn(), + }); + + mockAccountRepository = mock({ + create: vi.fn(), + deleteAccountsBySocialMediaId: vi.fn(), + findAccountsByUserId: vi.fn(), + getAccountBySocialMedia: vi.fn(), + getAccounts: vi.fn(), + }); + + mockTokenRepository = mock({ + upsert: vi.fn(), + }); + sut = new AuthorizeTwitterService( mockLogger, mockTwitterService, @@ -29,34 +61,26 @@ describe('[Service] Authorize Twitter', () => { expect(sut).toBeDefined(); }); - it('success', async () => { + it('success with account', async () => { const spyLogger = vi.spyOn(mockLogger, 'info'); - mockTwitterService.getTwitterOAuthToken.mockResolvedValueOnce({ + vi.spyOn(mockTwitterService, 'getTwitterOAuthToken').mockResolvedValueOnce({ access_token: 'access_token', expires_in: 7200, scope: '123', token_type: 'bearer', }); - mockTwitterService.getTwitterUser.mockResolvedValueOnce({ + vi.spyOn(mockTwitterService, 'getTwitterUser').mockResolvedValueOnce({ id: '123', name: 'name', username: 'username', }); - mockAccountRepository.getAccountBySocialMedia.mockResolvedValueOnce({ - avatarUrl: faker.image.avatar(), - createdAt: faker.date.past(), - favorite: faker.datatype.boolean(), - id: faker.string.uuid(), - name: faker.person.firstName(), - socialMediaId: faker.number.int(), - socialMediaUserId: faker.string.uuid(), - updatedAt: faker.date.recent(), - userId: faker.string.uuid(), - username: faker.internet.userName(), - }); + vi.spyOn( + mockAccountRepository, + 'getAccountBySocialMedia' + ).mockResolvedValueOnce(fakeAccount); const input = { code: '123', @@ -76,5 +100,79 @@ describe('[Service] Authorize Twitter', () => { ); expect(mockAccountRepository.getAccountBySocialMedia).toHaveBeenCalled(); expect(mockAccountRepository.create).not.toHaveBeenCalled(); + expect(mockTokenRepository.upsert).toHaveBeenCalled(); + }); + + it('should throw an error if twitterOAuthToken is not returned', async () => { + const spyLogger = vi.spyOn(mockLogger, 'info'); + + vi.spyOn(mockTwitterService, 'getTwitterOAuthToken').mockResolvedValueOnce( + null as unknown as TwitterTokenResponse + ); + + const input = { + code: '123', + state: '123', + }; + + await expect(sut.execute(input)).rejects.toThrowError('Erro'); + + expect(spyLogger).toHaveBeenCalledWith( + 'Inicialize authorize twitter service' + ); + + expect(mockTwitterService.getTwitterOAuthToken).toHaveBeenCalledWith( + input.code + ); + expect(mockTwitterService.getTwitterUser).not.toHaveBeenCalled(); + expect( + mockAccountRepository.getAccountBySocialMedia + ).not.toHaveBeenCalled(); + }); + + it('creates account if it does not exist', async () => { + const spyLogger = vi.spyOn(mockLogger, 'info'); + + vi.spyOn(mockTwitterService, 'getTwitterOAuthToken').mockResolvedValueOnce({ + access_token: 'access_token', + expires_in: 7200, + scope: '123', + token_type: 'bearer', + }); + + vi.spyOn(mockTwitterService, 'getTwitterUser').mockResolvedValueOnce({ + id: '123', + name: 'name', + username: 'username', + }); + + vi.spyOn( + mockAccountRepository, + 'getAccountBySocialMedia' + ).mockResolvedValueOnce(null); + + vi.spyOn(mockAccountRepository, 'create').mockResolvedValueOnce( + fakeAccount + ); + + const input = { + code: '123', + state: '123', + }; + + await sut.execute(input); + + expect(spyLogger).toHaveBeenCalledWith( + 'Inicialize authorize twitter service' + ); + expect(mockTwitterService.getTwitterOAuthToken).toHaveBeenCalledWith( + input.code + ); + expect(mockTwitterService.getTwitterUser).toHaveBeenCalledWith( + 'access_token' + ); + expect(mockAccountRepository.getAccountBySocialMedia).toHaveBeenCalled(); + expect(mockAccountRepository.create).toHaveBeenCalled(); + expect(mockTokenRepository.upsert).toHaveBeenCalled(); }); });