 eb12253ff0
			
		
	
	eb12253ff0
	
	
	
		
			
			Shift+m marks the current file as reviewed and navigates to the next unreviewed file. Bug: Issue 9280 Change-Id: I11ac225dfbfdf07b10b35297314031c48fd0799c
		
			
				
	
	
		
			1129 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			1129 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html>
 | |
| <!--
 | |
| @license
 | |
| Copyright (C) 2015 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-diff-view</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="../../../bower_components/page/page.js"></script>
 | |
| <script src="../../../scripts/util.js"></script>
 | |
| 
 | |
| <link rel="import" href="gr-diff-view.html">
 | |
| 
 | |
| <script>void(0);</script>
 | |
| 
 | |
| <test-fixture id="basic">
 | |
|   <template>
 | |
|     <gr-diff-view></gr-diff-view>
 | |
|   </template>
 | |
| </test-fixture>
 | |
| 
 | |
| <test-fixture id="blank">
 | |
|   <template>
 | |
|     <div></div>
 | |
|   </template>
 | |
| </test-fixture>
 | |
| 
 | |
| <script>
 | |
|   suite('gr-diff-view tests', () => {
 | |
|     const kb = window.Gerrit.KeyboardShortcutBinder;
 | |
|     kb.bindShortcut(kb.Shortcut.LEFT_PANE, 'shift+left');
 | |
|     kb.bindShortcut(kb.Shortcut.RIGHT_PANE, 'shift+right');
 | |
|     kb.bindShortcut(kb.Shortcut.NEXT_LINE, 'j', 'down');
 | |
|     kb.bindShortcut(kb.Shortcut.PREV_LINE, 'k', 'up');
 | |
|     kb.bindShortcut(kb.Shortcut.NEXT_FILE_WITH_COMMENTS, 'shift+j');
 | |
|     kb.bindShortcut(kb.Shortcut.PREV_FILE_WITH_COMMENTS, 'shift+k');
 | |
|     kb.bindShortcut(kb.Shortcut.NEW_COMMENT, 'c');
 | |
|     kb.bindShortcut(kb.Shortcut.SAVE_COMMENT, 'ctrl+s');
 | |
|     kb.bindShortcut(kb.Shortcut.NEXT_FILE, ']');
 | |
|     kb.bindShortcut(kb.Shortcut.PREV_FILE, '[');
 | |
|     kb.bindShortcut(kb.Shortcut.NEXT_CHUNK, 'n');
 | |
|     kb.bindShortcut(kb.Shortcut.NEXT_COMMENT_THREAD, 'shift+n');
 | |
|     kb.bindShortcut(kb.Shortcut.PREV_CHUNK, 'p');
 | |
|     kb.bindShortcut(kb.Shortcut.PREV_COMMENT_THREAD, 'shift+p');
 | |
|     kb.bindShortcut(kb.Shortcut.OPEN_REPLY_DIALOG, 'a');
 | |
|     kb.bindShortcut(kb.Shortcut.TOGGLE_LEFT_PANE, 'shift+a');
 | |
|     kb.bindShortcut(kb.Shortcut.UP_TO_CHANGE, 'u');
 | |
|     kb.bindShortcut(kb.Shortcut.OPEN_DIFF_PREFS, ',');
 | |
|     kb.bindShortcut(kb.Shortcut.TOGGLE_DIFF_MODE, 'm');
 | |
|     kb.bindShortcut(kb.Shortcut.TOGGLE_FILE_REVIEWED, 'r');
 | |
|     kb.bindShortcut(kb.Shortcut.EXPAND_ALL_DIFF_CONTEXT, 'shift+x');
 | |
|     kb.bindShortcut(kb.Shortcut.EXPAND_ALL_COMMENT_THREADS, 'e');
 | |
|     kb.bindShortcut(kb.Shortcut.COLLAPSE_ALL_COMMENT_THREADS, 'shift+e');
 | |
|     kb.bindShortcut(kb.Shortcut.NEXT_UNREVIEWED_FILE, 'shift+m');
 | |
| 
 | |
|     let element;
 | |
|     let sandbox;
 | |
| 
 | |
|     const PARENT = 'PARENT';
 | |
| 
 | |
|     setup(() => {
 | |
|       sandbox = sinon.sandbox.create();
 | |
| 
 | |
|       stub('gr-rest-api-interface', {
 | |
|         getConfig() { return Promise.resolve({change: {}}); },
 | |
|         getLoggedIn() { return Promise.resolve(false); },
 | |
|         getProjectConfig() { return Promise.resolve({}); },
 | |
|         getDiffChangeDetail() { return Promise.resolve({}); },
 | |
|         getChangeFiles() { return Promise.resolve({}); },
 | |
|         saveFileReviewed() { return Promise.resolve(); },
 | |
|         getDiffComments() { return Promise.resolve({}); },
 | |
|         getDiffRobotComments() { return Promise.resolve({}); },
 | |
|         getDiffDrafts() { return Promise.resolve({}); },
 | |
|         getReviewedFiles() { return Promise.resolve([]); },
 | |
|       });
 | |
|       element = fixture('basic');
 | |
|       return element._loadComments();
 | |
|     });
 | |
| 
 | |
|     teardown(() => {
 | |
|       sandbox.restore();
 | |
|     });
 | |
| 
 | |
|     test('params change triggers diffViewDisplayed()', () => {
 | |
|       sandbox.stub(element.$.reporting, 'diffViewDisplayed');
 | |
|       sandbox.stub(element.$.diffHost, 'reload').returns(Promise.resolve());
 | |
|       sandbox.spy(element, '_paramsChanged');
 | |
|       element.params = {
 | |
|         view: Gerrit.Nav.View.DIFF,
 | |
|         changeNum: '42',
 | |
|         patchNum: '2',
 | |
|         basePatchNum: '1',
 | |
|         path: '/COMMIT_MSG',
 | |
|       };
 | |
| 
 | |
|       return element._paramsChanged.returnValues[0].then(() => {
 | |
|         assert.isTrue(element.$.reporting.diffViewDisplayed.calledOnce);
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     test('toggle left diff with a hotkey', () => {
 | |
|       const toggleLeftDiffStub = sandbox.stub(
 | |
|           element.$.diffHost, 'toggleLeftDiff');
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 65, 'shift', 'a');
 | |
|       assert.isTrue(toggleLeftDiffStub.calledOnce);
 | |
|     });
 | |
| 
 | |
|     test('keyboard shortcuts', () => {
 | |
|       element._changeNum = '42';
 | |
|       element._patchRange = {
 | |
|         basePatchNum: PARENT,
 | |
|         patchNum: '10',
 | |
|       };
 | |
|       element._change = {
 | |
|         _number: 42,
 | |
|         revisions: {
 | |
|           a: {_number: 10, commit: {parents: []}},
 | |
|         },
 | |
|       };
 | |
|       element._fileList = ['chell.go', 'glados.txt', 'wheatley.md'];
 | |
|       element._path = 'glados.txt';
 | |
|       element.changeViewState.selectedFileIndex = 1;
 | |
| 
 | |
|       const diffNavStub = sandbox.stub(Gerrit.Nav, 'navigateToDiff');
 | |
|       const changeNavStub = sandbox.stub(Gerrit.Nav, 'navigateToChange');
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 85, null, 'u');
 | |
|       assert(changeNavStub.lastCall.calledWith(element._change),
 | |
|           'Should navigate to /c/42/');
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 221, null, ']');
 | |
|       assert(diffNavStub.lastCall.calledWith(element._change, 'wheatley.md',
 | |
|           '10', PARENT), 'Should navigate to /c/42/10/wheatley.md');
 | |
|       element._path = 'wheatley.md';
 | |
|       assert.equal(element.changeViewState.selectedFileIndex, 2);
 | |
|       assert.isTrue(element._loading);
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
 | |
|       assert(diffNavStub.lastCall.calledWith(element._change, 'glados.txt',
 | |
|           '10', PARENT), 'Should navigate to /c/42/10/glados.txt');
 | |
|       element._path = 'glados.txt';
 | |
|       assert.equal(element.changeViewState.selectedFileIndex, 1);
 | |
|       assert.isTrue(element._loading);
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
 | |
|       assert(diffNavStub.lastCall.calledWith(element._change, 'chell.go', '10',
 | |
|           PARENT), 'Should navigate to /c/42/10/chell.go');
 | |
|       element._path = 'chell.go';
 | |
|       assert.equal(element.changeViewState.selectedFileIndex, 0);
 | |
|       assert.isTrue(element._loading);
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
 | |
|       assert(changeNavStub.lastCall.calledWith(element._change),
 | |
|           'Should navigate to /c/42/');
 | |
|       assert.equal(element.changeViewState.selectedFileIndex, 0);
 | |
|       assert.isTrue(element._loading);
 | |
| 
 | |
|       const showPrefsStub =
 | |
|           sandbox.stub(element.$.diffPreferences.$.prefsOverlay, 'open',
 | |
|               () => Promise.resolve());
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 188, null, ',');
 | |
|       assert(showPrefsStub.calledOnce);
 | |
| 
 | |
|       let scrollStub = sandbox.stub(element.$.cursor, 'moveToNextChunk');
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 78, null, 'n');
 | |
|       assert(scrollStub.calledOnce);
 | |
| 
 | |
|       scrollStub = sandbox.stub(element.$.cursor, 'moveToPreviousChunk');
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 80, null, 'p');
 | |
|       assert(scrollStub.calledOnce);
 | |
| 
 | |
|       scrollStub = sandbox.stub(element.$.cursor, 'moveToNextCommentThread');
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 78, 'shift', 'n');
 | |
|       assert(scrollStub.calledOnce);
 | |
| 
 | |
|       scrollStub = sandbox.stub(element.$.cursor,
 | |
|           'moveToPreviousCommentThread');
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 80, 'shift', 'p');
 | |
