1+ import addUser from "../utils/addUser" ;
2+ import chai from "chai" ;
3+ const { expect } = chai ;
4+ import userDataFixture from "../fixtures/user/user" ;
5+ import sinon from "sinon" ;
6+ import chaiHttp from "chai-http" ;
7+ import cleanDb from "../utils/cleanDb" ;
8+ import { CreateOnboardingExtensionBody } from "../../types/onboardingExtension" ;
9+ import {
10+ REQUEST_ALREADY_PENDING ,
11+ REQUEST_STATE , REQUEST_TYPE ,
12+ ONBOARDING_REQUEST_CREATED_SUCCESSFULLY ,
13+ UNAUTHORIZED_TO_CREATE_ONBOARDING_EXTENSION_REQUEST
14+ } from "../../constants/requests" ;
15+ const { generateToken } = require ( "../../test/utils/generateBotToken" ) ;
16+ import app from "../../server" ;
17+ import { createUserStatusWithState } from "../../utils/userStatus" ;
18+ const firestore = require ( "../../utils/firestore" ) ;
19+ const userStatusModel = firestore . collection ( "usersStatus" ) ;
20+ import * as requestsQuery from "../../models/requests"
21+ import { userState } from "../../constants/userStatus" ;
22+ const { CLOUDFLARE_WORKER , BAD_TOKEN } = require ( "../../constants/bot" ) ;
23+ const userData = userDataFixture ( ) ;
24+ chai . use ( chaiHttp ) ;
25+
26+ describe ( "/requests Onboarding Extension" , ( ) => {
27+ describe ( "POST /requests" , ( ) => {
28+ let testUserId : string ;
29+ let testUserIdForInvalidDiscordJoinedDate : string ;
30+ let testUserDiscordIdForInvalidDiscordJoinedDate : string = "54321" ;
31+
32+ const testUserDiscordId : string = "654321" ;
33+ const extensionRequest = {
34+ state : REQUEST_STATE . APPROVED ,
35+ type : REQUEST_TYPE . ONBOARDING ,
36+ requestNumber : 1
37+ } ;
38+ const postEndpoint = "/requests" ;
39+ const botToken = generateToken ( { name : CLOUDFLARE_WORKER } )
40+ const body : CreateOnboardingExtensionBody = {
41+ type : REQUEST_TYPE . ONBOARDING ,
42+ numberOfDays : 5 ,
43+ reason : "This is the reason" ,
44+ userId : testUserDiscordId ,
45+ } ;
46+
47+ beforeEach ( async ( ) => {
48+ testUserId = await addUser ( {
49+ ...userData [ 6 ] ,
50+ discordId : testUserDiscordId ,
51+ discordJoinedAt : "2023-04-06T01:47:34.488000+00:00"
52+ } ) ;
53+ testUserIdForInvalidDiscordJoinedDate = await addUser ( {
54+ ...userData [ 1 ] ,
55+ discordId : testUserDiscordIdForInvalidDiscordJoinedDate ,
56+ discordJoinedAt : "2023-04-06T01"
57+ } ) ;
58+ } ) ;
59+
60+ afterEach ( async ( ) => {
61+ sinon . restore ( ) ;
62+ await cleanDb ( ) ;
63+ } )
64+
65+ it ( "should not call verifyDiscordBot and return 401 response when extension type is not onboarding" , ( done ) => {
66+ chai . request ( app )
67+ . post ( `${ postEndpoint } ?dev=true` )
68+ . send ( { ...body , type : REQUEST_TYPE . OOO } )
69+ . end ( ( err , res ) => {
70+ if ( err ) return done ( err ) ;
71+ expect ( res . statusCode ) . to . equal ( 401 ) ;
72+ expect ( res . body . error ) . to . equal ( "Unauthorized" ) ;
73+ expect ( res . body . message ) . to . equal ( "Unauthenticated User" ) ;
74+ done ( ) ;
75+ } )
76+ } )
77+
78+ it ( "should return Feature not implemented when dev is not true" , ( done ) => {
79+ chai . request ( app )
80+ . post ( `${ postEndpoint } ` )
81+ . send ( body )
82+ . end ( ( err , res ) => {
83+ if ( err ) return done ( err ) ;
84+ expect ( res . statusCode ) . to . equal ( 501 ) ;
85+ expect ( res . body . message ) . to . equal ( "Feature not implemented" ) ;
86+ done ( ) ;
87+ } )
88+ } )
89+
90+ it ( "should return Invalid Request when authorization header is missing" , ( done ) => {
91+ chai
92+ . request ( app )
93+ . post ( `${ postEndpoint } ?dev=true` )
94+ . set ( "authorization" , "" )
95+ . send ( body )
96+ . end ( ( err , res ) => {
97+ if ( err ) return done ( err ) ;
98+ expect ( res . statusCode ) . to . equal ( 400 ) ;
99+ expect ( res . body . message ) . to . equal ( "Invalid Request" ) ;
100+ done ( ) ;
101+ } )
102+ } )
103+
104+ it ( "should return Unauthorized Bot for invalid token" , ( done ) => {
105+ chai . request ( app )
106+ . post ( `${ postEndpoint } ?dev=true` )
107+ . set ( "authorization" , `Bearer ${ BAD_TOKEN } ` )
108+ . send ( body )
109+ . end ( ( err , res ) => {
110+ if ( err ) return done ( err ) ;
111+ expect ( res . statusCode ) . to . equal ( 401 ) ;
112+ expect ( res . body . message ) . to . equal ( "Unauthorized Bot" ) ;
113+ done ( ) ;
114+ } )
115+ } )
116+
117+ it ( "should return 400 response for invalid value type of numberOfDays" , ( done ) => {
118+ chai . request ( app )
119+ . post ( `${ postEndpoint } ?dev=true` )
120+ . set ( "authorization" , `Bearer ${ botToken } ` )
121+ . send ( { ...body , numberOfDays :"1" } )
122+ . end ( ( err , res ) => {
123+ if ( err ) return done ( err ) ;
124+ expect ( res . statusCode ) . to . equal ( 400 ) ;
125+ expect ( res . body . message ) . to . equal ( "numberOfDays must be a number" ) ;
126+ expect ( res . body . error ) . to . equal ( "Bad Request" ) ;
127+ done ( ) ;
128+ } )
129+ } )
130+
131+ it ( "should return 400 response for invalid value of numberOfDays" , ( done ) => {
132+ chai . request ( app )
133+ . post ( `${ postEndpoint } ?dev=true` )
134+ . set ( "authorization" , `Bearer ${ botToken } ` )
135+ . send ( { ...body , numberOfDays :1.4 } )
136+ . end ( ( err , res ) => {
137+ if ( err ) return done ( err ) ;
138+ expect ( res . statusCode ) . to . equal ( 400 ) ;
139+ expect ( res . body . message ) . to . equal ( "numberOfDays must be a integer" ) ;
140+ expect ( res . body . error ) . to . equal ( "Bad Request" ) ;
141+ done ( ) ;
142+ } )
143+ } )
144+
145+ it ( "should return 400 response for invalid userId" , ( done ) => {
146+ chai . request ( app )
147+ . post ( `${ postEndpoint } ?dev=true` )
148+ . set ( "authorization" , `Bearer ${ botToken } ` )
149+ . send ( { ...body , userId : undefined } )
150+ . end ( ( err , res ) => {
151+ if ( err ) return done ( err ) ;
152+ expect ( res . statusCode ) . to . equal ( 400 ) ;
153+ expect ( res . body . message ) . to . equal ( "userId is required" ) ;
154+ expect ( res . body . error ) . to . equal ( "Bad Request" ) ;
155+ done ( ) ;
156+ } )
157+ } )
158+
159+ it ( "should return 500 response when fails to create extension request" , ( done ) => {
160+ createUserStatusWithState ( testUserId , userStatusModel , userState . ONBOARDING ) ;
161+ sinon . stub ( requestsQuery , "createRequest" )
162+ . throws ( "Error while creating extension request" ) ;
163+ chai . request ( app )
164+ . post ( `${ postEndpoint } ?dev=true` )
165+ . set ( "authorization" , `Bearer ${ botToken } ` )
166+ . send ( body )
167+ . end ( ( err , res ) => {
168+ if ( err ) return done ( err ) ;
169+ expect ( res . statusCode ) . to . equal ( 500 ) ;
170+ expect ( res . body . message ) . to . equal ( "An internal server error occurred" ) ;
171+ done ( ) ;
172+ } )
173+ } )
174+
175+ it ( "should return 500 response when discordJoinedAt date string is invalid" , ( done ) => {
176+ createUserStatusWithState ( testUserIdForInvalidDiscordJoinedDate , userStatusModel , userState . ONBOARDING ) ;
177+ chai . request ( app )
178+ . post ( `${ postEndpoint } ?dev=true` )
179+ . set ( "authorization" , `Bearer ${ botToken } ` )
180+ . send ( { ...body , userId : testUserDiscordIdForInvalidDiscordJoinedDate } )
181+ . end ( ( err , res ) => {
182+ if ( err ) return done ( err ) ;
183+ expect ( res . statusCode ) . to . equal ( 500 ) ;
184+ expect ( res . body . message ) . to . equal ( "An internal server error occurred" ) ;
185+ done ( ) ;
186+ } )
187+ } )
188+
189+ it ( "should return 404 response when user does not exist" , ( done ) => {
190+ chai . request ( app )
191+ . post ( `${ postEndpoint } ?dev=true` )
192+ . set ( "authorization" , `Bearer ${ botToken } ` )
193+ . send ( { ...body , userId : "11111" } )
194+ . end ( ( err , res ) => {
195+ if ( err ) return done ( err ) ;
196+ expect ( res . statusCode ) . to . equal ( 404 ) ;
197+ expect ( res . body . error ) . to . equal ( "Not Found" ) ;
198+ expect ( res . body . message ) . to . equal ( "User not found" ) ;
199+ done ( ) ;
200+ } )
201+ } )
202+
203+ it ( "should return 403 response when user's status is not onboarding" , ( done ) => {
204+ createUserStatusWithState ( testUserId , userStatusModel , userState . ACTIVE ) ;
205+ chai . request ( app )
206+ . post ( `${ postEndpoint } ?dev=true` )
207+ . set ( "authorization" , `Bearer ${ botToken } ` )
208+ . send ( body )
209+ . end ( ( err , res ) => {
210+ if ( err ) return done ( err ) ;
211+ expect ( res . statusCode ) . to . equal ( 403 ) ;
212+ expect ( res . body . error ) . to . equal ( "Forbidden" ) ;
213+ expect ( res . body . message ) . to . equal ( UNAUTHORIZED_TO_CREATE_ONBOARDING_EXTENSION_REQUEST ) ;
214+ done ( ) ;
215+ } )
216+ } )
217+
218+ it ( "should return 400 response when a user already has a pending request" , ( done ) => {
219+ createUserStatusWithState ( testUserId , userStatusModel , userState . ONBOARDING ) ;
220+ requestsQuery . createRequest ( { ...extensionRequest , state : REQUEST_STATE . PENDING , userId : testUserId } ) ;
221+
222+ chai . request ( app )
223+ . post ( `${ postEndpoint } ?dev=true` )
224+ . set ( "authorization" , `Bearer ${ botToken } ` )
225+ . send ( body )
226+ . end ( ( err , res ) => {
227+ if ( err ) return done ( err ) ;
228+ expect ( res . statusCode ) . to . equal ( 400 ) ;
229+ expect ( res . body . error ) . to . equal ( "Bad Request" ) ;
230+ expect ( res . body . message ) . to . equal ( REQUEST_ALREADY_PENDING ) ;
231+ done ( ) ;
232+ } )
233+ } )
234+
235+ it ( "should return 201 for successful response when user has onboarding state" , ( done ) => {
236+ createUserStatusWithState ( testUserId , userStatusModel , userState . ONBOARDING ) ;
237+ chai . request ( app )
238+ . post ( `${ postEndpoint } ?dev=true` )
239+ . set ( "authorization" , `Bearer ${ botToken } ` )
240+ . send ( body )
241+ . end ( ( err , res ) => {
242+ if ( err ) return done ( err ) ;
243+ expect ( res . statusCode ) . to . equal ( 201 ) ;
244+ expect ( res . body . message ) . to . equal ( ONBOARDING_REQUEST_CREATED_SUCCESSFULLY ) ;
245+ expect ( res . body . data . requestNumber ) . to . equal ( 1 ) ;
246+ expect ( res . body . data . reason ) . to . equal ( body . reason ) ;
247+ expect ( res . body . data . state ) . to . equal ( REQUEST_STATE . PENDING ) ;
248+ done ( ) ;
249+ } )
250+ } )
251+
252+ it ( "should return 201 response when previous latest extension request is approved" , async ( ) => {
253+ createUserStatusWithState ( testUserId , userStatusModel , userState . ONBOARDING ) ;
254+ const latestApprovedExtension = await requestsQuery . createRequest ( {
255+ ...extensionRequest ,
256+ userId : testUserId ,
257+ state : REQUEST_STATE . APPROVED ,
258+ newEndsOn : Date . now ( ) + 2 * 24 * 60 * 60 * 1000 ,
259+ oldEndsOn : Date . now ( ) - 24 * 60 * 60 * 1000 ,
260+ } ) ;
261+
262+ const res = await chai . request ( app )
263+ . post ( `${ postEndpoint } ?dev=true` )
264+ . set ( "authorization" , `Bearer ${ botToken } ` )
265+ . send ( body ) ;
266+
267+ expect ( res . statusCode ) . to . equal ( 201 ) ;
268+ expect ( res . body . message ) . to . equal ( ONBOARDING_REQUEST_CREATED_SUCCESSFULLY ) ;
269+ expect ( res . body . data . requestNumber ) . to . equal ( 2 ) ;
270+ expect ( res . body . data . reason ) . to . equal ( body . reason ) ;
271+ expect ( res . body . data . state ) . to . equal ( REQUEST_STATE . PENDING ) ;
272+ expect ( res . body . data . oldEndsOn ) . to . equal ( latestApprovedExtension . newEndsOn ) ;
273+ expect ( res . body . data . newEndsOn ) . to . equal ( latestApprovedExtension . newEndsOn + ( body . numberOfDays * 24 * 60 * 60 * 1000 ) ) ;
274+ } )
275+
276+ it ( "should return 201 response when previous latest extension request is rejected" , async ( ) => {
277+ createUserStatusWithState ( testUserId , userStatusModel , userState . ONBOARDING ) ;
278+ const currentDate = Date . now ( ) ;
279+ const latestRejectedExtension = await requestsQuery . createRequest ( {
280+ ...extensionRequest ,
281+ state : REQUEST_STATE . REJECTED ,
282+ userId : testUserId ,
283+ newEndsOn : currentDate ,
284+ oldEndsOn : currentDate - 24 * 60 * 60 * 1000 ,
285+ } ) ;
286+
287+ const res = await chai . request ( app )
288+ . post ( `${ postEndpoint } ?dev=true` )
289+ . set ( "authorization" , `Bearer ${ botToken } ` )
290+ . send ( body ) ;
291+
292+ expect ( res . statusCode ) . to . equal ( 201 ) ;
293+ expect ( res . body . message ) . to . equal ( ONBOARDING_REQUEST_CREATED_SUCCESSFULLY ) ;
294+ expect ( res . body . data . requestNumber ) . to . equal ( 2 ) ;
295+ expect ( res . body . data . reason ) . to . equal ( body . reason ) ; ;
296+ expect ( res . body . data . state ) . to . equal ( REQUEST_STATE . PENDING ) ;
297+ expect ( res . body . data . oldEndsOn ) . to . equal ( latestRejectedExtension . oldEndsOn ) ;
298+ expect ( new Date ( res . body . data . newEndsOn ) . toDateString ( ) )
299+ . to . equal ( new Date ( currentDate + ( body . numberOfDays * 24 * 60 * 60 * 1000 ) ) . toDateString ( ) ) ;
300+ } )
301+ } )
302+ } ) ;
0 commit comments