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+ email : 'abc@xyz.com' ,
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+ email : '123@abc.com' ,
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