import { Application } from 'express'; import faker from 'faker'; import supertest from 'supertest'; import { getCustomRepository } from 'typeorm'; import { AuthProvider } from '@/services'; import { User } from '../src/entities'; import { ApiClientRepository } from '../src/repositories'; import { setupServer } from '../src/server'; import { UserRole } from '../src/types'; type GetUserOptions = { username?: string; password?: string; email?: string; skipVerification?: boolean; makeAdmin?: boolean; }; export const getUser = async (options?: GetUserOptions): Promise => { const { username, email, password, skipVerification, makeAdmin } = { username: faker.internet.userName().split('.').join('_').slice(0, 15), email: faker.internet.email(), password: faker.internet.password(40), ...options, }; const authProvider = new AuthProvider(); const user = ( await authProvider.passwordStrategy.signUpWithEmailAndPasswordOrFail({ username, email, password, }) ).user; // verify users in test if (!skipVerification) { const userWithPasswordAuth = await User.findOne(user.id, { relations: ['passwordAuth'], }); if (userWithPasswordAuth?.passwordAuth) { userWithPasswordAuth.passwordAuth.isVerified = true; await userWithPasswordAuth.passwordAuth.save(); } } if (makeAdmin) { user.roles.push(UserRole.ADMIN); await user.save(); } return user; }; export const getAuthHeader = async (user: User): Promise => { const apiKey = await getCustomRepository(ApiClientRepository).generateApiKey({ user, }); const authHeader = `Basic ${Buffer.from(`${apiKey}:`).toString('base64')}`; return authHeader; }; type RequestOptions = { method: 'get' | 'post' | 'put' | 'patch' | 'delete'; url: string; query?: Record; headers?: Record; data?: string | Record | Record[]; }; let server: Application | undefined; export const execute = async ( options: RequestOptions ): Promise => { if (!server) { server = await setupServer(); } let response = supertest(server)[options.method](options.url); if (options.query) { response = response.query(options.query); } if (options.headers) { response = response.set(options.headers); } if (options.data) { response = response.send(options.data); } return response; }; export const startSession = async ( options?: GetUserOptions ): Promise<{ user: User; execute: (options: RequestOptions) => Promise; }> => { const user = await getUser(options); const authHeader = await getAuthHeader(user); const sessionExecute = async (options: RequestOptions) => { const headers = { Authorization: authHeader, ...options.headers }; return execute({ ...options, headers }); }; return { execute: sessionExecute, user, }; };