|       assert(scrollStub.calledOnce);
 | |
| 
 | |
|       const computeContainerClassStub = sandbox.stub(element.$.diffHost.$.diff,
 | |
|           '_computeContainerClass');
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 74, null, 'j');
 | |
|       assert(computeContainerClassStub.lastCall.calledWithExactly(
 | |
|           false, 'SIDE_BY_SIDE', true));
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 27, null, 'esc');
 | |
|       assert(computeContainerClassStub.lastCall.calledWithExactly(
 | |
|           false, 'SIDE_BY_SIDE', false));
 | |
| 
 | |
|       sandbox.stub(element, '_setReviewed');
 | |
|       element.$.reviewed.checked = false;
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 82, 'shift', 'r');
 | |
|       assert.isFalse(element._setReviewed.called);
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 82, null, 'r');
 | |
|       assert.isTrue(element._setReviewed.called);
 | |
|       assert.equal(element._setReviewed.lastCall.args[0], true);
 | |
|     });
 | |
| 
 | |
|     test('shift+x shortcut expands all diff context', () => {
 | |
|       const expandStub = sandbox.stub(element.$.diffHost, 'expandAllContext');
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 88, 'shift', 'x');
 | |
|       flushAsynchronousOperations();
 | |
|       assert.isTrue(expandStub.called);
 | |
|     });
 | |
| 
 | |
|     test('keyboard shortcuts with patch range', () => {
 | |
|       element._changeNum = '42';
 | |
|       element._patchRange = {
 | |
|         basePatchNum: '5',
 | |
|         patchNum: '10',
 | |
|       };
 | |
|       element._change = {
 | |
|         _number: 42,
 | |
|         revisions: {
 | |
|           a: {_number: 10, commit: {parents: []}},
 | |
|           b: {_number: 5, commit: {parents: []}},
 | |
|         },
 | |
|       };
 | |
|       element._fileList = ['chell.go', 'glados.txt', 'wheatley.md'];
 | |
|       element._path = 'glados.txt';
 | |
| 
 | |
|       const diffNavStub = sandbox.stub(Gerrit.Nav, 'navigateToDiff');
 | |
|       const changeNavStub = sandbox.stub(Gerrit.Nav, 'navigateToChange');
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 65, null, 'a');
 | |
|       assert.isTrue(changeNavStub.notCalled, 'The `a` keyboard shortcut ' +
 | |
|           'should only work when the user is logged in.');
 | |
|       assert.isNull(window.sessionStorage.getItem(
 | |
|           'changeView.showReplyDialog'));
 | |
| 
 | |
|       element._loggedIn = true;
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 65, null, 'a');
 | |
|       assert.isTrue(element.changeViewState.showReplyDialog);
 | |
| 
 | |
|       assert(changeNavStub.lastCall.calledWithExactly(element._change, '10',
 | |
|           '5'), 'Should navigate to /c/42/5..10');
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 85, null, 'u');
 | |
|       assert(changeNavStub.lastCall.calledWithExactly(element._change, '10',
 | |
|           '5'), 'Should navigate to /c/42/5..10');
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 221, null, ']');
 | |
|       assert.isTrue(element._loading);
 | |
|       assert(diffNavStub.lastCall.calledWithExactly(element._change,
 | |
|           'wheatley.md', '10', '5'),
 | |
|           'Should navigate to /c/42/5..10/wheatley.md');
 | |
|       element._path = 'wheatley.md';
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
 | |
|       assert.isTrue(element._loading);
 | |
|       assert(diffNavStub.lastCall.calledWithExactly(element._change,
 | |
|           'glados.txt', '10', '5'),
 | |
|           'Should navigate to /c/42/5..10/glados.txt');
 | |
|       element._path = 'glados.txt';
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
 | |
