diff options
Diffstat (limited to 'polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html')
-rw-r--r-- | polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html | 544 |
1 files changed, 440 insertions, 104 deletions
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html index fa37eb9e55..354bfef6c9 100644 --- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html +++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html @@ -1,5 +1,6 @@ <!DOCTYPE html> <!-- +@license Copyright (C) 2015 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); @@ -42,6 +43,32 @@ limitations under the License. <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; @@ -51,23 +78,45 @@ limitations under the License. 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(null); }, + getDiffChangeDetail() { return Promise.resolve({}); }, getChangeFiles() { return Promise.resolve({}); }, saveFileReviewed() { return Promise.resolve(); }, + getDiffComments() { return Promise.resolve({}); }, getDiffRobotComments() { return Promise.resolve({}); }, - getDiffDrafts() { 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.$.diff, 'toggleLeftDiff'); + const toggleLeftDiffStub = sandbox.stub( + element.$.diffHost, 'toggleLeftDiff'); MockInteractions.pressAndReleaseKeyOn(element, 65, 'shift', 'a'); assert.isTrue(toggleLeftDiffStub.calledOnce); }); @@ -81,7 +130,7 @@ limitations under the License. element._change = { _number: 42, revisions: { - a: {_number: 10}, + a: {_number: 10, commit: {parents: []}}, }, }; element._fileList = ['chell.go', 'glados.txt', 'wheatley.md']; @@ -123,7 +172,7 @@ limitations under the License. assert.isTrue(element._loading); const showPrefsStub = - sandbox.stub(element.$.diffPreferences.$.prefsOverlay, 'open', + sandbox.stub(element.$.diffPreferencesDialog, 'open', () => Promise.resolve()); MockInteractions.pressAndReleaseKeyOn(element, 188, null, ','); @@ -146,7 +195,7 @@ limitations under the License. MockInteractions.pressAndReleaseKeyOn(element, 80, 'shift', 'p'); assert(scrollStub.calledOnce); - const computeContainerClassStub = sandbox.stub(element.$.diff, + const computeContainerClassStub = sandbox.stub(element.$.diffHost.$.diff, '_computeContainerClass'); MockInteractions.pressAndReleaseKeyOn(element, 74, null, 'j'); assert(computeContainerClassStub.lastCall.calledWithExactly( @@ -155,6 +204,22 @@ limitations under the License. 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', () => { @@ -166,8 +231,8 @@ limitations under the License. element._change = { _number: 42, revisions: { - a: {_number: 10}, - b: {_number: 5}, + a: {_number: 10, commit: {parents: []}}, + b: {_number: 5, commit: {parents: []}}, }, }; element._fileList = ['chell.go', 'glados.txt', 'wheatley.md']; @@ -230,8 +295,8 @@ limitations under the License. element._change = { _number: 42, revisions: { - a: {_number: 1}, - b: {_number: 2}, + a: {_number: 1, commit: {parents: []}}, + b: {_number: 2, commit: {parents: []}}, }, }; element._fileList = ['chell.go', 'glados.txt', 'wheatley.md']; @@ -300,7 +365,7 @@ limitations under the License. test('prefsButton opens gr-diff-preferences', () => { const handlePrefsTapSpy = sandbox.spy(element, '_handlePrefsTap'); - const overlayOpenStub = sandbox.stub(element.$.diffPreferences, + const overlayOpenStub = sandbox.stub(element.$.diffPreferencesDialog, 'open'); const prefsButton = Polymer.dom(element.root).querySelector('.prefsButton'); @@ -311,6 +376,34 @@ limitations under the License. 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) => { @@ -321,54 +414,49 @@ limitations under the License. }); }); - test('jump to file dropdown', () => { + test('_formattedFiles', () => { element._changeNum = '42'; element._patchRange = { basePatchNum: PARENT, patchNum: '10', }; element._change = {_number: 42}; - element._fileList = ['chell.go', 'glados.txt', 'wheatley.md']; + element._fileList = ['chell.go', 'glados.txt', 'wheatley.md', + '/COMMIT_MSG', '/MERGE_LIST']; element._path = 'glados.txt'; - flushAsynchronousOperations(); - const linkEls = - Polymer.dom(element.root).querySelectorAll('.dropdown-content > a'); - assert.equal(linkEls.length, 3); - assert.isFalse(linkEls[0].hasAttribute('selected')); - assert.isTrue(linkEls[1].hasAttribute('selected')); - assert.isFalse(linkEls[2].hasAttribute('selected')); - assert.equal(linkEls[0].getAttribute('data-key-nav'), '['); - assert.equal(linkEls[1].getAttribute('data-key-nav'), ''); - assert.equal(linkEls[2].getAttribute('data-key-nav'), ']'); - assert.equal(linkEls[0].getAttribute('href'), '42-chell.go-10-PARENT'); - assert.equal(linkEls[1].getAttribute('href'), - '42-glados.txt-10-PARENT'); - assert.equal(linkEls[2].getAttribute('href'), - '42-wheatley.md-10-PARENT'); - }); + 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: '', + }, + ]; - test('jump to file dropdown with patch range', () => { - element._changeNum = '42'; - element._patchRange = { - basePatchNum: '5', - patchNum: '10', - }; - element._change = {_number: 42}; - element._fileList = ['chell.go', 'glados.txt', 'wheatley.md']; - element._path = 'glados.txt'; - flushAsynchronousOperations(); - const linkEls = - Polymer.dom(element.root).querySelectorAll('.dropdown-content > a'); - assert.equal(linkEls.length, 3); - assert.isFalse(linkEls[0].hasAttribute('selected')); - assert.isTrue(linkEls[1].hasAttribute('selected')); - assert.isFalse(linkEls[2].hasAttribute('selected')); - assert.equal(linkEls[0].getAttribute('data-key-nav'), '['); - assert.equal(linkEls[1].getAttribute('data-key-nav'), ''); - assert.equal(linkEls[2].getAttribute('data-key-nav'), ']'); - assert.equal(linkEls[0].getAttribute('href'), '42-chell.go-10-5'); - assert.equal(linkEls[1].getAttribute('href'), '42-glados.txt-10-5'); - assert.equal(linkEls[2].getAttribute('href'), '42-wheatley.md-10-5'); + assert.deepEqual(element._formattedFiles, expectedFormattedFiles); + assert.equal(element._formattedFiles[1].value, element._path); }); test('prev/up/next links', () => { @@ -380,7 +468,7 @@ limitations under the License. element._change = { _number: 42, revisions: { - a: {_number: 10}, + a: {_number: 10, commit: {parents: []}}, }, }; element._fileList = ['chell.go', 'glados.txt', 'wheatley.md']; @@ -421,8 +509,8 @@ limitations under the License. element._change = { _number: 42, revisions: { - a: {_number: 5}, - b: {_number: 10}, + a: {_number: 5, commit: {parents: []}}, + b: {_number: 10, commit: {parents: []}}, }, }; element._fileList = ['chell.go', 'glados.txt', 'wheatley.md']; @@ -469,6 +557,7 @@ limitations under the License. }); test('download link', () => { + element._change = {project: 'test'}, element._changeNum = '42'; element._patchRange = { basePatchNum: PARENT, @@ -479,18 +568,17 @@ limitations under the License. flushAsynchronousOperations(); const link = element.$$('.downloadLink'); assert.equal(link.getAttribute('href'), - '/changes/42/revisions/10/patch?zip&path=glados.txt'); + '/changes/test~42/revisions/10/patch?zip&path=glados.txt'); assert.isTrue(link.hasAttribute('download')); }); - test('file review status', done => { - stub('gr-rest-api-interface', { - getDiffComments() { return Promise.resolve({}); }, - }); + test('_prefs.manual_review is respected', () => { const saveReviewedStub = sandbox.stub(element, '_saveReviewedState', () => Promise.resolve()); - sandbox.stub(element.$.diff, 'reload'); + const getReviewedStub = sandbox.stub(element, '_getReviewedStatus', + () => Promise.resolve()); + sandbox.stub(element.$.diffHost, 'reload'); element._loggedIn = true; element.params = { view: Gerrit.Nav.View.DIFF, @@ -499,22 +587,54 @@ limitations under the License. basePatchNum: '1', path: '/COMMIT_MSG', }; + element._prefs = {manual_review: true}; + flushAsynchronousOperations(); - flush(() => { - const commitMsg = Polymer.dom(element.root).querySelector( - 'input[type="checkbox"]'); + assert.isFalse(saveReviewedStub.called); + assert.isTrue(getReviewedStub.called); - assert.isTrue(commitMsg.checked); - MockInteractions.tap(commitMsg); - assert.isFalse(commitMsg.checked); - assert.isTrue(saveReviewedStub.lastCall.calledWithExactly(false)); + element._prefs = {}; + flushAsynchronousOperations(); - MockInteractions.tap(commitMsg); - assert.isTrue(commitMsg.checked); - assert.isTrue(saveReviewedStub.lastCall.calledWithExactly(true)); + assert.isTrue(saveReviewedStub.called); + assert.isTrue(getReviewedStub.calledOnce); + }); - done(); - }); + 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', () => { @@ -523,16 +643,13 @@ limitations under the License. element._patchRange = {patchNum: element.EDIT_NAME}; flushAsynchronousOperations(); - assert.isTrue(element._editLoaded); + assert.isTrue(element._editMode); element._setReviewed(); assert.isFalse(saveReviewedStub.called); }); test('hash is determined from params', done => { - stub('gr-rest-api-interface', { - getDiffComments() { return Promise.resolve({}); }, - }); - sandbox.stub(element.$.diff, 'reload'); + sandbox.stub(element.$.diffHost, 'reload'); sandbox.stub(element, '_initCursor'); element._loggedIn = true; @@ -553,25 +670,25 @@ limitations under the License. test('diff mode selector correctly toggles the diff', () => { const select = element.$.modeSelect; - const diffDisplay = element.$.diff; + 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.nativeSelect.value); + assert.equal(element._getDiffViewMode(), select.mode); // The mode selected in the view state reflects the view rednered in the // diff. - assert.equal(select.nativeSelect.value, diffDisplay.viewMode); + assert.equal(select.mode, diffDisplay.viewMode); // We will simulate a user change of the selected mode. const newMode = 'UNIFIED_DIFF'; - // Set the actual value of the select, and simulate the change event. - select.nativeSelect.value = newMode; - element.fire('change', {}, {node: select.nativeSelect}); + + // 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.nativeSelect.value); + assert.equal(element._getDiffViewMode(), select.mode); assert.equal(element._getDiffViewMode(), diffDisplay.viewMode); }); @@ -584,17 +701,76 @@ limitations under the License. // Attach a new gr-diff-view so we can intercept the preferences fetch. const view = document.createElement('gr-diff-view'); - const select = view.$.modeSelect; fixture('blank').appendChild(view); flushAsynchronousOperations(); // At this point the diff mode doesn't yet have the user's preference. - assert.equal(select.nativeSelect.value, 'SIDE_BY_SIDE'); + assert.equal(view._getDiffViewMode(), 'SIDE_BY_SIDE'); // Receive the overriding preference. resolvePrefs({default_diff_view: 'UNIFIED'}); flushAsynchronousOperations(); - assert.equal(select.nativeSelect.value, 'SIDE_BY_SIDE'); + 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', () => { @@ -624,6 +800,18 @@ limitations under the License. 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'); @@ -677,13 +865,21 @@ limitations under the License. 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 => { - stub('gr-comment-api', { - loadAll() { return Promise.resolve(); }, - getPaths() { return {}; }, - getCommentsForPath() { return {meta: {}}; }, - }); element._loadComments().then(() => { assert.equal(Object.keys(element._commentMap).length, 0); done(); @@ -691,16 +887,11 @@ limitations under the License. }); test('has paths', done => { - stub('gr-comment-api', { - loadAll() { return Promise.resolve(); }, - getPaths() { - return { - 'path/to/file/one.cpp': [{patch_set: 3, message: 'lorem'}], - 'path-to/file/two.py': [{patch_set: 5, message: 'ipsum'}], - }; - }, - getCommentsForPath() { return {meta: {}}; }, + 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', @@ -757,17 +948,131 @@ limitations under the License. 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('_computeEditLoaded', () => { - const callCompute = range => element._computeEditLoaded({base: range}); + 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'})); }); - suite('editLoaded behavior', () => { + 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; }); @@ -788,5 +1093,36 @@ limitations under the License. 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> |