import { JwtModule } from '@nestjs/jwt';
import { getModelToken } from '@nestjs/mongoose';
import { PassportModule } from '@nestjs/passport';
import { Test, TestingModule } from '@nestjs/testing';
import { AuthServiceMock } from '../../test/mock/services/auth.mock.service';
import { ConfigurationModule } from '../configuration/configuration.module';
import { MailerModule } from '../mailer/mailer.module';
import { User } from '../users/schemas/user.schema';
import { UsersService } from '../users/services/users.service';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { LoginDto } from './login-dto';

describe('AuthController', () => {
  let controller: AuthController;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      imports: [
        PassportModule,
        MailerModule,
        ConfigurationModule,
        JwtModule.register({
          secret: process.env.JWT_SECRET,
          signOptions: { expiresIn: '86400s' }, // 24h validity
        }),
      ],
      controllers: [AuthController],
      providers: [
        AuthService,
        UsersService,
        {
          provide: AuthService,
          useClass: AuthServiceMock,
        },
        {
          provide: getModelToken('User'),
          useValue: User,
        },
      ],
    }).compile();

    controller = module.get<AuthController>(AuthController);
  });

  it('should be defined', () => {
    expect(controller).toBeDefined();
  });

  it('should login valid user', async () => {
    const loginCredentials: LoginDto = { email: 'paula.dubois@mii.com', password: process.env.USER_PWD };
    const result = await controller.login(loginCredentials);
    expect(result).toStrictEqual({
      _id: 'tsfsf6296',
      email: 'pauline.dupont@mii.com',
      emailVerified: true,
      name: 'DUBOIS',
      password: '$2a$12$vLQjJ9zAWyUwiFLeQDa6w.XzrlgPBhw.2GWrjog/yuEjIaZnQwmZu',
      role: 0,
      surname: 'Paula',
      validationToken:
        'cf1c74c22cedb6b575945098db42d2f493fb759c9142c6aff7980f252886f36ee086574ee99a06bc99119079257116c959c8ec870949cebdef2b293666dbca42',
    });
  });

  it('should not login invalid user', async () => {
    const loginCredentials: LoginDto = { email: 'jacques.dupont@mii.com', password: process.env.USER_PWD };
    try {
      await controller.login(loginCredentials);
    } catch (e) {
      expect(e.response).toBe('Invalid credentials');
      expect(e.message).toBe('Invalid credentials');
      expect(e.status).toBe(401);
    }
  });
});