import request from 'supertest'; import { Test } from '@nestjs/testing'; import { HttpStatus, INestApplication } from '@nestjs/common'; import { APP_GUARD } from '@nestjs/core'; import jwt from 'jsonwebtoken'; import { Controller, Get } from '@nestjs/common'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; import { AuthenticationGuard } from './authentication.guard'; import { AuthClientService } from '../modules/auth/auth.service'; import ErrorCodes from '../utils/errorCodes'; import { User } from './user.decorator'; import { PERMISSIONS_GROUPS } from './permissions.enum'; const logger = { info: (...args) => args, error: (...args) => args, }; @Controller('user') class UserController { @Get() public getUser(@User() user) { return { user }; } @Get('options') public getUserWithOptions(@User({}) user) { return { user }; } @Get('not-required') public getUserNotRequired(@User({ required: false }) user) { return { user }; } @Get('required') public getUserRequired(@User({ required: true }) user) { return { user }; } } describe('user.decorator', () => { let app: INestApplication; const jwt_secret = { kid: 'token-testing-shared-key', pem: '$tr0ng-SH4Red-secr3t!!!~gl0ba1~]', }; const fakeUserPayload = { user_id: 'd50d33c7-6c2b-463c-861f-e21667e7c125', username: 'super.admin', permissions: [PERMISSIONS_GROUPS.ANALYZE.permissions.METABASE].map( ({ seqid }) => seqid, ), customer_id: '9d18e8ae-24b9-41a3-9e8f-a25ce57555b11', customer_name: 'dadosfera', customer_tier: 'BASIC', access_token: '', }; beforeAll(async () => { const moduleRef = await Test.createTestingModule({ providers: [ { provide: AuthClientService, useValue: { getPublicKeys: async () => ({ keys: [jwt_secret], }), }, }, { provide: DadosferaLogger, useValue: { logger }, }, { provide: APP_GUARD, useClass: AuthenticationGuard, }, ], controllers: [UserController], }).compile(); app = moduleRef.createNestApplication(); await app.init(); }); afterAll(async () => { await app.close(); }); function AssertNoAuth(res: request.Response) { expect(res.statusCode).toBe(HttpStatus.OK); expect(res.body).toStrictEqual({}); } function AssertWithAuth(res: request.Response) { expect(res.statusCode).toBe(HttpStatus.OK); expect(res.body).toStrictEqual({ user: fakeUserPayload }); } function AssertRequiredNoAuth(res: request.Response) { expect(res.statusCode).toBe(HttpStatus.UNAUTHORIZED); expect(res.body).toStrictEqual({ code: ErrorCodes.AUTH.UNAUTHORIZED, error: 'Não autenticado', message: 'É necessário estar logado para realizar essa operação', statusCode: HttpStatus.UNAUTHORIZED, }); } function UserTest(accessToken: string) { describe(`with${accessToken ? '' : 'out'} token`, () => { it('should GET /user', async () => { const res = await request(app.getHttpServer()) .get('/user') .set({ Authorization: accessToken }); if (accessToken) { AssertWithAuth(res); } else { AssertNoAuth(res); } }); it('should GET /user/options', async () => { const res = await request(app.getHttpServer()) .get('/user/options') .set({ Authorization: accessToken }); if (accessToken) { AssertWithAuth(res); } else { AssertNoAuth(res); } }); it('should GET /user/not-required', async () => { const res = await request(app.getHttpServer()) .get('/user/not-required') .set({ Authorization: accessToken }); if (accessToken) { AssertWithAuth(res); } else { AssertNoAuth(res); } }); it('should GET /user/required if logged', async () => { const res = await request(app.getHttpServer()) .get('/user/required') .set({ Authorization: accessToken }); if (accessToken) { AssertWithAuth(res); } else { AssertRequiredNoAuth(res); } }); }); } function CreateToken(overrides?) { const tokenPayload = { ...fakeUserPayload, token_use: 'access', ...overrides?.user, }; return jwt.sign(tokenPayload, jwt_secret.pem, { keyid: jwt_secret.kid, ...overrides?.jwt, }); } UserTest(null); const token = CreateToken(); fakeUserPayload.access_token = token; UserTest(token); });