Skip to content

Commit dfbab8d

Browse files
author
hersveit
committed
tests
1 parent 60baf4a commit dfbab8d

35 files changed

+871
-561
lines changed

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
"prebuild": "rimraf dist",
1010
"build": "yarn prisma:generate && nest build",
1111
"format": "prettier --write \"src/**/*.ts\"",
12-
"start:dev": "NODE_ENV=development nest start --watch",
13-
"start:debug": "NODE_ENV=development nest start --debug --watch",
14-
"start:prod": "NODE_ENV=production node dist/main",
12+
"start:dev": "cross-env NODE_ENV=development nest start --watch",
13+
"start:debug": "cross-env NODE_ENV=development nest start --debug --watch",
14+
"start:prod": "cross-env NODE_ENV=production node dist/main",
1515
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
16-
"test": "TEST=true jest",
16+
"test": "cross-env TEST=true jest",
1717
"test:coverage": "jest --coverage",
1818
"prisma:generate": "npx prisma generate --schema=\"./src/schema.prisma\"",
1919
"prisma:watch": "npx nodemon --ext prisma --exec yarn prisma:generate",
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
3+
import { createMock, DeepMocked } from '@golevelup/ts-jest';
4+
import { DatabaseServiceProvider } from '../services/database/database.service';
5+
6+
export type DeepMockedDatabaseServiceProvider = ReturnType<typeof getMockedDatabase>;
7+
8+
export function getMockedDatabase() {
9+
const db = {
10+
Prisma: createMock<DatabaseServiceProvider['Prisma']>(),
11+
};
12+
(db.Prisma as any)['user'] = createMock();
13+
(db.Prisma as any)['emailConfirm'] = createMock();
14+
(db.Prisma as any)['refreshToken'] = createMock();
15+
16+
return db as unknown as DeepMocked<DatabaseServiceProvider> & {
17+
Prisma: DeepMocked<DatabaseServiceProvider['Prisma']> & {
18+
user: DeepMocked<DatabaseServiceProvider['Prisma']['user']>;
19+
emailConfirm: DeepMocked<DatabaseServiceProvider['Prisma']['emailConfirm']>;
20+
refreshToken: DeepMocked<DatabaseServiceProvider['Prisma']['refreshToken']>;
21+
};
22+
};
23+
}

src/__mocks__/confirmEmail.stub.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { EmailConfirm } from '@prisma/client';
22

3-
export const getConfirmEmailStub = (): EmailConfirm => {
3+
export function getConfirmEmailStub(): EmailConfirm {
44
return {
55
id: 0,
66
confirmUuid: 'test uuid',
77
userId: 0,
88
};
9-
};
9+
}

src/__mocks__/error.stub.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/__mocks__/user.stub.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { EmailConfirm, RefreshToken, User } from '@prisma/client';
22

