<!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;

    setup(function() {
      element = fixture('basic');
    });

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

      var fetchStub = sinon.stub(window, 'fetch', function() {
        return Promise.resolve({text: function() {
          return Promise.resolve(testJSON);
        }});
      });
      element.fetchJSON('/dummy/url').then(function(obj) {
        assert.deepEqual(obj, {hello: 'bonjour'});
        fetchStub.restore();
        done();
      });
    });

    test('cached results', function(done) {
      var n = 0;
      var fetchJSONStub = sinon.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);
          fetchJSONStub.restore();
          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 fetchStub = sinon.stub(window, 'fetch', function() {
        return Promise.resolve({text: function() {
          return Promise.resolve(')]}\'\n{}');
        }});
      });
      var params = {
        sp: 'hola',
        gr: 'guten tag',
        noval: null,
      };
      element.fetchJSON('/path/', null, params);
      assert.equal(fetchStub.args[0][0], '/path/?gr=guten%20tag&noval&sp=hola');
      fetchStub.restore();
    });

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

    test('parent diff comments are properly grouped', function(done) {
      var fetchJSONStub = sinon.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?',
          });
          assert.equal(obj.comments.length, 1);
          assert.deepEqual(obj.comments[0], {
            message: 'this isn’t quite right',
          });
          fetchJSONStub.restore();
          done();
        });
    });

    test('differing patch diff comments are properly grouped', function(done) {
      var fetchJSONStub = sinon.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',
          });
          assert.equal(obj.comments.length, 2);
          assert.deepEqual(obj.comments[0], {
            message: 'What on earth are you thinking, here?',
          });
          assert.deepEqual(obj.comments[1], {
            message: '¯\\_(ツ)_/¯',
          });
          fetchJSONStub.restore();
          done();
        });
    });

  });
</script>
