From fb5477c77d25fe7bdc1c5750d985a43dd2fef6f2 Mon Sep 17 00:00:00 2001
From: juliaam <juliademoraess@gmail.com>
Date: Mon, 9 Sep 2024 11:07:17 -0300
Subject: [PATCH] fix: authorize twitter-service

---
 .../authorize-twitter-service.test.ts         | 136 +++++++++++++++---
 1 file changed, 117 insertions(+), 19 deletions(-)

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<Logger>(loggerMock);
-  const mockTwitterService = mock<TwitterService>();
-  const mockAccountRepository = mock<AccountRepository>();
-  const mockTokenRepository = mock<TokenRepository>();
+  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<Logger>(loggerMock);
+
+    mockTwitterService = mock<TwitterService>({
+      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();
   });
 });