<!DOCTYPE html>
<!--
Copyright (C) 2016 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.
-->

<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-rest-api-interface</title>

<script src="../../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>

<link rel="import" href="../../../bower_components/iron-test-helpers/iron-test-helpers.html">
<link rel="import" href="gr-rest-api-interface.html">

<test-fixture id="basic">
  <template>
    <gr-rest-api-interface></gr-rest-api-interface>
  </template>
</test-fixture>

<script>
  suite('gr-rest-api-interface tests', function() {
    var element;
    var sandbox;

    setup(function() {
      sandbox = sinon.sandbox.create();
      element = fixture('basic');
    });

    teardown(function() {
      sandbox.restore();
    });

    test('JSON prefix is properly removed', function(done) {
      var testJSON = ')]}\'\n{"hello": "bonjour"}';

      sandbox.stub(window, 'fetch', function() {
        return Promise.resolve({
          ok: true,
          text: function() {
            return Promise.resolve(testJSON);
          },
        });
      });
      element.fetchJSON('/dummy/url').then(function(obj) {
        assert.deepEqual(obj, {hello: 'bonjour'});
        done();
      });
    });

    test('cached results', function(done) {
      var n = 0;
      sandbox.stub(element, 'fetchJSON', function() {
        return Promise.resolve(++n);
      });
      var promises = [];
      promises.push(element._fetchSharedCacheURL('/foo'));
      promises.push(element._fetchSharedCacheURL('/foo'));
      promises.push(element._fetchSharedCacheURL('/foo'));

      Promise.all(promises).then(function(results) {
        assert.deepEqual(results, [1, 1, 1]);
        element._fetchSharedCacheURL('/foo').then(function(foo) {
          assert.equal(foo, 1);
          done();
        });
      });
    });

    test('cached promise', function(done) {
      var promise = Promise.reject('foo');
      element._cache['/foo'] = promise;
      element._fetchSharedCacheURL('/foo').catch(function(p) {
        assert.equal(p, 'foo');
        done();
      });
    });

    test('params are properly encoded', function() {
      var url = element._urlWithParams('/path/', {
        sp: 'hola',
        gr: 'guten tag',
        noval: null,
      });
      assert.equal(url, '/path/?sp=hola&gr=guten%20tag&noval');

      url = element._urlWithParams('/path/', {
        sp: 'hola',
        en: ['hey', 'hi'],
      });
      assert.equal(url, '/path/?sp=hola&en=hey&en=hi');

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

    test('request callbacks can be canceled', function(done) {
      var cancelCalled = false;
      sandbox.stub(window, 'fetch', function() {
        return Promise.resolve({
          body: {
            cancel: function() { cancelCalled = true; }
          },
        });
      });
      element.fetchJSON('/dummy/url', null, function() { return true; }).then(
        function(obj) {
          assert.isUndefined(obj);
          assert.isTrue(cancelCalled);
          done();
        });
    });

    test('parent diff comments are properly grouped', function(done) {
      sandbox.stub(element, 'fetchJSON', function() {
        return Promise.resolve({
          '/COMMIT_MSG': [],
          'sieve.go': [
            {
              message: 'this isn’t quite right',
            },
            {
              side: 'PARENT',
              message: 'how did this work in the first place?',
            },
          ],
        });
      });
      element._getDiffComments('42', '', 'PARENT', 1, 'sieve.go').then(
        function(obj) {
          assert.equal(obj.baseComments.length, 1);
          assert.deepEqual(obj.baseComments[0], {
            side: 'PARENT',
            message: 'how did this work in the first place?',
            path: 'sieve.go',
          });
          assert.equal(obj.comments.length, 1);
          assert.deepEqual(obj.comments[0], {
            message: 'this isn’t quite right',
            path: 'sieve.go',
          });
          done();
        });
    });

    test('differing patch diff comments are properly grouped', function(done) {
      sandbox.stub(element, 'fetchJSON', function(url) {
        if (url == '/changes/42/revisions/1') {
          return Promise.resolve({
            '/COMMIT_MSG': [],
            'sieve.go': [
              {
                message: 'this isn’t quite right',
              },
              {
                side: 'PARENT',
                message: 'how did this work in the first place?',
              },
            ],
          });
        } else if (url == '/changes/42/revisions/2') {
          return Promise.resolve({
            '/COMMIT_MSG': [],
            'sieve.go': [
              {
                message: 'What on earth are you thinking, here?',
              },
              {
                side: 'PARENT',
                message: 'Yeah not sure how this worked either?',
              },
              {
                message: '¯\\_(ツ)_/¯',
              },
            ],
          });
        }
      });
      element._getDiffComments('42', '', 1, 2, 'sieve.go').then(
        function(obj) {
          assert.equal(obj.baseComments.length, 1);
          assert.deepEqual(obj.baseComments[0], {
            message: 'this isn’t quite right',
            path: 'sieve.go',
          });
          assert.equal(obj.comments.length, 2);
          assert.deepEqual(obj.comments[0], {
            message: 'What on earth are you thinking, here?',
            path: 'sieve.go',
          });
          assert.deepEqual(obj.comments[1], {
            message: '¯\\_(ツ)_/¯',
            path: 'sieve.go',
          });
          done();
        });
    });

    test('special file path sorting', function() {
      assert.deepEqual(
          ['.b', '/COMMIT_MSG', '.a', 'file'].sort(
              element.specialFilePathCompare),
          ['/COMMIT_MSG', '.a', '.b', 'file']);

      assert.deepEqual(
          ['.b', '/COMMIT_MSG', 'foo/bar/baz.cc', 'foo/bar/baz.h'].sort(
              element.specialFilePathCompare),
          ['/COMMIT_MSG', '.b', 'foo/bar/baz.h', 'foo/bar/baz.cc']);

      assert.deepEqual(
          ['.b', '/COMMIT_MSG', 'foo/bar/baz.cc', 'foo/bar/baz.hpp'].sort(
              element.specialFilePathCompare),
          ['/COMMIT_MSG', '.b', 'foo/bar/baz.hpp', 'foo/bar/baz.cc']);

      assert.deepEqual(
          ['.b', '/COMMIT_MSG', 'foo/bar/baz.cc', 'foo/bar/baz.hxx'].sort(
              element.specialFilePathCompare),
          ['/COMMIT_MSG', '.b', 'foo/bar/baz.hxx', 'foo/bar/baz.cc']);

      assert.deepEqual(
          ['foo/bar.h', 'foo/bar.hxx', 'foo/bar.hpp'].sort(
              element.specialFilePathCompare),
          ['foo/bar.h', 'foo/bar.hpp', 'foo/bar.hxx']);

      // Regression test for Issue 4448.
      assert.deepEqual([
          'minidump/minidump_memory_writer.cc',
          'minidump/minidump_memory_writer.h',
          'minidump/minidump_thread_writer.cc',
          'minidump/minidump_thread_writer.h',
          ]
        .sort(element.specialFilePathCompare),
          [
            'minidump/minidump_memory_writer.h',
            'minidump/minidump_memory_writer.cc',
            'minidump/minidump_thread_writer.h',
            'minidump/minidump_thread_writer.cc',
          ]);

      // Regression test for Issue 4545.
      assert.deepEqual([
          'task_test.go',
          'task.go',
          ]
        .sort(element.specialFilePathCompare),
          [
            'task.go',
            'task_test.go',
          ]);
    });

    test('rebase always enabled', function(done) {
      var resolveFetchJSON;
      sandbox.stub(element, 'fetchJSON').returns(
          new Promise(function(resolve) {
            resolveFetchJSON = resolve;
          }));
      element.getChangeRevisionActions('42', '1337').then(
          function(response) {
            assert.isTrue(response.rebase.enabled);
            done();
          });
      resolveFetchJSON({rebase: {}});
    });

    test('server error', function(done) {
      var getResponseObjectStub = sandbox.stub(element, 'getResponseObject');
      sandbox.stub(window, 'fetch', function() {
        return Promise.resolve({ok: false});
      });
      var serverErrorEventPromise = new Promise(function(resolve) {
        element.addEventListener('server-error', function() { resolve(); });
      });

      element.fetchJSON().then(
          function(response) {
            assert.isUndefined(response);
            assert.isTrue(getResponseObjectStub.notCalled);
            serverErrorEventPromise.then(function() {
              done();
            });
          });
    });

    test('refreshCredentials', function(done) {
      var responses = [
        {
          ok: false,
          status: 403,
          text: function() { return Promise.resolve(); }
        },
        {
          ok: true,
          status: 200,
          text: function() { return Promise.resolve(')]}\'{}'); }
        },
      ];
      sandbox.stub(window, 'fetch', function(url) {
        if (url === '/accounts/self/detail') {
          return Promise.resolve(responses.shift());
        }
      });
      element.getLoggedIn().then(function(isLoggedIn) {
        assert.isFalse(isLoggedIn);
        element.refreshCredentials().then(function(isRefreshed) {
          assert.isTrue(isRefreshed);
          done();
        });
      });
    });

    test('legacy n,z key in change url is replaced', function() {
      var stub = sandbox.stub(element, 'fetchJSON');
      element.getChanges(1, null, 'n,z');
      assert.equal(stub.args[0][3].S, 0);
    });

    test('saveDiffPreferences invalidates cache line', function() {
      var cacheKey = '/accounts/self/preferences.diff';
      var sendStub = sandbox.stub(element, 'send');
      element._cache[cacheKey] = {tab_size: 4};
      element.saveDiffPreferences({tab_size: 8});
      assert.isTrue(sendStub.called);
      assert.notOk(element._cache[cacheKey]);
    });
  });
</script>
