"use strict";

var _hubJobClient = require("../hubJobClient");
var _types = require("@wix/bex-utils/@wix/ambassador-hub-v1-job/types");
// Mock the SDK http factories so each returns an identifiable descriptor; the
// mocked httpClient then routes on `__fn` and we can assert the payloads.
jest.mock('@wix/bex-utils/@wix/ambassador-hub-v1-job/http', () => ({
  createFileUploadUrl: jest.fn(payload => ({
    __fn: 'createFileUploadUrl',
    payload
  })),
  submitJob: jest.fn(payload => ({
    __fn: 'submitJob',
    payload
  })),
  getJob: jest.fn(payload => ({
    __fn: 'getJob',
    payload
  })),
  terminateJob: jest.fn(payload => ({
    __fn: 'terminateJob',
    payload
  })),
  listMovementLogs: jest.fn(payload => ({
    __fn: 'listMovementLogs',
    payload
  }))
}));
const RESPONSES = {
  createFileUploadUrl: {
    uploadUrl: 'https://upload.example/abc',
    fileId: 'file-1'
  },
  submitJob: {
    job: {
      id: 'job-1'
    }
  },
  getJob: {
    job: {
      id: 'job-1',
      status: 'IN_PROGRESS'
    }
  },
  terminateJob: {},
  listMovementLogs: {
    logs: [{
      sourceItemId: '3'
    }]
  }
};
function makeDeps() {
  // Routes RPC factories on `__fn`; the file upload comes in as a raw request
  // config (no `__fn`) and just needs to resolve.
  const request = jest.fn(async req => ({
    data: '__fn' in req ? RESPONSES[req.__fn] : {},
    status: 200,
    statusText: 'OK',
    headers: {}
  }));
  const httpClient = {
    request
  };
  const withErrorHandler = jest.fn(fn => fn());
  const errorHandler = {
    withErrorHandler
  };
  return {
    httpClient,
    errorHandler,
    request
  };
}
describe('hubJobClient', () => {
  let client;
  let request;
  beforeEach(() => {
    const deps = makeDeps();
    request = deps.request;
    client = (0, _hubJobClient.createHubJobClient)(deps);
  });
  describe('uploadFile', () => {
    const file = new File(['a,b\n1,2'], 'data.csv', {
      type: 'text/csv'
    });
    it('reserves an upload url, PUTs the file, and returns the fileId', async () => {
      const fileId = await client.uploadFile(file);
      expect(fileId).toBe('file-1');
      // createFileUploadUrl called with the file name
      expect(request).toHaveBeenCalledWith(expect.objectContaining({
        __fn: 'createFileUploadUrl',
        payload: {
          fileName: 'data.csv'
        }
      }));
      // PUT the file to the returned signed url via httpClient.request
      expect(request).toHaveBeenCalledWith({
        url: 'https://upload.example/abc',
        method: 'PUT',
        data: file
      });
    });
    it('rejects when the upload PUT fails (client throws on non-2xx)', async () => {
      request.mockImplementation(async req => {
        if (req.method === 'PUT') {
          throw new Error('Request failed with status code 500');
        }
        return {
          data: RESPONSES[req.__fn],
          status: 200,
          statusText: 'OK',
          headers: {}
        };
      });
      await expect(client.uploadFile(file)).rejects.toThrow('Request failed with status code 500');
    });
  });
  describe('submitImportJob', () => {
    const destination = {
      wixDataCollection: {
        collectionId: 'Movies'
      }
    };
    it('returns the job id and sends a CSV file source with the destination', async () => {
      const jobId = await client.submitImportJob({
        fileId: 'file-1',
        destination,
        name: 'data.csv'
      });
      expect(jobId).toBe('job-1');
      expect(request).toHaveBeenCalledWith(expect.objectContaining({
        __fn: 'submitJob',
        payload: expect.objectContaining({
          name: 'data.csv',
          source: {
            file: {
              fileId: 'file-1',
              format: _types.FileFormat.CSV
            }
          },
          destination
        })
      }));
    });
    it('throws when no job id is returned', async () => {
      RESPONSES.submitJob = {
        job: {}
      };
      await expect(client.submitImportJob({
        fileId: 'file-1',
        destination
      })).rejects.toThrow('submitJob returned no job id');
      RESPONSES.submitJob = {
        job: {
          id: 'job-1'
        }
      };
    });
  });
  describe('getJob', () => {
    it('returns the job', async () => {
      const job = await client.getJob('job-1');
      expect(job).toEqual({
        id: 'job-1',
        status: 'IN_PROGRESS'
      });
      expect(request).toHaveBeenCalledWith(expect.objectContaining({
        __fn: 'getJob',
        payload: {
          jobId: 'job-1'
        }
      }));
    });
  });
  describe('terminateJob', () => {
    it('requests termination by job id', async () => {
      await client.terminateJob('job-1');
      expect(request).toHaveBeenCalledWith(expect.objectContaining({
        __fn: 'terminateJob',
        payload: {
          jobId: 'job-1'
        }
      }));
    });
  });
  describe('listMovementLogs', () => {
    it('returns the logs response', async () => {
      const res = await client.listMovementLogs('job-1');
      expect(res.logs).toEqual([{
        sourceItemId: '3'
      }]);
    });
    it('passes paging when provided', async () => {
      await client.listMovementLogs('job-1', {
        limit: 50
      });
      expect(request).toHaveBeenCalledWith(expect.objectContaining({
        __fn: 'listMovementLogs',
        payload: {
          jobId: 'job-1',
          paging: {
            limit: 50
          }
        }
      }));
    });
  });
});
//# sourceMappingURL=hubJobClient.spec.js.map