Skip to content
Snippets Groups Projects
users.service.spec.ts 14.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • import { Test, TestingModule } from '@nestjs/testing';
    
    import { MailerModule } from '../mailer/mailer.module';
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    import { User } from './schemas/user.schema';
    
    import { UsersService } from './users.service';
    
    import { getModelToken } from '@nestjs/mongoose';
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    import { CreateUserDto } from './dto/create-user.dto';
    
    import { HttpException, HttpStatus } from '@nestjs/common';
    import { LoginDto } from '../auth/login-dto';
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    import { EmailChangeDto } from './dto/change-email.dto';
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    import * as bcrypt from 'bcrypt';
    
    import { ConfigurationModule } from '../configuration/configuration.module';
    
    import { IUser } from './interfaces/user.interface';
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    function hashPassword() {
      return bcrypt.hashSync(process.env.USER_PWD, process.env.SALT);
    }
    
    
    describe('UsersService', () => {
      let service: UsersService;
    
      beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
    
          imports: [MailerModule, ConfigurationModule],
    
          providers: [
            UsersService,
            {
              provide: getModelToken('User'),
              useValue: User,
            },
          ],
    
        }).compile();
    
        service = module.get<UsersService>(UsersService);
      });
    
    
      describe('User Service create', () => {
        it('UsersService should be defined', () => {
          expect(service).toBeDefined();
        });
    
        it('User should be created', async () => {
          const result: User = {
            role: 0,
            validationToken:
              'cf1c74c22cedb6b575945098db42d2f493fb759c9142c6aff7980f252886f36ee086574ee99a06bc99119079257116c959c8ec870949cebdef2b293666dbca42',
            emailVerified: false,
            email: 'jacques.dupont@mii.com',
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
            password: hashPassword(),
    
            newEmail: '',
            changeEmailToken: '',
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
            resetPasswordToken: null,
    
    Jérémie BRISON's avatar
    Jérémie BRISON committed
            structuresLink: [],
    
            structureOutdatedMailSent: [],
            pendingStructuresLink: [],
            name: 'Jacques',
            surname: 'Dupont',
            phone: '06 06 06 06 06',
    
          const userDto: CreateUserDto = {
            email: 'jacques.dupont@mii.com',
            password: 'test1A!!',
            name: 'Jacques',
            surname: 'Dupont',
            phone: '06 06 06 06 06',
          }; //NOSONAR
    
          jest.spyOn(service, 'create').mockImplementation(async (): Promise<User> => result);
          expect(await service.create(userDto)).toBe(result);
        });
    
        it('User should not be created, already exist', async () => {
          const result = new HttpException('User already exists', HttpStatus.BAD_REQUEST);
    
          const userDto: CreateUserDto = {
            email: 'jacques.dupont@mii.com',
            password: 'test1A!!',
            name: 'Jacques',
            surname: 'Dupont',
            phone: '06 06 06 06 06',
          }; //NOSONAR
    
          jest.spyOn(service, 'create').mockImplementation(async (): Promise<any> => result);
    
          expect(await service.create(userDto)).toBe(result);
        });
    
        it('User should not be created, weak password', async () => {
          const result = new HttpException(
    
            'Weak password, it must contain one lowercase alphabetical character, one uppercase alphabetical character, one numeric character, one special character and be eight characters or longer',
    
            HttpStatus.UNPROCESSABLE_ENTITY
          );
    
          const userDto: CreateUserDto = {
            email: 'jacques.dupont@mii.com',
            password: 'test',
            name: 'Jacques',
            surname: 'Dupont',
            phone: '06 06 06 06 06',
          }; //NOSONAR
    
          jest.spyOn(service, 'create').mockImplementation(async (): Promise<any> => result);
    
          expect(await service.create(userDto)).toBe(result);
        });
      });
    
      describe('findByLogin', () => {
        it('should find', async () => {
          const result = {
            validationToken:
              'cf1c74c22cedb6b575945098db42d2f493fb759c9142c6aff7980f252886f36ee086574ee99a06bc99119079257116c959c8ec870949cebdef2b293666dbca42',
            emailVerified: false,
            email: 'jacques.dupont@mii.com',
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
            password: hashPassword(),
    
            newEmail: '',
            changeEmailToken: '',
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
            resetPasswordToken: null,
    
    Jérémie BRISON's avatar
    Jérémie BRISON committed
            structuresLink: [],
    
            pendingStructuresLink: [],
            structureOutdatedMailSent: [],
            name: 'Jacques',
            surname: 'Dupont',
            phone: '06 06 06 06 06',
    
          const loginDto: LoginDto = { email: 'jacques.dupont@mii.com', password: 'test1A!!' }; //NOSONAR
    
          jest.spyOn(service, 'findByLogin').mockImplementation(async (): Promise<User> => result);
          expect(await service.findByLogin(loginDto)).toBe(result);
        });
    
        it('user does not exist, should be unauthorized issue', async () => {
          const result: HttpException = new HttpException('Invalid credentials', HttpStatus.UNAUTHORIZED);
    
          const loginDto: LoginDto = { email: 'jean.dupont@mii.com', password: 'test1A!!' }; //NOSONAR
    
          jest.spyOn(service, 'findByLogin').mockImplementation(async (): Promise<any> => result);
    
          expect(await service.findByLogin(loginDto)).toBe(result);
        });
    
        it('wrong password, should be unauthorized issue', async () => {
          const result: HttpException = new HttpException('Invalid credentials', HttpStatus.UNAUTHORIZED);
    
          const loginDto: LoginDto = { email: 'jacques.dupont@mii.com', password: 'test1A!!!' }; //NOSONAR
    
          jest.spyOn(service, 'findByLogin').mockImplementation(async (): Promise<any> => result);
    
          expect(await service.findByLogin(loginDto)).toBe(result);
        });
      });
    
      describe('validateUser', () => {
        it('should not validateUser', async () => {
          const result = new HttpException('Invalid token', HttpStatus.UNAUTHORIZED);
          jest.spyOn(service, 'validateUser').mockImplementation(async (): Promise<HttpException> => result);
          expect(await service.validateUser('add3d', 'qdqdqdqd185')).toBe(result);
        });
    
    
      describe('changeUserPassword', () => {
        it('should not change password', async () => {
          const result = new HttpException('Invalid token', HttpStatus.UNAUTHORIZED);
          jest.spyOn(service, 'changeUserPassword').mockImplementation(async (): Promise<HttpException> => result);
          expect(await service.changeUserPassword('add3d', 'azertyU1', 'azertyU1!d')).toBe(result);
        });
        it('should not change password', async () => {
          const result = new HttpException('Invalid token', HttpStatus.UNPROCESSABLE_ENTITY);
          jest.spyOn(service, 'changeUserPassword').mockImplementation(async (): Promise<HttpException> => result);
          expect(await service.changeUserPassword('add3d', 'azertyU1!d', 'a')).toBe(result);
        });
    
        it('should change password', async () => {
    
          const result = new HttpException('Invalid token', HttpStatus.CREATED);
          jest.spyOn(service, 'changeUserPassword').mockImplementation(async (): Promise<HttpException> => result);
          expect(await service.changeUserPassword('add3d', 'azertyU1!d', 'azertyU1!d')).toBe(result);
        });
      });
    
    
      describe('changeUserEmail', () => {
        it('should find and add token', async () => {
          const result = {
            validationToken: '',
            emailVerified: true,
            email: 'jacques.dupont@mii.com',
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
            password: hashPassword(),
    
            role: 0,
            newEmail: 'test.dupont@mail.com',
    
    Jérémie BRISON's avatar
    Jérémie BRISON committed
            structuresLink: [],
    
            pendingStructuresLink: [],
            structureOutdatedMailSent: [],
            name: 'Jacques',
            surname: 'Dupont',
            phone: '06 06 06 06 06',
    
            changeEmailToken:
              '9bb3542bdc5ca8801ad4cee00403c1052bc95dee768dcbb65b1f719870578ed79f71f52fdc3e6bf02fd200a72b8b6f56fc26950df30c8cd7e427a485f80181b9',
          };
          const emailDto: EmailChangeDto = { newEmail: 'test.dupont@mail.com', oldEmail: 'jacques.dupont@mii.com' }; //NOSONAR
          jest.spyOn(service, 'changeUserEmail').mockImplementation(async (): Promise<User> => result);
          expect(await service.changeUserEmail(emailDto)).toBe(result);
        });
        it('user does not exist, should be unauthorized issue', async () => {
          const result: HttpException = new HttpException('Email sent if account exist', HttpStatus.UNAUTHORIZED);
          const emailDto: EmailChangeDto = { newEmail: 'test.dupont@mail.com', oldEmail: 'jacques.dupont@mii.com' }; //NOSONAR
          jest.spyOn(service, 'changeUserEmail').mockImplementation(async (): Promise<any> => result);
          expect(await service.changeUserEmail(emailDto)).toBe(result);
        });
        it('email already used, should be not acceptable issue', async () => {
          const result: HttpException = new HttpException('Email already used', HttpStatus.NOT_ACCEPTABLE);
          const emailDto: EmailChangeDto = { newEmail: 'jacques.dupont@mii.com', oldEmail: 'jacques.dupont@mii.com' }; //NOSONAR
          jest.spyOn(service, 'changeUserEmail').mockImplementation(async (): Promise<any> => result);
          expect(await service.changeUserEmail(emailDto)).toBe(result);
        });
        it('should change email', async () => {
          const result = {
            validationToken: '',
            emailVerified: true,
            email: 'test.dupont@mail.com',
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
            password: hashPassword(),
    
            role: 0,
            newEmail: '',
    
            changeEmailToken: '',
    
    Jérémie BRISON's avatar
    Jérémie BRISON committed
            structuresLink: [],
    
            pendingStructuresLink: [],
            structureOutdatedMailSent: [],
            name: 'Jacques',
            surname: 'Dupont',
            phone: '06 06 06 06 06',
    
            '9bb3542bdc5ca8801ad4cee00403c1052bc95dee768dcbb65b1f719870578ed79f71f52fdc3e6bf02fd200a72b8b6f56fc26950df30c8cd7e427a485f80181b9'; //NOSONAR
          jest.spyOn(service, 'verifyAndUpdateUserEmail').mockImplementation(async (): Promise<User> => result);
          expect(await service.verifyAndUpdateUserEmail(token)).toBe(result);
        });
        it('should not change email', async () => {
          const result: HttpException = new HttpException('Invalid token', HttpStatus.UNAUTHORIZED);
    
          const token = '9bb3542bdc5ca8801aa72b8b6f56fc26950df30c8cd7e427a485f80181b9FAKETOKEN'; //NOSONAR
    
          jest.spyOn(service, 'verifyAndUpdateUserEmail').mockImplementation(async (): Promise<any> => result);
          expect(await service.verifyAndUpdateUserEmail(token)).toBe(result);
        });
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      describe('sendResetPasswordEmail', () => {
        it('should not send email', async () => {
          const result = new HttpException('Email sent if account exist', HttpStatus.OK);
          jest.spyOn(service, 'sendResetPasswordEmail').mockImplementation(async (): Promise<HttpException> => result);
          expect(await service.sendResetPasswordEmail('test@mii.com')).toBe(result);
        });
    
        it('should send email', async () => {
          const result = new HttpException('Email sent if account exist', HttpStatus.OK);
          jest.spyOn(service, 'sendResetPasswordEmail').mockImplementation(async (): Promise<HttpException> => result);
          expect(await service.sendResetPasswordEmail('test@mii.com')).toBe(result);
        });
      });
    
      describe('validatePasswordResetToken', () => {
        it('should not validate new password: token does`nt exist', async () => {
          const result = new HttpException('Invalid token', HttpStatus.UNAUTHORIZED);
          jest.spyOn(service, 'validatePasswordResetToken').mockImplementation(async (): Promise<HttpException> => result);
          expect(
            await service.validatePasswordResetToken(
              'test@mii.com',
              '5def4cb41106f89c212679e164911776618bd529e4f78e2883f7dd01776612a1b4a2ad7edabf2a3e3638aa605966c7a4b69d5f07d9617334e58332ba5f9305'
            )
          ).toBe(result);
        });
    
        it('should not validate new password: weak password', async () => {
          const result = new HttpException(
    
            'Weak password, it must contain one lowercase alphabetical character, one uppercase alphabetical character, one numeric character, one special character and be eight characters or longer',
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
            HttpStatus.UNPROCESSABLE_ENTITY
          );
          jest.spyOn(service, 'validatePasswordResetToken').mockImplementation(async (): Promise<HttpException> => result);
          expect(
            await service.validatePasswordResetToken(
              'test@mii.com',
              '5def4cb41106f89c212679e164911776618bd529e4f78e2883f7dd01776612a1b4a2ad7edabf2a3e3638aa605966c7a4b69d5f07d9617334e58332ba5f9305a6'
            )
          ).toBe(result);
        });
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        it('should validate new password', async () => {
          const result = new HttpException('Password Reset', HttpStatus.OK);
          jest.spyOn(service, 'validatePasswordResetToken').mockImplementation(async (): Promise<HttpException> => result);
          expect(
            await service.validatePasswordResetToken(
              'test@mii.com',
              '5def4cb41106f89c212679e164911776618bd529e4f78e2883f7dd01776612a1b4a2ad7edabf2a3e3638aa605966c7a4b69d5f07d9617334e58332ba5f9305a6'
            )
          ).toBe(result);
        });
    
    Jérémie BRISON's avatar
    Jérémie BRISON committed
    
        it('should return structureLink tab ', async () => {
          const result = [53];
          jest.spyOn(service, 'updateStructureLinked').mockImplementation(async (): Promise<any> => result);
    
          expect(await service.updateStructureLinked('test@mii.com', '6001a37716b08100062e4160')).toBe(result);
    
    Jérémie BRISON's avatar
    Jérémie BRISON committed
        });
    
        it('should return invalid User ', async () => {
          const result = new HttpException('Invalid user', HttpStatus.NOT_FOUND);
          jest.spyOn(service, 'updateStructureLinked').mockImplementation(async (): Promise<any> => result);
    
          expect(await service.updateStructureLinked('test@mii.com', '6001a37716b08100062e4160')).toBe(result);
    
    
      it('should find All Unattacheduser', async () => {
        const result = [
          {
            _id: '123',
            validationToken:
              'cf1c74c22cedb6b575945098db42d2f493fb759c9142c6aff7980f252886f36ee086574ee99a06bc99119079257116c959c8ec870949cebdef2b293666dbca42',
            emailVerified: false,
            email: 'jacques.dupont@mii.com',
            password: hashPassword(),
            role: 0,
            newEmail: '',
            changeEmailToken: '',
            resetPasswordToken: null,
            structuresLink: [],
            pendingStructuresLink: [],
            structureOutdatedMailSent: [],
            name: 'Jacques',
            surname: 'Dupont',
            phone: '06 06 06 06 06',
          } as IUser,
        ];
        jest.spyOn(service, 'findAllUnattached').mockImplementation(async (): Promise<IUser[]> => result);
        expect(await service.findAllUnattached()).toBe(result);
      });
    
      it('should find attached users', async () => {
        const result = [];
        jest.spyOn(service, 'findAllAttached').mockImplementation(async (): Promise<IUser[]> => result);
        expect((await service.findAllAttached()).length).toBe(0);
      });
    
      it('should find UnVerified Users', async () => {
        const result = [];
        jest.spyOn(service, 'findAllUnVerified').mockImplementation(async (): Promise<IUser[]> => result);
        expect((await service.findAllUnVerified()).length).toBe(0);
      });