import { postData } from '.';
import { ResponseError } from './postData';

const HTTPOPTIONS = { url: 'a-url' };
const DATA = 'some-data';

describe('postData', () => {
  afterEach(() => {
    (global.fetch as jest.Mock).mockClear();
  });

  it('should work with resolve', async () => {
    const RESOLVE_RESPONSE = new Response();
    jest.spyOn(global, 'fetch').mockImplementation(async () => RESOLVE_RESPONSE);

    await expect(postData(HTTPOPTIONS, DATA)).resolves.toBe(RESOLVE_RESPONSE);
  });

  it('should throw when call fails', async () => {
    const REJECT_RESPONSE = new ResponseError(
      new Response(null, { status: 500, statusText: 'Rejected' }),
    );
    jest.spyOn(global, 'fetch').mockImplementation(async () => {
      throw REJECT_RESPONSE;
    });

    await expect(postData(HTTPOPTIONS, DATA)).rejects.toThrow(REJECT_RESPONSE);
  });

  it('should throw an Error when API returns an error code', async () => {
    const ERROR_RESPONSE = new Response(null, { status: 500, statusText: 'Internal server error' });
    jest.spyOn(global, 'fetch').mockImplementation(async () => ERROR_RESPONSE);

    await expect(postData(HTTPOPTIONS, DATA)).rejects.toThrow();
  });

  it('should pass additional form data to request body', async () => {
    const mockFetch = jest.fn(async () => new Response());
    jest.spyOn(global, 'fetch').mockImplementation(mockFetch);

    const data = new FormData();
    data.append('file', 'file');
    data.append('profileId', '1');
    await postData(HTTPOPTIONS, data);

    expect(mockFetch).toHaveBeenCalledWith('a-url', { method: 'POST', body: data });
  });

  it('should override `Content-type` and add any custom headers to the request', async () => {
    const mockFetch = jest.fn(async () => new Response());
    jest.spyOn(global, 'fetch').mockImplementation(mockFetch);

    const headers: HeadersInit = {
      'Content-type': 'foo',
      'Accept-language': 'hu',
    };
    await postData({ ...HTTPOPTIONS, headers }, DATA);

    expect(mockFetch).toHaveBeenCalledWith('a-url', {
      method: 'POST',
      headers,
      body: DATA,
    });
  });
});
