import { buildRights , IUser , KYCStatus , Role , UserStatus , UserRegistrationData , EmailConfirmationResponse } from '@energyweb/origin-backend-core' ; import { HttpStatus , INestApplication } from '@nestjs/common' ; import { expect } from 'chai' ; import request from 'supertest' ; import { DatabaseService } from '@energyweb/origin-backend-utils' ; import { bootstrapTestInstance , registerAndLogin } from './origin-backend' ; import { omit } from './utils' ; import { UserService } from '../src/pods/user/user.service' ; import { OrganizationService } from '../src/pods/organization/organization.service' ; import { EmailConfirmationService } from '../src/pods/email-confirmation/email-confirmation.service' ; export const userToRegister = { title : 'Mr' , firstName : 'John' , lastName : 'Rambo' , email : 'john@example.com' , password : 'FirstBlood2' , telephone : '+11' } ; describe ( 'User e2e tests' , ( ) => { let app ; let databaseService ; let userService ; let organizationService ; let emailConfirmationService ; before ( async ( ) => { ( { app , databaseService , userService , organizationService , emailConfirmationService } = await bootstrapTestInstance ( ) ) ; await app . init ( ) ; } ) ; beforeEach ( async ( ) => { await databaseService . truncate ( 'user' , 'organization' , 'email_confirmation' ) ; } ) ; after ( async ( ) => { await app . close ( ) ; } ) ; it ( 'should be able to register user' , async ( ) => { await request ( app . getHttpServer ( ) ) . post ( `/user/register` ) . send ( userToRegister ) . expect ( ( res ) => { const user = res . body as IUser ; expect ( user . email ) . equals ( userToRegister . email ) ; expect ( user . organization ) . to . be . undefined ; expect ( user . rights ) . equals ( buildRights ( [ Role . OrganizationAdmin ] ) ) ; expect ( user . status ) . equals ( UserStatus . Pending ) ; expect ( user . kycStatus ) . equals ( KYCStatus . Pending ) ; expect ( ( user as any ) . password ) . to . be . undefined ; } ) ; let accessToken ; await request ( app . getHttpServer ( ) ) . post ( '/auth/login' ) . send ( { username : userToRegister . email , password : userToRegister . password } ) . expect ( ( res ) => ( { accessToken } = res . body ) ) ; const registeredUser = await userService . findOne ( { email : userToRegister . email } ) ; registeredUser . status = UserStatus . Active ; await userService . update ( registeredUser . id , registeredUser ) ; await request ( app . getHttpServer ( ) ) . get ( `/user/me` ) . set ( 'Authorization' , `Bearer ${ accessToken }` ) . expect ( ( res ) => { const user = res . body as IUser ; expect ( user . email ) . equals ( userToRegister . email ) ; } ) ; } ) ; it ( 'should not be able to register user with password which doesn`t match requirements' , async ( ) => { const newUserToRegister = { ... userToRegister , password : 'test' } ; await request ( app . getHttpServer ( ) ) . post ( `/user/register` ) . send ( newUserToRegister ) . expect ( HttpStatus . BAD_REQUEST ) ; } ) ; it ( 'should not be able to register user with the same email' , async ( ) => { await request ( app . getHttpServer ( ) ) . post ( `/user/register` ) . send ( userToRegister ) . expect ( HttpStatus . CREATED ) ; const otherUserWithSameEmail = { ... userToRegister , firstName : 'Samuel' , lastName : 'Trautman' } ; await request ( app . getHttpServer ( ) ) . post ( `/user/register` ) . send ( otherUserWithSameEmail ) . expect ( HttpStatus . CONFLICT ) ; } ) ; it ( 'should not be able to register user with missing input data' , async ( ) => { await request ( app . getHttpServer ( ) ) . post ( `/user/register` ) . send ( omit ( userToRegister , 'password' ) ) . expect ( HttpStatus . BAD_REQUEST ) ; } ) ; it ( 'user should be able to get his user data' , async ( ) => { const { accessToken , user } = await registerAndLogin ( app , userService , organizationService , [ Role . OrganizationUser , Role . OrganizationDeviceManager ] ) ; await request ( app . getHttpServer ( ) ) . get ( `/user/${ user . id }` ) . set ( 'Authorization' , `Bearer ${ accessToken }` ) . expect ( HttpStatus . OK ) ; } ) ; it ( 'user should not be able to get user data of another user' , async ( ) => { const { user } = await registerAndLogin ( app , userService , organizationService , [ Role . OrganizationUser , Role . OrganizationDeviceManager ] ) ; const { accessToken : accessToken2 } = await registerAndLogin ( app , userService , organizationService , [ Role . OrganizationUser , Role . OrganizationDeviceManager ] , 'differentOrganization' , 'differentOrganization' ) ; await request ( app . getHttpServer ( ) ) . get ( `/user/${ user . id }` ) . set ( 'Authorization' , `Bearer ${ accessToken2 }` ) . expect ( HttpStatus . UNAUTHORIZED ) ; } ) ; it ( 'admin/support agent should be able to get user data of another user' , async ( ) => { const { accessToken } = await registerAndLogin ( app , userService , organizationService , [ Role . Admin ] ) ; const { user } = await registerAndLogin ( app , userService , organizationService , [ Role . OrganizationUser , Role . OrganizationDeviceManager ] , 'differentOrganization' , 'differentOrganization' ) ; await request ( app . getHttpServer ( ) ) . get ( `/user/${ user . id }` ) . set ( 'Authorization' , `Bearer ${ accessToken }` ) . expect ( HttpStatus . OK ) ; } ) ; it ( 'org admin should be able to get user data of another user' , async ( ) => { const { accessToken } = await registerAndLogin ( app , userService , organizationService , [ Role . OrganizationAdmin ] ) ; const { user } = await registerAndLogin ( app , userService , organizationService , [ Role . OrganizationUser , Role . OrganizationDeviceManager ] ) ; await request ( app . getHttpServer ( ) ) . get ( `/user/${ user . id }` ) . set ( 'Authorization' , `Bearer ${ accessToken }` ) . expect ( HttpStatus . OK ) ; } ) ; it ( 'org admin should not be able to get user data from another organization' , async ( ) => { const { accessToken } = await registerAndLogin ( app , userService , organizationService , [ Role . OrganizationAdmin ] ) ; const { user } = await registerAndLogin ( app , userService , organizationService , [ Role . OrganizationUser , Role . OrganizationDeviceManager ] , 'differentOrganization' , 'differentOrganization' ) ; await request ( app . getHttpServer ( ) ) . get ( `/user/${ user . id }` ) . set ( 'Authorization' , `Bearer ${ accessToken }` ) . expect ( HttpStatus . UNAUTHORIZED ) ; } ) ; it ( 'new user should have confirmation token set' , async ( ) => { const { user } = await registerAndLogin ( app , userService , organizationService , [ Role . OrganizationUser ] ) ; const { confirmed , token , expiryTimestamp } = await emailConfirmationService . get ( user . id ) ; expect ( confirmed ) . to . be . false ; expect ( token . length ) . to . equal ( 128 ) ; expect ( expiryTimestamp ) . to . be . above ( 0 ) ; } ) ; it ( 'user should be able to confirm email' , async ( ) => { const { user , accessToken } = await registerAndLogin ( app , userService , organizationService , [ Role . OrganizationUser ] ) ; const { token } = await emailConfirmationService . get ( user . id ) ; await request ( app . getHttpServer ( ) ) . get ( `/user/me` ) . set ( 'Authorization' , `Bearer ${ accessToken }` ) . expect ( ( res ) => { const { emailConfirmed } = res . body as IUser ; expect ( emailConfirmed ) . to . be . false ; } ) ; await request ( app . getHttpServer ( ) ) . put ( `/user/confirm-email/${ token }` ) . set ( 'Authorization' , `Bearer ${ accessToken }` ) . expect ( ( res ) => { const response = res . text as EmailConfirmationResponse ; expect ( response ) . equals ( EmailConfirmationResponse . Success ) ; } ) ; await request ( app . getHttpServer ( ) ) . get ( `/user/me` ) . set ( 'Authorization' , `Bearer ${ accessToken }` ) . expect ( ( res ) => { const { emailConfirmed } = res . body as IUser ; expect ( emailConfirmed ) . to . be . true ; } ) ; } ) ; it ( 'user should be able to re-request confirmation email' , async ( ) => { const { accessToken } = await registerAndLogin ( app , userService , organizationService , [ Role . OrganizationUser ] ) ; await request ( app . getHttpServer ( ) ) . put ( `/user/re-send-confirm-email` ) . set ( 'Authorization' , `Bearer ${ accessToken }` ) . expect ( HttpStatus . OK ) ; } ) ; it ( 'user should not be able to re-confirm confirmed email' , async ( ) => { const { user , accessToken } = await registerAndLogin ( app , userService , organizationService , [ Role . OrganizationUser ] ) ; const { token } = await emailConfirmationService . get ( user . id ) ; await request ( app . getHttpServer ( ) ) . put ( `/user/confirm-email/${ token }` ) . set ( 'Authorization' , `Bearer ${ accessToken }` ) . expect ( ( res ) => { const response = res . text as EmailConfirmationResponse ; expect ( response ) . equals ( EmailConfirmationResponse . Success ) ; } ) ; await request ( app . getHttpServer ( ) ) . put ( `/user/confirm-email/${ token }` ) . set ( 'Authorization' , `Bearer ${ accessToken }` ) . expect ( ( res ) => { const response = res . text as EmailConfirmationResponse ; expect ( response ) . equals ( EmailConfirmationResponse . AlreadyConfirmed ) ; } ) ; } ) ; } ) ;