text: const dotenv = require('dotenv');
  dotenv.config();
  process.env.NODE_ENV = 'test';
  const request = require('supertest');
  const db = require('../../config/dbConnection');
  const app = require('../../app.js');
  const authConstant = require('../../constants/authConstant');
  const routes = require('../../routes');
  app.use(routes);
  
  beforeAll(async function () {
    await db.sync({});
  });
  
  afterAll(async function (){
    await db.dropAllSchemas();
    await db.drop();
    await db.close();
  });
  
  describe('POST /register -> if email and username is given', () => {
    test('should register a user', async () => {
      let registeredUser = await request(app)
        .post('/admin/auth/register')
        .send({
          'username':'Destini92',
          'password':'btTd0mHyECO4Jvs',
          'email':'Kaya.Swaniawski@hotmail.com',
          'name':'Tommie Christiansen',
          'mobileNo':'1-399-431-0238 x30408',
          'role':authConstant.USER_ROLE.Admin
        });
      expect(registeredUser.headers['content-type']).toEqual('application/json; charset=utf-8');
      expect(registeredUser.body.status).toBe('SUCCESS');
      expect(registeredUser.body.data).toMatchObject({ id: expect.any(Number) });
      expect(registeredUser.statusCode).toBe(200);
    });
  });
  
  describe('POST /login -> if username and password is correct', () => {
    test('should return user with authentication token', async () => {
      let user = await request(app)
        .post('/admin/auth/login')
        .send(
          {
            username: 'Kaya.Swaniawski@hotmail.com',
            password: 'btTd0mHyECO4Jvs'
          }
        );
      expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');
      expect(user.body.status).toBe('SUCCESS');
      expect(user.body.data).toMatchObject({
        id: expect.any(Number),
        token: expect.any(String)
      }); 
      expect(user.statusCode).toBe(200);
    });
  });
  
  describe('POST /login -> if username is incorrect', () => {
    test('should return unauthorized status and user not exists', async () => {
      let user = await request(app)
        .post('/admin/auth/login')
        .send(
          {
            username: 'wrong.username',
            password: 'btTd0mHyECO4Jvs'
          }
        );
  
      expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');
      expect(user.body.status).toBe('BAD_REQUEST');
      expect(user.statusCode).toBe(400);
    });
  });
  
  describe('POST /login -> if password is incorrect', () => {
    test('should return unauthorized status and incorrect password', async () => {
      let user = await request(app)
        .post('/admin/auth/login')
        .send(
          {
            username: 'Kaya.Swaniawski@hotmail.com',
            password: 'wrong@password'
          }
        );
  
      expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');
      expect(user.body.status).toBe('BAD_REQUEST');
      expect(user.statusCode).toBe(400);
    });
  });
  
  describe('POST /login -> if username or password is empty string or has not passed in body', () => {
    test('should return bad request status and insufficient parameters', async () => {
      let user = await request(app)
        .post('/admin/auth/login')
        .send({});
  
      expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');
      expect(user.body.status).toBe('BAD_REQUEST');
      expect(user.body.message).toBe('Insufficient parameters');
      expect(user.statusCode).toBe(400);
    });
  });
  
  describe('POST /forgot-password -> if email has not passed from request body', () => {
    test('should return bad request status and insufficient parameters', async () => {
      let user = await request(app)
        .post('/admin/auth/forgot-password')
        .send({ email: '' });
  
      expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');
      expect(user.body.status).toBe('BAD_REQUEST');
      expect(user.body.message).toBe('Insufficient parameters');
      expect(user.statusCode).toBe(400);
    });
  });
  
  describe('POST /forgot-password -> if email passed from request body is not available in database', () => {
    test('should return record not found status', async () => {
      let user = await request(app)
        .post('/admin/auth/forgot-password')
        .send({ 'email': 'unavailable.email@hotmail.com', });
  
      expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');
      expect(user.body.status).toBe('RECORD_NOT_FOUND');
      expect(user.body.message).toBe('Record not found with specified criteria.');
      expect(user.statusCode).toBe(200);
    });
  });
  
  describe('POST /forgot-password -> if email passed from request body is valid and OTP sent successfully', () => {
    test('should return success message', async () => {
      const expectedOutputMessages = [
        'otp successfully send.',
        'otp successfully send to your email.',
        'otp successfully send to your mobile number.'
      ];
      let user = await request(app)
        .post('/admin/auth/forgot-password')
        .send({ 'email':'Kaya.Swaniawski@hotmail.com', });
  
      expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');
      expect(user.body.status).toBe('SUCCESS');
      expect(expectedOutputMessages).toContain(user.body.message);
      expect(user.statusCode).toBe(200);
    });
  });
  
  describe('POST /validate-otp -> otp is sent in request body and OTP is correct', () => {
    test('should return success', () => {
      return request(app)
        .post('/admin/auth/login')
        .send(
          {
            username: 'Kaya.Swaniawski@hotmail.com',
            password: 'btTd0mHyECO4Jvs'
          }).then(login => () => {
          return request(app)
            .get(`/admin/user/${login.body.data.id}`)
            .set({
              Accept: 'application/json',
              Authorization: `Bearer ${login.body.data.token}`
            }).then(foundUser => {
              return request(app)
                .post('/admin/auth/validate-otp')
                .send({ 'otp': foundUser.body.data.resetPasswordLink.code, }).then(user => {
                  expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');
                  expect(user.body.status).toBe('SUCCESS');
                  expect(user.statusCode).toBe(200);
                });
            });
        });
    });
  });
  
  describe('POST /validate-otp -> if OTP is incorrect or OTP has expired', () => {
    test('should return invalid OTP', async () => {
      let user = await request(app)
        .post('/admin/auth/validate-otp')
        .send({ 'otp': '12334' });
      expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');
      expect(user.body.status).toBe('FAILURE');
      expect(user.statusCode).toBe(200);
      expect(user.body.message).toBe('Invalid OTP');
    });
  });
  
  describe('POST /validate-otp -> if request body is empty or otp has not been sent in body', () => {
    test('should return insufficient parameter', async () => {
      let user = await request(app)
        .post('/admin/auth/validate-otp')
        .send({});
  
      expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');
      expect(user.body.status).toBe('BAD_REQUEST');
      expect(user.statusCode).toBe(400);
    });
  });
  
  describe('PUT /reset-password -> code is sent in request body and code is correct', () => {
    test('should return success', () => {
      return request(app)
        .post('/admin/auth/login')
        .send(
          {
            username: 'Kaya.Swaniawski@hotmail.com',
            password: 'btTd0mHyECO4Jvs'
          }).then(login => () => {
          return request(app)
            .get(`/admin/user/${login.body.data.id}`)
            .set({
              Accept: 'application/json',
              Authorization: `Bearer ${login.body.data.token}`
            }).then(foundUser => {
              return request(app)
                .put('/admin/auth/validate-otp')
                .send({
                  'code': foundUser.body.data.resetPasswordLink.code,
                  'newPassword':'newPassword'
                }).then(user => {
                  expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');
                  expect(user.body.status).toBe('SUCCESS');
                  expect(user.statusCode).toBe(200);
                });
            });
        });
    });
  });
  
  describe('PUT /reset-password -> if request body is empty or code/newPassword is not given', () => {
    test('should return insufficient parameter', async () => {
      let user = await request(app)
        .put('/admin/auth/reset-password')
        .send({});
  
      expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');
      expect(user.body.status).toBe('BAD_REQUEST');
      expect(user.statusCode).toBe(400);
    });
  });
  
  describe('PUT /reset-password -> if code is invalid', () => {
    test('should return invalid code', async () => {
      let user = await request(app)
        .put('/admin/auth/reset-password')
        .send({
          'code': '123',
          'newPassword': 'testPassword'
        });
  
      expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');
      expect(user.body.status).toBe('FAILURE');
      expect(user.body.message).toBe('Invalid Code');
      expect(user.statusCode).toBe(200);
    });
  });
  