/* eslint global-require: 0 */

describe('rubygems.js', () => {
  beforeEach(() => {
    jest.resetAllMocks();
    jest.resetModules();
  });

  describe('search', () => {
    let got;
    let rubygems;
    let cache;

    const result = require('../__mocks__/result.json')[0];
    const mockResult = {
      title: result.name,
      value: result.project_uri,
      subtitle: result.info,
    };

    beforeEach(() => {
      jest.mock('got');
      got = require('got');

      jest.mock('cache-conf');
      cache = { get: jest.fn(), isExpired: jest.fn(), set: jest.fn() };
      require('cache-conf').mockImplementation(() => (cache));

      rubygems = require('../src/rubygems');

      got.mockImplementation(() => new Promise(resolve => resolve({
        body: require('../__mocks__/result.json'),
      })));
    });

    test('call got with url and options', () => (
      rubygems.search('middleman-google-analytics')
        .then(() => {
          expect(got).toHaveBeenCalledWith(
            'https://rubygems.org/api/v1/search.json',
            {
              json: true,
              query: {
                query: 'middleman-google-analytics',
              },
            },
          );
        })
    ));

    test('returns an array', () => (
      rubygems.search('middleman-google-analytics')
        .then((packages) => {
          expect(packages).toBeInstanceOf(Array);
        })
      ));

    test('returns the expected title', () => (
      rubygems.search('middleman-google-analytics')
        .then((packages) => {
          expect(packages[0].title).toBe(mockResult.title);
        })
      ));

    test('returns the expected value', () => (
      rubygems.search('middleman-google-analytics')
        .then((packages) => {
          expect(packages[0].value).toBe(mockResult.value);
        })
      ));

    test('returns the expected subtitle', () => (
      rubygems.search('middleman-google-analytics')
        .then((packages) => {
          expect(packages[0].subtitle).toBe(mockResult.subtitle);
        })
    ));

    test('returns the expected error', () => {
      got.mockImplementation(() => new Promise((resolve, reject) => reject({
        response: {
          body: "Request is missing param 'query'",
        },
      })));

      return rubygems.search('middleman-google-analytics')
        .catch((packages) => {
          expect(packages.response.body).toBe("Request is missing param 'query'");
        });
    });

    test('call cache.get with the expected arguments', () => (
      rubygems.search('middleman-google-analytics')
        .then(() => {
          expect(cache.get).toBeCalledWith(
            'zazu-rubygems.middleman-google-analytics',
            { ignoreMaxAge: true },
          );
        })
    ));

    test('call cache.set with the expected arguments', () => (
      rubygems.search('middleman-google-analytics')
        .then(() => {
          expect(cache.set).toBeCalledWith(
            'zazu-rubygems.middleman-google-analytics',
            [mockResult],
            { maxAge: 3600000 },
          );
        })
    ));

    test('call cache.isExpired with the expected argument', () => {
      cache.get = jest.fn(() => ([mockResult]));

      return rubygems.search('middleman-google-analytics')
        .then(() => {
          expect(cache.isExpired).toBeCalledWith('zazu-rubygems.middleman-google-analytics');
        });
    });

    test('returns the cache result', () => {
      cache.isExpired = jest.fn(() => false);
      cache.get = jest.fn(() => ([mockResult]));

      return rubygems.search('middleman-google-analytics')
        .then((packages) => {
          expect(packages).toEqual([mockResult]);
        });
    });

    test('returns the cache result when an error occurs', () => {
      cache.isExpired = jest.fn(() => true);
      cache.get = jest.fn(() => ([mockResult]));
      got.mockImplementation(() => new Promise((resolve, reject) => reject()));

      return rubygems.search('middleman-google-analytics')
        .then((packages) => {
          expect(packages).toEqual([mockResult]);
        });
    });
  });

  describe('integration', () => {
    jest.mock('cache-conf');

    const rubygems = require('../src/rubygems');
    const searchResult = rubygems.search('middleman-google-analytics');

    test('returns an array', () => (
      searchResult.then((packages) => {
        expect(packages).toBeInstanceOf(Array);
      })
    ));

    test('returns an object with a title', () => (
      searchResult.then((packages) => {
        expect(packages[0].title).toBeDefined();
      })
    ));

    test('returns an object with a value', () => (
      searchResult.then((packages) => {
        expect(packages[0].value).toBeDefined();
      })
    ));

    test('returns an object with a subtitle', () => (
      searchResult.then((packages) => {
        expect(packages[0].subtitle).toBeDefined();
      })
    ));
  });
});

@@ -294,18 +294,19 @@
 esult = 
+%5B
 %7B%0A
-
       ti
@@ -390,16 +390,17 @@
 o,%0A    %7D
+%5D
 ;%0A%0A    b
@@ -1598,16 +1598,19 @@
 ckResult
+%5B0%5D
 .title);
@@ -1812,16 +1812,19 @@
 ckResult
+%5B0%5D
 .value);
@@ -2032,16 +2032,19 @@
 ckResult
+%5B0%5D
 .subtitl
@@ -3036,17 +3036,16 @@
         
-%5B
 mockResu
@@ -3046,17 +3046,16 @@
 ckResult
-%5D
 ,%0A      
@@ -3207,33 +3207,32 @@
  jest.fn(() =%3E (
-%5B
 mockResult%5D));%0A%0A
@@ -3217,33 +3217,32 @@
 ) =%3E (mockResult
-%5D
 ));%0A%0A      retur
@@ -3542,33 +3542,32 @@
  jest.fn(() =%3E (
-%5B
 mockResult%5D));%0A%0A
@@ -3556,25 +3556,24 @@
  (mockResult
-%5D
 ));%0A%0A      r
@@ -3681,33 +3681,32 @@
 ckages).toEqual(
-%5B
 mockResult%5D);%0A  
@@ -3691,33 +3691,32 @@
 Equal(mockResult
-%5D
 );%0A        %7D);%0A 
@@ -3867,17 +3867,16 @@
 (() =%3E (
-%5B
 mockResu
@@ -3877,17 +3877,16 @@
 ckResult
-%5D
 ));%0A    
@@ -4086,17 +4086,16 @@
 toEqual(
-%5B
 mockResu
@@ -4096,17 +4096,16 @@
 ckResult
-%5D
 );%0A     

Simplify code. Change the type of mockResult