<!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',
          });
          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: '¯\\_(ツ)_/¯',
          });
          done();
        });
    });

  });
</script>
