import { mockedAccessToken, mockedLoginData, mockedRefreshToken } from '../../mocks/data';
import { fetchFreshToken, fetchToken, getFreshToken, getToken } from '../auth';
import { APIErrorType } from '../index';

describe('getToken function', () => {
  test('successful get token', async () => {
    const response = await getToken();

    expect(response).toBeDefined();
    expect(response).toBe(mockedAccessToken);
  });
});

describe('getFreshToken function', () => {
  test('successful get fresh token', async () => {
    const response = await getFreshToken();
    expect(response).toBeDefined();
    expect(response).toBe(mockedAccessToken);
  });
});

describe('fetch token api', () => {
  test('successful fetch token', async () => {
    const response = await fetchToken(mockedLoginData);

    expect(response).toBeDefined();
    expect(response).toMatchObject({ access: mockedAccessToken });
    expect(response).toMatchObject({ refresh: mockedRefreshToken });
  });

  test('failure fetch token', async () => {
    const { mobile, password } = mockedLoginData;
    try {
      await fetchToken({ mobile, password: password.substring(1) });
      // Fail test if above expression doesn't throw anything.
      expect(true).toBe(false);
    } catch (e) {
      const error = e as APIErrorType;
      expect(error.status).toBe(400);
    }
  });
});

describe('fetch fresh token api', () => {
  test('successful fetch fresh token', async () => {
    const response = await fetchFreshToken(mockedRefreshToken);
    expect(response).toBeDefined();
    expect(response).toMatchObject({ access: mockedAccessToken });
  });

  test('failure fetch fresh token', async () => {
    try {
      await fetchFreshToken(mockedRefreshToken.substring(1));
      // Fail test if above expression doesn't throw anything.
      expect(true).toBe(false);
    } catch (e) {
      const error = e as APIErrorType;
      expect(error.status).toBe(400);
    }
  });
});
