/**
 * @license
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import '../../../../test/common-test-setup-karma.js';
import {SiteBasedCache, FetchPromisesCache, GrRestApiHelper} from './gr-rest-api-helper.js';
import {appContext} from '../../../../services/app-context.js';
import {stubAuth} from '../../../../test/test-utils.js';

suite('gr-rest-api-helper tests', () => {
  let helper;

  let cache;
  let fetchPromisesCache;
  let originalCanonicalPath;
  let authFetchStub;

  setup(() => {
    cache = new SiteBasedCache();
    fetchPromisesCache = new FetchPromisesCache();

    originalCanonicalPath = window.CANONICAL_PATH;
    window.CANONICAL_PATH = 'testhelper';

    const mockRestApiInterface = {
      fire: sinon.stub(),
    };

    const testJSON = ')]}\'\n{"hello": "bonjour"}';
    authFetchStub = stubAuth('fetch').returns(Promise.resolve({
      ok: true,
      text() {
        return Promise.resolve(testJSON);
      },
    }));

    helper = new GrRestApiHelper(cache, appContext.authService,
        fetchPromisesCache, mockRestApiInterface);
  });

  teardown(() => {
    window.CANONICAL_PATH = originalCanonicalPath;
  });

  suite('fetchJSON()', () => {
    test('Sets header to accept application/json', () => {
      helper.fetchJSON({url: '/dummy/url'});
      assert.isTrue(authFetchStub.called);
      assert.equal(authFetchStub.lastCall.args[1].headers.get('Accept'),
          'application/json');
    });

    test('Use header option accept when provided', () => {
      const headers = new Headers();
      headers.append('Accept', '*/*');
      const fetchOptions = {headers};
      helper.fetchJSON({url: '/dummy/url', fetchOptions});
      assert.isTrue(authFetchStub.called);
      assert.equal(authFetchStub.lastCall.args[1].headers.get('Accept'),
          '*/*');
    });
  });

  test('JSON prefix is properly removed',
      () => helper.fetchJSON({url: '/dummy/url'}).then(obj => {
        assert.deepEqual(obj, {hello: 'bonjour'});
      })
  );

  test('cached results', () => {
    let n = 0;
    sinon.stub(helper, 'fetchJSON').callsFake(() => Promise.resolve(++n));
    const promises = [];
    promises.push(helper.fetchCacheURL('/foo'));
    promises.push(helper.fetchCacheURL('/foo'));
    promises.push(helper.fetchCacheURL('/foo'));

    return Promise.all(promises).then(results => {
      assert.deepEqual(results, [1, 1, 1]);
      return helper.fetchCacheURL('/foo').then(foo => {
        assert.equal(foo, 1);
      });
    });
  });

  test('cached promise', () => {
    const promise = Promise.reject(new Error('foo'));
    cache.set('/foo', promise);
    return helper.fetchCacheURL({url: '/foo'}).catch(p => {
      assert.equal(p.message, 'foo');
    });
  });

  test('cache invalidation', () => {
    cache.set('/foo/bar', 1);
    cache.set('/bar', 2);
    fetchPromisesCache.set('/foo/bar', 3);
    fetchPromisesCache.set('/bar', 4);
    helper.invalidateFetchPromisesPrefix('/foo/');
    assert.isFalse(cache.has('/foo/bar'));
    assert.isTrue(cache.has('/bar'));
    assert.isUndefined(fetchPromisesCache.get('/foo/bar'));
    assert.strictEqual(4, fetchPromisesCache.get('/bar'));
  });

  test('params are properly encoded', () => {
    let url = helper.urlWithParams('/path/', {
      sp: 'hola',
      gr: 'guten tag',
      noval: null,
    });
    assert.equal(url,
        window.CANONICAL_PATH + '/path/?sp=hola&gr=guten%20tag&noval');

    url = helper.urlWithParams('/path/', {
      sp: 'hola',
      en: ['hey', 'hi'],
    });
    assert.equal(url, window.CANONICAL_PATH + '/path/?sp=hola&en=hey&en=hi');

    // Order must be maintained with array params.
    url = helper.urlWithParams('/path/', {
      l: ['c', 'b', 'a'],
    });
    assert.equal(url, window.CANONICAL_PATH + '/path/?l=c&l=b&l=a');
  });

  test('request callbacks can be canceled', () => {
    let cancelCalled = false;
    authFetchStub.returns(Promise.resolve({
      body: {
        cancel() { cancelCalled = true; },
      },
    }));
    const cancelCondition = () => true;
    return helper.fetchJSON({url: '/dummy/url', cancelCondition}).then(obj => {
      assert.isUndefined(obj);
      assert.isTrue(cancelCalled);
    });
  });
});