|       assert.isTrue(element._loading);
 | |
|       assert(diffNavStub.lastCall.calledWithExactly(element._change, 'chell.go',
 | |
|           '10', '5'),
 | |
|           'Should navigate to /c/42/5..10/chell.go');
 | |
|       element._path = 'chell.go';
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
 | |
|       assert.isTrue(element._loading);
 | |
|       assert(changeNavStub.lastCall.calledWithExactly(element._change, '10',
 | |
|           '5'),
 | |
|           'Should navigate to /c/42/5..10');
 | |
|     });
 | |
| 
 | |
|     test('keyboard shortcuts with old patch number', () => {
 | |
|       element._changeNum = '42';
 | |
|       element._patchRange = {
 | |
|         basePatchNum: PARENT,
 | |
|         patchNum: '1',
 | |
|       };
 | |
|       element._change = {
 | |
|         _number: 42,
 | |
|         revisions: {
 | |
|           a: {_number: 1, commit: {parents: []}},
 | |
|           b: {_number: 2, commit: {parents: []}},
 | |
|         },
 | |
|       };
 | |
|       element._fileList = ['chell.go', 'glados.txt', 'wheatley.md'];
 | |
|       element._path = 'glados.txt';
 | |
| 
 | |
|       const diffNavStub = sandbox.stub(Gerrit.Nav, 'navigateToDiff');
 | |
|       const changeNavStub = sandbox.stub(Gerrit.Nav, 'navigateToChange');
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 65, null, 'a');
 | |
|       assert.isTrue(changeNavStub.notCalled, 'The `a` keyboard shortcut ' +
 | |
|           'should only work when the user is logged in.');
 | |
|       assert.isNull(window.sessionStorage.getItem(
 | |
|           'changeView.showReplyDialog'));
 | |
| 
 | |
|       element._loggedIn = true;
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 65, null, 'a');
 | |
|       assert.isTrue(element.changeViewState.showReplyDialog);
 | |
| 
 | |
|       assert(changeNavStub.lastCall.calledWithExactly(element._change, '1',
 | |
|           PARENT), 'Should navigate to /c/42/1');
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 85, null, 'u');
 | |
|       assert(changeNavStub.lastCall.calledWithExactly(element._change, '1',
 | |
|           PARENT), 'Should navigate to /c/42/1');
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 221, null, ']');
 | |
|       assert(diffNavStub.lastCall.calledWithExactly(element._change,
 | |
|           'wheatley.md', '1', PARENT),
 | |
|           'Should navigate to /c/42/1/wheatley.md');
 | |
|       element._path = 'wheatley.md';
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
 | |
|       assert(diffNavStub.lastCall.calledWithExactly(element._change,
 | |
|           'glados.txt', '1', PARENT),
 | |
|           'Should navigate to /c/42/1/glados.txt');
 | |
|       element._path = 'glados.txt';
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
 | |
|       assert(diffNavStub.lastCall.calledWithExactly(element._change, 'chell.go',
 | |
|           '1', PARENT), 'Should navigate to /c/42/1/chell.go');
 | |
|       element._path = 'chell.go';
 | |
| 
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 219, null, '[');
 | |
|       assert(changeNavStub.lastCall.calledWithExactly(element._change, '1',
 | |
|           PARENT), 'Should navigate to /c/42/1');
 | |
|     });
 | |
| 
 | |
|     test('Diff preferences hidden when no prefs or logged out', () => {
 | |
|       element._loggedIn = false;
 | |
|       flushAsynchronousOperations();
 | |
|       assert.isTrue(element.$.diffPrefsContainer.hidden);
 | |
| 
 | |
|       element._loggedIn = true;
 | |
|       flushAsynchronousOperations();
 | |
|       assert.isTrue(element.$.diffPrefsContainer.hidden);
 | |
| 
 | |
|       element._loggedIn = false;
 | |
|       element._prefs = {font_size: '12'};
 | |
|       flushAsynchronousOperations();
 | |
|       assert.isTrue(element.$.diffPrefsContainer.hidden);
 | |
| 
 | |
|       element._loggedIn = true;
 | |
|       flushAsynchronousOperations();
 | |
|       assert.isFalse(element.$.diffPrefsContainer.hidden);
 | |
|     });
 | |
| 
 | |
|     test('prefsButton opens gr-diff-preferences', () => {
 | |
|       const handlePrefsTapSpy = sandbox.spy(element, '_handlePrefsTap');
 | |
|       const overlayOpenStub = sandbox.stub(element.$.diffPreferences,
 | |
|           'open');
 | |
|       const prefsButton =
 | |
|           Polymer.dom(element.root).querySelector('.prefsButton');
 | |
| 
 | |
|       MockInteractions.tap(prefsButton);
 | |
| 
 | |
|       assert.isTrue(handlePrefsTapSpy.called);
 | |
|       assert.isTrue(overlayOpenStub.called);
 | |
|     });
 | |
| 
 | |