3-
export const getUserStub = (): User & {
3+
export function getUserStub(): User & {
44
refreshToken: RefreshToken | null;
55
emailConfirm: EmailConfirm | null;
6-
} => {
6+
} {
77
return {
88
id: 0,
99
email: 'test@example.com',
@@ -13,4 +13,4 @@ export const getUserStub = (): User & {
1313
refreshToken: null,
1414
emailConfirm: null,
1515
};
16-
};
16+
}

src/app/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ import { APP_INTERCEPTOR } from '@nestjs/core';
77
import { TransactionsContext } from '../utils/transactions.utils';
88
import { HttpInterceptor } from '../core/interceptor.core';
99
import { DatabaseService } from '../services/database/database.service';
10+
import { Logger } from '../core/logger.core';
1011

1112
@Module({
1213
imports: [
14+
Logger,
1315
ConfigService,
1416
DatabaseService,
1517
RequestContextModule.forRoot({
Lines changed: 101 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,31 @@
11
import * as cookieParser from 'cookie-parser';
2-
import { sha256 } from './../../../utils/crypt.utils';
3-
import { EmailAlreadyConfirmed, EmailNotConfirmed } from './../../../services/auth/auth.model';
4-
import { getErrorStub } from './../../../__mocks__/error.stub';
5-
import { UserAlreadyExist, EmailOrPasswordIncorrect } from './../../../services/user/user.model';
62
import * as request from 'supertest';
7-
import { AuthControllerProvider } from './../auth.controller';
8-
import { MailServiceProvider } from './../../../services/mail/mail.service';
9-
import { RefreshTokensRepositoryProvider } from './../../../repositories/refreshTokens/refreshTokens.repository';
10-
import { EmailConfirmsRepositoryProvider } from './../../../repositories/emailConfirms/emailConfirms.repository';
11-
import { AuthServiceProvider } from './../../../services/auth/auth.service';
3+
import { AuthControllerProvider } from '../auth.controller';
4+
import { MailServiceProvider } from '../../../services/mail/mail.service';
5+
import { AuthServiceProvider } from '../../../services/auth/auth.service';
126
import { createMock, DeepMocked } from '@golevelup/ts-jest';
137
import { RequestContextModule } from '@medibloc/nestjs-request-context';
148
import { JwtModule } from '@nestjs/jwt';
159
import { Test } from '@nestjs/testing';
1610
import { HttpInterceptor } from '../../../core/interceptor.core';
17-
import { ErrorsRepositoryProvider } from '../../../repositories/errors/errors.repository';
18-
import { UsersRepositoryProvider } from '../../../repositories/users/users.repository';
1911
import { JwtStrategy } from '../../../services/auth/strategies/jwt.strategy';
2012
import { ConfigServiceProvider } from '../../../services/config/config.service';
21-
import { ErrorsServiceProvider } from '../../../services/errors/errors.service';
2213
import { UserServiceProvider } from '../../../services/user/user.service';
2314
import { ConfigServiceFake } from '../../../__mocks__/ConfigServiceFake';
2415
import { TransactionsContextFake } from '../../../__mocks__/TransactionsContextFake';
25-
import { AppWrap } from './../../../utils/tests.utils';
16+
import { AppWrap } from '../../../utils/tests.utils';
2617
import { JwtRefreshTokenStrategy } from '../../../services/auth/strategies/jwt-refresh.strategy';
2718
import { getUserStub } from '../../../__mocks__/user.stub';
28-
import { getConfirmEmailStub } from '../../../__mocks__/confirmEmail.stub';
2919
import { DatabaseServiceProvider } from '../../../services/database/database.service';
30-
import { EmailConfirm, RefreshToken, User } from '@prisma/client';
20+
import { ModuleRef } from '@nestjs/core';
21+
import { LoggerProvider } from '../../../core/logger.core';
3122

3223
describe('AuthController', () => {
3324
const appWrap = {} as AppWrap;
34-
let authService: DeepMocked<AuthServiceProvider>;
35-
let userService: DeepMocked<UserServiceProvider>;
36-
let errorsService: DeepMocked<ErrorsServiceProvider>;
37-
let mailService: DeepMocked<MailServiceProvider>;
3825
let db: {
3926
Prisma: DeepMocked<DatabaseServiceProvider['Prisma']>;
4027
};
41-
42-
let REFRESH_TOKEN: RefreshToken;
43-
let USER: User & { refreshToken: RefreshToken | null; emailConfirm: EmailConfirm | null };
28+
let authService: DeepMocked<AuthServiceProvider>;
4429

4530
beforeAll(async () => {
4631
const dbMock = createMock<DeepMocked<DatabaseServiceProvider['Prisma']>>();
@@ -77,10 +62,6 @@ describe('AuthController', () => {
7762
provide: UserServiceProvider,
7863
useValue: createMock<UserServiceProvider>(),
7964
},
80-
{
81-
provide: ErrorsServiceProvider,
82-
useValue: createMock<ErrorsServiceProvider>(),
83-
},
8465
{
8566
provide: MailServiceProvider,
8667
useValue: createMock<MailServiceProvider>(),
@@ -90,70 +71,129 @@ describe('AuthController', () => {
9071
],
9172
controllers: [AuthControllerProvider],
9273
}).compile();
93-
94-
authService = module.get(AuthServiceProvider);
95-
userService = module.get(UserServiceProvider);
96-
errorsService = module.get(ErrorsServiceProvider);
97-
mailService = module.get(MailServiceProvider);
9874
db = module.get(DatabaseServiceProvider);
75+
authService = module.get(AuthServiceProvider);
9976

10077
appWrap.app = module.createNestApplication();
10178
appWrap.app.useGlobalInterceptors(
102-
new HttpInterceptor(db as unknown as DatabaseServiceProvider),
79+
new HttpInterceptor(
80+
createMock<ModuleRef>(),
81+
db as unknown as DatabaseServiceProvider,
82+
createMock<LoggerProvider>(),
83+
),
10384
);
10485
appWrap.app.use(cookieParser());
10586
await appWrap.app.init();
10687

88+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
10789
db.Prisma.$transaction.mockImplementation((cb: (arg: any) => any) => cb({}));
10890
});
10991

11092
afterAll(async () => {
11193
await appWrap.app.close();
11294
});
11395

114-
beforeEach(() => {
115-
USER = getUserStub();
116-
REFRESH_TOKEN = {
117-
id: 0,
118-
hash: 'e1eae9e373ba62a80cdbd4422fc002553447aeb38fdb8dbf511a52d3e8c5e417',
119-
userId: 0,
120-
};
121-
});
96+
describe('POST /api/auth/sign-up', () => {
97+
it('dto validation', async () => {
98+
const response = await request(appWrap.app.getHttpServer())
99+
.post('/api/auth/sign-up')
100+
.set('Content-Type', 'application/x-www-form-urlencoded')
101+
.send({ email: getUserStub().email });
122102

123-
const successSetupForGenerateTokens = () => {
124-
userService.findVerifiedUser.mockResolvedValue({
125-
...USER,
126-
emailConfirmed: true,
127-
hash: 'ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f',
128-
});
129-
};
103+
expect(response.statusCode).toEqual(400);
104+
expect(response.body.error).toEqual('Bad Request');
130105

131-
const successSetupSignIn = () => {
132-
userService.findVerifiedUser.mockResolvedValue({
133-
...USER,
134-
emailConfirmed: true,
135-
hash: 'ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f',
106+
const response1 = await request(appWrap.app.getHttpServer())
107+
.post('/api/auth/sign-up')
108+
.set('Content-Type', 'application/x-www-form-urlencoded')
109+
.send({ password: '123456789' });
110+
111+
expect(response1.statusCode).toEqual(400);
112+
expect(response1.body.error).toEqual('Bad Request');
136113
});
137-
successSetupForGenerateTokens();
138-
};
139114

140-
describe('POST /api/auth/sign-up', () => {
141-
it('should work dto validation', async () => {
115+
it('should return valid response', async () => {
142116
const response = await request(appWrap.app.getHttpServer())
143117
.post('/api/auth/sign-up')
144118
.set('Content-Type', 'application/x-www-form-urlencoded')
119+
.send({ email: getUserStub().email, password: '123456789' });
120+
121+
expect(authService.signUp).toBeCalledWith({
122+
email: getUserStub().email,
123+
password: '123456789',
124+
});
125+
expect(response.statusCode).toEqual(200);
126+
expect(response.body).toEqual({ success: true });
127+
});
128+
});
129+
130+
describe('POST /api/auth/sign-in', () => {
131+
it('dto validation', async () => {
132+
const response = await request(appWrap.app.getHttpServer())
133+
.post('/api/auth/sign-in')
134+
.set('Content-Type', 'application/x-www-form-urlencoded')
145135
.send({ email: getUserStub().email });
146136

147-
expect(response.statusCode).toBe(400);
148-
expect(response.body.error).toBe('Bad Request');
137+
expect(response.statusCode).toEqual(400);
138+
expect(response.body.error).toEqual('Bad Request');
149139

150140
const response1 = await request(appWrap.app.getHttpServer())
151-
.post('/api/auth/sign-up')
141+
.post('/api/auth/sign-in')
152142
.set('Content-Type', 'application/x-www-form-urlencoded')
153143
.send({ password: '123456789' });
154144

155-
expect(response1.statusCode).toBe(400);
156-
expect(response1.body.error).toBe('Bad Request');
145+
expect(response1.statusCode).toEqual(400);
146+
expect(response1.body.error).toEqual('Bad Request');
147+
});
148+
149+
it('should return valid response', async () => {
150+
authService.signIn.mockResolvedValueOnce({ accessToken: '1', refreshCookie: '2' });
151+
const response = await request(appWrap.app.getHttpServer())
152+
.post('/api/auth/sign-in')
153+
.set('Content-Type', 'application/x-www-form-urlencoded')
154+
.send({ email: getUserStub().email, password: '123456789' });
155+
156+
expect(authService.signIn).toBeCalledWith({
157+
email: getUserStub().email,
158+
password: '123456789',
159+
});
160+
expect(response.statusCode).toEqual(200);
161+
expect(response.body).toEqual({
162+
success: true,
163+
data: { accessToken: '1' },
164+
});
165+
expect(response.headers['set-cookie']).toEqual(['2']);
166+
});
167+
});
168+
169+
describe('POST /api/auth/confirm-email', () => {
170+
it('dto validation', async () => {
171+
const response = await request(appWrap.app.getHttpServer())
172+
.post('/api/auth/confirm-email')
173+
.set('Content-Type', 'application/x-www-form-urlencoded')
174+
.send({});
175+
176+
expect(response.statusCode).toEqual(400);
177+
expect(response.body.error).toEqual('Bad Request');
178+
});
179+
180+
it('should return valid response', async () => {
181+
authService.confirmEmail.mockResolvedValueOnce({
182+
accessToken: '1',
183+
refreshCookie: '2',
184+
});
185+
const response = await request(appWrap.app.getHttpServer())
186+
.post('/api/auth/confirm-email')
187+
.set('Content-Type', 'application/x-www-form-urlencoded')
188+
.send({ confirmUuid: '123' });
189+
190+
expect(authService.confirmEmail).toBeCalledWith('123');
191+
expect(response.statusCode).toEqual(200);
192+
expect(response.body).toEqual({
193+
success: true,
194+
data: { accessToken: '1' },
195+
});
196+
expect(response.headers['set-cookie']).toEqual(['2']);
157197
});
158198
});
159199
});

0 commit comments

Comments
 (0)