1
+ jest . resetAllMocks ( ) ; // make sure we do not have any mocks set from unit tests
2
+
3
+ import supertest from 'supertest' ;
4
+ import app from '../../../../src/app' ;
5
+ import UserRepo from '../../../../src/database/repository/UserRepo' ;
6
+ import KeystoreRepo from '../../../../src/database/repository/KeystoreRepo' ;
7
+ import User , { IUser } from '../../../../src/database/model/User' ;
8
+ import bcrypt from 'bcrypt' ;
9
+ import * as authUtils from '../../../../src/auth/authUtils' ;
10
+ import { IRole , RoleCode } from '../../../../src/database/model/Role' ;
11
+ import { Types } from 'mongoose' ;
12
+ import ApiKey , { IApiKey } from '../../../../src/database/model/ApiKey' ;
13
+
14
+ export const createTokensSpy = jest . spyOn ( authUtils , 'createTokens' ) ;
15
+ export const bcryptCompareSpy = jest . spyOn ( bcrypt , 'compare' ) ;
16
+ export const userFindByEmailSpy = jest . spyOn ( UserRepo , 'findByEmail' ) ;
17
+ export const keystoreCreateSpy = jest . spyOn ( KeystoreRepo , 'create' ) ;
18
+
19
+ describe ( 'Integration Test: Login basic route' , ( ) => {
20
+
21
+ const endpoint = '/v1/login/basic' ;
22
+ const request = supertest ( app ) ;
23
+ const password = '123456' ;
24
+
25
+ let user : IUser ;
26
+ let apikey : IApiKey ;
27
+
28
+ beforeAll ( async ( ) => {
29
+ await User . remove ( { } ) ; // delete all data from user table
30
+ user = await User . create ( < IUser > {
31
+ name : 'abc' ,
32
+
33
+ password : bcrypt . hashSync ( password , 10 ) ,
34
+ status : true ,
35
+ updatedAt : new Date ( ) ,
36
+ createdAt : new Date ( ) ,
37
+ profilePicUrl : 'https:/abc.com/xyz' ,
38
+ roles : [ < IRole > { _id : new Types . ObjectId ( ) , code : RoleCode . LEARNER } ]
39
+ } ) ;
40
+ apikey = await ApiKey . findOne ( { status : true } ) ;
41
+ } ) ;
42
+
43
+ afterAll ( async ( ) => {
44
+ await User . remove ( { } ) ; // delete all data from user table
45
+ } ) ;
46
+
47
+ beforeEach ( ( ) => {
48
+ userFindByEmailSpy . mockClear ( ) ;
49
+ keystoreCreateSpy . mockClear ( ) ;
50
+ bcryptCompareSpy . mockClear ( ) ;
51
+ createTokensSpy . mockClear ( ) ;
52
+ } ) ;
53
+
54
+ it ( 'Should send error when empty body is sent' , async ( ) => {
55
+ const response = await addHeaders ( request . post ( endpoint ) , apikey ) ;
56
+ expect ( response . status ) . toBe ( 400 ) ;
57
+ expect ( userFindByEmailSpy ) . not . toBeCalled ( ) ;
58
+ expect ( bcryptCompareSpy ) . not . toBeCalled ( ) ;
59
+ expect ( keystoreCreateSpy ) . not . toBeCalled ( ) ;
60
+ expect ( createTokensSpy ) . not . toBeCalled ( ) ;
61
+ } ) ;
62
+
63
+ it ( 'Should send error when email is only sent' , async ( ) => {
64
+ const response = await addHeaders ( request . post ( endpoint )
65
+ . send ( { email : user . email } ) ,
66
+ apikey
67
+ ) ;
68
+ expect ( response . status ) . toBe ( 400 ) ;
69
+ expect ( response . body . message ) . toMatch ( / p a s s w o r d / ) ;
70
+ expect ( userFindByEmailSpy ) . not . toBeCalled ( ) ;
71
+ expect ( bcryptCompareSpy ) . not . toBeCalled ( ) ;
72
+ expect ( keystoreCreateSpy ) . not . toBeCalled ( ) ;
73
+ expect ( createTokensSpy ) . not . toBeCalled ( ) ;
74
+ } ) ;
75
+
76
+ it ( 'Should send error when password is only sent' , async ( ) => {
77
+ const response = await addHeaders ( request . post ( endpoint )
78
+ . send ( { password : password } ) ,
79
+ apikey
80
+ ) ;
81
+ expect ( response . status ) . toBe ( 400 ) ;
82
+ expect ( response . body . message ) . toMatch ( / e m a i l / ) ;
83
+ expect ( userFindByEmailSpy ) . not . toBeCalled ( ) ;
84
+ expect ( bcryptCompareSpy ) . not . toBeCalled ( ) ;
85
+ expect ( keystoreCreateSpy ) . not . toBeCalled ( ) ;
86
+ expect ( createTokensSpy ) . not . toBeCalled ( ) ;
87
+ } ) ;
88
+
89
+ it ( 'Should send error when email is not valid format' , async ( ) => {
90
+ const response = await addHeaders ( request . post ( endpoint )
91
+ . send ( { email : '123' } ) ,
92
+ apikey
93
+ ) ;
94
+ expect ( response . status ) . toBe ( 400 ) ;
95
+ expect ( response . body . message ) . toMatch ( / v a l i d e m a i l / ) ;
96
+ expect ( userFindByEmailSpy ) . not . toBeCalled ( ) ;
97
+ expect ( bcryptCompareSpy ) . not . toBeCalled ( ) ;
98
+ expect ( keystoreCreateSpy ) . not . toBeCalled ( ) ;
99
+ expect ( createTokensSpy ) . not . toBeCalled ( ) ;
100
+ } ) ;
101
+
102
+ it ( 'Should send error when password is not valid format' , async ( ) => {
103
+ const response = await addHeaders ( request . post ( endpoint )
104
+ . send ( {
105
+ email : user . email ,
106
+ password : '123'
107
+ } ) ,
108
+ apikey
109
+ ) ;
110
+ expect ( response . status ) . toBe ( 400 ) ;
111
+ expect ( response . body . message ) . toMatch ( / p a s s w o r d l e n g t h / ) ;
112
+ expect ( response . body . message ) . toMatch ( / 6 c h a r / ) ;
113
+ expect ( userFindByEmailSpy ) . not . toBeCalled ( ) ;
114
+ expect ( bcryptCompareSpy ) . not . toBeCalled ( ) ;
115
+ expect ( keystoreCreateSpy ) . not . toBeCalled ( ) ;
116
+ expect ( createTokensSpy ) . not . toBeCalled ( ) ;
117
+ } ) ;
118
+
119
+ it ( 'Should send error when user not registered for email' , async ( ) => {
120
+ const response = await addHeaders ( request . post ( endpoint )
121
+ . send ( {
122
+
123
+ password : password ,
124
+ } ) ,
125
+ apikey
126
+ ) ;
127
+ expect ( response . status ) . toBe ( 400 ) ;
128
+ expect ( response . body . message ) . toMatch ( / n o t r e g i s t e r e d / ) ;
129
+ expect ( userFindByEmailSpy ) . toBeCalledTimes ( 1 ) ;
130
+ expect ( bcryptCompareSpy ) . not . toBeCalled ( ) ;
131
+ expect ( keystoreCreateSpy ) . not . toBeCalled ( ) ;
132
+ expect ( createTokensSpy ) . not . toBeCalled ( ) ;
133
+ } ) ;
134
+
135
+ it ( 'Should send error for wrong password' , async ( ) => {
136
+ const response = await addHeaders ( request . post ( endpoint )
137
+ . send ( {
138
+ email : user . email ,
139
+ password : 'abc123' ,
140
+ } ) ,
141
+ apikey
142
+ ) ;
143
+ expect ( response . status ) . toBe ( 401 ) ;
144
+ expect ( response . body . message ) . toMatch ( / a u t h e n t i c a t i o n f a i l u r e / i) ;
145
+ expect ( userFindByEmailSpy ) . toBeCalledTimes ( 1 ) ;
146
+ expect ( bcryptCompareSpy ) . toBeCalledTimes ( 1 ) ;
147
+ expect ( keystoreCreateSpy ) . not . toBeCalled ( ) ;
148
+ expect ( createTokensSpy ) . not . toBeCalled ( ) ;
149
+ } ) ;
150
+
151
+ it ( 'Should send success response for correct credentials' , async ( ) => {
152
+ const response = await addHeaders ( request . post ( endpoint )
153
+ . send ( {
154
+ email : user . email ,
155
+ password : password ,
156
+ } ) ,
157
+ apikey
158
+ ) ;
159
+ expect ( response . status ) . toBe ( 200 ) ;
160
+ expect ( response . body . message ) . toMatch ( / S u c c e s s / i) ;
161
+ expect ( response . body . data ) . toBeDefined ( ) ;
162
+
163
+ expect ( response . body . data . user ) . toHaveProperty ( '_id' ) ;
164
+ expect ( response . body . data . user ) . toHaveProperty ( 'name' ) ;
165
+ expect ( response . body . data . user ) . toHaveProperty ( 'roles' ) ;
166
+ expect ( response . body . data . user ) . toHaveProperty ( 'profilePicUrl' ) ;
167
+
168
+ expect ( response . body . data . tokens ) . toBeDefined ( ) ;
169
+ expect ( response . body . data . tokens ) . toHaveProperty ( 'accessToken' ) ;
170
+ expect ( response . body . data . tokens ) . toHaveProperty ( 'refreshToken' ) ;
171
+
172
+ expect ( userFindByEmailSpy ) . toBeCalledTimes ( 1 ) ;
173
+ expect ( keystoreCreateSpy ) . toBeCalledTimes ( 1 ) ;
174
+ expect ( bcryptCompareSpy ) . toBeCalledTimes ( 1 ) ;
175
+ expect ( createTokensSpy ) . toBeCalledTimes ( 1 ) ;
176
+
177
+ expect ( bcryptCompareSpy ) . toBeCalledWith ( password , user . password ) ;
178
+ } ) ;
179
+ } ) ;
180
+
181
+ export const addHeaders = ( request : any , apikey : IApiKey ) => request
182
+ . set ( 'Content-Type' , 'application/json' )
183
+ . set ( 'x-api-key' , apikey . key ) ;
0 commit comments