|     test('_computeCommentString', done => {
 | |
|       loadCommentSpy = sandbox.spy(element.$.commentAPI, 'loadAll');
 | |
|       const path = '/test';
 | |
|       element.$.commentAPI.loadAll().then(comments => {
 | |
|         const commentCountStub =
 | |
|             sandbox.stub(comments, 'computeCommentCount');
 | |
|         const unresolvedCountStub =
 | |
|             sandbox.stub(comments, 'computeUnresolvedNum');
 | |
|         commentCountStub.withArgs(1, path).returns(0);
 | |
|         commentCountStub.withArgs(2, path).returns(1);
 | |
|         commentCountStub.withArgs(3, path).returns(2);
 | |
|         commentCountStub.withArgs(4, path).returns(0);
 | |
|         unresolvedCountStub.withArgs(1, path).returns(1);
 | |
|         unresolvedCountStub.withArgs(2, path).returns(0);
 | |
|         unresolvedCountStub.withArgs(3, path).returns(2);
 | |
|         unresolvedCountStub.withArgs(4, path).returns(0);
 | |
| 
 | |
|         assert.equal(element._computeCommentString(comments, 1, path),
 | |
|             '1 unresolved');
 | |
|         assert.equal(element._computeCommentString(comments, 2, path),
 | |
|             '1 comment');
 | |
|         assert.equal(element._computeCommentString(comments, 3, path),
 | |
|             '2 comments, 2 unresolved');
 | |
|         assert.equal(element._computeCommentString(comments, 4, path), '');
 | |
|         done();
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     suite('url params', () => {
 | |
|       setup(() => {
 | |
|         sandbox.stub(Gerrit.Nav, 'getUrlForDiff', (c, p, pn, bpn) => {
 | |
|           return `${c._number}-${p}-${pn}-${bpn}`;
 | |
|         });
 | |
|         sandbox.stub(Gerrit.Nav, 'getUrlForChange', (c, pn, bpn) => {
 | |
|           return `${c._number}-${pn}-${bpn}`;
 | |
|         });
 | |
|       });
 | |
| 
 | |
|       test('_formattedFiles', () => {
 | |
|         element._changeNum = '42';
 | |
|         element._patchRange = {
 | |
|           basePatchNum: PARENT,
 | |
|           patchNum: '10',
 | |
|         };
 | |
|         element._change = {_number: 42};
 | |
|         element._fileList = ['chell.go', 'glados.txt', 'wheatley.md',
 | |
|           '/COMMIT_MSG', '/MERGE_LIST'];
 | |
|         element._path = 'glados.txt';
 | |
|         const expectedFormattedFiles = [
 | |
|           {
 | |
|             text: 'chell.go',
 | |
|             mobileText: 'chell.go',
 | |
|             value: 'chell.go',
 | |
|             bottomText: '',
 | |
|           }, {
 | |
|             text: 'glados.txt',
 | |
|             mobileText: 'glados.txt',
 | |
|             value: 'glados.txt',
 | |
|             bottomText: '',
 | |
|           }, {
 | |
|             text: 'wheatley.md',
 | |
|             mobileText: 'wheatley.md',
 | |
|             value: 'wheatley.md',
 | |
|             bottomText: '',
 | |
|           },
 | |
|           {
 | |
|             text: 'Commit message',
 | |
|             mobileText: 'Commit message',
 | |
|             value: '/COMMIT_MSG',
 | |
|             bottomText: '',
 | |
|           },
 | |
|           {
 | |
|             text: 'Merge list',
 | |
|             mobileText: 'Merge list',
 | |
|             value: '/MERGE_LIST',
 | |
|             bottomText: '',
 | |
|           },
 | |
|         ];
 | |
| 
 | |
|         assert.deepEqual(element._formattedFiles, expectedFormattedFiles);
 | |
|         assert.equal(element._formattedFiles[1].value, element._path);
 | |
|       });
 | |
| 
 | |
|       test('prev/up/next links', () => {
 | |
|         element._changeNum = '42';
 | |
|         element._patchRange = {
 | |
|           basePatchNum: PARENT,
 | |
|           patchNum: '10',
 | |
|         };
 | |
|         element._change = {
 | |
|           _number: 42,
 | |
|           revisions: {
 | |
|             a: {_number: 10, commit: {parents: []}},
 | |
|           },
 | |
|         };
 | |
|         element._fileList = ['chell.go', 'glados.txt', 'wheatley.md'];
 | |
|         element._path = 'glados.txt';
 | |
|         flushAsynchronousOperations();
 | |
|         const linkEls = Polymer.dom(element.root).querySelectorAll('.navLink');
 | |
|         assert.equal(linkEls.length, 3);
 | |
|         assert.equal(linkEls[0].getAttribute('href'), '42-chell.go-10-PARENT');
 | |
|         assert.equal(linkEls[1].getAttribute('href'), '42-undefined-undefined');
 | |
|         assert.equal(linkEls[2].getAttribute('href'),
 | |
|             '42-wheatley.md-10-PARENT');
 | |
|         element._path = 'wheatley.md';
 | |
|         flushAsynchronousOperations();
 | |
|         assert.equal(linkEls[0].getAttribute('href'),
 | |
|             '42-glados.txt-10-PARENT');
 | |
|         assert.equal(linkEls[1].getAttribute('href'), '42-undefined-undefined');
 | |
|         assert.isFalse(linkEls[2].hasAttribute('href'));
 | |
|         element._path = 'chell.go';
 | |
|         flushAsynchronousOperations();
 | |
|         assert.isFalse(linkEls[0].hasAttribute('href'));
 | |
|         assert.equal(linkEls[1].getAttribute('href'), '42-undefined-undefined');
 | |
|         assert.equal(linkEls[2].getAttribute('href'),
 | |
|             '42-glados.txt-10-PARENT');
 | |
|         element._path = 'not_a_real_file';
 | |
|         flushAsynchronousOperations();
 | |
|         assert.equal(linkEls[0].getAttribute('href'),
 | |
|             '42-wheatley.md-10-PARENT');
 | |
|         assert.equal(linkEls[1].getAttribute('href'), '42-undefined-undefined');
 | |
|         assert.equal(linkEls[2].getAttribute('href'), '42-chell.go-10-PARENT');
 | |
|       });
 | |
| 
 | |
|       test('prev/up/next links with patch range', () => {
 | |
|         element._changeNum = '42';
 | |
|         element._patchRange = {
 | |
|           basePatchNum: '5',
 | |
|           patchNum: '10',
 | |
|         };
 | |
|         element._change = {
 | |
|           _number: 42,
 | |
|           revisions: {
 | |
|             a: {_number: 5, commit: {parents: []}},
 | |
|             b: {_number: 10, commit: {parents: []}},
 | |
|           },
 | |
|         };
 | |
|         element._fileList = ['chell.go', 'glados.txt', 'wheatley.md'];
 | |
|         element._path = 'glados.txt';
 | |
|         flushAsynchronousOperations();
 | |
|         const linkEls = Polymer.dom(element.root).querySelectorAll('.navLink');
 | |
|         assert.equal(linkEls.length, 3);
 | |
|         assert.equal(linkEls[0].getAttribute('href'), '42-chell.go-10-5');
 | |
|         assert.equal(linkEls[1].getAttribute('href'), '42-10-5');
 | |
|         assert.equal(linkEls[2].getAttribute('href'), '42-wheatley.md-10-5');
 | |
|         element._path = 'wheatley.md';
 | |
|         flushAsynchronousOperations();
 | |
|         assert.equal(linkEls[0].getAttribute('href'), '42-glados.txt-10-5');
 | |
|         assert.equal(linkEls[1].getAttribute('href'), '42-10-5');
 | |
|         assert.isFalse(linkEls[2].hasAttribute('href'));
 | |
|         element._path = 'chell.go';
 | |
|         flushAsynchronousOperations();
 | |
|         assert.isFalse(linkEls[0].hasAttribute('href'));
 | |
|         assert.equal(linkEls[1].getAttribute('href'), '42-10-5');
 | |
|         assert.equal(linkEls[2].getAttribute('href'), '42-glados.txt-10-5');
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     test('_handlePatchChange calls navigateToDiff correctly', () => {
 | |
|       const navigateStub = sandbox.stub(Gerrit.Nav, 'navigateToDiff');
 | |
|       element._change = {_number: 321, project: 'foo/bar'};
 | |
|       element._path = 'path/to/file.txt';
 | |
| 
 | |
|       element._patchRange = {
 | |
|         basePatchNum: 'PARENT',
 | |
|         patchNum: '3',
 | |
|       };
 | |
| 
 | |
|       const detail = {
 | |
|         basePatchNum: 'PARENT',
 | |
|         patchNum: '1',
 | |
|       };
 | |
| 
 | |
|       element.$.rangeSelect.dispatchEvent(
 | |
|           new CustomEvent('patch-range-change', {detail, bubbles: false}));
 | |
| 
 | |
|       assert(navigateStub.lastCall.calledWithExactly(element._change,
 | |
|           element._path, '1', 'PARENT'));
 | |
|     });
 | |
| 
 | |
|     test('download link', () => {
 | |
|       element._change = {project: 'test'},
 | |
|       element._changeNum = '42';
 | |
|       element._patchRange = {
 | |
|         basePatchNum: PARENT,
 | |
|         patchNum: '10',
 | |
|       };
 | |
|       element._fileList = ['chell.go', 'glados.txt', 'wheatley.md'];
 | |
|       element._path = 'glados.txt';
 | |
|       flushAsynchronousOperations();
 | |
|       const link = element.$$('.downloadLink');
 | |
|       assert.equal(link.getAttribute('href'),
 | |
|           '/changes/test~42/revisions/10/patch?zip&path=glados.txt');
 | |
|       assert.isTrue(link.hasAttribute('download'));
 | |
|     });
 | |
| 
 | |
|     test('_prefs.manual_review is respected', () => {
 | |
|       const saveReviewedStub = sandbox.stub(element, '_saveReviewedState',
 | |
|           () => Promise.resolve());
 | |
|       const getReviewedStub = sandbox.stub(element, '_getReviewedStatus',
 | |
|           () => Promise.resolve());
 | |
| 
 | |
|       sandbox.stub(element.$.diffHost, 'reload');
 | |
|       element._loggedIn = true;
 | |
|       element.params = {
 | |
|         view: Gerrit.Nav.View.DIFF,
 | |
|         changeNum: '42',
 | |
|         patchNum: '2',
 | |
|         basePatchNum: '1',
 | |
|         path: '/COMMIT_MSG',
 | |
|       };
 | |
|       element._prefs = {manual_review: true};
 | |
|       flushAsynchronousOperations();
 | |
| 
 | |
|       assert.isFalse(saveReviewedStub.called);
 | |
|       assert.isTrue(getReviewedStub.called);
 | |
| 
 | |
|       element._prefs = {};
 | |
|       flushAsynchronousOperations();
 | |
| 
 | |
|       assert.isTrue(saveReviewedStub.called);
 | |
|       assert.isTrue(getReviewedStub.calledOnce);
 | |
|     });
 | |
| 
 | |
|     test('file review status', () => {
 | |
|       const saveReviewedStub = sandbox.stub(element, '_saveReviewedState',
 | |
|           () => Promise.resolve());
 | |
|       sandbox.stub(element.$.diffHost, 'reload');
 | |
| 
 | |
|       element._loggedIn = true;
 | |
|       element.params = {
 | |
|         view: Gerrit.Nav.View.DIFF,
 | |
|         changeNum: '42',
 | |
|         patchNum: '2',
 | |
|         basePatchNum: '1',
 | |
|         path: '/COMMIT_MSG',
 | |
|       };
 | |
|       element._prefs = {};
 | |
|       flushAsynchronousOperations();
 | |
| 
 | |
|       const commitMsg = Polymer.dom(element.root).querySelector(
 | |
|           'input[type="checkbox"]');
 | |
| 
 | |
|       assert.isTrue(commitMsg.checked);
 | |
|       MockInteractions.tap(commitMsg);
 | |
|       assert.isFalse(commitMsg.checked);
 | |
|       assert.isTrue(saveReviewedStub.lastCall.calledWithExactly(false));
 | |
| 
 | |
|       MockInteractions.tap(commitMsg);
 | |
|       assert.isTrue(commitMsg.checked);
 | |
|       assert.isTrue(saveReviewedStub.lastCall.calledWithExactly(true));
 | |
|       const callCount = saveReviewedStub.callCount;
 | |
| 
 | |
|       element.set('params.view', Gerrit.Nav.View.CHANGE);
 | |
|       flushAsynchronousOperations();
 | |
| 
 | |
|       // saveReviewedState observer observes params, but should not fire when
 | |
|       // view !== Gerrit.Nav.View.DIFF.
 | |
|       assert.equal(saveReviewedStub.callCount, callCount);
 | |
|     });
 | |
| 
 | |
|     test('file review status with edit loaded', () => {
 | |
|       const saveReviewedStub = sandbox.stub(element, '_saveReviewedState');
 | |
| 
 | |
|       element._patchRange = {patchNum: element.EDIT_NAME};
 | |
|       flushAsynchronousOperations();
 | |
| 
 | |
|       assert.isTrue(element._editMode);
 | |
|       element._setReviewed();
 | |
|       assert.isFalse(saveReviewedStub.called);
 | |
|     });
 | |
| 
 | |
|     test('hash is determined from params', done => {
 | |
|       sandbox.stub(element.$.diffHost, 'reload');
 | |
|       sandbox.stub(element, '_initCursor');
 | |
| 
 | |
|       element._loggedIn = true;
 | |
|       element.params = {
 | |
|         view: Gerrit.Nav.View.DIFF,
 | |
|         changeNum: '42',
 | |
|         patchNum: '2',
 | |
|         basePatchNum: '1',
 | |
|         path: '/COMMIT_MSG',
 | |
|         hash: 10,
 | |
|       };
 | |
| 
 | |
|       flush(() => {
 | |
|         assert.isTrue(element._initCursor.calledOnce);
 | |
|         done();
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     test('diff mode selector correctly toggles the diff', () => {
 | |
|       const select = element.$.modeSelect;
 | |
|       const diffDisplay = element.$.diffHost;
 | |
|       element._userPrefs = {default_diff_view: 'SIDE_BY_SIDE'};
 | |
| 
 | |
|       // The mode selected in the view state reflects the selected option.
 | |
|       assert.equal(element._getDiffViewMode(), select.mode);
 | |
| 
 | |
|       // The mode selected in the view state reflects the view rednered in the
 | |
|       // diff.
 | |
|       assert.equal(select.mode, diffDisplay.viewMode);
 | |
| 
 | |
|       // We will simulate a user change of the selected mode.
 | |
|       const newMode = 'UNIFIED_DIFF';
 | |
| 
 | |
|       // Set the mode, and simulate the change event.
 | |
|       element.set('changeViewState.diffMode', newMode);
 | |
| 
 | |
|       // Make sure the handler was called and the state is still coherent.
 | |
|       assert.equal(element._getDiffViewMode(), newMode);
 | |
|       assert.equal(element._getDiffViewMode(), select.mode);
 | |
|       assert.equal(element._getDiffViewMode(), diffDisplay.viewMode);
 | |
|     });
 | |
| 
 | |
|     test('diff mode selector initializes from preferences', () => {
 | |
|       let resolvePrefs;
 | |
|       const prefsPromise = new Promise(resolve => {
 | |
|         resolvePrefs = resolve;
 | |
|       });
 | |
|       sandbox.stub(element.$.restAPI, 'getPreferences', () => prefsPromise);
 | |
| 
 | |
|       // Attach a new gr-diff-view so we can intercept the preferences fetch.
 | |
|       const view = document.createElement('gr-diff-view');
 | |
|       fixture('blank').appendChild(view);
 | |
|       flushAsynchronousOperations();
 | |
| 
 | |
|       // At this point the diff mode doesn't yet have the user's preference.
 | |
|       assert.equal(view._getDiffViewMode(), 'SIDE_BY_SIDE');
 | |
| 
 | |
|       // Receive the overriding preference.
 | |
|       resolvePrefs({default_diff_view: 'UNIFIED'});
 | |
|       flushAsynchronousOperations();
 | |
|       assert.equal(element._getDiffViewMode(), 'SIDE_BY_SIDE');
 | |
|     });
 | |
| 
 | |
|     suite('_commitRange', () => {
 | |
|       setup(() => {
 | |
|         sandbox.stub(element.$.diffHost, 'reload');
 | |
|         sandbox.stub(element, '_initCursor');
 | |
|         sandbox.stub(element, '_getChangeDetail').returns(Promise.resolve({
 | |
|           _number: 42,
 | |
|           revisions: {
 | |
|             'commit-sha-1': {
 | |
|               _number: 1,
 | |
|               commit: {
 | |
|                 parents: [{commit: 'sha-1-parent'}],
 | |
|               },
 | |
|             },
 | |
|             'commit-sha-2': {_number: 2},
 | |
|             'commit-sha-3': {_number: 3},
 | |
|             'commit-sha-4': {_number: 4},
 | |
|             'commit-sha-5': {
 | |
|               _number: 5,
 | |
|               commit: {
 | |
|                 parents: [{commit: 'sha-5-parent'}],
 | |
|               },
 | |
|             },
 | |
|           },
 | |
|         }));
 | |
|       });
 | |
| 
 | |
|       test('uses the patchNum and basePatchNum ', done => {
 | |
|         element.params = {
 | |
|           view: Gerrit.Nav.View.DIFF,
 | |
|           changeNum: '42',
 | |
|           patchNum: '4',
 | |
|           basePatchNum: '2',
 | |
|           path: '/COMMIT_MSG',
 | |
|         };
 | |
|         flush(() => {
 | |
|           assert.deepEqual(element._commitRange, {
 | |
|             baseCommit: 'commit-sha-2',
 | |
|             commit: 'commit-sha-4',
 | |
|           });
 | |
|           done();
 | |
|         });
 | |
|       });
 | |
| 
 | |
|       test('uses the parent when there is no base patch num ', done => {
 | |
|         element.params = {
 | |
|           view: Gerrit.Nav.View.DIFF,
 | |
|           changeNum: '42',
 | |
|           patchNum: '5',
 | |
|           path: '/COMMIT_MSG',
 | |
|         };
 | |
|         flush(() => {
 | |
|           assert.deepEqual(element._commitRange, {
 | |
|             commit: 'commit-sha-5',
 | |
|             baseCommit: 'sha-5-parent',
 | |
|           });
 | |
|           done();
 | |
|         });
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     test('_initCursor', () => {
 | |
|       assert.isNotOk(element.$.cursor.initialLineNumber);
 | |
| 
 | |
|       // Does nothing when params specify no cursor address:
 | |
|       element._initCursor({});
 | |
|       assert.isNotOk(element.$.cursor.initialLineNumber);
 | |
| 
 | |
|       // Does nothing when params specify side but no number:
 | |
|       element._initCursor({leftSide: true});
 | |
|       assert.isNotOk(element.$.cursor.initialLineNumber);
 | |
| 
 | |
|       // Revision hash: specifies lineNum but not side.
 | |
|       element._initCursor({lineNum: 234});
 | |
|       assert.equal(element.$.cursor.initialLineNumber, 234);
 | |
|       assert.equal(element.$.cursor.side, 'right');
 | |
| 
 | |
|       // Base hash: specifies lineNum and side.
 | |
|       element._initCursor({leftSide: true, lineNum: 345});
 | |
|       assert.equal(element.$.cursor.initialLineNumber, 345);
 | |
|       assert.equal(element.$.cursor.side, 'left');
 | |
| 
 | |
|       // Specifies right side:
 | |
|       element._initCursor({leftSide: false, lineNum: 123});
 | |
|       assert.equal(element.$.cursor.initialLineNumber, 123);
 | |
|       assert.equal(element.$.cursor.side, 'right');
 | |
|     });
 | |
| 
 | |
|     test('_getLineOfInterest', () => {
 | |
|       assert.isNull(element._getLineOfInterest({}));
 | |
| 
 | |
|       let result = element._getLineOfInterest({lineNum: 12});
 | |
|       assert.equal(result.number, 12);
 | |
|       assert.isNotOk(result.leftSide);
 | |
| 
 | |
|       result = element._getLineOfInterest({lineNum: 12, leftSide: true});
 | |
|       assert.equal(result.number, 12);
 | |
|       assert.isOk(result.leftSide);
 | |
|     });
 | |
| 
 | |
|     test('_onLineSelected', () => {
 | |
|       const getUrlStub = sandbox.stub(Gerrit.Nav, 'getUrlForDiffById');
 | |
|       const replaceStateStub = sandbox.stub(history, 'replaceState');
 | |
|       const moveStub = sandbox.stub(element.$.cursor, 'moveToLineNumber');
 | |
|       sandbox.stub(element.$.cursor, 'getAddress')
 | |
|           .returns({number: 123, isLeftSide: false});
 | |
| 
 | |
|       element._changeNum = 321;
 | |
|       element._change = {_number: 321, project: 'foo/bar'};
 | |
|       element._patchRange = {
 | |
|         basePatchNum: '3',
 | |
|         patchNum: '5',
 | |
|       };
 | |
|       const e = {};
 | |
|       const detail = {number: 123, side: 'right'};
 | |
| 
 | |
|       element._onLineSelected(e, detail);
 | |
| 
 | |
|       assert.isTrue(moveStub.called);
 | |
|       assert.equal(moveStub.lastCall.args[0], detail.number);
 | |
|       assert.equal(moveStub.lastCall.args[1], detail.side);
 | |
| 
 | |
|       assert.isTrue(replaceStateStub.called);
 | |
|       assert.isTrue(getUrlStub.called);
 | |
|     });
 | |
| 
 | |
|     test('_onLineSelected w/o line address', () => {
 | |
|       const getUrlStub = sandbox.stub(Gerrit.Nav, 'getUrlForDiffById');
 | |
|       sandbox.stub(history, 'replaceState');
 | |
|       sandbox.stub(element.$.cursor, 'moveToLineNumber');
 | |
|       sandbox.stub(element.$.cursor, 'getAddress').returns(null);
 | |
|       element._changeNum = 321;
 | |
|       element._change = {_number: 321, project: 'foo/bar'};
 | |
|       element._patchRange = {basePatchNum: '3', patchNum: '5'};
 | |
|       element._onLineSelected({}, {number: 123, side: 'right'});
 | |
|       assert.isTrue(getUrlStub.calledOnce);
 | |
|       assert.isUndefined(getUrlStub.lastCall.args[5]);
 | |
|       assert.isUndefined(getUrlStub.lastCall.args[6]);
 | |
|     });
 | |
| 
 | |
|     test('_getDiffViewMode', () => {
 | |
|       // No user prefs or change view state set.
 | |
|       assert.equal(element._getDiffViewMode(), 'SIDE_BY_SIDE');
 | |
| 
 | |
|       // User prefs but no change view state set.
 | |
|       element._userPrefs = {default_diff_view: 'UNIFIED_DIFF'};
 | |
|       assert.equal(element._getDiffViewMode(), 'UNIFIED_DIFF');
 | |
| 
 | |
|       // User prefs and change view state set.
 | |
|       element.changeViewState = {diffMode: 'SIDE_BY_SIDE'};
 | |
|       assert.equal(element._getDiffViewMode(), 'SIDE_BY_SIDE');
 | |
|     });
 | |
| 
 | |
|     test('_handleToggleDiffMode', () => {
 | |
|       sandbox.stub(element, 'shouldSuppressKeyboardShortcut').returns(false);
 | |
|       const e = {preventDefault: () => {}};
 | |
|       // Initial state.
 | |
|       assert.equal(element._getDiffViewMode(), 'SIDE_BY_SIDE');
 | |
| 
 | |
|       element._handleToggleDiffMode(e);
 | |
|       assert.equal(element._getDiffViewMode(), 'UNIFIED_DIFF');
 | |
| 
 | |
|       element._handleToggleDiffMode(e);
 | |
|       assert.equal(element._getDiffViewMode(), 'SIDE_BY_SIDE');
 | |
|     });
 | |
| 
 | |
|     suite('_loadComments', () => {
 | |
|       test('empty', done => {
 | |
|         element._loadComments().then(() => {
 | |
|           assert.equal(Object.keys(element._commentMap).length, 0);
 | |
|           done();
 | |
|         });
 | |
|       });
 | |
| 
 | |
|       test('has paths', done => {
 | |
|         sandbox.stub(element, '_getPaths').returns({
 | |
|           'path/to/file/one.cpp': [{patch_set: 3, message: 'lorem'}],
 | |
|           'path-to/file/two.py': [{patch_set: 5, message: 'ipsum'}],
 | |
|         });
 | |
|         sandbox.stub(element, '_getCommentsForPath').returns({meta: {}});
 | |
|         element._changeNum = '42';
 | |
|         element._patchRange = {
 | |
|           basePatchNum: '3',
 | |
|           patchNum: '5',
 | |
|         };
 | |
|         element._loadComments().then(() => {
 | |
|           assert.deepEqual(Object.keys(element._commentMap),
 | |
|               ['path/to/file/one.cpp', 'path-to/file/two.py']);
 | |
|           done();
 | |
|         });
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     suite('_computeCommentSkips', () => {
 | |
|       test('empty file list', () => {
 | |
|         const commentMap = {
 | |
|           'path/one.jpg': true,
 | |
|           'path/three.wav': true,
 | |
|         };
 | |
|         const path = 'path/two.m4v';
 | |
|         const fileList = [];
 | |
|         const result = element._computeCommentSkips(commentMap, fileList, path);
 | |
|         assert.isNull(result.previous);
 | |
|         assert.isNull(result.next);
 | |
|       });
 | |
| 
 | |
|       test('finds skips', () => {
 | |
|         const fileList = ['path/one.jpg', 'path/two.m4v', 'path/three.wav'];
 | |
|         let path = fileList[1];
 | |
|         const commentMap = {};
 | |
|         commentMap[fileList[0]] = true;
 | |
|         commentMap[fileList[1]] = false;
 | |
|         commentMap[fileList[2]] = true;
 | |
| 
 | |
|         let result = element._computeCommentSkips(commentMap, fileList, path);
 | |
|         assert.equal(result.previous, fileList[0]);
 | |
|         assert.equal(result.next, fileList[2]);
 | |
| 
 | |
|         commentMap[fileList[1]] = true;
 | |
| 
 | |
|         result = element._computeCommentSkips(commentMap, fileList, path);
 | |
|         assert.equal(result.previous, fileList[0]);
 | |
|         assert.equal(result.next, fileList[2]);
 | |
| 
 | |
|         path = fileList[0];
 | |
| 
 | |
|         result = element._computeCommentSkips(commentMap, fileList, path);
 | |
|         assert.isNull(result.previous);
 | |
|         assert.equal(result.next, fileList[1]);
 | |
| 
 | |
|         path = fileList[2];
 | |
| 
 | |
|         result = element._computeCommentSkips(commentMap, fileList, path);
 | |
|         assert.equal(result.previous, fileList[1]);
 | |
|         assert.isNull(result.next);
 | |
|       });
 | |
| 
 | |
|       suite('skip next/previous', () => {
 | |
|         let navToChangeStub;
 | |
|         let navToDiffStub;
 | |
| 
 | |
|         setup(() => {
 | |
|           navToChangeStub = sandbox.stub(element, '_navToChangeView');
 | |
|           navToDiffStub = sandbox.stub(Gerrit.Nav, 'navigateToDiff');
 | |
|           element._fileList = [
 | |
|             'path/one.jpg', 'path/two.m4v', 'path/three.wav',
 | |
|           ];
 | |
|           element._patchRange = {patchNum: '2', basePatchNum: '1'};
 | |
|         });
 | |
| 
 | |
|         suite('_moveToPreviousFileWithComment', () => {
 | |
|           test('no skips', () => {
 | |
|             element._moveToPreviousFileWithComment();
 | |
|             assert.isFalse(navToChangeStub.called);
 | |
|             assert.isFalse(navToDiffStub.called);
 | |
|           });
 | |
| 
 | |
|           test('no previous', () => {
 | |
|             const commentMap = {};
 | |
|             commentMap[element._fileList[0]] = false;
 | |
|             commentMap[element._fileList[1]] = false;
 | |
|             commentMap[element._fileList[2]] = true;
 | |
|             element._commentMap = commentMap;
 | |
|             element._path = element._fileList[1];
 | |
| 
 | |
|             element._moveToPreviousFileWithComment();
 | |
|             assert.isTrue(navToChangeStub.calledOnce);
 | |
|             assert.isFalse(navToDiffStub.called);
 | |
|           });
 | |
| 
 | |
|           test('w/ previous', () => {
 | |
|             const commentMap = {};
 | |
|             commentMap[element._fileList[0]] = true;
 | |
|             commentMap[element._fileList[1]] = false;
 | |
|             commentMap[element._fileList[2]] = true;
 | |
|             element._commentMap = commentMap;
 | |
|             element._path = element._fileList[1];
 | |
| 
 | |
|             element._moveToPreviousFileWithComment();
 | |
|             assert.isFalse(navToChangeStub.called);
 | |
|             assert.isTrue(navToDiffStub.calledOnce);
 | |
|           });
 | |
|         });
 | |
| 
 | |
|         suite('_moveToNextFileWithComment', () => {
 | |
|           test('no skips', () => {
 | |
|             element._moveToNextFileWithComment();
 | |
|             assert.isFalse(navToChangeStub.called);
 | |
|             assert.isFalse(navToDiffStub.called);
 | |
|           });
 | |
| 
 | |
|           test('no previous', () => {
 | |
|             const commentMap = {};
 | |
|             commentMap[element._fileList[0]] = true;
 | |
|             commentMap[element._fileList[1]] = false;
 | |
|             commentMap[element._fileList[2]] = false;
 | |
|             element._commentMap = commentMap;
 | |
|             element._path = element._fileList[1];
 | |
| 
 | |
|             element._moveToNextFileWithComment();
 | |
|             assert.isTrue(navToChangeStub.calledOnce);
 | |
|             assert.isFalse(navToDiffStub.called);
 | |
|           });
 | |
| 
 | |
|           test('w/ previous', () => {
 | |
|             const commentMap = {};
 | |
|             commentMap[element._fileList[0]] = true;
 | |
|             commentMap[element._fileList[1]] = false;
 | |
|             commentMap[element._fileList[2]] = true;
 | |
|             element._commentMap = commentMap;
 | |
|             element._path = element._fileList[1];
 | |
| 
 | |
|             element._moveToNextFileWithComment();
 | |
|             assert.isFalse(navToChangeStub.called);
 | |
|             assert.isTrue(navToDiffStub.calledOnce);
 | |
|           });
 | |
|         });
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     test('_computeEditMode', () => {
 | |
|       const callCompute = range => element._computeEditMode({base: range});
 | |
|       assert.isFalse(callCompute({}));
 | |
|       assert.isFalse(callCompute({basePatchNum: 'PARENT', patchNum: 1}));
 | |
|       assert.isFalse(callCompute({basePatchNum: 'edit', patchNum: 1}));
 | |
|       assert.isTrue(callCompute({basePatchNum: 1, patchNum: 'edit'}));
 | |
|     });
 | |
| 
 | |
|     test('_computeFileNum', () => {
 | |
|       assert.equal(element._computeFileNum('/foo',
 | |
|           [{value: '/foo'}, {value: '/bar'}]), 1);
 | |
|       assert.equal(element._computeFileNum('/bar',
 | |
|           [{value: '/foo'}, {value: '/bar'}]), 2);
 | |
|     });
 | |
| 
 | |
|     test('_computeFileNumClass', () => {
 | |
|       assert.equal(element._computeFileNumClass(0, []), '');
 | |
|       assert.equal(element._computeFileNumClass(1,
 | |
|           [{value: '/foo'}, {value: '/bar'}]), 'show');
 | |
|     });
 | |
| 
 | |
|     test('_getReviewedStatus', () => {
 | |
|       const promises = [];
 | |
|       element.$.restAPI.getReviewedFiles.restore();
 | |
| 
 | |
|       sandbox.stub(element.$.restAPI, 'getReviewedFiles')
 | |
|           .returns(Promise.resolve(['path']));
 | |
| 
 | |
|       promises.push(element._getReviewedStatus(true, null, null, 'path')
 | |
|           .then(reviewed => assert.isFalse(reviewed)));
 | |
| 
 | |
|       promises.push(element._getReviewedStatus(false, null, null, 'otherPath')
 | |
|           .then(reviewed => assert.isFalse(reviewed)));
 | |
| 
 | |
|       promises.push(element._getReviewedStatus(false, null, null, 'path')
 | |
|           .then(reviewed => assert.isTrue(reviewed)));
 | |
| 
 | |
|       return Promise.all(promises);
 | |
|     });
 | |
| 
 | |
|     suite('editMode behavior', () => {
 | |
|       setup(() => {
 | |
|         element._loggedIn = true;
 | |
|       });
 | |
| 
 | |
|       const isVisible = el => {
 | |
|         assert.ok(el);
 | |
|         return getComputedStyle(el).getPropertyValue('display') !== 'none';
 | |
|       };
 | |
| 
 | |
|       test('reviewed checkbox', () => {
 | |
|         sandbox.stub(element, '_handlePatchChange');
 | |
|         element._patchRange = {patchNum: '1'};
 | |
|         // Reviewed checkbox should be shown.
 | |
|         assert.isTrue(isVisible(element.$.reviewed));
 | |
|         element.set('_patchRange.patchNum', element.EDIT_NAME);
 | |
|         flushAsynchronousOperations();
 | |
| 
 | |
|         assert.isFalse(isVisible(element.$.reviewed));
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     test('_paramsChanged sets in projectLookup', () => {
 | |
|       sandbox.stub(element, '_getLineOfInterest');
 | |
|       sandbox.stub(element, '_initCursor');
 | |
|       const setStub = sandbox.stub(element.$.restAPI, 'setInProjectLookup');
 | |
|       element._paramsChanged({
 | |
|         view: Gerrit.Nav.View.DIFF,
 | |
|         changeNum: 101,
 | |
|         project: 'test-project',
 | |
|         path: '',
 | |
|       });
 | |
|       assert.isTrue(setStub.calledOnce);
 | |
|       assert.isTrue(setStub.calledWith(101, 'test-project'));
 | |
|     });
 | |
| 
 | |
|     test('shift+m navigates to next unreviewed file', () => {
 | |
|       element._fileList = ['file1', 'file2', 'file3'];
 | |
|       element._reviewedFiles = new Set(['file1', 'file2']);
 | |
|       element._path = 'file1';
 | |
|       const reviewedStub = sandbox.stub(element, '_setReviewed');
 | |
|       const navStub = sandbox.stub(element, '_navToFile');
 | |
|       MockInteractions.pressAndReleaseKeyOn(element, 77, 'shift', 'm');
 | |
|       flushAsynchronousOperations();
 | |
| 
 | |
|       assert.isTrue(reviewedStub.lastCall.args[0]);
 | |
|       assert.deepEqual(navStub.lastCall.args, [
 | |
|         'file1',
 | |
|         ['file1', 'file3'],
 | |
|         1,
 | |
|       ]);
 | |
|     });
 | |
|   });
 | |
| </script>
 |