From 4f10d777d981c4027f27bddd0b7e30c7995b6372 Mon Sep 17 00:00:00 2001 From: Tao Zhou Date: Fri, 7 Feb 2020 13:30:34 +0100 Subject: [PATCH] Fix tests for M80 As of M80(chrome version >= 80), chrome removed the native htmlImports support, tho we have the polyfill from webcomponents, the loading of html changed from sync to async which cause a lot test to fail in M80. The fix is introducing a util method `readyToTest` which wait until htmlImports finished before running any tests. Updated some tests to have only one top suite per test so we only need one `readyToTest` and also multiple `readyToTest` actually affect tests' stub functionality. Tested locally with `npm run test` on all passed tests and also with manual failure to make sure the updated tests can still catch any errors if have. Bug: Issue 12294 Change-Id: Ib0c464f8ff9f36a401e6c3b249e6bb6d68ee6e2f --- .../async-foreach-behavior_test.html | 4 +- .../base-url-behavior_test.html | 4 +- .../docs-url-behavior_test.html | 4 +- .../dom-util-behavior_test.html | 4 +- .../gr-access-behavior_test.html | 4 +- .../gr-admin-nav-behavior_test.html | 4 +- .../gr-change-table-behavior_test.html | 4 +- .../gr-display-name-behavior_test.html | 4 +- .../gr-list-view-behavior_test.html | 4 +- .../gr-patch-set-behavior_test.html | 4 +- .../gr-path-list-behavior_test.html | 4 +- .../gr-tooltip-behavior_test.html | 4 +- .../gr-url-encoding-behavior_test.html | 4 +- .../keyboard-shortcut-behavior_test.html | 4 +- .../rest-client-behavior_test.html | 4 +- .../safe-types-behavior_test.html | 4 +- .../gr-access-section_test.html | 4 +- .../gr-admin-group-list_test.html | 4 +- .../gr-admin-view/gr-admin-view_test.html | 4 +- .../gr-confirm-delete-item-dialog_test.html | 4 +- .../gr-create-change-dialog_test.html | 4 +- .../gr-create-group-dialog_test.html | 4 +- .../gr-create-pointer-dialog_test.html | 4 +- .../gr-create-repo-dialog_test.html | 4 +- .../gr-group-audit-log_test.html | 4 +- .../gr-group-members_test.html | 4 +- .../admin/gr-group/gr-group_test.html | 4 +- .../gr-permission/gr-permission_test.html | 4 +- .../gr-plugin-config-array-editor_test.html | 4 +- .../gr-plugin-list/gr-plugin-list_test.html | 4 +- .../gr-repo-access/gr-repo-access_test.html | 4 +- .../gr-repo-command/gr-repo-command_test.html | 4 +- .../gr-repo-commands_test.html | 4 +- .../gr-repo-dashboards_test.html | 4 +- .../gr-repo-detail-list_test.html | 908 ++--- .../admin/gr-repo-list/gr-repo-list_test.html | 4 +- .../gr-repo-plugin-config_test.html | 4 +- .../elements/admin/gr-repo/gr-repo_test.html | 4 +- .../gr-rule-editor/gr-rule-editor_test.html | 4 +- .../gr-change-list-item_test.html | 4 +- .../gr-change-list-view_test.html | 4 +- .../gr-change-list/gr-change-list_test.html | 340 +- .../gr-create-change-help_test.html | 4 +- .../gr-create-commands-dialog_test.html | 4 +- .../gr-dashboard-view_test.html | 4 +- .../gr-repo-header/gr-repo-header_test.html | 4 +- .../gr-user-header/gr-user-header_test.html | 4 +- .../gr-change-actions_test.html | 3437 +++++++++-------- .../gr-change-metadata-it_test.html | 4 +- .../gr-change-metadata_test.html | 4 +- .../gr-change-requirements_test.html | 4 +- .../gr-change-view/gr-change-view_test.html | 4 +- .../gr-comment-list/gr-comment-list_test.html | 4 +- .../gr-commit-info/gr-commit-info_test.html | 4 +- .../gr-confirm-abandon-dialog_test.html | 4 +- ...nfirm-cherrypick-conflict-dialog_test.html | 4 +- .../gr-confirm-cherrypick-dialog_test.html | 4 +- .../gr-confirm-move-dialog_test.html | 4 +- .../gr-confirm-rebase-dialog_test.html | 4 +- .../gr-confirm-revert-dialog_test.html | 4 +- ...confirm-revert-submission-dialog_test.html | 4 +- .../gr-confirm-submit-dialog_test.html | 4 +- .../gr-download-dialog_test.html | 4 +- .../gr-file-list-header_test.html | 4 +- .../gr-file-list/gr-file-list_test.html | 3030 +++++++-------- .../gr-included-in-dialog_test.html | 4 +- .../gr-label-score-row_test.html | 4 +- .../gr-label-scores/gr-label-scores_test.html | 4 +- .../change/gr-message/gr-message_test.html | 4 +- .../gr-messages-list_test.html | 908 ++--- .../gr-related-changes-list_test.html | 4 +- .../gr-reply-dialog-it_test.html | 4 +- .../gr-reply-dialog/gr-reply-dialog_test.html | 4 +- .../gr-reviewer-list_test.html | 4 +- .../gr-thread-list/gr-thread-list_test.html | 4 +- .../gr-upload-help-dialog_test.html | 4 +- .../gr-account-dropdown_test.html | 4 +- .../gr-error-dialog/gr-error-dialog_test.html | 4 +- .../gr-error-manager_test.html | 3 +- .../gr-key-binding-display_test.html | 4 +- .../gr-keyboard-shortcuts-dialog_test.html | 4 +- .../gr-main-header/gr-main-header_test.html | 4 +- .../gr-navigation/gr-navigation_test.html | 4 +- .../core/gr-reporting/gr-reporting_test.html | 4 +- .../core/gr-router/gr-router_test.html | 4 +- .../gr-search-bar/gr-search-bar_test.html | 4 +- .../gr-smart-search/gr-smart-search_test.html | 4 +- .../app/elements/custom-dark-theme_test.html | 4 +- .../app/elements/custom-light-theme_test.html | 4 +- .../gr-apply-fix-dialog_test.html | 3 +- .../gr-comment-api/gr-comment-api-mock.js | 64 +- .../gr-comment-api/gr-comment-api_test.html | 4 +- .../gr-coverage-layer_test.html | 4 +- .../gr-diff-builder-unified_test.html | 4 +- .../gr-diff-builder/gr-diff-builder_test.html | 4 +- .../gr-diff-cursor/gr-diff-cursor_test.html | 36 +- .../gr-diff-highlight/gr-annotation_test.html | 4 +- .../gr-diff-highlight_test.html | 4 +- .../diff/gr-diff-host/gr-diff-host_test.html | 4 +- .../gr-diff-mode-selector_test.html | 4 +- .../gr-diff-processor_test.html | 4 +- .../gr-diff-selection_test.html | 4 +- .../diff/gr-diff-view/gr-diff-view_test.html | 2415 ++++++------ .../diff/gr-diff/gr-diff-group_test.html | 4 +- .../elements/diff/gr-diff/gr-diff_test.html | 4 +- .../gr-patch-range-select_test.html | 4 +- .../gr-ranged-comment-layer_test.html | 4 +- .../gr-selection-action-box_test.html | 4 +- .../gr-syntax-layer/gr-syntax-layer_test.html | 4 +- .../gr-documentation-search_test.html | 4 +- .../gr-default-editor_test.html | 4 +- .../gr-edit-controls_test.html | 622 +-- .../gr-edit-file-controls_test.html | 132 +- .../gr-editor-view/gr-editor-view_test.html | 716 ++-- polygerrit-ui/app/elements/gr-app_test.html | 4 +- .../gr-admin-api/gr-admin-api_test.html | 4 +- .../gr-attribute-helper_test.html | 21 +- .../gr-dom-hooks/gr-dom-hooks_test.html | 4 +- .../gr-endpoint-decorator_test.html | 4 +- .../gr-event-helper/gr-event-helper_test.html | 27 +- .../gr-external-style_test.html | 4 +- .../gr-plugin-host/gr-plugin-host_test.html | 4 +- .../gr-plugin-popup_test.html | 4 +- .../gr-popup-interface_test.html | 10 +- .../plugins/gr-repo-api/gr-repo-api_test.html | 4 +- .../gr-settings-api/gr-settings-api_test.html | 4 +- .../gr-styles-api/gr-styles-api_test.html | 218 +- .../gr-theme-api/gr-theme-api_test.html | 4 +- .../gr-account-info/gr-account-info_test.html | 4 +- .../gr-agreements-list_test.html | 4 +- .../gr-change-table-editor_test.html | 4 +- .../gr-cla-view/gr-cla-view_test.html | 4 +- .../gr-edit-preferences_test.html | 4 +- .../gr-email-editor/gr-email-editor_test.html | 4 +- .../gr-gpg-editor/gr-gpg-editor_test.html | 4 +- .../gr-group-list/gr-group-list_test.html | 4 +- .../gr-http-password_test.html | 4 +- .../gr-identities/gr-identities_test.html | 4 +- .../gr-menu-editor/gr-menu-editor_test.html | 4 +- .../gr-registration-dialog_test.html | 4 +- .../gr-settings-view_test.html | 4 +- .../gr-ssh-editor/gr-ssh-editor_test.html | 4 +- .../gr-watched-projects-editor_test.html | 4 +- .../gr-account-entry_test.html | 4 +- .../gr-account-label_test.html | 4 +- .../gr-account-link/gr-account-link_test.html | 4 +- .../gr-account-list/gr-account-list_test.html | 4 +- .../shared/gr-alert/gr-alert_test.html | 4 +- .../gr-autocomplete-dropdown_test.html | 4 +- .../gr-autocomplete/gr-autocomplete_test.html | 4 +- .../shared/gr-avatar/gr-avatar_test.html | 112 +- .../shared/gr-button/gr-button_test.html | 4 +- .../gr-change-star/gr-change-star_test.html | 4 +- .../gr-change-status_test.html | 4 +- .../gr-comment-thread_test.html | 339 +- .../shared/gr-comment/gr-comment_test.html | 1804 ++++----- .../gr-copy-clipboard_test.html | 4 +- .../gr-count-string-formatter_test.html | 4 +- .../gr-cursor-manager_test.html | 4 +- .../gr-date-formatter_test.html | 4 +- .../shared/gr-dialog/gr-dialog_test.html | 4 +- .../gr-diff-preferences_test.html | 4 +- .../gr-download-commands_test.html | 4 +- .../gr-dropdown-list_test.html | 4 +- .../shared/gr-dropdown/gr-dropdown_test.html | 4 +- .../gr-editable-content_test.html | 4 +- .../gr-editable-label_test.html | 40 +- .../gr-event-interface_test.html | 4 +- .../gr-fixed-panel/gr-fixed-panel_test.html | 4 +- .../gr-formatted-text_test.html | 4 +- .../gr-hovercard/gr-hovercard_test.html | 4 +- .../gr-annotation-actions-context_test.html | 4 +- .../gr-annotation-actions-js-api_test.html | 4 +- .../gr-api-utils_test.html | 4 +- .../gr-change-actions-js-api_test.html | 4 +- .../gr-change-reply-js-api_test.html | 4 +- .../gr-js-api-interface/gr-gerrit_test.html | 4 +- .../gr-js-api-interface_test.html | 6 +- .../gr-plugin-action-context_test.html | 4 +- .../gr-plugin-endpoints_test.html | 4 +- .../gr-plugin-loader_test.html | 6 +- .../gr-plugin-rest-api_test.html | 4 +- .../gr-label-info/gr-label-info_test.html | 4 +- .../gr-labeled-autocomplete_test.html | 4 +- .../gr-lib-loader/gr-lib-loader_test.html | 4 +- .../gr-limited-text/gr-limited-text_test.html | 4 +- .../gr-linked-chip/gr-linked-chip_test.html | 4 +- .../gr-linked-text/gr-linked-text_test.html | 4 +- .../gr-list-view/gr-list-view_test.html | 4 +- .../shared/gr-overlay/gr-overlay_test.html | 4 +- .../shared/gr-page-nav/gr-page-nav_test.html | 4 +- .../gr-repo-branch-picker_test.html | 4 +- .../shared/gr-rest-api-interface/gr-auth.js | 1 + .../gr-rest-api-interface/gr-auth_test.html | 4 +- .../gr-etag-decorator_test.html | 4 +- .../gr-rest-api-interface_test.html | 4 +- .../gr-rest-apis/gr-rest-api-helper_test.html | 4 +- .../gr-reviewer-updates-parser_test.html | 4 +- .../mock-diff-response_test.html | 1 + .../shared/gr-select/gr-select_test.html | 20 +- .../gr-shell-command_test.html | 4 +- .../shared/gr-storage/gr-storage_test.html | 4 +- .../shared/gr-textarea/gr-textarea_test.html | 60 +- .../gr-tooltip-content_test.html | 4 +- .../shared/gr-tooltip/gr-tooltip_test.html | 4 +- .../revision-info/revision-info_test.html | 4 +- .../gr-display-name-utils_test.html | 4 +- .../gr-email-suggestions-provider_test.html | 4 +- .../gr-group-suggestions-provider_test.html | 4 +- .../gr-reviewer-suggestions-provider.js | 1 + ...gr-reviewer-suggestions-provider_test.html | 4 +- polygerrit-ui/app/test/test-pre-setup.js | 11 + 212 files changed, 8255 insertions(+), 7768 deletions(-) create mode 100644 polygerrit-ui/app/test/test-pre-setup.js diff --git a/polygerrit-ui/app/behaviors/async-foreach-behavior/async-foreach-behavior_test.html b/polygerrit-ui/app/behaviors/async-foreach-behavior/async-foreach-behavior_test.html index 03ba6b1764..f2f0e6b911 100644 --- a/polygerrit-ui/app/behaviors/async-foreach-behavior/async-foreach-behavior_test.html +++ b/polygerrit-ui/app/behaviors/async-foreach-behavior/async-foreach-behavior_test.html @@ -23,11 +23,13 @@ limitations under the License. + + + docs-url-behavior @@ -33,7 +34,8 @@ limitations under the License. + @@ -40,7 +41,8 @@ limitations under the License. + @@ -33,7 +34,8 @@ limitations under the License. + @@ -33,7 +34,8 @@ limitations under the License. + @@ -41,7 +42,8 @@ limitations under the License. + @@ -33,7 +34,8 @@ limitations under the License. + @@ -33,7 +34,8 @@ limitations under the License. + gr-patch-set-behavior @@ -25,7 +26,8 @@ limitations under the License. + gr-path-list-behavior @@ -25,7 +26,8 @@ limitations under the License. + @@ -34,7 +35,8 @@ limitations under the License. + @@ -34,7 +35,8 @@ limitations under the License. + @@ -41,7 +42,8 @@ limitations under the License. + + @@ -34,7 +35,8 @@ limitations under the License. + @@ -36,7 +37,8 @@ limitations under the License. + @@ -54,7 +55,8 @@ limitations under the License. }; }; - suite('gr-admin-group-list tests', () => { + suite('gr-admin-group-list tests', async () => { + await readyToTest(); let element; let groups; let sandbox; diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html index 7b0c723430..8436cf1947 100644 --- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html +++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html @@ -23,6 +23,7 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -36,7 +37,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -36,7 +37,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -50,7 +51,8 @@ limitations under the License. return plugin; }; - suite('gr-plugin-list tests', () => { + suite('gr-plugin-list tests', async () => { + await readyToTest(); let element; let plugins; let sandbox; diff --git a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.html b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.html index e0e25e01cb..8b3fd82bb0 100644 --- a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.html +++ b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.html @@ -24,6 +24,7 @@ limitations under the License. + @@ -36,7 +37,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -36,7 +37,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -69,495 +70,498 @@ limitations under the License. }; }; - suite('Branches', () => { - let element; - let branches; - let sandbox; + suite('gr-repo-detail-list', async () => { + await readyToTest(); + suite('Branches', () => { + let element; + let branches; + let sandbox; - setup(() => { - sandbox = sinon.sandbox.create(); - element = fixture('basic'); - element.detailType = 'branches'; - counter = 0; - sandbox.stub(page, 'show'); - }); - - teardown(() => { - sandbox.restore(); - }); - - suite('list of repo branches', () => { - setup(done => { - branches = [{ - ref: 'HEAD', - revision: 'master', - }].concat(_.times(25, branchGenerator)); - - stub('gr-rest-api-interface', { - getRepoBranches(num, project, offset) { - return Promise.resolve(branches); - }, - }); - - const params = { - repo: 'test', - detail: 'branches', - }; - - element._paramsChanged(params).then(() => { flush(done); }); + setup(() => { + sandbox = sinon.sandbox.create(); + element = fixture('basic'); + element.detailType = 'branches'; + counter = 0; + sandbox.stub(page, 'show'); }); - test('test for branch in the list', done => { - flush(() => { - assert.equal(element._items[2].ref, 'refs/heads/test2'); - done(); + teardown(() => { + sandbox.restore(); + }); + + suite('list of repo branches', () => { + setup(done => { + branches = [{ + ref: 'HEAD', + revision: 'master', + }].concat(_.times(25, branchGenerator)); + + stub('gr-rest-api-interface', { + getRepoBranches(num, project, offset) { + return Promise.resolve(branches); + }, + }); + + const params = { + repo: 'test', + detail: 'branches', + }; + + element._paramsChanged(params).then(() => { flush(done); }); + }); + + test('test for branch in the list', done => { + flush(() => { + assert.equal(element._items[2].ref, 'refs/heads/test2'); + done(); + }); + }); + + test('test for web links in the branches list', done => { + flush(() => { + assert.equal(element._items[2].web_links[0].url, + 'https://git.example.org/branch/test;refs/heads/test2'); + done(); + }); + }); + + test('test for refs/heads/ being striped from ref', done => { + flush(() => { + assert.equal(element._stripRefs(element._items[2].ref, + element.detailType), 'test2'); + done(); + }); + }); + + test('_shownItems', () => { + assert.equal(element._shownItems.length, 25); + }); + + test('Edit HEAD button not admin', done => { + sandbox.stub(element, '_getLoggedIn').returns(Promise.resolve(true)); + sandbox.stub(element.$.restAPI, 'getRepoAccess').returns( + Promise.resolve({ + test: {is_owner: false}, + })); + element._determineIfOwner('test').then(() => { + assert.equal(element._isOwner, false); + assert.equal(getComputedStyle(Polymer.dom(element.root) + .querySelector('.revisionNoEditing')).display, 'inline'); + assert.equal(getComputedStyle(Polymer.dom(element.root) + .querySelector('.revisionEdit')).display, 'none'); + done(); + }); + }); + + test('Edit HEAD button admin', done => { + const saveBtn = Polymer.dom(element.root).querySelector('.saveBtn'); + const cancelBtn = Polymer.dom(element.root).querySelector('.cancelBtn'); + const editBtn = Polymer.dom(element.root).querySelector('.editBtn'); + const revisionNoEditing = Polymer.dom(element.root) + .querySelector('.revisionNoEditing'); + const revisionWithEditing = Polymer.dom(element.root) + .querySelector('.revisionWithEditing'); + + sandbox.stub(element, '_getLoggedIn').returns(Promise.resolve(true)); + sandbox.stub(element.$.restAPI, 'getRepoAccess').returns( + Promise.resolve({ + test: {is_owner: true}, + })); + sandbox.stub(element, '_handleSaveRevision'); + element._determineIfOwner('test').then(() => { + assert.equal(element._isOwner, true); + // The revision container for non-editing enabled row is not visible. + assert.equal(getComputedStyle(revisionNoEditing).display, 'none'); + + // The revision container for editing enabled row is visible. + assert.notEqual(getComputedStyle(Polymer.dom(element.root) + .querySelector('.revisionEdit')).display, 'none'); + + // The revision and edit button are visible. + assert.notEqual(getComputedStyle(revisionWithEditing).display, + 'none'); + assert.notEqual(getComputedStyle(editBtn).display, 'none'); + + // The input, cancel, and save buttons are not visible. + const hiddenElements = Polymer.dom(element.root) + .querySelectorAll('.canEdit .editItem'); + + for (const item of hiddenElements) { + assert.equal(getComputedStyle(item).display, 'none'); + } + + MockInteractions.tap(editBtn); + flushAsynchronousOperations(); + // The revision and edit button are not visible. + assert.equal(getComputedStyle(revisionWithEditing).display, 'none'); + assert.equal(getComputedStyle(editBtn).display, 'none'); + + // The input, cancel, and save buttons are not visible. + for (item of hiddenElements) { + assert.notEqual(getComputedStyle(item).display, 'none'); + } + + // The revised ref was set correctly + assert.equal(element._revisedRef, 'master'); + + assert.isFalse(saveBtn.disabled); + + // Delete the ref. + element._revisedRef = ''; + assert.isTrue(saveBtn.disabled); + + // Change the ref to something else + element._revisedRef = 'newRef'; + element._repo = 'test'; + assert.isFalse(saveBtn.disabled); + + // Save button calls handleSave. since this is stubbed, the edit + // section remains open. + MockInteractions.tap(saveBtn); + assert.isTrue(element._handleSaveRevision.called); + + // When cancel is tapped, the edit secion closes. + MockInteractions.tap(cancelBtn); + flushAsynchronousOperations(); + + // The revision and edit button are visible. + assert.notEqual(getComputedStyle(revisionWithEditing).display, + 'none'); + assert.notEqual(getComputedStyle(editBtn).display, 'none'); + + // The input, cancel, and save buttons are not visible. + for (const item of hiddenElements) { + assert.equal(getComputedStyle(item).display, 'none'); + } + done(); + }); + }); + + test('_handleSaveRevision with invalid rev', done => { + const event = {model: {set: sandbox.stub()}}; + element._isEditing = true; + sandbox.stub(element.$.restAPI, 'setRepoHead').returns( + Promise.resolve({ + status: 400, + }) + ); + + element._setRepoHead('test', 'newRef', event).then(() => { + assert.isTrue(element._isEditing); + assert.isFalse(event.model.set.called); + done(); + }); + }); + + test('_handleSaveRevision with valid rev', done => { + const event = {model: {set: sandbox.stub()}}; + element._isEditing = true; + sandbox.stub(element.$.restAPI, 'setRepoHead').returns( + Promise.resolve({ + status: 200, + }) + ); + + element._setRepoHead('test', 'newRef', event).then(() => { + assert.isFalse(element._isEditing); + assert.isTrue(event.model.set.called); + done(); + }); + }); + + test('test _computeItemName', () => { + assert.deepEqual(element._computeItemName('branches'), 'Branch'); + assert.deepEqual(element._computeItemName('tags'), 'Tag'); }); }); - test('test for web links in the branches list', done => { - flush(() => { - assert.equal(element._items[2].web_links[0].url, - 'https://git.example.org/branch/test;refs/heads/test2'); - done(); + suite('list with less then 25 branches', () => { + setup(done => { + branches = _.times(25, branchGenerator); + + stub('gr-rest-api-interface', { + getRepoBranches(num, repo, offset) { + return Promise.resolve(branches); + }, + }); + + const params = { + repo: 'test', + detail: 'branches', + }; + + element._paramsChanged(params).then(() => { flush(done); }); + }); + + test('_shownItems', () => { + assert.equal(element._shownItems.length, 25); }); }); - test('test for refs/heads/ being striped from ref', done => { - flush(() => { - assert.equal(element._stripRefs(element._items[2].ref, - element.detailType), 'test2'); - done(); + suite('filter', () => { + test('_paramsChanged', done => { + sandbox.stub( + element.$.restAPI, + 'getRepoBranches', + () => Promise.resolve(branches)); + const params = { + detail: 'branches', + repo: 'test', + filter: 'test', + offset: 25, + }; + element._paramsChanged(params).then(() => { + assert.equal(element.$.restAPI.getRepoBranches.lastCall.args[0], + 'test'); + assert.equal(element.$.restAPI.getRepoBranches.lastCall.args[1], + 'test'); + assert.equal(element.$.restAPI.getRepoBranches.lastCall.args[2], + 25); + assert.equal(element.$.restAPI.getRepoBranches.lastCall.args[3], + 25); + done(); + }); }); }); - test('_shownItems', () => { - assert.equal(element._shownItems.length, 25); - }); + suite('404', () => { + test('fires page-error', done => { + const response = {status: 404}; + sandbox.stub(element.$.restAPI, 'getRepoBranches', + (filter, repo, reposBranchesPerPage, opt_offset, errFn) => { + errFn(response); + }); - test('Edit HEAD button not admin', done => { - sandbox.stub(element, '_getLoggedIn').returns(Promise.resolve(true)); - sandbox.stub(element.$.restAPI, 'getRepoAccess').returns( - Promise.resolve({ - test: {is_owner: false}, - })); - element._determineIfOwner('test').then(() => { - assert.equal(element._isOwner, false); - assert.equal(getComputedStyle(Polymer.dom(element.root) - .querySelector('.revisionNoEditing')).display, 'inline'); - assert.equal(getComputedStyle(Polymer.dom(element.root) - .querySelector('.revisionEdit')).display, 'none'); - done(); - }); - }); + element.addEventListener('page-error', e => { + assert.deepEqual(e.detail.response, response); + done(); + }); - test('Edit HEAD button admin', done => { - const saveBtn = Polymer.dom(element.root).querySelector('.saveBtn'); - const cancelBtn = Polymer.dom(element.root).querySelector('.cancelBtn'); - const editBtn = Polymer.dom(element.root).querySelector('.editBtn'); - const revisionNoEditing = Polymer.dom(element.root) - .querySelector('.revisionNoEditing'); - const revisionWithEditing = Polymer.dom(element.root) - .querySelector('.revisionWithEditing'); - - sandbox.stub(element, '_getLoggedIn').returns(Promise.resolve(true)); - sandbox.stub(element.$.restAPI, 'getRepoAccess').returns( - Promise.resolve({ - test: {is_owner: true}, - })); - sandbox.stub(element, '_handleSaveRevision'); - element._determineIfOwner('test').then(() => { - assert.equal(element._isOwner, true); - // The revision container for non-editing enabled row is not visible. - assert.equal(getComputedStyle(revisionNoEditing).display, 'none'); - - // The revision container for editing enabled row is visible. - assert.notEqual(getComputedStyle(Polymer.dom(element.root) - .querySelector('.revisionEdit')).display, 'none'); - - // The revision and edit button are visible. - assert.notEqual(getComputedStyle(revisionWithEditing).display, - 'none'); - assert.notEqual(getComputedStyle(editBtn).display, 'none'); - - // The input, cancel, and save buttons are not visible. - const hiddenElements = Polymer.dom(element.root) - .querySelectorAll('.canEdit .editItem'); - - for (const item of hiddenElements) { - assert.equal(getComputedStyle(item).display, 'none'); - } - - MockInteractions.tap(editBtn); - flushAsynchronousOperations(); - // The revision and edit button are not visible. - assert.equal(getComputedStyle(revisionWithEditing).display, 'none'); - assert.equal(getComputedStyle(editBtn).display, 'none'); - - // The input, cancel, and save buttons are not visible. - for (item of hiddenElements) { - assert.notEqual(getComputedStyle(item).display, 'none'); - } - - // The revised ref was set correctly - assert.equal(element._revisedRef, 'master'); - - assert.isFalse(saveBtn.disabled); - - // Delete the ref. - element._revisedRef = ''; - assert.isTrue(saveBtn.disabled); - - // Change the ref to something else - element._revisedRef = 'newRef'; - element._repo = 'test'; - assert.isFalse(saveBtn.disabled); - - // Save button calls handleSave. since this is stubbed, the edit - // section remains open. - MockInteractions.tap(saveBtn); - assert.isTrue(element._handleSaveRevision.called); - - // When cancel is tapped, the edit secion closes. - MockInteractions.tap(cancelBtn); - flushAsynchronousOperations(); - - // The revision and edit button are visible. - assert.notEqual(getComputedStyle(revisionWithEditing).display, - 'none'); - assert.notEqual(getComputedStyle(editBtn).display, 'none'); - - // The input, cancel, and save buttons are not visible. - for (const item of hiddenElements) { - assert.equal(getComputedStyle(item).display, 'none'); - } - done(); - }); - }); - - test('_handleSaveRevision with invalid rev', done => { - const event = {model: {set: sandbox.stub()}}; - element._isEditing = true; - sandbox.stub(element.$.restAPI, 'setRepoHead').returns( - Promise.resolve({ - status: 400, - }) - ); - - element._setRepoHead('test', 'newRef', event).then(() => { - assert.isTrue(element._isEditing); - assert.isFalse(event.model.set.called); - done(); - }); - }); - - test('_handleSaveRevision with valid rev', done => { - const event = {model: {set: sandbox.stub()}}; - element._isEditing = true; - sandbox.stub(element.$.restAPI, 'setRepoHead').returns( - Promise.resolve({ - status: 200, - }) - ); - - element._setRepoHead('test', 'newRef', event).then(() => { - assert.isFalse(element._isEditing); - assert.isTrue(event.model.set.called); - done(); - }); - }); - - test('test _computeItemName', () => { - assert.deepEqual(element._computeItemName('branches'), 'Branch'); - assert.deepEqual(element._computeItemName('tags'), 'Tag'); - }); - }); - - suite('list with less then 25 branches', () => { - setup(done => { - branches = _.times(25, branchGenerator); - - stub('gr-rest-api-interface', { - getRepoBranches(num, repo, offset) { - return Promise.resolve(branches); - }, - }); - - const params = { - repo: 'test', - detail: 'branches', - }; - - element._paramsChanged(params).then(() => { flush(done); }); - }); - - test('_shownItems', () => { - assert.equal(element._shownItems.length, 25); - }); - }); - - suite('filter', () => { - test('_paramsChanged', done => { - sandbox.stub( - element.$.restAPI, - 'getRepoBranches', - () => Promise.resolve(branches)); - const params = { - detail: 'branches', - repo: 'test', - filter: 'test', - offset: 25, - }; - element._paramsChanged(params).then(() => { - assert.equal(element.$.restAPI.getRepoBranches.lastCall.args[0], - 'test'); - assert.equal(element.$.restAPI.getRepoBranches.lastCall.args[1], - 'test'); - assert.equal(element.$.restAPI.getRepoBranches.lastCall.args[2], - 25); - assert.equal(element.$.restAPI.getRepoBranches.lastCall.args[3], - 25); - done(); + const params = { + detail: 'branches', + repo: 'test', + filter: 'test', + offset: 25, + }; + element._paramsChanged(params); }); }); }); - suite('404', () => { - test('fires page-error', done => { - const response = {status: 404}; - sandbox.stub(element.$.restAPI, 'getRepoBranches', - (filter, repo, reposBranchesPerPage, opt_offset, errFn) => { - errFn(response); - }); + suite('Tags', () => { + let element; + let tags; + let sandbox; - element.addEventListener('page-error', e => { - assert.deepEqual(e.detail.response, response); - done(); - }); - - const params = { - detail: 'branches', - repo: 'test', - filter: 'test', - offset: 25, - }; - element._paramsChanged(params); - }); - }); - }); - - suite('Tags', () => { - let element; - let tags; - let sandbox; - - setup(() => { - sandbox = sinon.sandbox.create(); - element = fixture('basic'); - element.detailType = 'tags'; - counter = 0; - sandbox.stub(page, 'show'); - }); - - teardown(() => { - sandbox.restore(); - }); - - test('_computeMessage', () => { - let message = 'v2.15-rc1↵-----BEGIN PGP SIGNATURE-----↵Version: GnuPG v' + - '1↵↵iQIcBAABAgAGBQJZ27O7AAoJEF/XxZqaEoiMy6kQAMoQCpGr3J6JITI4BVWsr7QM↵xy' + - 'EcWH5YPUko5EPTbkABHmaVyFmKGkuIQdn6c+NIbqJOk+5XT4oUyRSo1T569HPJ↵3kyxEJi' + - 'T1ryvp5BIHwdvHx58fjw1+YkiWLZuZq1FFkUYqnWTYCrkv7Fok98pdOmV↵CL1Hgugi5uK8' + - '/kxf1M7+Nv6piaZ140pwSb1h6QdAjaZVfaBCnoxlG4LRUqHvEYay↵f4QYgFT67auHIGkZ4' + - 'moUcsp2Du/1jSsCWL/CPwjPFGbbckVAjLCMT9yD3NKwpEZF↵pfsiZyHI9dL0M+QjVrM+RD' + - 'HwIIJwra8R0IMkDlQ6MDrFlKNqNBbo588S6UPrm71L↵YuiwWlcrK9ZIybxT6LzbR65Rvez' + - 'DSitQ+xeIfpZE19/X6BCnvlARLE8k/tC2JksI↵lEZi7Lf3FQdIcwwyt98tJkS9HX9v9jbC' + - '5QXifnoj3Li8tHSLuQ1dJCxHQiis6ojI↵OWUFkm0IHBXVNHA2dqYBdM+pL12mlI3wp6Ica' + - '4cdEVDwzu+j1xnVSFUa+d+Y2xJF↵7mytuyhHiKG4hm+zbhMv6WD8Q3FoDsJZeLY99l0hYQ' + - 'SnnkMduFVroIs45pAs8gUA↵RvYla8mm9w/543IJAPzzFarPVLSsSyQ7tJl3UBzjKRNH/rX' + - 'W+F22qyWD1zyHPUIR↵C00ItmwlAvveImYKpQAH↵=L+K9↵-----END PGP SIGNATURE---' + - '--'; - assert.equal(element._computeMessage(message), 'v2.15-rc1↵'); - message = 'v2.15-rc1'; - assert.equal(element._computeMessage(message), 'v2.15-rc1'); - }); - - suite('list of repo tags', () => { - setup(done => { - tags = _.times(26, tagGenerator); - - stub('gr-rest-api-interface', { - getRepoTags(num, repo, offset) { - return Promise.resolve(tags); - }, - }); - - const params = { - repo: 'test', - detail: 'tags', - }; - - element._paramsChanged(params).then(() => { flush(done); }); + setup(() => { + sandbox = sinon.sandbox.create(); + element = fixture('basic'); + element.detailType = 'tags'; + counter = 0; + sandbox.stub(page, 'show'); }); - test('test for tag in the list', done => { - flush(() => { - assert.equal(element._items[1].ref, 'refs/tags/test2'); - done(); + teardown(() => { + sandbox.restore(); + }); + + test('_computeMessage', () => { + let message = 'v2.15-rc1↵-----BEGIN PGP SIGNATURE-----↵Version: GnuPG v' + + '1↵↵iQIcBAABAgAGBQJZ27O7AAoJEF/XxZqaEoiMy6kQAMoQCpGr3J6JITI4BVWsr7QM↵xy' + + 'EcWH5YPUko5EPTbkABHmaVyFmKGkuIQdn6c+NIbqJOk+5XT4oUyRSo1T569HPJ↵3kyxEJi' + + 'T1ryvp5BIHwdvHx58fjw1+YkiWLZuZq1FFkUYqnWTYCrkv7Fok98pdOmV↵CL1Hgugi5uK8' + + '/kxf1M7+Nv6piaZ140pwSb1h6QdAjaZVfaBCnoxlG4LRUqHvEYay↵f4QYgFT67auHIGkZ4' + + 'moUcsp2Du/1jSsCWL/CPwjPFGbbckVAjLCMT9yD3NKwpEZF↵pfsiZyHI9dL0M+QjVrM+RD' + + 'HwIIJwra8R0IMkDlQ6MDrFlKNqNBbo588S6UPrm71L↵YuiwWlcrK9ZIybxT6LzbR65Rvez' + + 'DSitQ+xeIfpZE19/X6BCnvlARLE8k/tC2JksI↵lEZi7Lf3FQdIcwwyt98tJkS9HX9v9jbC' + + '5QXifnoj3Li8tHSLuQ1dJCxHQiis6ojI↵OWUFkm0IHBXVNHA2dqYBdM+pL12mlI3wp6Ica' + + '4cdEVDwzu+j1xnVSFUa+d+Y2xJF↵7mytuyhHiKG4hm+zbhMv6WD8Q3FoDsJZeLY99l0hYQ' + + 'SnnkMduFVroIs45pAs8gUA↵RvYla8mm9w/543IJAPzzFarPVLSsSyQ7tJl3UBzjKRNH/rX' + + 'W+F22qyWD1zyHPUIR↵C00ItmwlAvveImYKpQAH↵=L+K9↵-----END PGP SIGNATURE---' + + '--'; + assert.equal(element._computeMessage(message), 'v2.15-rc1↵'); + message = 'v2.15-rc1'; + assert.equal(element._computeMessage(message), 'v2.15-rc1'); + }); + + suite('list of repo tags', () => { + setup(done => { + tags = _.times(26, tagGenerator); + + stub('gr-rest-api-interface', { + getRepoTags(num, repo, offset) { + return Promise.resolve(tags); + }, + }); + + const params = { + repo: 'test', + detail: 'tags', + }; + + element._paramsChanged(params).then(() => { flush(done); }); + }); + + test('test for tag in the list', done => { + flush(() => { + assert.equal(element._items[1].ref, 'refs/tags/test2'); + done(); + }); + }); + + test('test for tag message in the list', done => { + flush(() => { + assert.equal(element._items[1].message, 'Annotated tag'); + done(); + }); + }); + + test('test for tagger in the tag list', done => { + const tagger = { + name: 'Test User', + email: 'test.user@gmail.com', + date: '2017-09-19 14:54:00.000000000', + tz: 540, + }; + flush(() => { + assert.deepEqual(element._items[1].tagger, tagger); + done(); + }); + }); + + test('test for web links in the tags list', done => { + flush(() => { + assert.equal(element._items[1].web_links[0].url, + 'https://git.example.org/tag/test;refs/tags/test2'); + done(); + }); + }); + + test('test for refs/tags/ being striped from ref', done => { + flush(() => { + assert.equal(element._stripRefs(element._items[1].ref, + element.detailType), 'test2'); + done(); + }); + }); + + test('_shownItems', () => { + assert.equal(element._shownItems.length, 25); + }); + + test('_computeHideTagger', () => { + const testObject1 = { + tagger: 'test', + }; + assert.equal(element._computeHideTagger(testObject1), ''); + + assert.equal(element._computeHideTagger(undefined), 'hide'); }); }); - test('test for tag message in the list', done => { - flush(() => { - assert.equal(element._items[1].message, 'Annotated tag'); - done(); + suite('list with less then 25 tags', () => { + setup(done => { + tags = _.times(25, tagGenerator); + + stub('gr-rest-api-interface', { + getRepoTags(num, project, offset) { + return Promise.resolve(tags); + }, + }); + + const params = { + repo: 'test', + detail: 'tags', + }; + + element._paramsChanged(params).then(() => { flush(done); }); + }); + + test('_shownItems', () => { + assert.equal(element._shownItems.length, 25); }); }); - test('test for tagger in the tag list', done => { - const tagger = { - name: 'Test User', - email: 'test.user@gmail.com', - date: '2017-09-19 14:54:00.000000000', - tz: 540, - }; - flush(() => { - assert.deepEqual(element._items[1].tagger, tagger); - done(); + suite('filter', () => { + test('_paramsChanged', done => { + sandbox.stub( + element.$.restAPI, + 'getRepoTags', + () => Promise.resolve(tags)); + const params = { + repo: 'test', + detail: 'tags', + filter: 'test', + offset: 25, + }; + element._paramsChanged(params).then(() => { + assert.equal(element.$.restAPI.getRepoTags.lastCall.args[0], + 'test'); + assert.equal(element.$.restAPI.getRepoTags.lastCall.args[1], + 'test'); + assert.equal(element.$.restAPI.getRepoTags.lastCall.args[2], + 25); + assert.equal(element.$.restAPI.getRepoTags.lastCall.args[3], + 25); + done(); + }); }); }); - test('test for web links in the tags list', done => { - flush(() => { - assert.equal(element._items[1].web_links[0].url, - 'https://git.example.org/tag/test;refs/tags/test2'); - done(); + suite('create new', () => { + test('_handleCreateClicked called when create-click fired', () => { + sandbox.stub(element, '_handleCreateClicked'); + element.$$('gr-list-view').fire('create-clicked'); + assert.isTrue(element._handleCreateClicked.called); + }); + + test('_handleCreateClicked opens modal', () => { + const openStub = sandbox.stub(element.$.createOverlay, 'open'); + element._handleCreateClicked(); + assert.isTrue(openStub.called); + }); + + test('_handleCreateItem called when confirm fired', () => { + sandbox.stub(element, '_handleCreateItem'); + element.$.createDialog.fire('confirm'); + assert.isTrue(element._handleCreateItem.called); + }); + + test('_handleCloseCreate called when cancel fired', () => { + sandbox.stub(element, '_handleCloseCreate'); + element.$.createDialog.fire('cancel'); + assert.isTrue(element._handleCloseCreate.called); }); }); - test('test for refs/tags/ being striped from ref', done => { - flush(() => { - assert.equal(element._stripRefs(element._items[1].ref, - element.detailType), 'test2'); - done(); + suite('404', () => { + test('fires page-error', done => { + const response = {status: 404}; + sandbox.stub(element.$.restAPI, 'getRepoTags', + (filter, repo, reposTagsPerPage, opt_offset, errFn) => { + errFn(response); + }); + + element.addEventListener('page-error', e => { + assert.deepEqual(e.detail.response, response); + done(); + }); + + const params = { + repo: 'test', + detail: 'tags', + filter: 'test', + offset: 25, + }; + element._paramsChanged(params); }); }); - test('_shownItems', () => { - assert.equal(element._shownItems.length, 25); + test('test _computeHideDeleteClass', () => { + assert.deepEqual(element._computeHideDeleteClass(true, false), 'show'); + assert.deepEqual(element._computeHideDeleteClass(false, true), 'show'); + assert.deepEqual(element._computeHideDeleteClass(false, false), ''); }); - - test('_computeHideTagger', () => { - const testObject1 = { - tagger: 'test', - }; - assert.equal(element._computeHideTagger(testObject1), ''); - - assert.equal(element._computeHideTagger(undefined), 'hide'); - }); - }); - - suite('list with less then 25 tags', () => { - setup(done => { - tags = _.times(25, tagGenerator); - - stub('gr-rest-api-interface', { - getRepoTags(num, project, offset) { - return Promise.resolve(tags); - }, - }); - - const params = { - repo: 'test', - detail: 'tags', - }; - - element._paramsChanged(params).then(() => { flush(done); }); - }); - - test('_shownItems', () => { - assert.equal(element._shownItems.length, 25); - }); - }); - - suite('filter', () => { - test('_paramsChanged', done => { - sandbox.stub( - element.$.restAPI, - 'getRepoTags', - () => Promise.resolve(tags)); - const params = { - repo: 'test', - detail: 'tags', - filter: 'test', - offset: 25, - }; - element._paramsChanged(params).then(() => { - assert.equal(element.$.restAPI.getRepoTags.lastCall.args[0], - 'test'); - assert.equal(element.$.restAPI.getRepoTags.lastCall.args[1], - 'test'); - assert.equal(element.$.restAPI.getRepoTags.lastCall.args[2], - 25); - assert.equal(element.$.restAPI.getRepoTags.lastCall.args[3], - 25); - done(); - }); - }); - }); - - suite('create new', () => { - test('_handleCreateClicked called when create-click fired', () => { - sandbox.stub(element, '_handleCreateClicked'); - element.$$('gr-list-view').fire('create-clicked'); - assert.isTrue(element._handleCreateClicked.called); - }); - - test('_handleCreateClicked opens modal', () => { - const openStub = sandbox.stub(element.$.createOverlay, 'open'); - element._handleCreateClicked(); - assert.isTrue(openStub.called); - }); - - test('_handleCreateItem called when confirm fired', () => { - sandbox.stub(element, '_handleCreateItem'); - element.$.createDialog.fire('confirm'); - assert.isTrue(element._handleCreateItem.called); - }); - - test('_handleCloseCreate called when cancel fired', () => { - sandbox.stub(element, '_handleCloseCreate'); - element.$.createDialog.fire('cancel'); - assert.isTrue(element._handleCloseCreate.called); - }); - }); - - suite('404', () => { - test('fires page-error', done => { - const response = {status: 404}; - sandbox.stub(element.$.restAPI, 'getRepoTags', - (filter, repo, reposTagsPerPage, opt_offset, errFn) => { - errFn(response); - }); - - element.addEventListener('page-error', e => { - assert.deepEqual(e.detail.response, response); - done(); - }); - - const params = { - repo: 'test', - detail: 'tags', - filter: 'test', - offset: 25, - }; - element._paramsChanged(params); - }); - }); - - test('test _computeHideDeleteClass', () => { - assert.deepEqual(element._computeHideDeleteClass(true, false), 'show'); - assert.deepEqual(element._computeHideDeleteClass(false, true), 'show'); - assert.deepEqual(element._computeHideDeleteClass(false, false), ''); }); }); diff --git a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.html b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.html index aed5c77dc0..b31544bd76 100644 --- a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.html +++ b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.html @@ -24,6 +24,7 @@ limitations under the License. + @@ -50,7 +51,8 @@ limitations under the License. }; }; - suite('gr-repo-list tests', () => { + suite('gr-repo-list tests', async () => { + await readyToTest(); let element; let repos; let sandbox; diff --git a/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config_test.html b/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config_test.html index ff0e52245e..d0a7a66cec 100644 --- a/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config_test.html +++ b/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config_test.html @@ -23,6 +23,7 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -36,7 +37,8 @@ limitations under the License. + @@ -37,7 +38,8 @@ limitations under the License. + @@ -39,7 +40,8 @@ limitations under the License. const CHANGE_ID = 'IcA3dAB3edAB9f60B8dcdA6ef71A75980e4B7127'; const COMMIT_HASH = '12345678'; - suite('gr-change-list-view tests', () => { + suite('gr-change-list-view tests', async () => { + await readyToTest(); let element; let sandbox; diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html index 75fd167700..b5e785e71a 100644 --- a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html +++ b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html @@ -23,6 +23,7 @@ limitations under the License. + @@ -43,7 +44,8 @@ limitations under the License. diff --git a/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help_test.html b/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help_test.html index f10fbf2f96..fd8efe293b 100644 --- a/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help_test.html +++ b/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help_test.html @@ -23,6 +23,7 @@ limitations under the License. + @@ -37,7 +38,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -38,1584 +39,814 @@ limitations under the License. diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.html b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.html index 8d85dce81f..3269dc0a83 100644 --- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.html +++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.html @@ -23,6 +23,7 @@ limitations under the License. + @@ -42,7 +43,8 @@ limitations under the License. + @@ -36,7 +37,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -44,7 +45,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -36,7 +37,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -36,7 +37,8 @@ limitations under the License. + @@ -37,7 +38,8 @@ limitations under the License. + @@ -119,7 +120,8 @@ limitations under the License. }; } - suite('gr-download-dialog', () => { + suite('gr-download-dialog', async () => { + await readyToTest(); let element; let sandbox; diff --git a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.html b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.html index 1b4b34db38..4979c32072 100644 --- a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.html +++ b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.html @@ -23,6 +23,7 @@ limitations under the License. + @@ -43,7 +44,8 @@ limitations under the License. + @@ -50,7 +51,9 @@ limitations under the License. diff --git a/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog_test.html b/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog_test.html index b97e0b45b1..bec6c7be81 100644 --- a/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog_test.html +++ b/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog_test.html @@ -23,6 +23,7 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -36,7 +37,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -70,7 +71,8 @@ limitations under the License. randomMessage(opt_params)); }; - suite('gr-messages-list tests', () => { + suite('gr-messages-list tests', async () => { + await readyToTest(); let element; let messages; let sandbox; @@ -132,483 +134,485 @@ limitations under the License. ], }; - setup(() => { - stub('gr-rest-api-interface', { - getConfig() { return Promise.resolve({}); }, - getLoggedIn() { return Promise.resolve(false); }, - getDiffComments() { return Promise.resolve(comments); }, - getDiffRobotComments() { return Promise.resolve({}); }, - getDiffDrafts() { return Promise.resolve({}); }, + suite('basic tests', () => { + setup(() => { + stub('gr-rest-api-interface', { + getConfig() { return Promise.resolve({}); }, + getLoggedIn() { return Promise.resolve(false); }, + getDiffComments() { return Promise.resolve(comments); }, + getDiffRobotComments() { return Promise.resolve({}); }, + getDiffDrafts() { return Promise.resolve({}); }, + }); + sandbox = sinon.sandbox.create(); + messages = _.times(3, randomMessage); + // Element must be wrapped in an element with direct access to the + // comment API. + commentApiWrapper = fixture('basic'); + element = commentApiWrapper.$.messagesList; + loadCommentSpy = sandbox.spy(commentApiWrapper.$.commentAPI, 'loadAll'); + element.messages = messages; + + // Stub methods on the changeComments object after changeComments has + // been initialized. + return commentApiWrapper.loadComments(); }); - sandbox = sinon.sandbox.create(); - messages = _.times(3, randomMessage); - // Element must be wrapped in an element with direct access to the - // comment API. - commentApiWrapper = fixture('basic'); - element = commentApiWrapper.$.messagesList; - loadCommentSpy = sandbox.spy(commentApiWrapper.$.commentAPI, 'loadAll'); - element.messages = messages; - // Stub methods on the changeComments object after changeComments has - // been initialized. - return commentApiWrapper.loadComments(); + teardown(() => { + sandbox.restore(); + }); + + test('show some old messages', () => { + assert.isTrue(element.$.messageControlsContainer.hasAttribute('hidden')); + element.messages = _.times(26, randomMessage); + flushAsynchronousOperations(); + + assert.isFalse(element.$.messageControlsContainer.hasAttribute('hidden')); + assert.equal(getMessages().length, 20); + assert.equal(element.$.incrementMessagesBtn.innerText.toUpperCase() + .trim(), 'SHOW 5 MORE'); + MockInteractions.tap(element.$.incrementMessagesBtn); + flushAsynchronousOperations(); + + assert.equal(getMessages().length, 25); + assert.equal(element.$.incrementMessagesBtn.innerText.toUpperCase() + .trim(), 'SHOW 1 MORE'); + MockInteractions.tap(element.$.incrementMessagesBtn); + flushAsynchronousOperations(); + + assert.isTrue(element.$.messageControlsContainer.hasAttribute('hidden')); + assert.equal(getMessages().length, 26); + }); + + test('show all old messages', () => { + assert.isTrue(element.$.messageControlsContainer.hasAttribute('hidden')); + element.messages = _.times(26, randomMessage); + flushAsynchronousOperations(); + + assert.isFalse(element.$.messageControlsContainer.hasAttribute('hidden')); + assert.equal(getMessages().length, 20); + assert.equal(element.$.oldMessagesBtn.innerText.toUpperCase(), + 'SHOW ALL 6 MESSAGES'); + MockInteractions.tap(element.$.oldMessagesBtn); + flushAsynchronousOperations(); + + assert.equal(getMessages().length, 26); + assert.isTrue(element.$.messageControlsContainer.hasAttribute('hidden')); + }); + + test('message count respects automated', () => { + element.messages = _.times(10, randomAutomated) + .concat(_.times(11, randomMessage)); + flushAsynchronousOperations(); + + assert.equal(element.$.oldMessagesBtn.innerText.toUpperCase(), + 'SHOW 1 MESSAGE'); + assert.isFalse(element.$.messageControlsContainer.hasAttribute('hidden')); + MockInteractions.tap(element.$.automatedMessageToggle); + flushAsynchronousOperations(); + + assert.isTrue(element.$.messageControlsContainer.hasAttribute('hidden')); + }); + + test('message count still respects non-automated on toggle', () => { + element.messages = _.times(10, randomMessage) + .concat(_.times(11, randomAutomated)); + flushAsynchronousOperations(); + + assert.equal(element.$.oldMessagesBtn.innerText.toUpperCase(), + 'SHOW 1 MESSAGE'); + assert.isFalse(element.$.messageControlsContainer.hasAttribute('hidden')); + MockInteractions.tap(element.$.automatedMessageToggle); + flushAsynchronousOperations(); + + assert.equal(element.$.oldMessagesBtn.innerText.toUpperCase(), + 'SHOW 1 MESSAGE'); + assert.isFalse(element.$.messageControlsContainer.hasAttribute('hidden')); + }); + + test('show all messages respects expand', () => { + element.messages = _.times(10, randomAutomated) + .concat(_.times(11, randomMessage)); + flushAsynchronousOperations(); + + MockInteractions.tap(element.shadowRoot + .querySelector('#collapse-messages')); // Expand all. + flushAsynchronousOperations(); + + let messages = getMessages(); + assert.equal(messages.length, 20); + for (const message of messages) { + assert.isTrue(message._expanded); + } + + MockInteractions.tap(element.$.oldMessagesBtn); + flushAsynchronousOperations(); + + messages = getMessages(); + assert.equal(messages.length, 21); + for (const message of messages) { + assert.isTrue(message._expanded); + } + }); + + test('show all messages respects collapse', () => { + element.messages = _.times(10, randomAutomated) + .concat(_.times(11, randomMessage)); + flushAsynchronousOperations(); + + MockInteractions.tap(element.shadowRoot + .querySelector('#collapse-messages')); // Expand all. + MockInteractions.tap(element.shadowRoot + .querySelector('#collapse-messages')); // Collapse all. + flushAsynchronousOperations(); + + let messages = getMessages(); + assert.equal(messages.length, 20); + for (const message of messages) { + assert.isFalse(message._expanded); + } + + MockInteractions.tap(element.$.oldMessagesBtn); + flushAsynchronousOperations(); + + messages = getMessages(); + assert.equal(messages.length, 21); + for (const message of messages) { + assert.isFalse(message._expanded); + } + }); + + test('expand/collapse all', () => { + let allMessageEls = getMessages(); + for (const message of allMessageEls) { + message._expanded = false; + } + MockInteractions.tap(allMessageEls[1]); + assert.isTrue(allMessageEls[1]._expanded); + + MockInteractions.tap(element.shadowRoot + .querySelector('#collapse-messages')); + allMessageEls = getMessages(); + for (const message of allMessageEls) { + assert.isTrue(message._expanded); + } + + MockInteractions.tap(element.shadowRoot + .querySelector('#collapse-messages')); + allMessageEls = getMessages(); + for (const message of allMessageEls) { + assert.isFalse(message._expanded); + } + }); + + test('expand/collapse from external keypress', () => { + MockInteractions.tap(element.shadowRoot + .querySelector('#collapse-messages')); + let allMessageEls = getMessages(); + for (const message of allMessageEls) { + assert.isTrue(message._expanded); + } + + // Expand/collapse all text also changes. + assert.equal(element.shadowRoot + .querySelector('#collapse-messages').textContent.trim(), + 'Collapse all'); + + MockInteractions.tap(element.shadowRoot + .querySelector('#collapse-messages')); + allMessageEls = getMessages(); + for (const message of allMessageEls) { + assert.isFalse(message._expanded); + } + // Expand/collapse all text also changes. + assert.equal(element.shadowRoot + .querySelector('#collapse-messages').textContent.trim(), + 'Expand all'); + }); + + test('hide messages does not appear when no automated messages', () => { + assert.isOk(element.shadowRoot + .querySelector('#automatedMessageToggleContainer[hidden]')); + }); + + test('scroll to message', () => { + const allMessageEls = getMessages(); + for (const message of allMessageEls) { + message.set('message.expanded', false); + } + + const scrollToStub = sandbox.stub(window, 'scrollTo'); + const highlightStub = sandbox.stub(element, '_highlightEl'); + + element.scrollToMessage('invalid'); + + for (const message of allMessageEls) { + assert.isFalse(message._expanded, + 'expected gr-message to not be expanded'); + } + + const messageID = messages[1].id; + element.scrollToMessage(messageID); + assert.isTrue( + element.$$('[data-message-id="' + messageID + '"]')._expanded); + + assert.isTrue(scrollToStub.calledOnce); + assert.isTrue(highlightStub.calledOnce); + }); + + test('scroll to message offscreen', () => { + const scrollToStub = sandbox.stub(window, 'scrollTo'); + const highlightStub = sandbox.stub(element, '_highlightEl'); + element.messages = _.times(25, randomMessage); + flushAsynchronousOperations(); + assert.isFalse(scrollToStub.called); + assert.isFalse(highlightStub.called); + + const messageID = element.messages[1].id; + element.scrollToMessage(messageID); + assert.isTrue(scrollToStub.calledOnce); + assert.isTrue(highlightStub.calledOnce); + assert.equal(element._visibleMessages.length, 24); + assert.isTrue( + element.$$('[data-message-id="' + messageID + '"]')._expanded); + }); + + test('messages', () => { + const messages = [].concat( + randomMessage(), + { + _index: 5, + _revision_number: 4, + message: 'Uploaded patch set 4.', + date: '2016-09-28 13:36:33.000000000', + author, + id: '8c19ccc949c6d482b061be6a28e10782abf0e7af', + }, + { + _index: 6, + _revision_number: 4, + message: 'Patch Set 4:\n\n(6 comments)', + date: '2016-09-28 13:36:33.000000000', + author, + id: 'e7bfdbc842f6b6d8064bc68e0f52b673f40c0ca5', + } + ); + element.messages = messages; + const isAuthor = function(author, message) { + return message.author._account_id === author._account_id; + }; + const isMarvin = isAuthor.bind(null, author); + flushAsynchronousOperations(); + const messageElements = getMessages(); + assert.equal(messageElements.length, messages.length); + assert.deepEqual(messageElements[1].message, messages[1]); + assert.deepEqual(messageElements[2].message, messages[2]); + assert.deepEqual(messageElements[1].comments.file1, + comments.file1.filter(isMarvin)); + assert.deepEqual(messageElements[1].comments.file2, + comments.file2.filter(isMarvin)); + assert.deepEqual(messageElements[2].comments, {}); + }); + + test('messages without author do not throw', () => { + const messages = [{ + _index: 5, + _revision_number: 4, + message: 'Uploaded patch set 4.', + date: '2016-09-28 13:36:33.000000000', + id: '8c19ccc949c6d482b061be6a28e10782abf0e7af', + }]; + element.messages = messages; + flushAsynchronousOperations(); + const messageEls = getMessages(); + assert.equal(messageEls.length, 1); + assert.equal(messageEls[0].message.message, messages[0].message); + }); + + test('hide increment text if increment >= total remaining', () => { + // Test with stubbed return values, as _numRemaining and _getDelta have + // their own tests. + sandbox.stub(element, '_getDelta').returns(5); + const remainingStub = sandbox.stub(element, '_numRemaining').returns(6); + assert.isFalse(element._computeIncrementHidden(null, null, null)); + remainingStub.restore(); + + sandbox.stub(element, '_numRemaining').returns(4); + assert.isTrue(element._computeIncrementHidden(null, null, null)); + }); }); - teardown(() => { - sandbox.restore(); - }); + suite('gr-messages-list automate tests', () => { + let element; + let messages; + let sandbox; + let commentApiWrapper; - test('show some old messages', () => { - assert.isTrue(element.$.messageControlsContainer.hasAttribute('hidden')); - element.messages = _.times(26, randomMessage); - flushAsynchronousOperations(); - - assert.isFalse(element.$.messageControlsContainer.hasAttribute('hidden')); - assert.equal(getMessages().length, 20); - assert.equal(element.$.incrementMessagesBtn.innerText.toUpperCase() - .trim(), 'SHOW 5 MORE'); - MockInteractions.tap(element.$.incrementMessagesBtn); - flushAsynchronousOperations(); - - assert.equal(getMessages().length, 25); - assert.equal(element.$.incrementMessagesBtn.innerText.toUpperCase() - .trim(), 'SHOW 1 MORE'); - MockInteractions.tap(element.$.incrementMessagesBtn); - flushAsynchronousOperations(); - - assert.isTrue(element.$.messageControlsContainer.hasAttribute('hidden')); - assert.equal(getMessages().length, 26); - }); - - test('show all old messages', () => { - assert.isTrue(element.$.messageControlsContainer.hasAttribute('hidden')); - element.messages = _.times(26, randomMessage); - flushAsynchronousOperations(); - - assert.isFalse(element.$.messageControlsContainer.hasAttribute('hidden')); - assert.equal(getMessages().length, 20); - assert.equal(element.$.oldMessagesBtn.innerText.toUpperCase(), - 'SHOW ALL 6 MESSAGES'); - MockInteractions.tap(element.$.oldMessagesBtn); - flushAsynchronousOperations(); - - assert.equal(getMessages().length, 26); - assert.isTrue(element.$.messageControlsContainer.hasAttribute('hidden')); - }); - - test('message count respects automated', () => { - element.messages = _.times(10, randomAutomated) - .concat(_.times(11, randomMessage)); - flushAsynchronousOperations(); - - assert.equal(element.$.oldMessagesBtn.innerText.toUpperCase(), - 'SHOW 1 MESSAGE'); - assert.isFalse(element.$.messageControlsContainer.hasAttribute('hidden')); - MockInteractions.tap(element.$.automatedMessageToggle); - flushAsynchronousOperations(); - - assert.isTrue(element.$.messageControlsContainer.hasAttribute('hidden')); - }); - - test('message count still respects non-automated on toggle', () => { - element.messages = _.times(10, randomMessage) - .concat(_.times(11, randomAutomated)); - flushAsynchronousOperations(); - - assert.equal(element.$.oldMessagesBtn.innerText.toUpperCase(), - 'SHOW 1 MESSAGE'); - assert.isFalse(element.$.messageControlsContainer.hasAttribute('hidden')); - MockInteractions.tap(element.$.automatedMessageToggle); - flushAsynchronousOperations(); - - assert.equal(element.$.oldMessagesBtn.innerText.toUpperCase(), - 'SHOW 1 MESSAGE'); - assert.isFalse(element.$.messageControlsContainer.hasAttribute('hidden')); - }); - - test('show all messages respects expand', () => { - element.messages = _.times(10, randomAutomated) - .concat(_.times(11, randomMessage)); - flushAsynchronousOperations(); - - MockInteractions.tap(element.shadowRoot - .querySelector('#collapse-messages')); // Expand all. - flushAsynchronousOperations(); - - let messages = getMessages(); - assert.equal(messages.length, 20); - for (const message of messages) { - assert.isTrue(message._expanded); - } - - MockInteractions.tap(element.$.oldMessagesBtn); - flushAsynchronousOperations(); - - messages = getMessages(); - assert.equal(messages.length, 21); - for (const message of messages) { - assert.isTrue(message._expanded); - } - }); - - test('show all messages respects collapse', () => { - element.messages = _.times(10, randomAutomated) - .concat(_.times(11, randomMessage)); - flushAsynchronousOperations(); - - MockInteractions.tap(element.shadowRoot - .querySelector('#collapse-messages')); // Expand all. - MockInteractions.tap(element.shadowRoot - .querySelector('#collapse-messages')); // Collapse all. - flushAsynchronousOperations(); - - let messages = getMessages(); - assert.equal(messages.length, 20); - for (const message of messages) { - assert.isFalse(message._expanded); - } - - MockInteractions.tap(element.$.oldMessagesBtn); - flushAsynchronousOperations(); - - messages = getMessages(); - assert.equal(messages.length, 21); - for (const message of messages) { - assert.isFalse(message._expanded); - } - }); - - test('expand/collapse all', () => { - let allMessageEls = getMessages(); - for (const message of allMessageEls) { - message._expanded = false; - } - MockInteractions.tap(allMessageEls[1]); - assert.isTrue(allMessageEls[1]._expanded); - - MockInteractions.tap(element.shadowRoot - .querySelector('#collapse-messages')); - allMessageEls = getMessages(); - for (const message of allMessageEls) { - assert.isTrue(message._expanded); - } - - MockInteractions.tap(element.shadowRoot - .querySelector('#collapse-messages')); - allMessageEls = getMessages(); - for (const message of allMessageEls) { - assert.isFalse(message._expanded); - } - }); - - test('expand/collapse from external keypress', () => { - MockInteractions.tap(element.shadowRoot - .querySelector('#collapse-messages')); - let allMessageEls = getMessages(); - for (const message of allMessageEls) { - assert.isTrue(message._expanded); - } - - // Expand/collapse all text also changes. - assert.equal(element.shadowRoot - .querySelector('#collapse-messages').textContent.trim(), - 'Collapse all'); - - MockInteractions.tap(element.shadowRoot - .querySelector('#collapse-messages')); - allMessageEls = getMessages(); - for (const message of allMessageEls) { - assert.isFalse(message._expanded); - } - // Expand/collapse all text also changes. - assert.equal(element.shadowRoot - .querySelector('#collapse-messages').textContent.trim(), - 'Expand all'); - }); - - test('hide messages does not appear when no automated messages', () => { - assert.isOk(element.shadowRoot - .querySelector('#automatedMessageToggleContainer[hidden]')); - }); - - test('scroll to message', () => { - const allMessageEls = getMessages(); - for (const message of allMessageEls) { - message.set('message.expanded', false); - } - - const scrollToStub = sandbox.stub(window, 'scrollTo'); - const highlightStub = sandbox.stub(element, '_highlightEl'); - - element.scrollToMessage('invalid'); - - for (const message of allMessageEls) { - assert.isFalse(message._expanded, - 'expected gr-message to not be expanded'); - } - - const messageID = messages[1].id; - element.scrollToMessage(messageID); - assert.isTrue( - element.$$('[data-message-id="' + messageID + '"]')._expanded); - - assert.isTrue(scrollToStub.calledOnce); - assert.isTrue(highlightStub.calledOnce); - }); - - test('scroll to message offscreen', () => { - const scrollToStub = sandbox.stub(window, 'scrollTo'); - const highlightStub = sandbox.stub(element, '_highlightEl'); - element.messages = _.times(25, randomMessage); - flushAsynchronousOperations(); - assert.isFalse(scrollToStub.called); - assert.isFalse(highlightStub.called); - - const messageID = element.messages[1].id; - element.scrollToMessage(messageID); - assert.isTrue(scrollToStub.calledOnce); - assert.isTrue(highlightStub.calledOnce); - assert.equal(element._visibleMessages.length, 24); - assert.isTrue( - element.$$('[data-message-id="' + messageID + '"]')._expanded); - }); - - test('messages', () => { - const messages = [].concat( - randomMessage(), - { - _index: 5, - _revision_number: 4, - message: 'Uploaded patch set 4.', - date: '2016-09-28 13:36:33.000000000', - author, - id: '8c19ccc949c6d482b061be6a28e10782abf0e7af', - }, - { - _index: 6, - _revision_number: 4, - message: 'Patch Set 4:\n\n(6 comments)', - date: '2016-09-28 13:36:33.000000000', - author, - id: 'e7bfdbc842f6b6d8064bc68e0f52b673f40c0ca5', - } - ); - element.messages = messages; - const isAuthor = function(author, message) { - return message.author._account_id === author._account_id; + const getMessages = function() { + return Polymer.dom(element.root).querySelectorAll('gr-message'); + }; + const getHiddenMessages = function() { + return Polymer.dom(element.root).querySelectorAll('gr-message[hidden]'); }; - const isMarvin = isAuthor.bind(null, author); - flushAsynchronousOperations(); - const messageElements = getMessages(); - assert.equal(messageElements.length, messages.length); - assert.deepEqual(messageElements[1].message, messages[1]); - assert.deepEqual(messageElements[2].message, messages[2]); - assert.deepEqual(messageElements[1].comments.file1, - comments.file1.filter(isMarvin)); - assert.deepEqual(messageElements[1].comments.file2, - comments.file2.filter(isMarvin)); - assert.deepEqual(messageElements[2].comments, {}); - }); - test('messages without author do not throw', () => { - const messages = [{ - _index: 5, - _revision_number: 4, - message: 'Uploaded patch set 4.', - date: '2016-09-28 13:36:33.000000000', - id: '8c19ccc949c6d482b061be6a28e10782abf0e7af', - }]; - element.messages = messages; - flushAsynchronousOperations(); - const messageEls = getMessages(); - assert.equal(messageEls.length, 1); - assert.equal(messageEls[0].message.message, messages[0].message); - }); + const randomMessageReviewer = { + reviewer: {}, + date: '2016-01-13 20:30:33.038000', + }; - test('hide increment text if increment >= total remaining', () => { - // Test with stubbed return values, as _numRemaining and _getDelta have - // their own tests. - sandbox.stub(element, '_getDelta').returns(5); - const remainingStub = sandbox.stub(element, '_numRemaining').returns(6); - assert.isFalse(element._computeIncrementHidden(null, null, null)); - remainingStub.restore(); - - sandbox.stub(element, '_numRemaining').returns(4); - assert.isTrue(element._computeIncrementHidden(null, null, null)); - }); - }); - - suite('gr-messages-list automate tests', () => { - let element; - let messages; - let sandbox; - let commentApiWrapper; - - const getMessages = function() { - return Polymer.dom(element.root).querySelectorAll('gr-message'); - }; - const getHiddenMessages = function() { - return Polymer.dom(element.root).querySelectorAll('gr-message[hidden]'); - }; - - const randomMessageReviewer = { - reviewer: {}, - date: '2016-01-13 20:30:33.038000', - }; - - setup(() => { - stub('gr-rest-api-interface', { - getConfig() { return Promise.resolve({}); }, - getLoggedIn() { return Promise.resolve(false); }, - getDiffComments() { return Promise.resolve({}); }, - getDiffRobotComments() { return Promise.resolve({}); }, - getDiffDrafts() { return Promise.resolve({}); }, - }); - - sandbox = sinon.sandbox.create(); - messages = _.times(2, randomAutomated); - messages.push(randomMessageReviewer); - - // Element must be wrapped in an element with direct access to the - // comment API. - commentApiWrapper = fixture('basic'); - element = commentApiWrapper.$.messagesList; - loadCommentSpy = sandbox.spy(commentApiWrapper.$.commentAPI, 'loadAll'); - element.messages = messages; - - // Stub methods on the changeComments object after changeComments has - // been initialized. - return commentApiWrapper.loadComments(); - }); - - teardown(() => { - sandbox.restore(); - }); - - test('hide autogenerated button is not hidden', () => { - assert.isNotOk(element.shadowRoot - .querySelector('#automatedMessageToggle[hidden]')); - }); - - test('autogenerated messages are not hidden initially', () => { - const allHiddenMessageEls = getHiddenMessages(); - - // There are no hidden messages. - assert.isFalse(!!allHiddenMessageEls.length); - }); - - test('autogenerated messages hidden after comments only toggle', () => { - let allHiddenMessageEls = getHiddenMessages(); - - element._hideAutomated = false; - MockInteractions.tap(element.$.automatedMessageToggle); - flushAsynchronousOperations(); - allMessageEls = getMessages(); - allHiddenMessageEls = getHiddenMessages(); - - // Autogenerated messages are now hidden. - assert.equal(allHiddenMessageEls.length, allMessageEls.length); - }); - - test('autogenerated messages not hidden after comments only toggle', - () => { - let allHiddenMessageEls = getHiddenMessages(); - - element._hideAutomated = true; - MockInteractions.tap(element.$.automatedMessageToggle); - allHiddenMessageEls = getHiddenMessages(); - - // Autogenerated messages are now hidden. - assert.isFalse(!!allHiddenMessageEls.length); + setup(() => { + stub('gr-rest-api-interface', { + getConfig() { return Promise.resolve({}); }, + getLoggedIn() { return Promise.resolve(false); }, + getDiffComments() { return Promise.resolve({}); }, + getDiffRobotComments() { return Promise.resolve({}); }, + getDiffDrafts() { return Promise.resolve({}); }, }); - test('_getDelta', () => { - let messages = [randomMessage()]; - assert.equal(element._getDelta([], messages, false), 1); - assert.equal(element._getDelta([], messages, true), 1); + sandbox = sinon.sandbox.create(); + messages = _.times(2, randomAutomated); + messages.push(randomMessageReviewer); - messages = _.times(7, randomMessage); - assert.equal(element._getDelta([], messages, false), 5); - assert.equal(element._getDelta([], messages, true), 5); + // Element must be wrapped in an element with direct access to the + // comment API. + commentApiWrapper = fixture('basic'); + element = commentApiWrapper.$.messagesList; + loadCommentSpy = sandbox.spy(commentApiWrapper.$.commentAPI, 'loadAll'); + element.messages = messages; - messages = _.times(4, randomMessage) - .concat(_.times(2, randomAutomated)) - .concat(_.times(3, randomMessage)); + // Stub methods on the changeComments object after changeComments has + // been initialized. + return commentApiWrapper.loadComments(); + }); - const dummyArr = _.times(2, randomMessage); - assert.equal(element._getDelta(dummyArr, messages, false), 5); - assert.equal(element._getDelta(dummyArr, messages, true), 7); - }); + teardown(() => { + sandbox.restore(); + }); - test('_getHumanMessages', () => { - assert.equal( - element._getHumanMessages(_.times(5, randomAutomated)).length, 0); - assert.equal( - element._getHumanMessages(_.times(5, randomMessage)).length, 5); + test('hide autogenerated button is not hidden', () => { + assert.isNotOk(element.shadowRoot + .querySelector('#automatedMessageToggle[hidden]')); + }); - let messages = _.shuffle(_.times(5, randomMessage) - .concat(_.times(5, randomAutomated))); - messages = element._getHumanMessages(messages); - assert.equal(messages.length, 5); - assert.isFalse(element._hasAutomatedMessages(messages)); - }); + test('autogenerated messages are not hidden initially', () => { + const allHiddenMessageEls = getHiddenMessages(); - test('initially show only 20 messages', () => { - sandbox.stub(element.$.reporting, 'reportInteraction', - (eventName, details) => { - assert.equal(typeof(eventName), 'string'); - if (details) { - assert.equal(typeof(details), 'object'); - } + // There are no hidden messages. + assert.isFalse(!!allHiddenMessageEls.length); + }); + + test('autogenerated messages hidden after comments only toggle', () => { + let allHiddenMessageEls = getHiddenMessages(); + + element._hideAutomated = false; + MockInteractions.tap(element.$.automatedMessageToggle); + flushAsynchronousOperations(); + allMessageEls = getMessages(); + allHiddenMessageEls = getHiddenMessages(); + + // Autogenerated messages are now hidden. + assert.equal(allHiddenMessageEls.length, allMessageEls.length); + }); + + test('autogenerated messages not hidden after comments only toggle', + () => { + let allHiddenMessageEls = getHiddenMessages(); + + element._hideAutomated = true; + MockInteractions.tap(element.$.automatedMessageToggle); + allHiddenMessageEls = getHiddenMessages(); + + // Autogenerated messages are now hidden. + assert.isFalse(!!allHiddenMessageEls.length); }); - const messages = Array.from(Array(23).keys()) - .map(() => { - return {}; - }); - element._processedMessagesChanged(messages); - assert.equal(element._visibleMessages.length, 20); - }); + test('_getDelta', () => { + let messages = [randomMessage()]; + assert.equal(element._getDelta([], messages, false), 1); + assert.equal(element._getDelta([], messages, true), 1); - test('_computeLabelExtremes', () => { - const computeSpy = sandbox.spy(element, '_computeLabelExtremes'); + messages = _.times(7, randomMessage); + assert.equal(element._getDelta([], messages, false), 5); + assert.equal(element._getDelta([], messages, true), 5); - element.labels = null; - assert.isTrue(computeSpy.calledOnce); - assert.deepEqual(computeSpy.lastCall.returnValue, {}); + messages = _.times(4, randomMessage) + .concat(_.times(2, randomAutomated)) + .concat(_.times(3, randomMessage)); - element.labels = {}; - assert.isTrue(computeSpy.calledTwice); - assert.deepEqual(computeSpy.lastCall.returnValue, {}); + const dummyArr = _.times(2, randomMessage); + assert.equal(element._getDelta(dummyArr, messages, false), 5); + assert.equal(element._getDelta(dummyArr, messages, true), 7); + }); - element.labels = {'my-label': {}}; - assert.isTrue(computeSpy.calledThrice); - assert.deepEqual(computeSpy.lastCall.returnValue, {}); + test('_getHumanMessages', () => { + assert.equal( + element._getHumanMessages(_.times(5, randomAutomated)).length, 0); + assert.equal( + element._getHumanMessages(_.times(5, randomMessage)).length, 5); - element.labels = {'my-label': {values: {}}}; - assert.equal(computeSpy.callCount, 4); - assert.deepEqual(computeSpy.lastCall.returnValue, {}); + let messages = _.shuffle(_.times(5, randomMessage) + .concat(_.times(5, randomAutomated))); + messages = element._getHumanMessages(messages); + assert.equal(messages.length, 5); + assert.isFalse(element._hasAutomatedMessages(messages)); + }); - element.labels = {'my-label': {values: {'-12': {}}}}; - assert.equal(computeSpy.callCount, 5); - assert.deepEqual(computeSpy.lastCall.returnValue, - {'my-label': {min: -12, max: -12}}); + test('initially show only 20 messages', () => { + sandbox.stub(element.$.reporting, 'reportInteraction', + (eventName, details) => { + assert.equal(typeof(eventName), 'string'); + if (details) { + assert.equal(typeof(details), 'object'); + } + }); + const messages = Array.from(Array(23).keys()) + .map(() => { + return {}; + }); + element._processedMessagesChanged(messages); - element.labels = { - 'my-label': {values: {'-2': {}, '-1': {}, '0': {}, '+1': {}, '+2': {}}}, - }; - assert.equal(computeSpy.callCount, 6); - assert.deepEqual(computeSpy.lastCall.returnValue, - {'my-label': {min: -2, max: 2}}); + assert.equal(element._visibleMessages.length, 20); + }); - element.labels = { - 'my-label': {values: {'-12': {}}}, - 'other-label': {values: {'-1': {}, ' 0': {}, '+1': {}}}, - }; - assert.equal(computeSpy.callCount, 7); - assert.deepEqual(computeSpy.lastCall.returnValue, { - 'my-label': {min: -12, max: -12}, - 'other-label': {min: -1, max: 1}, + test('_computeLabelExtremes', () => { + const computeSpy = sandbox.spy(element, '_computeLabelExtremes'); + + element.labels = null; + assert.isTrue(computeSpy.calledOnce); + assert.deepEqual(computeSpy.lastCall.returnValue, {}); + + element.labels = {}; + assert.isTrue(computeSpy.calledTwice); + assert.deepEqual(computeSpy.lastCall.returnValue, {}); + + element.labels = {'my-label': {}}; + assert.isTrue(computeSpy.calledThrice); + assert.deepEqual(computeSpy.lastCall.returnValue, {}); + + element.labels = {'my-label': {values: {}}}; + assert.equal(computeSpy.callCount, 4); + assert.deepEqual(computeSpy.lastCall.returnValue, {}); + + element.labels = {'my-label': {values: {'-12': {}}}}; + assert.equal(computeSpy.callCount, 5); + assert.deepEqual(computeSpy.lastCall.returnValue, + {'my-label': {min: -12, max: -12}}); + + element.labels = { + 'my-label': {values: {'-2': {}, '-1': {}, '0': {}, '+1': {}, '+2': {}}}, + }; + assert.equal(computeSpy.callCount, 6); + assert.deepEqual(computeSpy.lastCall.returnValue, + {'my-label': {min: -2, max: 2}}); + + element.labels = { + 'my-label': {values: {'-12': {}}}, + 'other-label': {values: {'-1': {}, ' 0': {}, '+1': {}}}, + }; + assert.equal(computeSpy.callCount, 7); + assert.deepEqual(computeSpy.lastCall.returnValue, { + 'my-label': {min: -12, max: -12}, + 'other-label': {min: -1, max: 1}, + }); }); }); }); diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html index 38b2fb94f5..8d900aff0c 100644 --- a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html +++ b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html @@ -23,6 +23,7 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -43,7 +44,8 @@ limitations under the License. + @@ -54,7 +55,8 @@ limitations under the License. }; } - suite('gr-reply-dialog tests', () => { + suite('gr-reply-dialog tests', async () => { + await readyToTest(); let element; let changeNum; let patchNum; diff --git a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.html b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.html index 18f7bc5a51..60343e40c6 100644 --- a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.html +++ b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.html @@ -23,6 +23,7 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -34,7 +35,8 @@ limitations under the License. + @@ -34,7 +35,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -38,7 +39,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -36,7 +37,8 @@ limitations under the License. + @@ -37,7 +38,8 @@ limitations under the License. + @@ -34,7 +35,8 @@ limitations under the License. + @@ -59,7 +60,8 @@ limitations under the License. + @@ -49,7 +50,8 @@ limitations under the License. diff --git a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-annotation_test.html b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-annotation_test.html index c7fe99783d..e040c15b0e 100644 --- a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-annotation_test.html +++ b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-annotation_test.html @@ -23,6 +23,7 @@ limitations under the License. + @@ -36,7 +37,8 @@ limitations under the License. + @@ -147,7 +148,8 @@ limitations under the License. + @@ -36,7 +37,8 @@ limitations under the License. + @@ -38,7 +39,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -107,7 +108,8 @@ limitations under the License. + @@ -44,477 +45,100 @@ limitations under the License. + + @@ -39,7 +40,8 @@ limitations under the License. + @@ -50,7 +51,8 @@ limitations under the License. + @@ -37,7 +38,8 @@ limitations under the License. + @@ -38,7 +39,8 @@ limitations under the License. + @@ -36,7 +37,8 @@ limitations under the License. + @@ -44,7 +45,8 @@ limitations under the License. }; }; - suite('gr-documentation-search tests', () => { + suite('gr-documentation-search tests', async () => { + await readyToTest(); let element; let documentationSearches; let sandbox; diff --git a/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor_test.html b/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor_test.html index 4635b1cf7c..228c70e17b 100644 --- a/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor_test.html +++ b/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor_test.html @@ -22,6 +22,7 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,338 +36,339 @@ limitations under the License. diff --git a/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls_test.html b/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls_test.html index dc26468f1d..bc1ee35200 100644 --- a/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls_test.html +++ b/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls_test.html @@ -22,6 +22,7 @@ limitations under the License. + @@ -36,70 +37,71 @@ limitations under the License. diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html index ebd624e270..1d264bc279 100644 --- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html +++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html @@ -22,6 +22,7 @@ limitations under the License. + @@ -35,378 +36,379 @@ limitations under the License. diff --git a/polygerrit-ui/app/elements/gr-app_test.html b/polygerrit-ui/app/elements/gr-app_test.html index 1014284148..cc25e5a97d 100644 --- a/polygerrit-ui/app/elements/gr-app_test.html +++ b/polygerrit-ui/app/elements/gr-app_test.html @@ -23,6 +23,7 @@ limitations under the License. + + @@ -30,7 +31,8 @@ limitations under the License. + @@ -30,16 +31,19 @@ limitations under the License. + @@ -49,7 +53,8 @@ limitations under the License. + @@ -36,7 +37,8 @@ limitations under the License. + @@ -46,7 +47,8 @@ limitations under the License. + @@ -30,21 +31,24 @@ limitations under the License. + @@ -54,7 +58,8 @@ limitations under the License. + @@ -33,7 +34,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -39,11 +40,16 @@ limitations under the License. - + + @@ -37,7 +38,8 @@ limitations under the License. + @@ -39,7 +40,8 @@ limitations under the License. + @@ -33,11 +34,16 @@ limitations under the License. - + diff --git a/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api_test.html b/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api_test.html index 588facb511..80853f5074 100644 --- a/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api_test.html +++ b/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api_test.html @@ -23,6 +23,7 @@ limitations under the License. + @@ -38,7 +39,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -41,7 +42,8 @@ limitations under the License. + @@ -41,7 +42,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -37,7 +38,8 @@ limitations under the License. + @@ -37,7 +38,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -45,7 +46,8 @@ limitations under the License. } } - suite('gr-account-list tests', () => { + suite('gr-account-list tests', async () => { + await readyToTest(); let _nextAccountId = 0; const makeAccount = function() { const accountId = ++_nextAccountId; diff --git a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.html b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.html index bfcc4311c8..381fa6bf80 100644 --- a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.html +++ b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.html @@ -23,11 +23,13 @@ limitations under the License. + + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -46,7 +47,8 @@ limitations under the License. const PRIVATE_TOOLTIP = 'This change is only visible to its owner and ' + 'current reviewers (or anyone with "View Private Changes" permission).'; - suite('gr-change-status tests', () => { + suite('gr-change-status tests', async () => { + await readyToTest(); let element; let sandbox; diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.html b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.html index c8627ba564..e6f4835af6 100644 --- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.html +++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.html @@ -23,6 +23,7 @@ limitations under the License. + @@ -43,185 +44,189 @@ limitations under the License. + \ No newline at end of file diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.html b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.html index e3391a0a19..8bc95181b5 100644 --- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.html +++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.html @@ -23,6 +23,7 @@ limitations under the License. + @@ -49,981 +50,986 @@ limitations under the License. return getComputedStyle(el).getPropertyValue('display') !== 'none'; } - suite('gr-comment tests', () => { - let element; - let sandbox; - setup(() => { - stub('gr-rest-api-interface', { - getAccount() { return Promise.resolve(null); }, - }); - element = fixture('basic'); - element.comment = { - author: { - name: 'Mr. Peanutbutter', - email: 'tenn1sballchaser@aol.com', - }, - id: 'baf0414d_60047215', - line: 5, - message: 'is this a crossover episode!?', - updated: '2015-12-08 19:48:33.843000000', - }; - sandbox = sinon.sandbox.create(); - }); + suite('gr-comment tests', async () => { + await readyToTest(); - teardown(() => { - sandbox.restore(); - }); - - test('collapsible comments', () => { - // When a comment (not draft) is loaded, it should be collapsed - assert.isTrue(element.collapsed); - assert.isFalse(isVisible(element.$$('gr-formatted-text')), - 'gr-formatted-text is not visible'); - assert.isFalse(isVisible(element.$$('.actions')), - 'actions are not visible'); - assert.isNotOk(element.textarea, 'textarea is not visible'); - - // The header middle content is only visible when comments are collapsed. - // It shows the message in a condensed way, and limits to a single line. - assert.isTrue(isVisible(element.$$('.collapsedContent')), - 'header middle content is visible'); - - // When the header row is clicked, the comment should expand - MockInteractions.tap(element.$.header); - assert.isFalse(element.collapsed); - assert.isTrue(isVisible(element.$$('gr-formatted-text')), - 'gr-formatted-text is visible'); - assert.isTrue(isVisible(element.$$('.actions')), - 'actions are visible'); - assert.isNotOk(element.textarea, 'textarea is not visible'); - assert.isFalse(isVisible(element.$$('.collapsedContent')), - 'header middle content is not visible'); - }); - - test('clicking on date link fires event', () => { - element.side = 'PARENT'; - const stub = sinon.stub(); - element.addEventListener('comment-anchor-tap', stub); - const dateEl = element.$$('.date'); - assert.ok(dateEl); - MockInteractions.tap(dateEl); - - assert.isTrue(stub.called); - assert.deepEqual(stub.lastCall.args[0].detail, - {side: element.side, number: element.comment.line}); - }); - - test('message is not retrieved from storage when other edits', done => { - const storageStub = sandbox.stub(element.$.storage, 'getDraftComment'); - const loadSpy = sandbox.spy(element, '_loadLocalDraft'); - - element.changeNum = 1; - element.patchNum = 1; - element.comment = { - author: { - name: 'Mr. Peanutbutter', - email: 'tenn1sballchaser@aol.com', - }, - line: 5, - __otherEditing: true, - }; - flush(() => { - assert.isTrue(loadSpy.called); - assert.isFalse(storageStub.called); - done(); - }); - }); - - test('message is retrieved from storage when no other edits', done => { - const storageStub = sandbox.stub(element.$.storage, 'getDraftComment'); - const loadSpy = sandbox.spy(element, '_loadLocalDraft'); - - element.changeNum = 1; - element.patchNum = 1; - element.comment = { - author: { - name: 'Mr. Peanutbutter', - email: 'tenn1sballchaser@aol.com', - }, - line: 5, - }; - flush(() => { - assert.isTrue(loadSpy.called); - assert.isTrue(storageStub.called); - done(); - }); - }); - - test('_getPatchNum', () => { - element.side = 'PARENT'; - element.patchNum = 1; - assert.equal(element._getPatchNum(), 'PARENT'); - element.side = 'REVISION'; - assert.equal(element._getPatchNum(), 1); - }); - - test('comment expand and collapse', () => { - element.collapsed = true; - assert.isFalse(isVisible(element.$$('gr-formatted-text')), - 'gr-formatted-text is not visible'); - assert.isFalse(isVisible(element.$$('.actions')), - 'actions are not visible'); - assert.isNotOk(element.textarea, 'textarea is not visible'); - assert.isTrue(isVisible(element.$$('.collapsedContent')), - 'header middle content is visible'); - - element.collapsed = false; - assert.isFalse(element.collapsed); - assert.isTrue(isVisible(element.$$('gr-formatted-text')), - 'gr-formatted-text is visible'); - assert.isTrue(isVisible(element.$$('.actions')), - 'actions are visible'); - assert.isNotOk(element.textarea, 'textarea is not visible'); - assert.isFalse(isVisible(element.$$('.collapsedContent')), - 'header middle content is is not visible'); - }); - - suite('while editing', () => { + suite('basic tests', () => { + let element; + let sandbox; setup(() => { - element.editing = true; - element._messageText = 'test'; - sandbox.stub(element, '_handleCancel'); - sandbox.stub(element, '_handleSave'); - flushAsynchronousOperations(); + stub('gr-rest-api-interface', { + getAccount() { return Promise.resolve(null); }, + }); + element = fixture('basic'); + element.comment = { + author: { + name: 'Mr. Peanutbutter', + email: 'tenn1sballchaser@aol.com', + }, + id: 'baf0414d_60047215', + line: 5, + message: 'is this a crossover episode!?', + updated: '2015-12-08 19:48:33.843000000', + }; + sandbox = sinon.sandbox.create(); }); - suite('when text is empty', () => { + teardown(() => { + sandbox.restore(); + }); + + test('collapsible comments', () => { + // When a comment (not draft) is loaded, it should be collapsed + assert.isTrue(element.collapsed); + assert.isFalse(isVisible(element.$$('gr-formatted-text')), + 'gr-formatted-text is not visible'); + assert.isFalse(isVisible(element.$$('.actions')), + 'actions are not visible'); + assert.isNotOk(element.textarea, 'textarea is not visible'); + + // The header middle content is only visible when comments are collapsed. + // It shows the message in a condensed way, and limits to a single line. + assert.isTrue(isVisible(element.$$('.collapsedContent')), + 'header middle content is visible'); + + // When the header row is clicked, the comment should expand + MockInteractions.tap(element.$.header); + assert.isFalse(element.collapsed); + assert.isTrue(isVisible(element.$$('gr-formatted-text')), + 'gr-formatted-text is visible'); + assert.isTrue(isVisible(element.$$('.actions')), + 'actions are visible'); + assert.isNotOk(element.textarea, 'textarea is not visible'); + assert.isFalse(isVisible(element.$$('.collapsedContent')), + 'header middle content is not visible'); + }); + + test('clicking on date link fires event', () => { + element.side = 'PARENT'; + const stub = sinon.stub(); + element.addEventListener('comment-anchor-tap', stub); + const dateEl = element.$$('.date'); + assert.ok(dateEl); + MockInteractions.tap(dateEl); + + assert.isTrue(stub.called); + assert.deepEqual(stub.lastCall.args[0].detail, + {side: element.side, number: element.comment.line}); + }); + + test('message is not retrieved from storage when other edits', done => { + const storageStub = sandbox.stub(element.$.storage, 'getDraftComment'); + const loadSpy = sandbox.spy(element, '_loadLocalDraft'); + + element.changeNum = 1; + element.patchNum = 1; + element.comment = { + author: { + name: 'Mr. Peanutbutter', + email: 'tenn1sballchaser@aol.com', + }, + line: 5, + __otherEditing: true, + }; + flush(() => { + assert.isTrue(loadSpy.called); + assert.isFalse(storageStub.called); + done(); + }); + }); + + test('message is retrieved from storage when no other edits', done => { + const storageStub = sandbox.stub(element.$.storage, 'getDraftComment'); + const loadSpy = sandbox.spy(element, '_loadLocalDraft'); + + element.changeNum = 1; + element.patchNum = 1; + element.comment = { + author: { + name: 'Mr. Peanutbutter', + email: 'tenn1sballchaser@aol.com', + }, + line: 5, + }; + flush(() => { + assert.isTrue(loadSpy.called); + assert.isTrue(storageStub.called); + done(); + }); + }); + + test('_getPatchNum', () => { + element.side = 'PARENT'; + element.patchNum = 1; + assert.equal(element._getPatchNum(), 'PARENT'); + element.side = 'REVISION'; + assert.equal(element._getPatchNum(), 1); + }); + + test('comment expand and collapse', () => { + element.collapsed = true; + assert.isFalse(isVisible(element.$$('gr-formatted-text')), + 'gr-formatted-text is not visible'); + assert.isFalse(isVisible(element.$$('.actions')), + 'actions are not visible'); + assert.isNotOk(element.textarea, 'textarea is not visible'); + assert.isTrue(isVisible(element.$$('.collapsedContent')), + 'header middle content is visible'); + + element.collapsed = false; + assert.isFalse(element.collapsed); + assert.isTrue(isVisible(element.$$('gr-formatted-text')), + 'gr-formatted-text is visible'); + assert.isTrue(isVisible(element.$$('.actions')), + 'actions are visible'); + assert.isNotOk(element.textarea, 'textarea is not visible'); + assert.isFalse(isVisible(element.$$('.collapsedContent')), + 'header middle content is is not visible'); + }); + + suite('while editing', () => { setup(() => { - element._messageText = ''; - element.comment = {}; + element.editing = true; + element._messageText = 'test'; + sandbox.stub(element, '_handleCancel'); + sandbox.stub(element, '_handleSave'); + flushAsynchronousOperations(); }); - test('esc closes comment when text is empty', () => { + suite('when text is empty', () => { + setup(() => { + element._messageText = ''; + element.comment = {}; + }); + + test('esc closes comment when text is empty', () => { + MockInteractions.pressAndReleaseKeyOn( + element.textarea, 27); // esc + assert.isTrue(element._handleCancel.called); + }); + + test('ctrl+enter does not save', () => { + MockInteractions.pressAndReleaseKeyOn( + element.textarea, 13, 'ctrl'); // ctrl + enter + assert.isFalse(element._handleSave.called); + }); + + test('meta+enter does not save', () => { + MockInteractions.pressAndReleaseKeyOn( + element.textarea, 13, 'meta'); // meta + enter + assert.isFalse(element._handleSave.called); + }); + + test('ctrl+s does not save', () => { + MockInteractions.pressAndReleaseKeyOn( + element.textarea, 83, 'ctrl'); // ctrl + s + assert.isFalse(element._handleSave.called); + }); + }); + + test('esc does not close comment that has content', () => { MockInteractions.pressAndReleaseKeyOn( element.textarea, 27); // esc - assert.isTrue(element._handleCancel.called); + assert.isFalse(element._handleCancel.called); }); - test('ctrl+enter does not save', () => { + test('ctrl+enter saves', () => { MockInteractions.pressAndReleaseKeyOn( element.textarea, 13, 'ctrl'); // ctrl + enter - assert.isFalse(element._handleSave.called); + assert.isTrue(element._handleSave.called); }); - test('meta+enter does not save', () => { + test('meta+enter saves', () => { MockInteractions.pressAndReleaseKeyOn( element.textarea, 13, 'meta'); // meta + enter - assert.isFalse(element._handleSave.called); + assert.isTrue(element._handleSave.called); }); - test('ctrl+s does not save', () => { + test('ctrl+s saves', () => { MockInteractions.pressAndReleaseKeyOn( element.textarea, 83, 'ctrl'); // ctrl + s - assert.isFalse(element._handleSave.called); + assert.isTrue(element._handleSave.called); }); }); - - test('esc does not close comment that has content', () => { - MockInteractions.pressAndReleaseKeyOn( - element.textarea, 27); // esc - assert.isFalse(element._handleCancel.called); + test('delete comment button for non-admins is hidden', () => { + element._isAdmin = false; + assert.isFalse(element.$$('.action.delete') + .classList.contains('showDeleteButtons')); }); - test('ctrl+enter saves', () => { - MockInteractions.pressAndReleaseKeyOn( - element.textarea, 13, 'ctrl'); // ctrl + enter - assert.isTrue(element._handleSave.called); + test('delete comment button for admins with draft is hidden', () => { + element._isAdmin = false; + element.draft = true; + assert.isFalse(element.$$('.action.delete') + .classList.contains('showDeleteButtons')); }); - test('meta+enter saves', () => { - MockInteractions.pressAndReleaseKeyOn( - element.textarea, 13, 'meta'); // meta + enter - assert.isTrue(element._handleSave.called); - }); - - test('ctrl+s saves', () => { - MockInteractions.pressAndReleaseKeyOn( - element.textarea, 83, 'ctrl'); // ctrl + s - assert.isTrue(element._handleSave.called); - }); - }); - test('delete comment button for non-admins is hidden', () => { - element._isAdmin = false; - assert.isFalse(element.$$('.action.delete') - .classList.contains('showDeleteButtons')); - }); - - test('delete comment button for admins with draft is hidden', () => { - element._isAdmin = false; - element.draft = true; - assert.isFalse(element.$$('.action.delete') - .classList.contains('showDeleteButtons')); - }); - - test('delete comment', done => { - sandbox.stub( - element.$.restAPI, 'deleteComment').returns(Promise.resolve({})); - sandbox.spy(element.confirmDeleteOverlay, 'open'); - element.changeNum = 42; - element.patchNum = 0xDEADBEEF; - element._isAdmin = true; - assert.isTrue(element.$$('.action.delete') - .classList.contains('showDeleteButtons')); - MockInteractions.tap(element.$$('.action.delete')); - flush(() => { - element.confirmDeleteOverlay.open.lastCall.returnValue.then(() => { - const dialog = - window.confirmDeleteOverlay.querySelector('#confirmDeleteComment'); - dialog.message = 'removal reason'; - element._handleConfirmDeleteComment(); - assert.isTrue(element.$.restAPI.deleteComment.calledWith( - 42, 0xDEADBEEF, 'baf0414d_60047215', 'removal reason')); - done(); - }); - }); - }); - - suite('draft update reporting', () => { - let endStub; - let getTimerStub; - let mockEvent; - - setup(() => { - mockEvent = {preventDefault() {}}; - sandbox.stub(element, 'save') - .returns(Promise.resolve({})); - sandbox.stub(element, '_discardDraft') - .returns(Promise.resolve({})); - endStub = sinon.stub(); - getTimerStub = sandbox.stub(element.$.reporting, 'getTimer') - .returns({end: endStub}); - }); - - test('create', () => { - element.comment = {}; - return element._handleSave(mockEvent).then(() => { - assert.isTrue(endStub.calledOnce); - assert.isTrue(getTimerStub.calledOnce); - assert.equal(getTimerStub.lastCall.args[0], 'CreateDraftComment'); - }); - }); - - test('update', () => { - element.comment = {id: 'abc_123'}; - return element._handleSave(mockEvent).then(() => { - assert.isTrue(endStub.calledOnce); - assert.isTrue(getTimerStub.calledOnce); - assert.equal(getTimerStub.lastCall.args[0], 'UpdateDraftComment'); - }); - }); - - test('discard', () => { - element.comment = {id: 'abc_123'}; - sandbox.stub(element, '_closeConfirmDiscardOverlay'); - return element._handleConfirmDiscard(mockEvent).then(() => { - assert.isTrue(endStub.calledOnce); - assert.isTrue(getTimerStub.calledOnce); - assert.equal(getTimerStub.lastCall.args[0], 'DiscardDraftComment'); - }); - }); - }); - - test('edit reports interaction', () => { - const reportStub = sandbox.stub(element.$.reporting, - 'recordDraftInteraction'); - MockInteractions.tap(element.$$('.edit')); - assert.isTrue(reportStub.calledOnce); - }); - - test('discard reports interaction', () => { - const reportStub = sandbox.stub(element.$.reporting, - 'recordDraftInteraction'); - element.draft = true; - MockInteractions.tap(element.$$('.discard')); - assert.isTrue(reportStub.calledOnce); - }); - }); - - suite('gr-comment draft tests', () => { - let element; - let sandbox; - - setup(() => { - stub('gr-rest-api-interface', { - getAccount() { return Promise.resolve(null); }, - saveDiffDraft() { - return Promise.resolve({ - ok: true, - text() { - return Promise.resolve( - ')]}\'\n{' + - '"id": "baf0414d_40572e03",' + - '"path": "/path/to/file",' + - '"line": 5,' + - '"updated": "2015-12-08 21:52:36.177000000",' + - '"message": "saved!"' + - '}' - ); - }, + test('delete comment', done => { + sandbox.stub( + element.$.restAPI, 'deleteComment').returns(Promise.resolve({})); + sandbox.spy(element.confirmDeleteOverlay, 'open'); + element.changeNum = 42; + element.patchNum = 0xDEADBEEF; + element._isAdmin = true; + assert.isTrue(element.$$('.action.delete') + .classList.contains('showDeleteButtons')); + MockInteractions.tap(element.$$('.action.delete')); + flush(() => { + element.confirmDeleteOverlay.open.lastCall.returnValue.then(() => { + const dialog = + window.confirmDeleteOverlay + .querySelector('#confirmDeleteComment'); + dialog.message = 'removal reason'; + element._handleConfirmDeleteComment(); + assert.isTrue(element.$.restAPI.deleteComment.calledWith( + 42, 0xDEADBEEF, 'baf0414d_60047215', 'removal reason')); + done(); }); - }, - removeChangeReviewer() { - return Promise.resolve({ok: true}); - }, - }); - stub('gr-storage', { - getDraftComment() { return null; }, - }); - element = fixture('draft'); - element.changeNum = 42; - element.patchNum = 1; - element.editing = false; - element.comment = { - __commentSide: 'right', - __draft: true, - __draftID: 'temp_draft_id', - path: '/path/to/file', - line: 5, - }; - element.commentSide = 'right'; - sandbox = sinon.sandbox.create(); - }); - - teardown(() => { - sandbox.restore(); - }); - - test('button visibility states', () => { - element.showActions = false; - assert.isTrue(element.$$('.humanActions').hasAttribute('hidden')); - assert.isTrue(element.$$('.robotActions').hasAttribute('hidden')); - - element.showActions = true; - assert.isFalse(element.$$('.humanActions').hasAttribute('hidden')); - assert.isTrue(element.$$('.robotActions').hasAttribute('hidden')); - - element.draft = true; - assert.isTrue(isVisible(element.$$('.edit')), 'edit is visible'); - assert.isTrue(isVisible(element.$$('.discard')), 'discard is visible'); - assert.isFalse(isVisible(element.$$('.save')), 'save is not visible'); - assert.isFalse(isVisible(element.$$('.cancel')), 'cancel is not visible'); - assert.isTrue(isVisible(element.$$('.resolve')), 'resolve is visible'); - assert.isFalse(element.$$('.humanActions').hasAttribute('hidden')); - assert.isTrue(element.$$('.robotActions').hasAttribute('hidden')); - - element.editing = true; - flushAsynchronousOperations(); - assert.isFalse(isVisible(element.$$('.edit')), 'edit is not visible'); - assert.isFalse(isVisible(element.$$('.discard')), 'discard not visible'); - assert.isTrue(isVisible(element.$$('.save')), 'save is visible'); - assert.isTrue(isVisible(element.$$('.cancel')), 'cancel is visible'); - assert.isTrue(isVisible(element.$$('.resolve')), 'resolve is visible'); - assert.isFalse(element.$$('.humanActions').hasAttribute('hidden')); - assert.isTrue(element.$$('.robotActions').hasAttribute('hidden')); - - element.draft = false; - element.editing = false; - flushAsynchronousOperations(); - assert.isFalse(isVisible(element.$$('.edit')), 'edit is not visible'); - assert.isFalse(isVisible(element.$$('.discard')), - 'discard is not visible'); - assert.isFalse(isVisible(element.$$('.save')), 'save is not visible'); - assert.isFalse(isVisible(element.$$('.cancel')), 'cancel is not visible'); - assert.isFalse(element.$$('.humanActions').hasAttribute('hidden')); - assert.isTrue(element.$$('.robotActions').hasAttribute('hidden')); - - element.comment.id = 'foo'; - element.draft = true; - element.editing = true; - flushAsynchronousOperations(); - assert.isTrue(isVisible(element.$$('.cancel')), 'cancel is visible'); - assert.isFalse(element.$$('.humanActions').hasAttribute('hidden')); - assert.isTrue(element.$$('.robotActions').hasAttribute('hidden')); - - // Delete button is not hidden by default - assert.isFalse(element.shadowRoot.querySelector('#deleteBtn').hidden); - - element.isRobotComment = true; - element.draft = true; - assert.isTrue(element.$$('.humanActions').hasAttribute('hidden')); - assert.isFalse(element.$$('.robotActions').hasAttribute('hidden')); - - // It is not expected to see Robot comment drafts, but if they appear, - // they will behave the same as non-drafts. - element.draft = false; - assert.isTrue(element.$$('.humanActions').hasAttribute('hidden')); - assert.isFalse(element.$$('.robotActions').hasAttribute('hidden')); - - // A robot comment with run ID should display plain text. - element.set(['comment', 'robot_run_id'], 'text'); - element.editing = false; - element.collapsed = false; - flushAsynchronousOperations(); - assert.isTrue(element.$$('.robotRun.link').textContent === 'Run Details'); - - // A robot comment with run ID and url should display a link. - element.set(['comment', 'url'], '/path/to/run'); - flushAsynchronousOperations(); - assert.notEqual(getComputedStyle(element.$$('.robotRun.link')).display, - 'none'); - - // Delete button is hidden for robot comments - assert.isTrue(element.shadowRoot.querySelector('#deleteBtn').hidden); - }); - - test('collapsible drafts', () => { - assert.isTrue(element.collapsed); - assert.isFalse(isVisible(element.$$('gr-formatted-text')), - 'gr-formatted-text is not visible'); - assert.isFalse(isVisible(element.$$('.actions')), - 'actions are not visible'); - assert.isNotOk(element.textarea, 'textarea is not visible'); - assert.isTrue(isVisible(element.$$('.collapsedContent')), - 'header middle content is visible'); - - MockInteractions.tap(element.$.header); - assert.isFalse(element.collapsed); - assert.isTrue(isVisible(element.$$('gr-formatted-text')), - 'gr-formatted-text is visible'); - assert.isTrue(isVisible(element.$$('.actions')), - 'actions are visible'); - assert.isNotOk(element.textarea, 'textarea is not visible'); - assert.isFalse(isVisible(element.$$('.collapsedContent')), - 'header middle content is is not visible'); - - // When the edit button is pressed, should still see the actions - // and also textarea - MockInteractions.tap(element.$$('.edit')); - flushAsynchronousOperations(); - assert.isFalse(element.collapsed); - assert.isFalse(isVisible(element.$$('gr-formatted-text')), - 'gr-formatted-text is not visible'); - assert.isTrue(isVisible(element.$$('.actions')), - 'actions are visible'); - assert.isTrue(isVisible(element.textarea), 'textarea is visible'); - assert.isFalse(isVisible(element.$$('.collapsedContent')), - 'header middle content is not visible'); - - // When toggle again, everything should be hidden except for textarea - // and header middle content should be visible - MockInteractions.tap(element.$.header); - assert.isTrue(element.collapsed); - assert.isFalse(isVisible(element.$$('gr-formatted-text')), - 'gr-formatted-text is not visible'); - assert.isFalse(isVisible(element.$$('.actions')), - 'actions are not visible'); - assert.isFalse(isVisible(element.$$('gr-textarea')), - 'textarea is not visible'); - assert.isTrue(isVisible(element.$$('.collapsedContent')), - 'header middle content is visible'); - - // When toggle again, textarea should remain open in the state it was - // before - MockInteractions.tap(element.$.header); - assert.isFalse(isVisible(element.$$('gr-formatted-text')), - 'gr-formatted-text is not visible'); - assert.isTrue(isVisible(element.$$('.actions')), - 'actions are visible'); - assert.isTrue(isVisible(element.textarea), 'textarea is visible'); - assert.isFalse(isVisible(element.$$('.collapsedContent')), - 'header middle content is not visible'); - }); - - test('robot comment layout', () => { - const comment = Object.assign({ - robot_id: 'happy_robot_id', - url: '/robot/comment', - author: { - name: 'Happy Robot', - }, - }, element.comment); - element.comment = comment; - element.collapsed = false; - flushAsynchronousOperations(); - - let runIdMessage; - runIdMessage = element.$$('.runIdMessage'); - assert.isFalse(runIdMessage.hidden); - - const runDetailsLink = element.$$('.robotRunLink'); - assert.isTrue(runDetailsLink.href.indexOf(element.comment.url) !== -1); - - const robotServiceName = element.$$('.authorName'); - assert.isTrue(robotServiceName.textContent === 'happy_robot_id'); - - const authorName = element.$$('.robotId'); - assert.isTrue(authorName.innerText === 'Happy Robot'); - - element.collapsed = true; - flushAsynchronousOperations(); - runIdMessage = element.$$('.runIdMessage'); - assert.isTrue(runIdMessage.hidden); - }); - - test('draft creation/cancellation', done => { - assert.isFalse(element.editing); - MockInteractions.tap(element.$$('.edit')); - assert.isTrue(element.editing); - - element._messageText = ''; - const eraseMessageDraftSpy = sandbox.spy(element, '_eraseDraftComment'); - - // Save should be disabled on an empty message. - let disabled = element.$$('.save').hasAttribute('disabled'); - assert.isTrue(disabled, 'save button should be disabled.'); - element._messageText = ' '; - disabled = element.$$('.save').hasAttribute('disabled'); - assert.isTrue(disabled, 'save button should be disabled.'); - - const updateStub = sinon.stub(); - element.addEventListener('comment-update', updateStub); - - let numDiscardEvents = 0; - element.addEventListener('comment-discard', e => { - numDiscardEvents++; - assert.isFalse(eraseMessageDraftSpy.called); - if (numDiscardEvents === 2) { - assert.isFalse(updateStub.called); - done(); - } - }); - MockInteractions.tap(element.$$('.cancel')); - element.flushDebouncer('fire-update'); - element._messageText = ''; - flushAsynchronousOperations(); - MockInteractions.pressAndReleaseKeyOn(element.textarea, 27); // esc - }); - - test('draft discard removes message from storage', done => { - element._messageText = ''; - const eraseMessageDraftSpy = sandbox.spy(element, '_eraseDraftComment'); - sandbox.stub(element, '_closeConfirmDiscardOverlay'); - - element.addEventListener('comment-discard', e => { - assert.isTrue(eraseMessageDraftSpy.called); - done(); - }); - element._handleConfirmDiscard({preventDefault: sinon.stub()}); - }); - - test('storage is cleared only after save success', () => { - element._messageText = 'test'; - const eraseStub = sandbox.stub(element, '_eraseDraftComment'); - sandbox.stub(element.$.restAPI, 'getResponseObject') - .returns(Promise.resolve({})); - - sandbox.stub(element, '_saveDraft').returns(Promise.resolve({ok: false})); - - const savePromise = element.save(); - assert.isFalse(eraseStub.called); - return savePromise.then(() => { - assert.isFalse(eraseStub.called); - - element._saveDraft.restore(); - sandbox.stub(element, '_saveDraft') - .returns(Promise.resolve({ok: true})); - return element.save().then(() => { - assert.isTrue(eraseStub.called); }); }); + + suite('draft update reporting', () => { + let endStub; + let getTimerStub; + let mockEvent; + + setup(() => { + mockEvent = {preventDefault() {}}; + sandbox.stub(element, 'save') + .returns(Promise.resolve({})); + sandbox.stub(element, '_discardDraft') + .returns(Promise.resolve({})); + endStub = sinon.stub(); + getTimerStub = sandbox.stub(element.$.reporting, 'getTimer') + .returns({end: endStub}); + }); + + test('create', () => { + element.comment = {}; + return element._handleSave(mockEvent).then(() => { + assert.isTrue(endStub.calledOnce); + assert.isTrue(getTimerStub.calledOnce); + assert.equal(getTimerStub.lastCall.args[0], 'CreateDraftComment'); + }); + }); + + test('update', () => { + element.comment = {id: 'abc_123'}; + return element._handleSave(mockEvent).then(() => { + assert.isTrue(endStub.calledOnce); + assert.isTrue(getTimerStub.calledOnce); + assert.equal(getTimerStub.lastCall.args[0], 'UpdateDraftComment'); + }); + }); + + test('discard', () => { + element.comment = {id: 'abc_123'}; + sandbox.stub(element, '_closeConfirmDiscardOverlay'); + return element._handleConfirmDiscard(mockEvent).then(() => { + assert.isTrue(endStub.calledOnce); + assert.isTrue(getTimerStub.calledOnce); + assert.equal(getTimerStub.lastCall.args[0], 'DiscardDraftComment'); + }); + }); + }); + + test('edit reports interaction', () => { + const reportStub = sandbox.stub(element.$.reporting, + 'recordDraftInteraction'); + MockInteractions.tap(element.$$('.edit')); + assert.isTrue(reportStub.calledOnce); + }); + + test('discard reports interaction', () => { + const reportStub = sandbox.stub(element.$.reporting, + 'recordDraftInteraction'); + element.draft = true; + MockInteractions.tap(element.$$('.discard')); + assert.isTrue(reportStub.calledOnce); + }); }); - test('_computeSaveDisabled', () => { - const comment = {unresolved: true}; - const msgComment = {message: 'test', unresolved: true}; - assert.equal(element._computeSaveDisabled('', comment, false), true); - assert.equal(element._computeSaveDisabled('test', comment, false), false); - assert.equal(element._computeSaveDisabled('', msgComment, false), true); - assert.equal( - element._computeSaveDisabled('test', msgComment, false), false); - assert.equal( - element._computeSaveDisabled('test2', msgComment, false), false); - assert.equal(element._computeSaveDisabled('test', comment, true), false); - assert.equal(element._computeSaveDisabled('', comment, true), true); - assert.equal(element._computeSaveDisabled('', comment, false), true); - }); - - suite('confirm discard', () => { - let discardStub; - let overlayStub; - let mockEvent; + suite('gr-comment draft tests', () => { + let element; + let sandbox; setup(() => { - discardStub = sandbox.stub(element, '_discardDraft'); - overlayStub = sandbox.stub(element, '_openOverlay') - .returns(Promise.resolve()); - mockEvent = {preventDefault: sinon.stub()}; - }); - - test('confirms discard of comments with message text', () => { - element._messageText = 'test'; - element._handleDiscard(mockEvent); - assert.isTrue(overlayStub.calledWith(element.confirmDiscardOverlay)); - assert.isFalse(discardStub.called); - }); - - test('no confirmation for comments without message text', () => { - element._messageText = ''; - element._handleDiscard(mockEvent); - assert.isFalse(overlayStub.called); - assert.isTrue(discardStub.calledOnce); - }); - }); - - test('ctrl+s saves comment', done => { - const stub = sinon.stub(element, 'save', () => { - assert.isTrue(stub.called); - stub.restore(); - done(); - return Promise.resolve(); - }); - element._messageText = 'is that the horse from horsing around??'; - element.editing = true; - flushAsynchronousOperations(); - MockInteractions.pressAndReleaseKeyOn( - element.textarea.$.textarea.textarea, - 83, 'ctrl'); // 'ctrl + s' - }); - - test('draft saving/editing', done => { - const fireStub = sinon.stub(element, 'fire'); - const cancelDebounce = sandbox.stub(element, 'cancelDebouncer'); - - element.draft = true; - MockInteractions.tap(element.$$('.edit')); - element._messageText = 'good news, everyone!'; - element.flushDebouncer('fire-update'); - element.flushDebouncer('store'); - assert(fireStub.calledWith('comment-update'), - 'comment-update should be sent'); - assert.isTrue(fireStub.calledOnce); - - element._messageText = 'good news, everyone!'; - element.flushDebouncer('fire-update'); - element.flushDebouncer('store'); - assert.isTrue(fireStub.calledOnce, - 'No events should fire for text editing'); - - MockInteractions.tap(element.$$('.save')); - - assert.isTrue(element.disabled, - 'Element should be disabled when creating draft.'); - - element._xhrPromise.then(draft => { - assert(fireStub.calledWith('comment-save'), - 'comment-save should be sent'); - assert(cancelDebounce.calledWith('store')); - - assert.deepEqual(fireStub.lastCall.args[1], { - comment: { - __commentSide: 'right', - __draft: true, - __draftID: 'temp_draft_id', - id: 'baf0414d_40572e03', - line: 5, - message: 'saved!', - path: '/path/to/file', - updated: '2015-12-08 21:52:36.177000000', + stub('gr-rest-api-interface', { + getAccount() { return Promise.resolve(null); }, + saveDiffDraft() { + return Promise.resolve({ + ok: true, + text() { + return Promise.resolve( + ')]}\'\n{' + + '"id": "baf0414d_40572e03",' + + '"path": "/path/to/file",' + + '"line": 5,' + + '"updated": "2015-12-08 21:52:36.177000000",' + + '"message": "saved!"' + + '}' + ); + }, + }); + }, + removeChangeReviewer() { + return Promise.resolve({ok: true}); }, - patchNum: 1, }); - assert.isFalse(element.disabled, - 'Element should be enabled when done creating draft.'); - assert.equal(draft.message, 'saved!'); - assert.isFalse(element.editing); - }).then(() => { + stub('gr-storage', { + getDraftComment() { return null; }, + }); + element = fixture('draft'); + element.changeNum = 42; + element.patchNum = 1; + element.editing = false; + element.comment = { + __commentSide: 'right', + __draft: true, + __draftID: 'temp_draft_id', + path: '/path/to/file', + line: 5, + }; + element.commentSide = 'right'; + sandbox = sinon.sandbox.create(); + }); + + teardown(() => { + sandbox.restore(); + }); + + test('button visibility states', () => { + element.showActions = false; + assert.isTrue(element.$$('.humanActions').hasAttribute('hidden')); + assert.isTrue(element.$$('.robotActions').hasAttribute('hidden')); + + element.showActions = true; + assert.isFalse(element.$$('.humanActions').hasAttribute('hidden')); + assert.isTrue(element.$$('.robotActions').hasAttribute('hidden')); + + element.draft = true; + assert.isTrue(isVisible(element.$$('.edit')), 'edit is visible'); + assert.isTrue(isVisible(element.$$('.discard')), 'discard is visible'); + assert.isFalse(isVisible(element.$$('.save')), 'save is not visible'); + assert.isFalse(isVisible(element.$$('.cancel')), 'cancel is not visible'); + assert.isTrue(isVisible(element.$$('.resolve')), 'resolve is visible'); + assert.isFalse(element.$$('.humanActions').hasAttribute('hidden')); + assert.isTrue(element.$$('.robotActions').hasAttribute('hidden')); + + element.editing = true; + flushAsynchronousOperations(); + assert.isFalse(isVisible(element.$$('.edit')), 'edit is not visible'); + assert.isFalse(isVisible(element.$$('.discard')), 'discard not visible'); + assert.isTrue(isVisible(element.$$('.save')), 'save is visible'); + assert.isTrue(isVisible(element.$$('.cancel')), 'cancel is visible'); + assert.isTrue(isVisible(element.$$('.resolve')), 'resolve is visible'); + assert.isFalse(element.$$('.humanActions').hasAttribute('hidden')); + assert.isTrue(element.$$('.robotActions').hasAttribute('hidden')); + + element.draft = false; + element.editing = false; + flushAsynchronousOperations(); + assert.isFalse(isVisible(element.$$('.edit')), 'edit is not visible'); + assert.isFalse(isVisible(element.$$('.discard')), + 'discard is not visible'); + assert.isFalse(isVisible(element.$$('.save')), 'save is not visible'); + assert.isFalse(isVisible(element.$$('.cancel')), 'cancel is not visible'); + assert.isFalse(element.$$('.humanActions').hasAttribute('hidden')); + assert.isTrue(element.$$('.robotActions').hasAttribute('hidden')); + + element.comment.id = 'foo'; + element.draft = true; + element.editing = true; + flushAsynchronousOperations(); + assert.isTrue(isVisible(element.$$('.cancel')), 'cancel is visible'); + assert.isFalse(element.$$('.humanActions').hasAttribute('hidden')); + assert.isTrue(element.$$('.robotActions').hasAttribute('hidden')); + + // Delete button is not hidden by default + assert.isFalse(element.shadowRoot.querySelector('#deleteBtn').hidden); + + element.isRobotComment = true; + element.draft = true; + assert.isTrue(element.$$('.humanActions').hasAttribute('hidden')); + assert.isFalse(element.$$('.robotActions').hasAttribute('hidden')); + + // It is not expected to see Robot comment drafts, but if they appear, + // they will behave the same as non-drafts. + element.draft = false; + assert.isTrue(element.$$('.humanActions').hasAttribute('hidden')); + assert.isFalse(element.$$('.robotActions').hasAttribute('hidden')); + + // A robot comment with run ID should display plain text. + element.set(['comment', 'robot_run_id'], 'text'); + element.editing = false; + element.collapsed = false; + flushAsynchronousOperations(); + assert.isTrue(element.$$('.robotRun.link').textContent === 'Run Details'); + + // A robot comment with run ID and url should display a link. + element.set(['comment', 'url'], '/path/to/run'); + flushAsynchronousOperations(); + assert.notEqual(getComputedStyle(element.$$('.robotRun.link')).display, + 'none'); + + // Delete button is hidden for robot comments + assert.isTrue(element.shadowRoot.querySelector('#deleteBtn').hidden); + }); + + test('collapsible drafts', () => { + assert.isTrue(element.collapsed); + assert.isFalse(isVisible(element.$$('gr-formatted-text')), + 'gr-formatted-text is not visible'); + assert.isFalse(isVisible(element.$$('.actions')), + 'actions are not visible'); + assert.isNotOk(element.textarea, 'textarea is not visible'); + assert.isTrue(isVisible(element.$$('.collapsedContent')), + 'header middle content is visible'); + + MockInteractions.tap(element.$.header); + assert.isFalse(element.collapsed); + assert.isTrue(isVisible(element.$$('gr-formatted-text')), + 'gr-formatted-text is visible'); + assert.isTrue(isVisible(element.$$('.actions')), + 'actions are visible'); + assert.isNotOk(element.textarea, 'textarea is not visible'); + assert.isFalse(isVisible(element.$$('.collapsedContent')), + 'header middle content is is not visible'); + + // When the edit button is pressed, should still see the actions + // and also textarea MockInteractions.tap(element.$$('.edit')); - element._messageText = 'You’ll be delivering a package to Chapek 9, ' + - 'a world where humans are killed on sight.'; + flushAsynchronousOperations(); + assert.isFalse(element.collapsed); + assert.isFalse(isVisible(element.$$('gr-formatted-text')), + 'gr-formatted-text is not visible'); + assert.isTrue(isVisible(element.$$('.actions')), + 'actions are visible'); + assert.isTrue(isVisible(element.textarea), 'textarea is visible'); + assert.isFalse(isVisible(element.$$('.collapsedContent')), + 'header middle content is not visible'); + + // When toggle again, everything should be hidden except for textarea + // and header middle content should be visible + MockInteractions.tap(element.$.header); + assert.isTrue(element.collapsed); + assert.isFalse(isVisible(element.$$('gr-formatted-text')), + 'gr-formatted-text is not visible'); + assert.isFalse(isVisible(element.$$('.actions')), + 'actions are not visible'); + assert.isFalse(isVisible(element.$$('gr-textarea')), + 'textarea is not visible'); + assert.isTrue(isVisible(element.$$('.collapsedContent')), + 'header middle content is visible'); + + // When toggle again, textarea should remain open in the state it was + // before + MockInteractions.tap(element.$.header); + assert.isFalse(isVisible(element.$$('gr-formatted-text')), + 'gr-formatted-text is not visible'); + assert.isTrue(isVisible(element.$$('.actions')), + 'actions are visible'); + assert.isTrue(isVisible(element.textarea), 'textarea is visible'); + assert.isFalse(isVisible(element.$$('.collapsedContent')), + 'header middle content is not visible'); + }); + + test('robot comment layout', () => { + const comment = Object.assign({ + robot_id: 'happy_robot_id', + url: '/robot/comment', + author: { + name: 'Happy Robot', + }, + }, element.comment); + element.comment = comment; + element.collapsed = false; + flushAsynchronousOperations(); + + let runIdMessage; + runIdMessage = element.$$('.runIdMessage'); + assert.isFalse(runIdMessage.hidden); + + const runDetailsLink = element.$$('.robotRunLink'); + assert.isTrue(runDetailsLink.href.indexOf(element.comment.url) !== -1); + + const robotServiceName = element.$$('.authorName'); + assert.isTrue(robotServiceName.textContent === 'happy_robot_id'); + + const authorName = element.$$('.robotId'); + assert.isTrue(authorName.innerText === 'Happy Robot'); + + element.collapsed = true; + flushAsynchronousOperations(); + runIdMessage = element.$$('.runIdMessage'); + assert.isTrue(runIdMessage.hidden); + }); + + test('draft creation/cancellation', done => { + assert.isFalse(element.editing); + MockInteractions.tap(element.$$('.edit')); + assert.isTrue(element.editing); + + element._messageText = ''; + const eraseMessageDraftSpy = sandbox.spy(element, '_eraseDraftComment'); + + // Save should be disabled on an empty message. + let disabled = element.$$('.save').hasAttribute('disabled'); + assert.isTrue(disabled, 'save button should be disabled.'); + element._messageText = ' '; + disabled = element.$$('.save').hasAttribute('disabled'); + assert.isTrue(disabled, 'save button should be disabled.'); + + const updateStub = sinon.stub(); + element.addEventListener('comment-update', updateStub); + + let numDiscardEvents = 0; + element.addEventListener('comment-discard', e => { + numDiscardEvents++; + assert.isFalse(eraseMessageDraftSpy.called); + if (numDiscardEvents === 2) { + assert.isFalse(updateStub.called); + done(); + } + }); + MockInteractions.tap(element.$$('.cancel')); + element.flushDebouncer('fire-update'); + element._messageText = ''; + flushAsynchronousOperations(); + MockInteractions.pressAndReleaseKeyOn(element.textarea, 27); // esc + }); + + test('draft discard removes message from storage', done => { + element._messageText = ''; + const eraseMessageDraftSpy = sandbox.spy(element, '_eraseDraftComment'); + sandbox.stub(element, '_closeConfirmDiscardOverlay'); + + element.addEventListener('comment-discard', e => { + assert.isTrue(eraseMessageDraftSpy.called); + done(); + }); + element._handleConfirmDiscard({preventDefault: sinon.stub()}); + }); + + test('storage is cleared only after save success', () => { + element._messageText = 'test'; + const eraseStub = sandbox.stub(element, '_eraseDraftComment'); + sandbox.stub(element.$.restAPI, 'getResponseObject') + .returns(Promise.resolve({})); + + sandbox.stub(element, '_saveDraft').returns(Promise.resolve({ok: false})); + + const savePromise = element.save(); + assert.isFalse(eraseStub.called); + return savePromise.then(() => { + assert.isFalse(eraseStub.called); + + element._saveDraft.restore(); + sandbox.stub(element, '_saveDraft') + .returns(Promise.resolve({ok: true})); + return element.save().then(() => { + assert.isTrue(eraseStub.called); + }); + }); + }); + + test('_computeSaveDisabled', () => { + const comment = {unresolved: true}; + const msgComment = {message: 'test', unresolved: true}; + assert.equal(element._computeSaveDisabled('', comment, false), true); + assert.equal(element._computeSaveDisabled('test', comment, false), false); + assert.equal(element._computeSaveDisabled('', msgComment, false), true); + assert.equal( + element._computeSaveDisabled('test', msgComment, false), false); + assert.equal( + element._computeSaveDisabled('test2', msgComment, false), false); + assert.equal(element._computeSaveDisabled('test', comment, true), false); + assert.equal(element._computeSaveDisabled('', comment, true), true); + assert.equal(element._computeSaveDisabled('', comment, false), true); + }); + + suite('confirm discard', () => { + let discardStub; + let overlayStub; + let mockEvent; + + setup(() => { + discardStub = sandbox.stub(element, '_discardDraft'); + overlayStub = sandbox.stub(element, '_openOverlay') + .returns(Promise.resolve()); + mockEvent = {preventDefault: sinon.stub()}; + }); + + test('confirms discard of comments with message text', () => { + element._messageText = 'test'; + element._handleDiscard(mockEvent); + assert.isTrue(overlayStub.calledWith(element.confirmDiscardOverlay)); + assert.isFalse(discardStub.called); + }); + + test('no confirmation for comments without message text', () => { + element._messageText = ''; + element._handleDiscard(mockEvent); + assert.isFalse(overlayStub.called); + assert.isTrue(discardStub.calledOnce); + }); + }); + + test('ctrl+s saves comment', done => { + const stub = sinon.stub(element, 'save', () => { + assert.isTrue(stub.called); + stub.restore(); + done(); + return Promise.resolve(); + }); + element._messageText = 'is that the horse from horsing around??'; + element.editing = true; + flushAsynchronousOperations(); + MockInteractions.pressAndReleaseKeyOn( + element.textarea.$.textarea.textarea, + 83, 'ctrl'); // 'ctrl + s' + }); + + test('draft saving/editing', done => { + const fireStub = sinon.stub(element, 'fire'); + const cancelDebounce = sandbox.stub(element, 'cancelDebouncer'); + + element.draft = true; + MockInteractions.tap(element.$$('.edit')); + element._messageText = 'good news, everyone!'; + element.flushDebouncer('fire-update'); + element.flushDebouncer('store'); + assert(fireStub.calledWith('comment-update'), + 'comment-update should be sent'); + assert.isTrue(fireStub.calledOnce); + + element._messageText = 'good news, everyone!'; + element.flushDebouncer('fire-update'); + element.flushDebouncer('store'); + assert.isTrue(fireStub.calledOnce, + 'No events should fire for text editing'); + MockInteractions.tap(element.$$('.save')); + assert.isTrue(element.disabled, - 'Element should be disabled when updating draft.'); + 'Element should be disabled when creating draft.'); element._xhrPromise.then(draft => { + assert(fireStub.calledWith('comment-save'), + 'comment-save should be sent'); + assert(cancelDebounce.calledWith('store')); + + assert.deepEqual(fireStub.lastCall.args[1], { + comment: { + __commentSide: 'right', + __draft: true, + __draftID: 'temp_draft_id', + id: 'baf0414d_40572e03', + line: 5, + message: 'saved!', + path: '/path/to/file', + updated: '2015-12-08 21:52:36.177000000', + }, + patchNum: 1, + }); assert.isFalse(element.disabled, - 'Element should be enabled when done updating draft.'); + 'Element should be enabled when done creating draft.'); assert.equal(draft.message, 'saved!'); assert.isFalse(element.editing); - fireStub.restore(); - done(); + }).then(() => { + MockInteractions.tap(element.$$('.edit')); + element._messageText = 'You’ll be delivering a package to Chapek 9, ' + + 'a world where humans are killed on sight.'; + MockInteractions.tap(element.$$('.save')); + assert.isTrue(element.disabled, + 'Element should be disabled when updating draft.'); + + element._xhrPromise.then(draft => { + assert.isFalse(element.disabled, + 'Element should be enabled when done updating draft.'); + assert.equal(draft.message, 'saved!'); + assert.isFalse(element.editing); + fireStub.restore(); + done(); + }); }); }); - }); - test('draft prevent save when disabled', () => { - const saveStub = sandbox.stub(element, 'save').returns(Promise.resolve()); - element.showActions = true; - element.draft = true; - MockInteractions.tap(element.$.header); - MockInteractions.tap(element.$$('.edit')); - element._messageText = 'good news, everyone!'; - element.flushDebouncer('fire-update'); - element.flushDebouncer('store'); + test('draft prevent save when disabled', () => { + const saveStub = sandbox.stub(element, 'save').returns(Promise.resolve()); + element.showActions = true; + element.draft = true; + MockInteractions.tap(element.$.header); + MockInteractions.tap(element.$$('.edit')); + element._messageText = 'good news, everyone!'; + element.flushDebouncer('fire-update'); + element.flushDebouncer('store'); - element.disabled = true; - MockInteractions.tap(element.$$('.save')); - assert.isFalse(saveStub.called); + element.disabled = true; + MockInteractions.tap(element.$$('.save')); + assert.isFalse(saveStub.called); - element.disabled = false; - MockInteractions.tap(element.$$('.save')); - assert.isTrue(saveStub.calledOnce); - }); + element.disabled = false; + MockInteractions.tap(element.$$('.save')); + assert.isTrue(saveStub.calledOnce); + }); - test('proper event fires on resolve, comment is not saved', done => { - const save = sandbox.stub(element, 'save'); - element.addEventListener('comment-update', e => { - assert.isTrue(e.detail.comment.unresolved); + test('proper event fires on resolve, comment is not saved', done => { + const save = sandbox.stub(element, 'save'); + element.addEventListener('comment-update', e => { + assert.isTrue(e.detail.comment.unresolved); + assert.isFalse(save.called); + done(); + }); + MockInteractions.tap(element.$$('.resolve input')); + }); + + test('resolved comment state indicated by checkbox', () => { + sandbox.stub(element, 'save'); + element.comment = {unresolved: false}; + assert.isTrue(element.$$('.resolve input').checked); + element.comment = {unresolved: true}; + assert.isFalse(element.$$('.resolve input').checked); + }); + + test('resolved checkbox saves with tap when !editing', () => { + element.editing = false; + const save = sandbox.stub(element, 'save'); + + element.comment = {unresolved: false}; + assert.isTrue(element.$$('.resolve input').checked); + element.comment = {unresolved: true}; + assert.isFalse(element.$$('.resolve input').checked); assert.isFalse(save.called); - done(); - }); - MockInteractions.tap(element.$$('.resolve input')); - }); - - test('resolved comment state indicated by checkbox', () => { - sandbox.stub(element, 'save'); - element.comment = {unresolved: false}; - assert.isTrue(element.$$('.resolve input').checked); - element.comment = {unresolved: true}; - assert.isFalse(element.$$('.resolve input').checked); - }); - - test('resolved checkbox saves with tap when !editing', () => { - element.editing = false; - const save = sandbox.stub(element, 'save'); - - element.comment = {unresolved: false}; - assert.isTrue(element.$$('.resolve input').checked); - element.comment = {unresolved: true}; - assert.isFalse(element.$$('.resolve input').checked); - assert.isFalse(save.called); - MockInteractions.tap(element.$.resolvedCheckbox); - assert.isTrue(element.$$('.resolve input').checked); - assert.isTrue(save.called); - }); - - suite('draft saving messages', () => { - test('_getSavingMessage', () => { - assert.equal(element._getSavingMessage(0), 'All changes saved'); - assert.equal(element._getSavingMessage(1), 'Saving 1 draft...'); - assert.equal(element._getSavingMessage(2), 'Saving 2 drafts...'); - assert.equal(element._getSavingMessage(3), 'Saving 3 drafts...'); + MockInteractions.tap(element.$.resolvedCheckbox); + assert.isTrue(element.$$('.resolve input').checked); + assert.isTrue(save.called); }); - test('_show{Start,End}Request', () => { - const updateStub = sandbox.stub(element, '_updateRequestToast'); - element._numPendingDraftRequests.number = 1; + suite('draft saving messages', () => { + test('_getSavingMessage', () => { + assert.equal(element._getSavingMessage(0), 'All changes saved'); + assert.equal(element._getSavingMessage(1), 'Saving 1 draft...'); + assert.equal(element._getSavingMessage(2), 'Saving 2 drafts...'); + assert.equal(element._getSavingMessage(3), 'Saving 3 drafts...'); + }); - element._showStartRequest(); - assert.isTrue(updateStub.calledOnce); - assert.equal(updateStub.lastCall.args[0], 2); - assert.equal(element._numPendingDraftRequests.number, 2); + test('_show{Start,End}Request', () => { + const updateStub = sandbox.stub(element, '_updateRequestToast'); + element._numPendingDraftRequests.number = 1; - element._showEndRequest(); - assert.isTrue(updateStub.calledTwice); - assert.equal(updateStub.lastCall.args[0], 1); - assert.equal(element._numPendingDraftRequests.number, 1); + element._showStartRequest(); + assert.isTrue(updateStub.calledOnce); + assert.equal(updateStub.lastCall.args[0], 2); + assert.equal(element._numPendingDraftRequests.number, 2); - element._showEndRequest(); - assert.isTrue(updateStub.calledThrice); - assert.equal(updateStub.lastCall.args[0], 0); - assert.equal(element._numPendingDraftRequests.number, 0); + element._showEndRequest(); + assert.isTrue(updateStub.calledTwice); + assert.equal(updateStub.lastCall.args[0], 1); + assert.equal(element._numPendingDraftRequests.number, 1); + + element._showEndRequest(); + assert.isTrue(updateStub.calledThrice); + assert.equal(updateStub.lastCall.args[0], 0); + assert.equal(element._numPendingDraftRequests.number, 0); + }); }); - }); - test('cancelling an unsaved draft discards, persists in storage', () => { - const discardSpy = sandbox.spy(element, '_fireDiscard'); - const storeStub = sandbox.stub(element.$.storage, 'setDraftComment'); - const eraseStub = sandbox.stub(element.$.storage, 'eraseDraftComment'); - element._messageText = 'test text'; - flushAsynchronousOperations(); - element.flushDebouncer('store'); + test('cancelling an unsaved draft discards, persists in storage', () => { + const discardSpy = sandbox.spy(element, '_fireDiscard'); + const storeStub = sandbox.stub(element.$.storage, 'setDraftComment'); + const eraseStub = sandbox.stub(element.$.storage, 'eraseDraftComment'); + element._messageText = 'test text'; + flushAsynchronousOperations(); + element.flushDebouncer('store'); - assert.isTrue(storeStub.called); - assert.equal(storeStub.lastCall.args[1], 'test text'); - element._handleCancel({preventDefault: () => {}}); - assert.isTrue(discardSpy.called); - assert.isFalse(eraseStub.called); - }); - - test('cancelling edit on a saved draft does not store', () => { - element.comment.id = 'foo'; - const discardSpy = sandbox.spy(element, '_fireDiscard'); - const storeStub = sandbox.stub(element.$.storage, 'setDraftComment'); - element._messageText = 'test text'; - flushAsynchronousOperations(); - element.flushDebouncer('store'); - - assert.isFalse(storeStub.called); - element._handleCancel({preventDefault: () => {}}); - assert.isTrue(discardSpy.called); - }); - - test('deleting text from saved draft and saving deletes the draft', () => { - element.comment = {id: 'foo', message: 'test'}; - element._messageText = ''; - const discardStub = sandbox.stub(element, '_discardDraft'); - - element.save(); - assert.isTrue(discardStub.called); - }); - - test('_handleFix fires create-fix event', done => { - element.addEventListener('create-fix-comment', e => { - assert.deepEqual(e.detail, element._getEventPayload()); - done(); + assert.isTrue(storeStub.called); + assert.equal(storeStub.lastCall.args[1], 'test text'); + element._handleCancel({preventDefault: () => {}}); + assert.isTrue(discardSpy.called); + assert.isFalse(eraseStub.called); }); - element.isRobotComment = true; - element.comments = [element.comment]; - flushAsynchronousOperations(); - MockInteractions.tap(element.$$('.fix')); - }); + test('cancelling edit on a saved draft does not store', () => { + element.comment.id = 'foo'; + const discardSpy = sandbox.spy(element, '_fireDiscard'); + const storeStub = sandbox.stub(element.$.storage, 'setDraftComment'); + element._messageText = 'test text'; + flushAsynchronousOperations(); + element.flushDebouncer('store'); - test('do not show Please Fix button if human reply exists', () => { - element.comments = [ - { - robot_id: 'happy_robot_id', - robot_run_id: '5838406743490560', - fix_suggestions: [ - { - fix_id: '478ff847_3bf47aaf', - description: 'Make the smiley happier by giving it a nose.', - replacements: [ - { - path: 'Documentation/config-gerrit.txt', - range: { - start_line: 10, - start_character: 7, - end_line: 10, - end_character: 9, + assert.isFalse(storeStub.called); + element._handleCancel({preventDefault: () => {}}); + assert.isTrue(discardSpy.called); + }); + + test('deleting text from saved draft and saving deletes the draft', () => { + element.comment = {id: 'foo', message: 'test'}; + element._messageText = ''; + const discardStub = sandbox.stub(element, '_discardDraft'); + + element.save(); + assert.isTrue(discardStub.called); + }); + + test('_handleFix fires create-fix event', done => { + element.addEventListener('create-fix-comment', e => { + assert.deepEqual(e.detail, element._getEventPayload()); + done(); + }); + element.isRobotComment = true; + element.comments = [element.comment]; + flushAsynchronousOperations(); + + MockInteractions.tap(element.$$('.fix')); + }); + + test('do not show Please Fix button if human reply exists', () => { + element.comments = [ + { + robot_id: 'happy_robot_id', + robot_run_id: '5838406743490560', + fix_suggestions: [ + { + fix_id: '478ff847_3bf47aaf', + description: 'Make the smiley happier by giving it a nose.', + replacements: [ + { + path: 'Documentation/config-gerrit.txt', + range: { + start_line: 10, + start_character: 7, + end_line: 10, + end_character: 9, + }, + replacement: ':-)', }, - replacement: ':-)', + ], + }, + ], + author: { + _account_id: 1030912, + name: 'Alice Kober-Sotzek', + email: 'aliceks@google.com', + avatars: [ + { + url: '/s32-p/photo.jpg', + height: 32, + }, + { + url: '/AaAdOFzPlFI/s56-p/photo.jpg', + height: 56, + }, + { + url: '/AaAdOFzPlFI/s100-p/photo.jpg', + height: 100, + }, + { + url: '/AaAdOFzPlFI/s120-p/photo.jpg', + height: 120, }, ], }, - ], - author: { - _account_id: 1030912, - name: 'Alice Kober-Sotzek', - email: 'aliceks@google.com', - avatars: [ + patch_set: 1, + id: 'eb0d03fd_5e95904f', + line: 10, + updated: '2017-04-04 15:36:17.000000000', + message: 'This is a robot comment with a fix.', + unresolved: false, + __commentSide: 'right', + collapsed: false, + }, + { + __draft: true, + __draftID: '0.wbrfbwj89sa', + __date: '2019-12-04T13:41:03.689Z', + path: 'Documentation/config-gerrit.txt', + patchNum: 1, + side: 'REVISION', + __commentSide: 'right', + line: 10, + in_reply_to: 'eb0d03fd_5e95904f', + message: '> This is a robot comment with a fix.\n\nPlease fix.', + unresolved: true, + }, + ]; + element.comment = element.comments[0]; + flushAsynchronousOperations(); + assert.isNull(element.$$('robotActions gr-button')); + }); + + test('show Please Fix if no human reply', () => { + element.comments = [ + { + robot_id: 'happy_robot_id', + robot_run_id: '5838406743490560', + fix_suggestions: [ { - url: '/s32-p/photo.jpg', - height: 32, - }, - { - url: '/AaAdOFzPlFI/s56-p/photo.jpg', - height: 56, - }, - { - url: '/AaAdOFzPlFI/s100-p/photo.jpg', - height: 100, - }, - { - url: '/AaAdOFzPlFI/s120-p/photo.jpg', - height: 120, + fix_id: '478ff847_3bf47aaf', + description: 'Make the smiley happier by giving it a nose.', + replacements: [ + { + path: 'Documentation/config-gerrit.txt', + range: { + start_line: 10, + start_character: 7, + end_line: 10, + end_character: 9, + }, + replacement: ':-)', + }, + ], }, ], - }, - patch_set: 1, - id: 'eb0d03fd_5e95904f', - line: 10, - updated: '2017-04-04 15:36:17.000000000', - message: 'This is a robot comment with a fix.', - unresolved: false, - __commentSide: 'right', - collapsed: false, - }, - { - __draft: true, - __draftID: '0.wbrfbwj89sa', - __date: '2019-12-04T13:41:03.689Z', - path: 'Documentation/config-gerrit.txt', - patchNum: 1, - side: 'REVISION', - __commentSide: 'right', - line: 10, - in_reply_to: 'eb0d03fd_5e95904f', - message: '> This is a robot comment with a fix.\n\nPlease fix.', - unresolved: true, - }, - ]; - element.comment = element.comments[0]; - flushAsynchronousOperations(); - assert.isNull(element.$$('robotActions gr-button')); - }); - - test('show Please Fix if no human reply', () => { - element.comments = [ - { - robot_id: 'happy_robot_id', - robot_run_id: '5838406743490560', - fix_suggestions: [ - { - fix_id: '478ff847_3bf47aaf', - description: 'Make the smiley happier by giving it a nose.', - replacements: [ + author: { + _account_id: 1030912, + name: 'Alice Kober-Sotzek', + email: 'aliceks@google.com', + avatars: [ { - path: 'Documentation/config-gerrit.txt', - range: { - start_line: 10, - start_character: 7, - end_line: 10, - end_character: 9, - }, - replacement: ':-)', + url: '/s32-p/photo.jpg', + height: 32, + }, + { + url: '/AaAdOFzPlFI/s56-p/photo.jpg', + height: 56, + }, + { + url: '/AaAdOFzPlFI/s100-p/photo.jpg', + height: 100, + }, + { + url: '/AaAdOFzPlFI/s120-p/photo.jpg', + height: 120, }, ], }, - ], - author: { - _account_id: 1030912, - name: 'Alice Kober-Sotzek', - email: 'aliceks@google.com', - avatars: [ - { - url: '/s32-p/photo.jpg', - height: 32, - }, - { - url: '/AaAdOFzPlFI/s56-p/photo.jpg', - height: 56, - }, - { - url: '/AaAdOFzPlFI/s100-p/photo.jpg', - height: 100, - }, - { - url: '/AaAdOFzPlFI/s120-p/photo.jpg', - height: 120, - }, - ], + patch_set: 1, + id: 'eb0d03fd_5e95904f', + line: 10, + updated: '2017-04-04 15:36:17.000000000', + message: 'This is a robot comment with a fix.', + unresolved: false, + __commentSide: 'right', + collapsed: false, }, - patch_set: 1, - id: 'eb0d03fd_5e95904f', - line: 10, - updated: '2017-04-04 15:36:17.000000000', - message: 'This is a robot comment with a fix.', - unresolved: false, - __commentSide: 'right', - collapsed: false, - }, - ]; - element.comment = element.comments[0]; - flushAsynchronousOperations(); - assert.isNotNull(element.$$('.robotActions gr-button')); - }); - - test('_handleShowFix fires open-fix-preview event', done => { - element.addEventListener('open-fix-preview', e => { - assert.deepEqual(e.detail, element._getEventPayload()); - done(); + ]; + element.comment = element.comments[0]; + flushAsynchronousOperations(); + assert.isNotNull(element.$$('.robotActions gr-button')); }); - element.comment = {fix_suggestions: [{}]}; - element.isRobotComment = true; - flushAsynchronousOperations(); - MockInteractions.tap(element.$$('.show-fix')); + test('_handleShowFix fires open-fix-preview event', done => { + element.addEventListener('open-fix-preview', e => { + assert.deepEqual(e.detail, element._getEventPayload()); + done(); + }); + element.comment = {fix_suggestions: [{}]}; + element.isRobotComment = true; + flushAsynchronousOperations(); + + MockInteractions.tap(element.$$('.show-fix')); + }); }); }); diff --git a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.html b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.html index 14490f0f17..677a952064 100644 --- a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.html +++ b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.html @@ -23,6 +23,7 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + + @@ -41,7 +42,8 @@ limitations under the License. + @@ -37,7 +38,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -37,7 +38,8 @@ limitations under the License. + @@ -54,7 +55,8 @@ limitations under the License. diff --git a/polygerrit-ui/app/elements/shared/gr-event-interface/gr-event-interface_test.html b/polygerrit-ui/app/elements/shared/gr-event-interface/gr-event-interface_test.html index 4509dfecc7..6e62b15db9 100644 --- a/polygerrit-ui/app/elements/shared/gr-event-interface/gr-event-interface_test.html +++ b/polygerrit-ui/app/elements/shared/gr-event-interface/gr-event-interface_test.html @@ -21,6 +21,7 @@ limitations under the License. + @@ -33,7 +34,8 @@ limitations under the License. + @@ -37,7 +38,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -38,7 +39,8 @@ limitations under the License. + @@ -37,7 +38,8 @@ limitations under the License. + @@ -38,7 +39,8 @@ limitations under the License. + @@ -31,7 +32,8 @@ limitations under the License. + + diff --git a/polygerrit-ui/app/elements/shared/gr-select/gr-select_test.html b/polygerrit-ui/app/elements/shared/gr-select/gr-select_test.html index cae61056c5..536f4f8e00 100644 --- a/polygerrit-ui/app/elements/shared/gr-select/gr-select_test.html +++ b/polygerrit-ui/app/elements/shared/gr-select/gr-select_test.html @@ -23,6 +23,7 @@ limitations under the License. + @@ -50,7 +51,8 @@ limitations under the License. diff --git a/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_test.html b/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_test.html index a4bdf584d0..5fbbdf8cf4 100644 --- a/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_test.html +++ b/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_test.html @@ -23,6 +23,7 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -34,7 +35,8 @@ limitations under the License. + @@ -46,7 +47,8 @@ limitations under the License. diff --git a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.html b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.html index 7098d7c0bb..82375529ac 100644 --- a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.html +++ b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.html @@ -22,6 +22,7 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + @@ -35,7 +36,8 @@ limitations under the License. + + + @@ -38,7 +39,8 @@ limitations under the License. + @@ -37,7 +38,8 @@ limitations under the License. + @@ -37,7 +38,8 @@ limitations under the License.