Change-Id: Iee8de3c68b3f78222a4ef63ba5de680a17033674
(cherry picked from commit f91e636ffb)
		
	
		
			
				
	
	
		
			1474 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			1474 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!DOCTYPE html>
 | 
						||
<!--
 | 
						||
@license
 | 
						||
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-lite.min.js"></script>
 | 
						||
<script src="../../../bower_components/web-component-tester/browser.js"></script>
 | 
						||
<link rel="import" href="../../../test/common-test-setup.html"/>
 | 
						||
<script src="../../../scripts/util.js"></script>
 | 
						||
 | 
						||
<link rel="import" href="gr-rest-api-interface.html">
 | 
						||
 | 
						||
<script>void(0);</script>
 | 
						||
 | 
						||
<test-fixture id="basic">
 | 
						||
  <template>
 | 
						||
    <gr-rest-api-interface></gr-rest-api-interface>
 | 
						||
  </template>
 | 
						||
</test-fixture>
 | 
						||
 | 
						||
<script>
 | 
						||
  suite('gr-rest-api-interface tests', () => {
 | 
						||
    let element;
 | 
						||
    let sandbox;
 | 
						||
    let ctr = 0;
 | 
						||
 | 
						||
    setup(() => {
 | 
						||
      // Modify CANONICAL_PATH to effectively reset cache.
 | 
						||
      ctr += 1;
 | 
						||
      window.CANONICAL_PATH = `test${ctr}`;
 | 
						||
 | 
						||
      sandbox = sinon.sandbox.create();
 | 
						||
      element = fixture('basic');
 | 
						||
      element._projectLookup = {};
 | 
						||
      const testJSON = ')]}\'\n{"hello": "bonjour"}';
 | 
						||
      sandbox.stub(window, 'fetch').returns(Promise.resolve({
 | 
						||
        ok: true,
 | 
						||
        text() {
 | 
						||
          return Promise.resolve(testJSON);
 | 
						||
        },
 | 
						||
      }));
 | 
						||
    });
 | 
						||
 | 
						||
    teardown(() => {
 | 
						||
      sandbox.restore();
 | 
						||
    });
 | 
						||
 | 
						||
    test('JSON prefix is properly removed', done => {
 | 
						||
      element._fetchJSON('/dummy/url').then(obj => {
 | 
						||
        assert.deepEqual(obj, {hello: 'bonjour'});
 | 
						||
        done();
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('cached results', done => {
 | 
						||
      let n = 0;
 | 
						||
      sandbox.stub(element, '_fetchJSON', () => {
 | 
						||
        return Promise.resolve(++n);
 | 
						||
      });
 | 
						||
      const promises = [];
 | 
						||
      promises.push(element._fetchSharedCacheURL('/foo'));
 | 
						||
      promises.push(element._fetchSharedCacheURL('/foo'));
 | 
						||
      promises.push(element._fetchSharedCacheURL('/foo'));
 | 
						||
 | 
						||
      Promise.all(promises).then(results => {
 | 
						||
        assert.deepEqual(results, [1, 1, 1]);
 | 
						||
        element._fetchSharedCacheURL('/foo').then(foo => {
 | 
						||
          assert.equal(foo, 1);
 | 
						||
          done();
 | 
						||
        });
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('cached promise', done => {
 | 
						||
      const promise = Promise.reject('foo');
 | 
						||
      element._cache.set('/foo', promise);
 | 
						||
      element._fetchSharedCacheURL({url: '/foo'}).catch(p => {
 | 
						||
        assert.equal(p, 'foo');
 | 
						||
        done();
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('params are properly encoded', () => {
 | 
						||
      let url = element._urlWithParams('/path/', {
 | 
						||
        sp: 'hola',
 | 
						||
        gr: 'guten tag',
 | 
						||
        noval: null,
 | 
						||
      });
 | 
						||
      assert.equal(url,
 | 
						||
          window.CANONICAL_PATH + '/path/?sp=hola&gr=guten%20tag&noval');
 | 
						||
 | 
						||
      url = element._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 = element._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', done => {
 | 
						||
      let cancelCalled = false;
 | 
						||
      window.fetch.returns(Promise.resolve({
 | 
						||
        body: {
 | 
						||
          cancel() { cancelCalled = true; },
 | 
						||
        },
 | 
						||
      }));
 | 
						||
      const cancelCondition = () => { return true; };
 | 
						||
      element._fetchJSON({url: '/dummy/url', cancelCondition}).then(
 | 
						||
          obj => {
 | 
						||
            assert.isUndefined(obj);
 | 
						||
            assert.isTrue(cancelCalled);
 | 
						||
            done();
 | 
						||
          });
 | 
						||
    });
 | 
						||
 | 
						||
    test('parent diff comments are properly grouped', done => {
 | 
						||
      sandbox.stub(element, '_fetchJSON', () => {
 | 
						||
        return Promise.resolve({
 | 
						||
          '/COMMIT_MSG': [],
 | 
						||
          'sieve.go': [
 | 
						||
            {
 | 
						||
              updated: '2017-02-03 22:32:28.000000000',
 | 
						||
              message: 'this isn’t quite right',
 | 
						||
            },
 | 
						||
            {
 | 
						||
              side: 'PARENT',
 | 
						||
              message: 'how did this work in the first place?',
 | 
						||
              updated: '2017-02-03 22:33:28.000000000',
 | 
						||
            },
 | 
						||
          ],
 | 
						||
        });
 | 
						||
      });
 | 
						||
      element._getDiffComments('42', '', 'PARENT', 1, 'sieve.go').then(
 | 
						||
          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',
 | 
						||
              updated: '2017-02-03 22:33:28.000000000',
 | 
						||
            });
 | 
						||
            assert.equal(obj.comments.length, 1);
 | 
						||
            assert.deepEqual(obj.comments[0], {
 | 
						||
              message: 'this isn’t quite right',
 | 
						||
              path: 'sieve.go',
 | 
						||
              updated: '2017-02-03 22:32:28.000000000',
 | 
						||
            });
 | 
						||
            done();
 | 
						||
          });
 | 
						||
    });
 | 
						||
 | 
						||
    test('_setRange', () => {
 | 
						||
      const comments = [
 | 
						||
        {
 | 
						||
          id: 1,
 | 
						||
          side: 'PARENT',
 | 
						||
          message: 'how did this work in the first place?',
 | 
						||
          updated: '2017-02-03 22:32:28.000000000',
 | 
						||
          range: {
 | 
						||
            start_line: 1,
 | 
						||
            start_character: 1,
 | 
						||
            end_line: 2,
 | 
						||
            end_character: 1,
 | 
						||
          },
 | 
						||
        },
 | 
						||
        {
 | 
						||
          id: 2,
 | 
						||
          in_reply_to: 1,
 | 
						||
          message: 'this isn’t quite right',
 | 
						||
          updated: '2017-02-03 22:33:28.000000000',
 | 
						||
        },
 | 
						||
      ];
 | 
						||
      const expectedResult = {
 | 
						||
        id: 2,
 | 
						||
        in_reply_to: 1,
 | 
						||
        message: 'this isn’t quite right',
 | 
						||
        updated: '2017-02-03 22:33:28.000000000',
 | 
						||
        range: {
 | 
						||
          start_line: 1,
 | 
						||
          start_character: 1,
 | 
						||
          end_line: 2,
 | 
						||
          end_character: 1,
 | 
						||
        },
 | 
						||
      };
 | 
						||
      const comment = comments[1];
 | 
						||
      assert.deepEqual(element._setRange(comments, comment), expectedResult);
 | 
						||
    });
 | 
						||
 | 
						||
    test('_setRanges', () => {
 | 
						||
      const comments = [
 | 
						||
        {
 | 
						||
          id: 3,
 | 
						||
          in_reply_to: 2,
 | 
						||
          message: 'this isn’t quite right either',
 | 
						||
          updated: '2017-02-03 22:34:28.000000000',
 | 
						||
        },
 | 
						||
        {
 | 
						||
          id: 2,
 | 
						||
          in_reply_to: 1,
 | 
						||
          message: 'this isn’t quite right',
 | 
						||
          updated: '2017-02-03 22:33:28.000000000',
 | 
						||
        },
 | 
						||
        {
 | 
						||
          id: 1,
 | 
						||
          side: 'PARENT',
 | 
						||
          message: 'how did this work in the first place?',
 | 
						||
          updated: '2017-02-03 22:32:28.000000000',
 | 
						||
          range: {
 | 
						||
            start_line: 1,
 | 
						||
            start_character: 1,
 | 
						||
            end_line: 2,
 | 
						||
            end_character: 1,
 | 
						||
          },
 | 
						||
        },
 | 
						||
      ];
 | 
						||
      const expectedResult = [
 | 
						||
        {
 | 
						||
          id: 1,
 | 
						||
          side: 'PARENT',
 | 
						||
          message: 'how did this work in the first place?',
 | 
						||
          updated: '2017-02-03 22:32:28.000000000',
 | 
						||
          range: {
 | 
						||
            start_line: 1,
 | 
						||
            start_character: 1,
 | 
						||
            end_line: 2,
 | 
						||
            end_character: 1,
 | 
						||
          },
 | 
						||
        },
 | 
						||
        {
 | 
						||
          id: 2,
 | 
						||
          in_reply_to: 1,
 | 
						||
          message: 'this isn’t quite right',
 | 
						||
          updated: '2017-02-03 22:33:28.000000000',
 | 
						||
          range: {
 | 
						||
            start_line: 1,
 | 
						||
            start_character: 1,
 | 
						||
            end_line: 2,
 | 
						||
            end_character: 1,
 | 
						||
          },
 | 
						||
        },
 | 
						||
        {
 | 
						||
          id: 3,
 | 
						||
          in_reply_to: 2,
 | 
						||
          message: 'this isn’t quite right either',
 | 
						||
          updated: '2017-02-03 22:34:28.000000000',
 | 
						||
          range: {
 | 
						||
            start_line: 1,
 | 
						||
            start_character: 1,
 | 
						||
            end_line: 2,
 | 
						||
            end_character: 1,
 | 
						||
          },
 | 
						||
        },
 | 
						||
      ];
 | 
						||
      assert.deepEqual(element._setRanges(comments), expectedResult);
 | 
						||
    });
 | 
						||
 | 
						||
    test('differing patch diff comments are properly grouped', done => {
 | 
						||
      sandbox.stub(element, 'getFromProjectLookup')
 | 
						||
          .returns(Promise.resolve('test'));
 | 
						||
      sandbox.stub(element, '_fetchJSON', request => {
 | 
						||
        const url = request.url;
 | 
						||
        if (url === '/changes/test~42/revisions/1') {
 | 
						||
          return Promise.resolve({
 | 
						||
            '/COMMIT_MSG': [],
 | 
						||
            'sieve.go': [
 | 
						||
              {
 | 
						||
                message: 'this isn’t quite right',
 | 
						||
                updated: '2017-02-03 22:32:28.000000000',
 | 
						||
              },
 | 
						||
              {
 | 
						||
                side: 'PARENT',
 | 
						||
                message: 'how did this work in the first place?',
 | 
						||
                updated: '2017-02-03 22:33:28.000000000',
 | 
						||
              },
 | 
						||
            ],
 | 
						||
          });
 | 
						||
        } else if (url === '/changes/test~42/revisions/2') {
 | 
						||
          return Promise.resolve({
 | 
						||
            '/COMMIT_MSG': [],
 | 
						||
            'sieve.go': [
 | 
						||
              {
 | 
						||
                message: 'What on earth are you thinking, here?',
 | 
						||
                updated: '2017-02-03 22:32:28.000000000',
 | 
						||
              },
 | 
						||
              {
 | 
						||
                side: 'PARENT',
 | 
						||
                message: 'Yeah not sure how this worked either?',
 | 
						||
                updated: '2017-02-03 22:33:28.000000000',
 | 
						||
              },
 | 
						||
              {
 | 
						||
                message: '¯\\_(ツ)_/¯',
 | 
						||
                updated: '2017-02-04 22:33:28.000000000',
 | 
						||
              },
 | 
						||
            ],
 | 
						||
          });
 | 
						||
        }
 | 
						||
      });
 | 
						||
      element._getDiffComments('42', '', 1, 2, 'sieve.go').then(
 | 
						||
          obj => {
 | 
						||
            assert.equal(obj.baseComments.length, 1);
 | 
						||
            assert.deepEqual(obj.baseComments[0], {
 | 
						||
              message: 'this isn’t quite right',
 | 
						||
              path: 'sieve.go',
 | 
						||
              updated: '2017-02-03 22:32:28.000000000',
 | 
						||
            });
 | 
						||
            assert.equal(obj.comments.length, 2);
 | 
						||
            assert.deepEqual(obj.comments[0], {
 | 
						||
              message: 'What on earth are you thinking, here?',
 | 
						||
              path: 'sieve.go',
 | 
						||
              updated: '2017-02-03 22:32:28.000000000',
 | 
						||
            });
 | 
						||
            assert.deepEqual(obj.comments[1], {
 | 
						||
              message: '¯\\_(ツ)_/¯',
 | 
						||
              path: 'sieve.go',
 | 
						||
              updated: '2017-02-04 22:33:28.000000000',
 | 
						||
            });
 | 
						||
            done();
 | 
						||
          });
 | 
						||
    });
 | 
						||
 | 
						||
    test('special file path sorting', () => {
 | 
						||
      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',
 | 
						||
          ]);
 | 
						||
    });
 | 
						||
 | 
						||
    suite('rebase action', () => {
 | 
						||
      let resolve_fetchJSON;
 | 
						||
      setup(() => {
 | 
						||
        sandbox.stub(element, '_fetchJSON').returns(
 | 
						||
            new Promise(resolve => {
 | 
						||
              resolve_fetchJSON = resolve;
 | 
						||
            }));
 | 
						||
      });
 | 
						||
 | 
						||
      test('no rebase on current', done => {
 | 
						||
        element.getChangeRevisionActions('42', '1337').then(
 | 
						||
            response => {
 | 
						||
              assert.isTrue(response.rebase.enabled);
 | 
						||
              assert.isFalse(response.rebase.rebaseOnCurrent);
 | 
						||
              done();
 | 
						||
            });
 | 
						||
        resolve_fetchJSON({rebase: {}});
 | 
						||
      });
 | 
						||
 | 
						||
      test('rebase on current', done => {
 | 
						||
        element.getChangeRevisionActions('42', '1337').then(
 | 
						||
            response => {
 | 
						||
              assert.isTrue(response.rebase.enabled);
 | 
						||
              assert.isTrue(response.rebase.rebaseOnCurrent);
 | 
						||
              done();
 | 
						||
            });
 | 
						||
        resolve_fetchJSON({rebase: {enabled: true}});
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
 | 
						||
    test('server error', done => {
 | 
						||
      const getResponseObjectStub = sandbox.stub(element, 'getResponseObject');
 | 
						||
      window.fetch.returns(Promise.resolve({ok: false}));
 | 
						||
      const serverErrorEventPromise = new Promise(resolve => {
 | 
						||
        element.addEventListener('server-error', resolve);
 | 
						||
      });
 | 
						||
 | 
						||
      element._fetchJSON({}).then(response => {
 | 
						||
        assert.isUndefined(response);
 | 
						||
        assert.isTrue(getResponseObjectStub.notCalled);
 | 
						||
        serverErrorEventPromise.then(() => done());
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('auth failure', done => {
 | 
						||
      const fakeAuthResponse = {
 | 
						||
        ok: false,
 | 
						||
        status: 403,
 | 
						||
      };
 | 
						||
      window.fetch.onFirstCall().returns(
 | 
						||
          Promise.reject({message: 'Failed to fetch'}));
 | 
						||
      window.fetch.onSecondCall().returns(Promise.resolve(fakeAuthResponse));
 | 
						||
      // Emulate logged in.
 | 
						||
      element._cache.set('/accounts/self/detail', {});
 | 
						||
      const serverErrorStub = sandbox.stub();
 | 
						||
      element.addEventListener('server-error', serverErrorStub);
 | 
						||
      const authErrorStub = sandbox.stub();
 | 
						||
      element.addEventListener('auth-error', authErrorStub);
 | 
						||
      element._fetchJSON('/bar').then(r => {
 | 
						||
        flush(() => {
 | 
						||
          assert.isTrue(authErrorStub.called);
 | 
						||
          assert.isFalse(serverErrorStub.called);
 | 
						||
          assert.isFalse(element._cache.has('/accounts/self/detail'));
 | 
						||
          done();
 | 
						||
        });
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('checkCredentials', done => {
 | 
						||
      const responses = [
 | 
						||
        {
 | 
						||
          ok: false,
 | 
						||
          status: 403,
 | 
						||
          text() { return Promise.resolve(); },
 | 
						||
        },
 | 
						||
        {
 | 
						||
          ok: true,
 | 
						||
          status: 200,
 | 
						||
          text() { return Promise.resolve(')]}\'{}'); },
 | 
						||
        },
 | 
						||
      ];
 | 
						||
      window.fetch.restore();
 | 
						||
      sandbox.stub(window, 'fetch', url => {
 | 
						||
        if (url === window.CANONICAL_PATH + '/accounts/self/detail') {
 | 
						||
          return Promise.resolve(responses.shift());
 | 
						||
        }
 | 
						||
      });
 | 
						||
 | 
						||
      element.getLoggedIn().then(account => {
 | 
						||
        assert.isNotOk(account);
 | 
						||
        element.checkCredentials().then(account => {
 | 
						||
          assert.isOk(account);
 | 
						||
          done();
 | 
						||
        });
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('checkCredentials promise rejection', () => {
 | 
						||
      window.fetch.restore();
 | 
						||
      element._cache.set('/accounts/self/detail', true);
 | 
						||
      sandbox.spy(element, 'checkCredentials');
 | 
						||
      sandbox.stub(window, 'fetch', url => {
 | 
						||
        return Promise.reject({message: 'Failed to fetch'});
 | 
						||
      });
 | 
						||
      return element.getConfig(true)
 | 
						||
          .catch(err => undefined)
 | 
						||
          .then(() => {
 | 
						||
            // When the top-level fetch call throws an error, it invokes
 | 
						||
            // checkCredentials, which in turn makes another fetch call.
 | 
						||
            // The second fetch call also fails, which leads to a second
 | 
						||
            // invocation of checkCredentials, which should immediately
 | 
						||
            // return instead of making further fetch calls.
 | 
						||
            assert.isTrue(element.checkCredentials.calledTwice);
 | 
						||
            assert.isTrue(window.fetch.calledTwice);
 | 
						||
          });
 | 
						||
    });
 | 
						||
 | 
						||
    test('legacy n,z key in change url is replaced', () => {
 | 
						||
      const stub = sandbox.stub(element, '_fetchJSON')
 | 
						||
          .returns(Promise.resolve([]));
 | 
						||
      element.getChanges(1, null, 'n,z');
 | 
						||
      assert.equal(stub.lastCall.args[0].params.S, 0);
 | 
						||
    });
 | 
						||
 | 
						||
    test('saveDiffPreferences invalidates cache line', () => {
 | 
						||
      const cacheKey = '/accounts/self/preferences.diff';
 | 
						||
      sandbox.stub(element, '_send');
 | 
						||
      element._cache.set(cacheKey, {tab_size: 4});
 | 
						||
      element.saveDiffPreferences({tab_size: 8});
 | 
						||
      assert.isTrue(element._send.called);
 | 
						||
      assert.isFalse(element._cache.has(cacheKey));
 | 
						||
    });
 | 
						||
 | 
						||
    test('getAccount when resp is null does not add anything to the cache',
 | 
						||
        done => {
 | 
						||
          const cacheKey = '/accounts/self/detail';
 | 
						||
          const stub = sandbox.stub(element, '_fetchSharedCacheURL',
 | 
						||
              () => Promise.resolve());
 | 
						||
 | 
						||
          element.getAccount().then(() => {
 | 
						||
            assert.isTrue(element._fetchSharedCacheURL.called);
 | 
						||
            assert.isFalse(element._cache.has(cacheKey));
 | 
						||
            done();
 | 
						||
          });
 | 
						||
 | 
						||
          element._cache.set(cacheKey, 'fake cache');
 | 
						||
          stub.lastCall.args[0].errFn();
 | 
						||
        });
 | 
						||
 | 
						||
    test('getAccount does not add to the cache when resp.status is 403',
 | 
						||
        done => {
 | 
						||
          const cacheKey = '/accounts/self/detail';
 | 
						||
          const stub = sandbox.stub(element, '_fetchSharedCacheURL',
 | 
						||
              () => Promise.resolve());
 | 
						||
 | 
						||
          element.getAccount().then(() => {
 | 
						||
            assert.isTrue(element._fetchSharedCacheURL.called);
 | 
						||
            assert.isFalse(element._cache.has(cacheKey));
 | 
						||
            done();
 | 
						||
          });
 | 
						||
          element._cache.set(cacheKey, 'fake cache');
 | 
						||
          stub.lastCall.args[0].errFn({status: 403});
 | 
						||
        });
 | 
						||
 | 
						||
    test('getAccount when resp is successful', done => {
 | 
						||
      const cacheKey = '/accounts/self/detail';
 | 
						||
      const stub = sandbox.stub(element, '_fetchSharedCacheURL',
 | 
						||
          () => Promise.resolve());
 | 
						||
 | 
						||
      element.getAccount().then(response => {
 | 
						||
        assert.isTrue(element._fetchSharedCacheURL.called);
 | 
						||
        assert.equal(element._cache.get(cacheKey), 'fake cache');
 | 
						||
        done();
 | 
						||
      });
 | 
						||
      element._cache.set(cacheKey, 'fake cache');
 | 
						||
 | 
						||
      stub.lastCall.args[0].errFn({});
 | 
						||
    });
 | 
						||
 | 
						||
    const preferenceSetup = function(testJSON, loggedIn, smallScreen) {
 | 
						||
      sandbox.stub(element, 'getLoggedIn', () => {
 | 
						||
        return Promise.resolve(loggedIn);
 | 
						||
      });
 | 
						||
      sandbox.stub(element, '_isNarrowScreen', () => {
 | 
						||
        return smallScreen;
 | 
						||
      });
 | 
						||
      sandbox.stub(element, '_fetchSharedCacheURL', () => {
 | 
						||
        return Promise.resolve(testJSON);
 | 
						||
      });
 | 
						||
    };
 | 
						||
 | 
						||
    test('getPreferences returns correctly on small screens logged in',
 | 
						||
        done => {
 | 
						||
          const testJSON = {diff_view: 'SIDE_BY_SIDE'};
 | 
						||
          const loggedIn = true;
 | 
						||
          const smallScreen = true;
 | 
						||
 | 
						||
          preferenceSetup(testJSON, loggedIn, smallScreen);
 | 
						||
 | 
						||
          element.getPreferences().then(obj => {
 | 
						||
            assert.equal(obj.default_diff_view, 'UNIFIED_DIFF');
 | 
						||
            assert.equal(obj.diff_view, 'SIDE_BY_SIDE');
 | 
						||
            done();
 | 
						||
          });
 | 
						||
        });
 | 
						||
 | 
						||
    test('getPreferences returns correctly on small screens not logged in',
 | 
						||
        done => {
 | 
						||
          const testJSON = {diff_view: 'SIDE_BY_SIDE'};
 | 
						||
          const loggedIn = false;
 | 
						||
          const smallScreen = true;
 | 
						||
 | 
						||
          preferenceSetup(testJSON, loggedIn, smallScreen);
 | 
						||
          element.getPreferences().then(obj => {
 | 
						||
            assert.equal(obj.default_diff_view, 'UNIFIED_DIFF');
 | 
						||
            assert.equal(obj.diff_view, 'SIDE_BY_SIDE');
 | 
						||
            done();
 | 
						||
          });
 | 
						||
        });
 | 
						||
 | 
						||
    test('getPreferences returns correctly on larger screens logged in',
 | 
						||
        done => {
 | 
						||
          const testJSON = {diff_view: 'UNIFIED_DIFF'};
 | 
						||
          const loggedIn = true;
 | 
						||
          const smallScreen = false;
 | 
						||
 | 
						||
          preferenceSetup(testJSON, loggedIn, smallScreen);
 | 
						||
 | 
						||
          element.getPreferences().then(obj => {
 | 
						||
            assert.equal(obj.default_diff_view, 'UNIFIED_DIFF');
 | 
						||
            assert.equal(obj.diff_view, 'UNIFIED_DIFF');
 | 
						||
            done();
 | 
						||
          });
 | 
						||
        });
 | 
						||
 | 
						||
    test('getPreferences returns correctly on larger screens not logged in',
 | 
						||
        done => {
 | 
						||
          const testJSON = {diff_view: 'UNIFIED_DIFF'};
 | 
						||
          const loggedIn = false;
 | 
						||
          const smallScreen = false;
 | 
						||
 | 
						||
          preferenceSetup(testJSON, loggedIn, smallScreen);
 | 
						||
 | 
						||
          element.getPreferences().then(obj => {
 | 
						||
            assert.equal(obj.default_diff_view, 'SIDE_BY_SIDE');
 | 
						||
            assert.equal(obj.diff_view, 'SIDE_BY_SIDE');
 | 
						||
            done();
 | 
						||
          });
 | 
						||
        });
 | 
						||
 | 
						||
    test('savPreferences normalizes download scheme', () => {
 | 
						||
      sandbox.stub(element, '_send');
 | 
						||
      element.savePreferences({download_scheme: 'HTTP'});
 | 
						||
      assert.isTrue(element._send.called);
 | 
						||
      assert.equal(element._send.lastCall.args[0].body.download_scheme, 'http');
 | 
						||
    });
 | 
						||
 | 
						||
    test('getDiffPreferences returns correct defaults', done => {
 | 
						||
      sandbox.stub(element, 'getLoggedIn', () => Promise.resolve(false));
 | 
						||
 | 
						||
      element.getDiffPreferences().then(obj => {
 | 
						||
        assert.equal(obj.auto_hide_diff_table_header, true);
 | 
						||
        assert.equal(obj.context, 10);
 | 
						||
        assert.equal(obj.cursor_blink_rate, 0);
 | 
						||
        assert.equal(obj.font_size, 12);
 | 
						||
        assert.equal(obj.ignore_whitespace, 'IGNORE_NONE');
 | 
						||
        assert.equal(obj.intraline_difference, true);
 | 
						||
        assert.equal(obj.line_length, 100);
 | 
						||
        assert.equal(obj.line_wrapping, false);
 | 
						||
        assert.equal(obj.show_line_endings, true);
 | 
						||
        assert.equal(obj.show_tabs, true);
 | 
						||
        assert.equal(obj.show_whitespace_errors, true);
 | 
						||
        assert.equal(obj.syntax_highlighting, true);
 | 
						||
        assert.equal(obj.tab_size, 8);
 | 
						||
        assert.equal(obj.theme, 'DEFAULT');
 | 
						||
        done();
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('saveDiffPreferences set show_tabs to false', () => {
 | 
						||
      sandbox.stub(element, '_send');
 | 
						||
      element.saveDiffPreferences({show_tabs: false});
 | 
						||
      assert.isTrue(element._send.called);
 | 
						||
      assert.equal(element._send.lastCall.args[0].body.show_tabs, false);
 | 
						||
    });
 | 
						||
 | 
						||
    test('getEditPreferences returns correct defaults', done => {
 | 
						||
      sandbox.stub(element, 'getLoggedIn', () => {
 | 
						||
        return Promise.resolve(false);
 | 
						||
      });
 | 
						||
 | 
						||
      element.getEditPreferences().then(obj => {
 | 
						||
        assert.equal(obj.auto_close_brackets, false);
 | 
						||
        assert.equal(obj.cursor_blink_rate, 0);
 | 
						||
        assert.equal(obj.hide_line_numbers, false);
 | 
						||
        assert.equal(obj.hide_top_menu, false);
 | 
						||
        assert.equal(obj.indent_unit, 2);
 | 
						||
        assert.equal(obj.indent_with_tabs, false);
 | 
						||
        assert.equal(obj.key_map_type, 'DEFAULT');
 | 
						||
        assert.equal(obj.line_length, 100);
 | 
						||
        assert.equal(obj.line_wrapping, false);
 | 
						||
        assert.equal(obj.match_brackets, true);
 | 
						||
        assert.equal(obj.show_base, false);
 | 
						||
        assert.equal(obj.show_tabs, true);
 | 
						||
        assert.equal(obj.show_whitespace_errors, true);
 | 
						||
        assert.equal(obj.syntax_highlighting, true);
 | 
						||
        assert.equal(obj.tab_size, 8);
 | 
						||
        assert.equal(obj.theme, 'DEFAULT');
 | 
						||
        done();
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('saveEditPreferences set show_tabs to false', () => {
 | 
						||
      sandbox.stub(element, '_send');
 | 
						||
      element.saveEditPreferences({show_tabs: false});
 | 
						||
      assert.isTrue(element._send.called);
 | 
						||
      assert.equal(element._send.lastCall.args[0].body.show_tabs, false);
 | 
						||
    });
 | 
						||
 | 
						||
    test('confirmEmail', () => {
 | 
						||
      sandbox.spy(element, '_send');
 | 
						||
      element.confirmEmail('foo');
 | 
						||
      assert.isTrue(element._send.calledOnce);
 | 
						||
      assert.equal(element._send.lastCall.args[0].method, 'PUT');
 | 
						||
      assert.equal(element._send.lastCall.args[0].url,
 | 
						||
          '/config/server/email.confirm');
 | 
						||
      assert.deepEqual(element._send.lastCall.args[0].body, {token: 'foo'});
 | 
						||
    });
 | 
						||
 | 
						||
    test('GrReviewerUpdatesParser.parse is used', () => {
 | 
						||
      sandbox.stub(GrReviewerUpdatesParser, 'parse').returns(
 | 
						||
          Promise.resolve('foo'));
 | 
						||
      return element.getChangeDetail(42).then(result => {
 | 
						||
        assert.isTrue(GrReviewerUpdatesParser.parse.calledOnce);
 | 
						||
        assert.equal(result, 'foo');
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('setAccountStatus', () => {
 | 
						||
      sandbox.stub(element, '_send').returns(Promise.resolve('OOO'));
 | 
						||
      element._cache.set('/accounts/self/detail', {});
 | 
						||
      return element.setAccountStatus('OOO').then(() => {
 | 
						||
        assert.isTrue(element._send.calledOnce);
 | 
						||
        assert.equal(element._send.lastCall.args[0].method, 'PUT');
 | 
						||
        assert.equal(element._send.lastCall.args[0].url,
 | 
						||
            '/accounts/self/status');
 | 
						||
        assert.deepEqual(element._send.lastCall.args[0].body,
 | 
						||
            {status: 'OOO'});
 | 
						||
        assert.deepEqual(element._cache.get('/accounts/self/detail'),
 | 
						||
            {status: 'OOO'});
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    suite('draft comments', () => {
 | 
						||
      test('_sendDiffDraftRequest pending requests tracked', () => {
 | 
						||
        const obj = element._pendingRequests;
 | 
						||
        sandbox.stub(element, '_getChangeURLAndSend', () => mockPromise());
 | 
						||
        assert.notOk(element.hasPendingDiffDrafts());
 | 
						||
 | 
						||
        element._sendDiffDraftRequest(null, null, null, {});
 | 
						||
        assert.equal(obj.sendDiffDraft.length, 1);
 | 
						||
        assert.isTrue(!!element.hasPendingDiffDrafts());
 | 
						||
 | 
						||
        element._sendDiffDraftRequest(null, null, null, {});
 | 
						||
        assert.equal(obj.sendDiffDraft.length, 2);
 | 
						||
        assert.isTrue(!!element.hasPendingDiffDrafts());
 | 
						||
 | 
						||
        for (const promise of obj.sendDiffDraft) { promise.resolve(); }
 | 
						||
 | 
						||
        return element.awaitPendingDiffDrafts().then(() => {
 | 
						||
          assert.equal(obj.sendDiffDraft.length, 0);
 | 
						||
          assert.isFalse(!!element.hasPendingDiffDrafts());
 | 
						||
        });
 | 
						||
      });
 | 
						||
 | 
						||
      suite('_failForCreate200', () => {
 | 
						||
        test('_sendDiffDraftRequest checks for 200 on create', () => {
 | 
						||
          const sendPromise = Promise.resolve();
 | 
						||
          sandbox.stub(element, '_getChangeURLAndSend').returns(sendPromise);
 | 
						||
          const failStub = sandbox.stub(element, '_failForCreate200')
 | 
						||
              .returns(Promise.resolve());
 | 
						||
          return element._sendDiffDraftRequest('PUT', 123, 4, {}).then(() => {
 | 
						||
            assert.isTrue(failStub.calledOnce);
 | 
						||
            assert.isTrue(failStub.calledWithExactly(sendPromise));
 | 
						||
          });
 | 
						||
        });
 | 
						||
 | 
						||
        test('_sendDiffDraftRequest no checks for 200 on non create', () => {
 | 
						||
          sandbox.stub(element, '_getChangeURLAndSend')
 | 
						||
              .returns(Promise.resolve());
 | 
						||
          const failStub = sandbox.stub(element, '_failForCreate200')
 | 
						||
              .returns(Promise.resolve());
 | 
						||
          return element._sendDiffDraftRequest('PUT', 123, 4, {id: '123'})
 | 
						||
              .then(() => {
 | 
						||
                assert.isFalse(failStub.called);
 | 
						||
              });
 | 
						||
        });
 | 
						||
 | 
						||
        test('_failForCreate200 fails on 200', done => {
 | 
						||
          const result = {
 | 
						||
            ok: true,
 | 
						||
            status: 200,
 | 
						||
            headers: {entries: () => [
 | 
						||
              ['Set-CoOkiE', 'secret'],
 | 
						||
              ['Innocuous', 'hello'],
 | 
						||
            ]},
 | 
						||
          };
 | 
						||
          element._failForCreate200(Promise.resolve(result)).then(() => {
 | 
						||
            assert.isTrue(false, 'Promise should not resolve');
 | 
						||
          }).catch(e => {
 | 
						||
            assert.isOk(e);
 | 
						||
            assert.include(e.message, 'Saving draft resulted in HTTP 200');
 | 
						||
            assert.include(e.message, 'hello');
 | 
						||
            assert.notInclude(e.message, 'secret');
 | 
						||
            done();
 | 
						||
          });
 | 
						||
        });
 | 
						||
 | 
						||
        test('_failForCreate200 does not fail on 201', done => {
 | 
						||
          const result = {
 | 
						||
            ok: true,
 | 
						||
            status: 201,
 | 
						||
            headers: {entries: () => []},
 | 
						||
          };
 | 
						||
          element._failForCreate200(Promise.resolve(result)).then(() => {
 | 
						||
            done();
 | 
						||
          }).catch(e => {
 | 
						||
            assert.isTrue(false, 'Promise should not fail');
 | 
						||
          });
 | 
						||
        });
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('saveChangeEdit', () => {
 | 
						||
      element._projectLookup = {1: 'test'};
 | 
						||
      const change_num = '1';
 | 
						||
      const file_name = 'index.php';
 | 
						||
      const file_contents = '<?php';
 | 
						||
      sandbox.stub(element, '_send').returns(
 | 
						||
          Promise.resolve([change_num, file_name, file_contents]));
 | 
						||
      sandbox.stub(element, 'getResponseObject')
 | 
						||
          .returns(Promise.resolve([change_num, file_name, file_contents]));
 | 
						||
      element._cache.set('/changes/' + change_num + '/edit/' + file_name, {});
 | 
						||
      return element.saveChangeEdit(change_num, file_name, file_contents)
 | 
						||
          .then(() => {
 | 
						||
            assert.isTrue(element._send.calledOnce);
 | 
						||
            assert.equal(element._send.lastCall.args[0].method, 'PUT');
 | 
						||
            assert.equal(element._send.lastCall.args[0].url,
 | 
						||
                '/changes/test~1/edit/' + file_name);
 | 
						||
            assert.equal(element._send.lastCall.args[0].body, file_contents);
 | 
						||
          });
 | 
						||
    });
 | 
						||
 | 
						||
    test('putChangeCommitMessage', () => {
 | 
						||
      element._projectLookup = {1: 'test'};
 | 
						||
      const change_num = '1';
 | 
						||
      const message = 'this is a commit message';
 | 
						||
      sandbox.stub(element, '_send').returns(
 | 
						||
          Promise.resolve([change_num, message]));
 | 
						||
      sandbox.stub(element, 'getResponseObject')
 | 
						||
          .returns(Promise.resolve([change_num, message]));
 | 
						||
      element._cache.set('/changes/' + change_num + '/message', {});
 | 
						||
      return element.putChangeCommitMessage(change_num, message).then(() => {
 | 
						||
        assert.isTrue(element._send.calledOnce);
 | 
						||
        assert.equal(element._send.lastCall.args[0].method, 'PUT');
 | 
						||
        assert.equal(element._send.lastCall.args[0].url,
 | 
						||
            '/changes/test~1/message');
 | 
						||
        assert.deepEqual(element._send.lastCall.args[0].body, {message});
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('startWorkInProgress', () => {
 | 
						||
      const sendStub = sandbox.stub(element, '_getChangeURLAndSend')
 | 
						||
          .returns(Promise.resolve('ok'));
 | 
						||
      element.startWorkInProgress('42');
 | 
						||
      assert.isTrue(sendStub.calledOnce);
 | 
						||
      assert.equal(sendStub.lastCall.args[0].changeNum, '42');
 | 
						||
      assert.equal(sendStub.lastCall.args[0].method, 'POST');
 | 
						||
      assert.isNotOk(sendStub.lastCall.args[0].patchNum);
 | 
						||
      assert.equal(sendStub.lastCall.args[0].endpoint, '/wip');
 | 
						||
      assert.deepEqual(sendStub.lastCall.args[0].body, {});
 | 
						||
 | 
						||
      element.startWorkInProgress('42', 'revising...');
 | 
						||
      assert.isTrue(sendStub.calledTwice);
 | 
						||
      assert.equal(sendStub.lastCall.args[0].changeNum, '42');
 | 
						||
      assert.equal(sendStub.lastCall.args[0].method, 'POST');
 | 
						||
      assert.isNotOk(sendStub.lastCall.args[0].patchNum);
 | 
						||
      assert.equal(sendStub.lastCall.args[0].endpoint, '/wip');
 | 
						||
      assert.deepEqual(sendStub.lastCall.args[0].body,
 | 
						||
          {message: 'revising...'});
 | 
						||
    });
 | 
						||
 | 
						||
    test('startReview', () => {
 | 
						||
      const sendStub = sandbox.stub(element, '_getChangeURLAndSend')
 | 
						||
          .returns(Promise.resolve({}));
 | 
						||
      element.startReview('42', {message: 'Please review.'});
 | 
						||
      assert.isTrue(sendStub.calledOnce);
 | 
						||
      assert.equal(sendStub.lastCall.args[0].changeNum, '42');
 | 
						||
      assert.equal(sendStub.lastCall.args[0].method, 'POST');
 | 
						||
      assert.isNotOk(sendStub.lastCall.args[0].patchNum);
 | 
						||
      assert.equal(sendStub.lastCall.args[0].endpoint, '/ready');
 | 
						||
      assert.deepEqual(sendStub.lastCall.args[0].body,
 | 
						||
          {message: 'Please review.'});
 | 
						||
    });
 | 
						||
 | 
						||
    test('deleteComment', () => {
 | 
						||
      const sendStub = sandbox.stub(element, '_getChangeURLAndSend')
 | 
						||
          .returns(Promise.resolve('some response'));
 | 
						||
      return element.deleteComment('foo', 'bar', '01234', 'removal reason')
 | 
						||
          .then(response => {
 | 
						||
            assert.equal(response, 'some response');
 | 
						||
            assert.isTrue(sendStub.calledOnce);
 | 
						||
            assert.equal(sendStub.lastCall.args[0].changeNum, 'foo');
 | 
						||
            assert.equal(sendStub.lastCall.args[0].method, 'POST');
 | 
						||
            assert.equal(sendStub.lastCall.args[0].patchNum, 'bar');
 | 
						||
            assert.equal(sendStub.lastCall.args[0].endpoint,
 | 
						||
                '/comments/01234/delete');
 | 
						||
            assert.deepEqual(sendStub.lastCall.args[0].body,
 | 
						||
                {reason: 'removal reason'});
 | 
						||
          });
 | 
						||
    });
 | 
						||
 | 
						||
    test('createRepo encodes name', () => {
 | 
						||
      const sendStub = sandbox.stub(element, '_send')
 | 
						||
          .returns(Promise.resolve());
 | 
						||
      return element.createRepo({name: 'x/y'}).then(() => {
 | 
						||
        assert.isTrue(sendStub.calledOnce);
 | 
						||
        assert.equal(sendStub.lastCall.args[0].url, '/projects/x%2Fy');
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('queryChangeFiles', () => {
 | 
						||
      const fetchStub = sandbox.stub(element, '_getChangeURLAndFetch')
 | 
						||
          .returns(Promise.resolve());
 | 
						||
      return element.queryChangeFiles('42', 'edit', 'test/path.js').then(() => {
 | 
						||
        assert.equal(fetchStub.lastCall.args[0].changeNum, '42');
 | 
						||
        assert.equal(fetchStub.lastCall.args[0].endpoint,
 | 
						||
            '/files?q=test%2Fpath.js');
 | 
						||
        assert.equal(fetchStub.lastCall.args[0].patchNum, 'edit');
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    suite('getRepos', () => {
 | 
						||
      const defaultQuery = 'state%3Aactive%20OR%20state%3Aread-only';
 | 
						||
 | 
						||
      setup(() => {
 | 
						||
        sandbox.stub(element, '_fetchSharedCacheURL');
 | 
						||
      });
 | 
						||
 | 
						||
      test('normal use', () => {
 | 
						||
        element.getRepos('test', 25);
 | 
						||
        assert.equal(element._fetchSharedCacheURL.lastCall.args[0].url,
 | 
						||
            '/projects/?n=26&S=0&query=test');
 | 
						||
 | 
						||
        element.getRepos(null, 25);
 | 
						||
        assert.equal(element._fetchSharedCacheURL.lastCall.args[0].url,
 | 
						||
            `/projects/?n=26&S=0&query=${defaultQuery}`);
 | 
						||
 | 
						||
        element.getRepos('test', 25, 25);
 | 
						||
        assert.equal(element._fetchSharedCacheURL.lastCall.args[0].url,
 | 
						||
            '/projects/?n=26&S=25&query=test');
 | 
						||
      });
 | 
						||
 | 
						||
      test('with blank', () => {
 | 
						||
        element.getRepos('test/test', 25);
 | 
						||
        assert.equal(element._fetchSharedCacheURL.lastCall.args[0].url,
 | 
						||
            '/projects/?n=26&S=0&query=inname%3Atest%20AND%20inname%3Atest');
 | 
						||
      });
 | 
						||
 | 
						||
      test('with hyphen', () => {
 | 
						||
        element.getRepos('foo-bar', 25);
 | 
						||
        assert.equal(element._fetchSharedCacheURL.lastCall.args[0].url,
 | 
						||
            '/projects/?n=26&S=0&query=inname%3Afoo%20AND%20inname%3Abar');
 | 
						||
      });
 | 
						||
 | 
						||
      test('with leading hyphen', () => {
 | 
						||
        element.getRepos('-bar', 25);
 | 
						||
        assert.equal(element._fetchSharedCacheURL.lastCall.args[0].url,
 | 
						||
            '/projects/?n=26&S=0&query=inname%3Abar');
 | 
						||
      });
 | 
						||
 | 
						||
      test('with trailing hyphen', () => {
 | 
						||
        element.getRepos('foo-bar-', 25);
 | 
						||
        assert.equal(element._fetchSharedCacheURL.lastCall.args[0].url,
 | 
						||
            '/projects/?n=26&S=0&query=inname%3Afoo%20AND%20inname%3Abar');
 | 
						||
      });
 | 
						||
 | 
						||
      test('with underscore', () => {
 | 
						||
        element.getRepos('foo_bar', 25);
 | 
						||
        assert.equal(element._fetchSharedCacheURL.lastCall.args[0].url,
 | 
						||
            '/projects/?n=26&S=0&query=inname%3Afoo%20AND%20inname%3Abar');
 | 
						||
      });
 | 
						||
 | 
						||
      test('with underscore', () => {
 | 
						||
        element.getRepos('foo_bar', 25);
 | 
						||
        assert.equal(element._fetchSharedCacheURL.lastCall.args[0].url,
 | 
						||
            '/projects/?n=26&S=0&query=inname%3Afoo%20AND%20inname%3Abar');
 | 
						||
      });
 | 
						||
 | 
						||
      test('hyphen only', () => {
 | 
						||
        element.getRepos('-', 25);
 | 
						||
        assert.equal(element._fetchSharedCacheURL.lastCall.args[0].url,
 | 
						||
            `/projects/?n=26&S=0&query=${defaultQuery}`);
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('getGroups filter regex', () => {
 | 
						||
      sandbox.stub(element, '_fetchSharedCacheURL');
 | 
						||
      element.getGroups('^test.*', 25);
 | 
						||
      assert.equal(element._fetchSharedCacheURL.lastCall.args[0].url,
 | 
						||
          '/groups/?n=26&S=0&r=%5Etest.*');
 | 
						||
    });
 | 
						||
 | 
						||
    test('gerrit auth is used', () => {
 | 
						||
      sandbox.stub(Gerrit.Auth, 'fetch').returns(Promise.resolve());
 | 
						||
      element._fetchJSON('foo');
 | 
						||
      assert(Gerrit.Auth.fetch.called);
 | 
						||
    });
 | 
						||
 | 
						||
    test('getSuggestedAccounts does not return _fetchJSON', () => {
 | 
						||
      const _fetchJSONSpy = sandbox.spy(element, '_fetchJSON');
 | 
						||
      return element.getSuggestedAccounts().then(accts => {
 | 
						||
        assert.isFalse(_fetchJSONSpy.called);
 | 
						||
        assert.equal(accts.length, 0);
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('_fetchJSON gets called by getSuggestedAccounts', () => {
 | 
						||
      const _fetchJSONStub = sandbox.stub(element, '_fetchJSON',
 | 
						||
          () => Promise.resolve());
 | 
						||
      return element.getSuggestedAccounts('own').then(() => {
 | 
						||
        assert.deepEqual(_fetchJSONStub.lastCall.args[0].params, {
 | 
						||
          q: 'own',
 | 
						||
          suggest: null,
 | 
						||
        });
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    suite('_getChangeDetail', () => {
 | 
						||
      test('_getChangeDetail passes params to ETags decorator', () => {
 | 
						||
        const changeNum = 4321;
 | 
						||
        element._projectLookup[changeNum] = 'test';
 | 
						||
        const params = {foo: 'bar'};
 | 
						||
        const expectedUrl =
 | 
						||
            window.CANONICAL_PATH + '/changes/test~4321/detail?foo=bar';
 | 
						||
        sandbox.stub(element._etags, 'getOptions');
 | 
						||
        sandbox.stub(element._etags, 'collect');
 | 
						||
        return element._getChangeDetail(changeNum, params).then(() => {
 | 
						||
          assert.isTrue(element._etags.getOptions.calledWithExactly(
 | 
						||
              expectedUrl));
 | 
						||
          assert.equal(element._etags.collect.lastCall.args[0], expectedUrl);
 | 
						||
        });
 | 
						||
      });
 | 
						||
 | 
						||
      test('_getChangeDetail calls errFn on 500', () => {
 | 
						||
        const errFn = sinon.stub();
 | 
						||
        sandbox.stub(element, 'getChangeActionURL')
 | 
						||
            .returns(Promise.resolve(''));
 | 
						||
        sandbox.stub(element, '_fetchRawJSON')
 | 
						||
            .returns(Promise.resolve({ok: false, status: 500}));
 | 
						||
        return element._getChangeDetail(123, {}, errFn).then(() => {
 | 
						||
          assert.isTrue(errFn.called);
 | 
						||
        });
 | 
						||
      });
 | 
						||
 | 
						||
      test('_getChangeDetail populates _projectLookup', () => {
 | 
						||
        sandbox.stub(element, 'getChangeActionURL')
 | 
						||
            .returns(Promise.resolve(''));
 | 
						||
        sandbox.stub(element, '_fetchRawJSON')
 | 
						||
            .returns(Promise.resolve({ok: true}));
 | 
						||
 | 
						||
        const mockResponse = {_number: 1, project: 'test'};
 | 
						||
        sandbox.stub(element, '_readResponsePayload').returns(Promise.resolve({
 | 
						||
          parsed: mockResponse,
 | 
						||
          raw: JSON.stringify(mockResponse),
 | 
						||
        }));
 | 
						||
        return element._getChangeDetail(1).then(() => {
 | 
						||
          assert.equal(Object.keys(element._projectLookup).length, 1);
 | 
						||
          assert.equal(element._projectLookup[1], 'test');
 | 
						||
        });
 | 
						||
      });
 | 
						||
 | 
						||
      suite('_getChangeDetail ETag cache', () => {
 | 
						||
        let requestUrl;
 | 
						||
        let mockResponseSerial;
 | 
						||
        let collectSpy;
 | 
						||
        let getPayloadSpy;
 | 
						||
 | 
						||
        setup(() => {
 | 
						||
          requestUrl = '/foo/bar';
 | 
						||
          const mockResponse = {foo: 'bar', baz: 42};
 | 
						||
          mockResponseSerial = element.JSON_PREFIX +
 | 
						||
              JSON.stringify(mockResponse);
 | 
						||
          sandbox.stub(element, '_urlWithParams').returns(requestUrl);
 | 
						||
          sandbox.stub(element, 'getChangeActionURL')
 | 
						||
              .returns(Promise.resolve(requestUrl));
 | 
						||
          collectSpy = sandbox.spy(element._etags, 'collect');
 | 
						||
          getPayloadSpy = sandbox.spy(element._etags, 'getCachedPayload');
 | 
						||
        });
 | 
						||
 | 
						||
        test('contributes to cache', () => {
 | 
						||
          sandbox.stub(element, '_fetchRawJSON').returns(Promise.resolve({
 | 
						||
            text: () => Promise.resolve(mockResponseSerial),
 | 
						||
            status: 200,
 | 
						||
            ok: true,
 | 
						||
          }));
 | 
						||
 | 
						||
          return element._getChangeDetail(123, {}).then(detail => {
 | 
						||
            assert.isFalse(getPayloadSpy.called);
 | 
						||
            assert.isTrue(collectSpy.calledOnce);
 | 
						||
            const cachedResponse = element._etags.getCachedPayload(requestUrl);
 | 
						||
            assert.equal(cachedResponse, mockResponseSerial);
 | 
						||
          });
 | 
						||
        });
 | 
						||
 | 
						||
        test('uses cache on HTTP 304', () => {
 | 
						||
          sandbox.stub(element, '_fetchRawJSON').returns(Promise.resolve({
 | 
						||
            text: () => Promise.resolve(mockResponseSerial),
 | 
						||
            status: 304,
 | 
						||
            ok: true,
 | 
						||
          }));
 | 
						||
 | 
						||
          return element._getChangeDetail(123, {}).then(detail => {
 | 
						||
            assert.isFalse(collectSpy.called);
 | 
						||
            assert.isTrue(getPayloadSpy.calledOnce);
 | 
						||
          });
 | 
						||
        });
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('setInProjectLookup', () => {
 | 
						||
      element.setInProjectLookup('test', 'project');
 | 
						||
      assert.deepEqual(element._projectLookup, {test: 'project'});
 | 
						||
    });
 | 
						||
 | 
						||
    suite('getFromProjectLookup', () => {
 | 
						||
      test('getChange fails', () => {
 | 
						||
        sandbox.stub(element, 'getChange')
 | 
						||
            .returns(Promise.resolve(null));
 | 
						||
        return element.getFromProjectLookup().then(val => {
 | 
						||
          assert.strictEqual(val, undefined);
 | 
						||
          assert.deepEqual(element._projectLookup, {});
 | 
						||
        });
 | 
						||
      });
 | 
						||
 | 
						||
      test('getChange succeeds, no project', () => {
 | 
						||
        sandbox.stub(element, 'getChange').returns(Promise.resolve(null));
 | 
						||
        return element.getFromProjectLookup().then(val => {
 | 
						||
          assert.strictEqual(val, undefined);
 | 
						||
          assert.deepEqual(element._projectLookup, {});
 | 
						||
        });
 | 
						||
      });
 | 
						||
 | 
						||
      test('getChange succeeds with project', () => {
 | 
						||
        sandbox.stub(element, 'getChange')
 | 
						||
            .returns(Promise.resolve({project: 'project'}));
 | 
						||
        return element.getFromProjectLookup('test').then(val => {
 | 
						||
          assert.equal(val, 'project');
 | 
						||
          assert.deepEqual(element._projectLookup, {test: 'project'});
 | 
						||
        });
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    suite('getChanges populates _projectLookup', () => {
 | 
						||
      test('multiple queries', () => {
 | 
						||
        sandbox.stub(element, '_fetchJSON')
 | 
						||
            .returns(Promise.resolve([
 | 
						||
              [
 | 
						||
                {_number: 1, project: 'test'},
 | 
						||
                {_number: 2, project: 'test'},
 | 
						||
              ], [
 | 
						||
                {_number: 3, project: 'test/test'},
 | 
						||
              ],
 | 
						||
            ]));
 | 
						||
        // When opt_query instanceof Array, _fetchJSON returns
 | 
						||
        // Array<Array<Object>>.
 | 
						||
        return element.getChanges(null, []).then(() => {
 | 
						||
          assert.equal(Object.keys(element._projectLookup).length, 3);
 | 
						||
          assert.equal(element._projectLookup[1], 'test');
 | 
						||
          assert.equal(element._projectLookup[2], 'test');
 | 
						||
          assert.equal(element._projectLookup[3], 'test/test');
 | 
						||
        });
 | 
						||
      });
 | 
						||
 | 
						||
      test('no query', () => {
 | 
						||
        sandbox.stub(element, '_fetchJSON')
 | 
						||
            .returns(Promise.resolve([
 | 
						||
              {_number: 1, project: 'test'},
 | 
						||
              {_number: 2, project: 'test'},
 | 
						||
              {_number: 3, project: 'test/test'},
 | 
						||
            ]));
 | 
						||
 | 
						||
        // When opt_query !instanceof Array, _fetchJSON returns
 | 
						||
        // Array<Object>.
 | 
						||
        return element.getChanges().then(() => {
 | 
						||
          assert.equal(Object.keys(element._projectLookup).length, 3);
 | 
						||
          assert.equal(element._projectLookup[1], 'test');
 | 
						||
          assert.equal(element._projectLookup[2], 'test');
 | 
						||
          assert.equal(element._projectLookup[3], 'test/test');
 | 
						||
        });
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('_getChangeURLAndFetch', () => {
 | 
						||
      element._projectLookup = {1: 'test'};
 | 
						||
      const fetchStub = sandbox.stub(element, '_fetchJSON')
 | 
						||
          .returns(Promise.resolve());
 | 
						||
      const req = {changeNum: 1, endpoint: '/test', patchNum: 1};
 | 
						||
      return element._getChangeURLAndFetch(req).then(() => {
 | 
						||
        assert.equal(fetchStub.lastCall.args[0].url,
 | 
						||
            '/changes/test~1/revisions/1/test');
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('_getChangeURLAndSend', () => {
 | 
						||
      element._projectLookup = {1: 'test'};
 | 
						||
      const sendStub = sandbox.stub(element, '_send')
 | 
						||
          .returns(Promise.resolve());
 | 
						||
 | 
						||
      const req = {
 | 
						||
        changeNum: 1,
 | 
						||
        method: 'POST',
 | 
						||
        patchNum: 1,
 | 
						||
        endpoint: '/test',
 | 
						||
      };
 | 
						||
      return element._getChangeURLAndSend(req).then(() => {
 | 
						||
        assert.isTrue(sendStub.calledOnce);
 | 
						||
        assert.equal(sendStub.lastCall.args[0].method, 'POST');
 | 
						||
        assert.equal(sendStub.lastCall.args[0].url,
 | 
						||
            '/changes/test~1/revisions/1/test');
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    suite('reading responses', () => {
 | 
						||
      test('_readResponsePayload', () => {
 | 
						||
        const mockObject = {foo: 'bar', baz: 'foo'};
 | 
						||
        const serial = element.JSON_PREFIX + JSON.stringify(mockObject);
 | 
						||
        const mockResponse = {text: () => Promise.resolve(serial)};
 | 
						||
        return element._readResponsePayload(mockResponse).then(payload => {
 | 
						||
          assert.deepEqual(payload.parsed, mockObject);
 | 
						||
          assert.equal(payload.raw, serial);
 | 
						||
        });
 | 
						||
      });
 | 
						||
 | 
						||
      test('_parsePrefixedJSON', () => {
 | 
						||
        const obj = {x: 3, y: {z: 4}, w: 23};
 | 
						||
        const serial = element.JSON_PREFIX + JSON.stringify(obj);
 | 
						||
        const result = element._parsePrefixedJSON(serial);
 | 
						||
        assert.deepEqual(result, obj);
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('setChangeTopic', () => {
 | 
						||
      const sendSpy = sandbox.spy(element, '_getChangeURLAndSend');
 | 
						||
      return element.setChangeTopic(123, 'foo-bar').then(() => {
 | 
						||
        assert.isTrue(sendSpy.calledOnce);
 | 
						||
        assert.deepEqual(sendSpy.lastCall.args[0].body, {topic: 'foo-bar'});
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('setChangeHashtag', () => {
 | 
						||
      const sendSpy = sandbox.spy(element, '_getChangeURLAndSend');
 | 
						||
      return element.setChangeHashtag(123, 'foo-bar').then(() => {
 | 
						||
        assert.isTrue(sendSpy.calledOnce);
 | 
						||
        assert.equal(sendSpy.lastCall.args[0].body, 'foo-bar');
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('generateAccountHttpPassword', () => {
 | 
						||
      const sendSpy = sandbox.spy(element, '_send');
 | 
						||
      return element.generateAccountHttpPassword().then(() => {
 | 
						||
        assert.isTrue(sendSpy.calledOnce);
 | 
						||
        assert.deepEqual(sendSpy.lastCall.args[0].body, {generate: true});
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    suite('getChangeFiles', () => {
 | 
						||
      test('patch only', () => {
 | 
						||
        const fetchStub = sandbox.stub(element, '_getChangeURLAndFetch')
 | 
						||
            .returns(Promise.resolve());
 | 
						||
        const range = {basePatchNum: 'PARENT', patchNum: 2};
 | 
						||
        return element.getChangeFiles(123, range).then(() => {
 | 
						||
          assert.isTrue(fetchStub.calledOnce);
 | 
						||
          assert.equal(fetchStub.lastCall.args[0].patchNum, 2);
 | 
						||
          assert.isNotOk(fetchStub.lastCall.args[0].params);
 | 
						||
        });
 | 
						||
      });
 | 
						||
 | 
						||
      test('simple range', () => {
 | 
						||
        const fetchStub = sandbox.stub(element, '_getChangeURLAndFetch')
 | 
						||
            .returns(Promise.resolve());
 | 
						||
        const range = {basePatchNum: 4, patchNum: 5};
 | 
						||
        return element.getChangeFiles(123, range).then(() => {
 | 
						||
          assert.isTrue(fetchStub.calledOnce);
 | 
						||
          assert.equal(fetchStub.lastCall.args[0].patchNum, 5);
 | 
						||
          assert.isOk(fetchStub.lastCall.args[0].params);
 | 
						||
          assert.equal(fetchStub.lastCall.args[0].params.base, 4);
 | 
						||
          assert.isNotOk(fetchStub.lastCall.args[0].params.parent);
 | 
						||
        });
 | 
						||
      });
 | 
						||
 | 
						||
      test('parent index', () => {
 | 
						||
        const fetchStub = sandbox.stub(element, '_getChangeURLAndFetch')
 | 
						||
            .returns(Promise.resolve());
 | 
						||
        const range = {basePatchNum: -3, patchNum: 5};
 | 
						||
        return element.getChangeFiles(123, range).then(() => {
 | 
						||
          assert.isTrue(fetchStub.calledOnce);
 | 
						||
          assert.equal(fetchStub.lastCall.args[0].patchNum, 5);
 | 
						||
          assert.isOk(fetchStub.lastCall.args[0].params);
 | 
						||
          assert.isNotOk(fetchStub.lastCall.args[0].params.base);
 | 
						||
          assert.equal(fetchStub.lastCall.args[0].params.parent, 3);
 | 
						||
        });
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    suite('getDiff', () => {
 | 
						||
      test('patchOnly', () => {
 | 
						||
        const fetchStub = sandbox.stub(element, '_getChangeURLAndFetch')
 | 
						||
            .returns(Promise.resolve());
 | 
						||
        return element.getDiff(123, 'PARENT', 2, 'foo/bar.baz').then(() => {
 | 
						||
          assert.isTrue(fetchStub.calledOnce);
 | 
						||
          assert.equal(fetchStub.lastCall.args[0].patchNum, 2);
 | 
						||
          assert.isOk(fetchStub.lastCall.args[0].params);
 | 
						||
          assert.isNotOk(fetchStub.lastCall.args[0].params.parent);
 | 
						||
          assert.isNotOk(fetchStub.lastCall.args[0].params.base);
 | 
						||
        });
 | 
						||
      });
 | 
						||
 | 
						||
      test('simple range', () => {
 | 
						||
        const fetchStub = sandbox.stub(element, '_getChangeURLAndFetch')
 | 
						||
            .returns(Promise.resolve());
 | 
						||
        return element.getDiff(123, 4, 5, 'foo/bar.baz').then(() => {
 | 
						||
          assert.isTrue(fetchStub.calledOnce);
 | 
						||
          assert.equal(fetchStub.lastCall.args[0].patchNum, 5);
 | 
						||
          assert.isOk(fetchStub.lastCall.args[0].params);
 | 
						||
          assert.isNotOk(fetchStub.lastCall.args[0].params.parent);
 | 
						||
          assert.equal(fetchStub.lastCall.args[0].params.base, 4);
 | 
						||
        });
 | 
						||
      });
 | 
						||
 | 
						||
      test('parent index', () => {
 | 
						||
        const fetchStub = sandbox.stub(element, '_getChangeURLAndFetch')
 | 
						||
            .returns(Promise.resolve());
 | 
						||
        return element.getDiff(123, -3, 5, 'foo/bar.baz').then(() => {
 | 
						||
          assert.isTrue(fetchStub.calledOnce);
 | 
						||
          assert.equal(fetchStub.lastCall.args[0].patchNum, 5);
 | 
						||
          assert.isOk(fetchStub.lastCall.args[0].params);
 | 
						||
          assert.isNotOk(fetchStub.lastCall.args[0].params.base);
 | 
						||
          assert.equal(fetchStub.lastCall.args[0].params.parent, 3);
 | 
						||
        });
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('getDashboard', () => {
 | 
						||
      const fetchStub = sandbox.stub(element, '_fetchSharedCacheURL');
 | 
						||
      element.getDashboard('gerrit/project', 'default:main');
 | 
						||
      assert.isTrue(fetchStub.calledOnce);
 | 
						||
      assert.equal(
 | 
						||
          fetchStub.lastCall.args[0].url,
 | 
						||
          '/projects/gerrit%2Fproject/dashboards/default%3Amain');
 | 
						||
    });
 | 
						||
 | 
						||
    test('getFileContent', () => {
 | 
						||
      sandbox.stub(element, '_getChangeURLAndSend')
 | 
						||
          .returns(Promise.resolve({
 | 
						||
            ok: 'true',
 | 
						||
            headers: {
 | 
						||
              get(header) {
 | 
						||
                if (header === 'X-FYI-Content-Type') {
 | 
						||
                  return 'text/java';
 | 
						||
                }
 | 
						||
              },
 | 
						||
            },
 | 
						||
          }));
 | 
						||
 | 
						||
      sandbox.stub(element, 'getResponseObject')
 | 
						||
          .returns(Promise.resolve('new content'));
 | 
						||
 | 
						||
      const edit = element.getFileContent('1', 'tst/path', 'EDIT').then(res => {
 | 
						||
        assert.deepEqual(res,
 | 
						||
            {content: 'new content', type: 'text/java', ok: true});
 | 
						||
      });
 | 
						||
 | 
						||
      const normal = element.getFileContent('1', 'tst/path', '3').then(res => {
 | 
						||
        assert.deepEqual(res,
 | 
						||
            {content: 'new content', type: 'text/java', ok: true});
 | 
						||
      });
 | 
						||
 | 
						||
      return Promise.all([edit, normal]);
 | 
						||
    });
 | 
						||
 | 
						||
    test('getFileContent suppresses 404s', done => {
 | 
						||
      const res = {status: 404};
 | 
						||
      const handler = e => {
 | 
						||
        assert.isFalse(e.detail.res.status === 404);
 | 
						||
        done();
 | 
						||
      };
 | 
						||
      element.addEventListener('server-error', handler);
 | 
						||
      sandbox.stub(Gerrit.Auth, 'fetch').returns(Promise.resolve(res));
 | 
						||
      sandbox.stub(element, '_changeBaseURL').returns(Promise.resolve(''));
 | 
						||
      element.getFileContent('1', 'tst/path', '1').then(() => {
 | 
						||
        flushAsynchronousOperations();
 | 
						||
 | 
						||
        res.status = 500;
 | 
						||
        element.getFileContent('1', 'tst/path', '1');
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('getChangeFilesOrEditFiles is edit-sensitive', () => {
 | 
						||
      const fn = element.getChangeOrEditFiles.bind(element);
 | 
						||
      const getChangeFilesStub = sandbox.stub(element, 'getChangeFiles')
 | 
						||
          .returns(Promise.resolve({}));
 | 
						||
      const getChangeEditFilesStub = sandbox.stub(element, 'getChangeEditFiles')
 | 
						||
          .returns(Promise.resolve({}));
 | 
						||
 | 
						||
      return fn('1', {patchNum: 'edit'}).then(() => {
 | 
						||
        assert.isTrue(getChangeEditFilesStub.calledOnce);
 | 
						||
        assert.isFalse(getChangeFilesStub.called);
 | 
						||
        return fn('1', {patchNum: '1'}).then(() => {
 | 
						||
          assert.isTrue(getChangeEditFilesStub.calledOnce);
 | 
						||
          assert.isTrue(getChangeFilesStub.calledOnce);
 | 
						||
        });
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('_fetch forwards request and logs', () => {
 | 
						||
      const logStub = sandbox.stub(element, '_logCall');
 | 
						||
      const response = {status: 404, text: sinon.stub()};
 | 
						||
      const url = 'my url';
 | 
						||
      const fetchOptions = {method: 'DELETE'};
 | 
						||
      sandbox.stub(element._auth, 'fetch').returns(Promise.resolve(response));
 | 
						||
      const startTime = 123;
 | 
						||
      sandbox.stub(Date, 'now').returns(startTime);
 | 
						||
      const req = {url, fetchOptions};
 | 
						||
      return element._fetch(req).then(() => {
 | 
						||
        assert.isTrue(logStub.calledOnce);
 | 
						||
        assert.isTrue(logStub.calledWith(req, startTime, response.status));
 | 
						||
        assert.isFalse(response.text.called);
 | 
						||
      });
 | 
						||
    });
 | 
						||
 | 
						||
    test('_logCall only reports requests with anonymized URLss', () => {
 | 
						||
      sandbox.stub(Date, 'now').returns(200);
 | 
						||
      const handler = sinon.stub();
 | 
						||
      element.addEventListener('rpc-log', handler);
 | 
						||
 | 
						||
      element._logCall({url: 'url'}, 100, 200);
 | 
						||
      assert.isFalse(handler.called);
 | 
						||
 | 
						||
      element._logCall({url: 'url', anonymizedUrl: 'not url'}, 100, 200);
 | 
						||
      flushAsynchronousOperations();
 | 
						||
      assert.isTrue(handler.calledOnce);
 | 
						||
    });
 | 
						||
 | 
						||
    test('saveChangeStarred', async () => {
 | 
						||
      sandbox.stub(element, 'getFromProjectLookup')
 | 
						||
          .returns(Promise.resolve('test'));
 | 
						||
      const sendStub =
 | 
						||
          sandbox.stub(element, '_send').returns(Promise.resolve());
 | 
						||
 | 
						||
      await element.saveChangeStarred(123, true);
 | 
						||
      assert.isTrue(sendStub.calledOnce);
 | 
						||
      assert.deepEqual(sendStub.lastCall.args[0], {
 | 
						||
        method: 'PUT',
 | 
						||
        url: '/accounts/self/starred.changes/test~123',
 | 
						||
        anonymizedUrl: '/accounts/self/starred.changes/*',
 | 
						||
      });
 | 
						||
 | 
						||
      await element.saveChangeStarred(456, false);
 | 
						||
      assert.isTrue(sendStub.calledTwice);
 | 
						||
      assert.deepEqual(sendStub.lastCall.args[0], {
 | 
						||
        method: 'DELETE',
 | 
						||
        url: '/accounts/self/starred.changes/test~456',
 | 
						||
        anonymizedUrl: '/accounts/self/starred.changes/*',
 | 
						||
      });
 | 
						||
    });
 | 
						||
  });
 | 
						||
</script>
 |