From 5893b5cb0baeb554e777be6382bcddacecd48a43 Mon Sep 17 00:00:00 2001 From: Leonardo Ferreira Lima Date: Tue, 26 Sep 2023 15:10:27 -0300 Subject: [PATCH] refactor: refactor user tests --- src/content/content.spec.ts | 7 ++ src/session/session.spec.ts | 7 +- src/user/__snapshots__/user.spec.ts.snap | 26 +++++ src/user/user.spec.ts | 118 ++++++++++++++--------- test/utils.ts | 30 +++++- 5 files changed, 137 insertions(+), 51 deletions(-) create mode 100644 src/user/__snapshots__/user.spec.ts.snap diff --git a/src/content/content.spec.ts b/src/content/content.spec.ts index 3584d42..b9de65b 100644 --- a/src/content/content.spec.ts +++ b/src/content/content.spec.ts @@ -7,6 +7,7 @@ import { expectRequest, mockOnceApiError, mockOnceResponse, + mockOnceSession, mockedRequest, mockedRequests, resetMocks, @@ -168,8 +169,12 @@ describe('Content', () => { }; it('should create content', async () => { + mockOnceSession(); + mockCreateContent(); + await tabNews.session.create(); + const response = await tabNews.content.create({ slug: 'e-opcional', title: 'test', @@ -190,6 +195,8 @@ describe('Content', () => { status: 'draft', source_url: 'https://google.com', }); + + expectRequest(request).cookie(TABNEWS_HEADERS.sessionId).toBeDefined(); }); it('should throw an error when create content with invalid parameters', () => { diff --git a/src/session/session.spec.ts b/src/session/session.spec.ts index f4ab9c6..eae53dd 100644 --- a/src/session/session.spec.ts +++ b/src/session/session.spec.ts @@ -85,8 +85,8 @@ describe('Session', () => { expectRequest(request).method.toBeDelete(); expectRequest(request) - .header(TABNEWS_HEADERS.cookie) - .toBe(`${TABNEWS_HEADERS.sessionId}=${session.token}`); + .cookie(TABNEWS_HEADERS.sessionId) + .toBe(session.token); }); it('should throw an error when has no session', async () => { @@ -107,7 +107,8 @@ describe('Session', () => { const request = mockedRequest(); - expectRequest(request).header(TABNEWS_HEADERS.cookie).toBeNull(); + expectRequest(request).method.toBeDelete(); + expectRequest(request).cookie(TABNEWS_HEADERS.sessionId).toBeUndefined(); }); }); diff --git a/src/user/__snapshots__/user.spec.ts.snap b/src/user/__snapshots__/user.spec.ts.snap new file mode 100644 index 0000000..ef1f488 --- /dev/null +++ b/src/user/__snapshots__/user.spec.ts.snap @@ -0,0 +1,26 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`User > me > should get me 1`] = ` +{ + "created_at": 2022-04-05T23:50:19.920Z, + "description": "description", + "email": "my@email.com", + "features": [ + "create:session", + "read:session", + "create:content", + "create:content:text_root", + "create:content:text_child", + "update:content", + "update:user", + ], + "id": "id", + "notifications": true, + "tabcash": 10, + "tabcoins": 9, + "updated_at": 2022-04-05T23:50:56.545Z, + "username": "username", +} +`; + +exports[`User > me > should throw an error when has no session 1`] = `"Usuário não pode executar esta operação."`; diff --git a/src/user/user.spec.ts b/src/user/user.spec.ts index 64b4980..1594277 100644 --- a/src/user/user.spec.ts +++ b/src/user/user.spec.ts @@ -1,65 +1,89 @@ import 'vitest-fetch-mock'; -import { expect, describe, it, beforeEach } from 'vitest'; +import { expect, describe, it, beforeEach, afterEach } from 'vitest'; +import { TABNEWS_ENDPOINTS, TABNEWS_HEADERS } from '@/commons'; import { TabNews } from '@/tabnews'; -import { createTabNews } from '@test/utils'; +import { + createTabNews, + expectRequest, + mockOnceApiError, + mockOnceResponse, + mockOnceSession, + mockedRequest, + resetMocks, +} from '@test/utils'; let tabNews: TabNews; +const user = { + id: 'id', + username: 'username', + email: 'my@email.com', + description: 'description', + notifications: true, + features: [ + 'create:session', + 'read:session', + 'create:content', + 'create:content:text_root', + 'create:content:text_child', + 'update:content', + 'update:user', + ], + tabcoins: 9, + tabcash: 10, + created_at: '2022-04-05T23:50:19.920Z', + updated_at: '2022-04-05T23:50:56.545Z', +}; + describe('User', () => { beforeEach(() => { tabNews = createTabNews(); }); + afterEach(() => { + resetMocks(); + }); + describe('me', () => { it('should get me', async () => { - fetchMock.mockOnceIf( - (request) => request.url.endsWith('/user'), - JSON.stringify({ - id: 'id', - username: 'username', - email: 'my@email.com', - description: 'description', - notifications: true, - features: [ - 'create:session', - 'read:session', - 'create:content', - 'create:content:text_root', - 'create:content:text_child', - 'update:content', - 'update:user', - ], - tabcoins: 9, - tabcash: 10, - created_at: '2022-04-05T23:50:19.920Z', - updated_at: '2022-04-05T23:50:56.545Z', - }), - ); - - const user = await tabNews.user.me(); - - expect(user).toMatchObject({ - id: 'id', - username: 'username', - email: 'my@email.com', - description: 'description', - notifications: true, - features: [ - 'create:session', - 'read:session', - 'create:content', - 'create:content:text_root', - 'create:content:text_child', - 'update:content', - 'update:user', - ], - tabcoins: 9, - tabcash: 10, - created_at: new Date('2022-04-05T23:50:19.920Z'), - updated_at: new Date('2022-04-05T23:50:56.545Z'), + mockOnceSession(); + + mockOnceResponse(TABNEWS_ENDPOINTS.user, user); + + await tabNews.session.create(); + + const me = await tabNews.user.me(); + + expect(me).toMatchSnapshot(); + + const request = mockedRequest(); + + expectRequest(request).method.toBeGet(); + + expectRequest(request).cookie(TABNEWS_HEADERS.sessionId).toBeDefined(); + }); + + it('should throw an error when has no session', async () => { + mockOnceApiError(TABNEWS_ENDPOINTS.user, { + name: 'ForbiddenError', + message: 'Usuário não pode executar esta operação.', + action: 'Verifique se este usuário possui a feature "read:session".', + status_code: 403, + error_id: '1ca4236b-1a68-4573-acb8-40b220b2fd76', + request_id: 'c17c3107-8cce-4b35-b510-0c1b5b92e3b6', + error_location_code: + 'MODEL:AUTHORIZATION:CAN_REQUEST:FEATURE_NOT_FOUND', }); + + expect(() => tabNews.user.me()).rejects.toThrowErrorMatchingSnapshot(); + + const request = mockedRequest(); + + expectRequest(request).method.toBeGet(); + + expectRequest(request).cookie(TABNEWS_HEADERS.sessionId).toBeUndefined(); }); }); }); diff --git a/test/utils.ts b/test/utils.ts index 2e42275..2cacf65 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -1,7 +1,7 @@ import { expect } from 'vitest'; import { MockParams } from 'vitest-fetch-mock'; -import { TABNEWS_ENDPOINTS } from '@/commons'; +import { TABNEWS_ENDPOINTS, TABNEWS_HEADERS } from '@/commons'; import { TabNewsApiError } from '@/commons/interfaces'; import { TabNewsConfig } from '@/interfaces'; import { TabNews } from '@/tabnews'; @@ -64,6 +64,22 @@ export function mockedRequest() { return request; } +const parseCookie = (cookie: string | null) => + !cookie + ? {} + : cookie + .split(';') + .map((v) => v.split('=')) + .reduce( + (acc, v) => { + acc[decodeURIComponent(v[0].trim())] = decodeURIComponent( + v[1].trim(), + ); + return acc; + }, + {} as Record, + ); + export function expectRequest(request: Request) { const url = new URL(request.url); @@ -88,6 +104,17 @@ export function expectRequest(request: Request) { toBeNull: () => expect(url.searchParams.get(parameter)).toBeNull(), }); + const cookie = (cookieName: string) => { + const cookies = parseCookie(request.headers.get(TABNEWS_HEADERS.cookie)); + + return { + toBe: (cookieValue: string) => + expect(cookies[cookieName]).toBe(cookieValue), + toBeDefined: () => expect(cookies[cookieName]).toBeDefined(), + toBeUndefined: () => expect(cookies[cookieName]).toBeUndefined, + }; + }; + return { body: { toBe: toBodyBe, @@ -99,6 +126,7 @@ export function expectRequest(request: Request) { }, header, query, + cookie, }; }