Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 1 | <!DOCTYPE html> |
| 2 | <!-- |
Dave Borowitz | 8cdc76b | 2018-03-26 10:04:27 -0400 | [diff] [blame] | 3 | @license |
Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 4 | Copyright (C) 2015 The Android Open Source Project |
| 5 | |
| 6 | Licensed under the Apache License, Version 2.0 (the "License"); |
| 7 | you may not use this file except in compliance with the License. |
| 8 | You may obtain a copy of the License at |
| 9 | |
| 10 | http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | |
| 12 | Unless required by applicable law or agreed to in writing, software |
| 13 | distributed under the License is distributed on an "AS IS" BASIS, |
| 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 15 | See the License for the specific language governing permissions and |
| 16 | limitations under the License. |
| 17 | --> |
| 18 | |
| 19 | <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> |
Andrew Bonventre | 882043f | 2016-02-22 18:12:27 -0500 | [diff] [blame] | 20 | <title>gr-reply-dialog</title> |
Ole Rehmsen | 6290935 | 2019-05-16 16:10:33 +0200 | [diff] [blame] | 21 | <script src="/test/common-test-setup.js"></script> |
| 22 | <script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script> |
Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 23 | |
Ole Rehmsen | ecf0b78 | 2019-05-16 11:29:39 +0200 | [diff] [blame] | 24 | <script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script> |
Ole Rehmsen | 3164074 | 2019-05-16 11:24:47 +0200 | [diff] [blame] | 25 | <script src="/bower_components/web-component-tester/browser.js"></script> |
Mike Samuel | e07c4b2 | 2017-06-02 13:08:19 -0400 | [diff] [blame] | 26 | <link rel="import" href="../../../test/common-test-setup.html"/> |
Andrew Bonventre | 78792e8 | 2016-03-04 17:48:22 -0500 | [diff] [blame] | 27 | <link rel="import" href="gr-reply-dialog.html"> |
Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 28 | |
Viktar Donich | 29e1ce5 | 2017-03-28 17:02:44 -0700 | [diff] [blame] | 29 | <script>void(0);</script> |
| 30 | |
Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 31 | <test-fixture id="basic"> |
| 32 | <template> |
Andrew Bonventre | 882043f | 2016-02-22 18:12:27 -0500 | [diff] [blame] | 33 | <gr-reply-dialog></gr-reply-dialog> |
Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 34 | </template> |
| 35 | </test-fixture> |
| 36 | |
| 37 | <script> |
Ben Rohlfs | 9bdbceb | 2019-07-03 17:06:52 +0200 | [diff] [blame] | 38 | function cloneableResponse(status, text) { |
| 39 | return { |
| 40 | ok: false, |
| 41 | status, |
| 42 | text() { |
| 43 | return Promise.resolve(text); |
| 44 | }, |
| 45 | clone() { |
| 46 | return { |
| 47 | ok: false, |
| 48 | status, |
| 49 | text() { |
| 50 | return Promise.resolve(text); |
| 51 | }, |
| 52 | }; |
| 53 | }, |
| 54 | }; |
| 55 | } |
| 56 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 57 | suite('gr-reply-dialog tests', () => { |
| 58 | let element; |
| 59 | let changeNum; |
| 60 | let patchNum; |
Wyatt Allen | 4f4b3a7 | 2016-07-28 12:05:53 -0700 | [diff] [blame] | 61 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 62 | let sandbox; |
| 63 | let getDraftCommentStub; |
| 64 | let setDraftCommentStub; |
| 65 | let eraseDraftCommentStub; |
Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 66 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 67 | let lastId = 0; |
| 68 | const makeAccount = function() { return {_account_id: lastId++}; }; |
| 69 | const makeGroup = function() { return {id: lastId++}; }; |
Kasper Nilsson | a827155 | 2017-01-17 11:54:40 -0800 | [diff] [blame] | 70 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 71 | setup(() => { |
Wyatt Allen | 4f4b3a7 | 2016-07-28 12:05:53 -0700 | [diff] [blame] | 72 | sandbox = sinon.sandbox.create(); |
| 73 | |
| 74 | changeNum = 42; |
| 75 | patchNum = 1; |
| 76 | |
Andrew Bonventre | 5c09ba9 | 2016-05-02 17:31:23 -0400 | [diff] [blame] | 77 | stub('gr-rest-api-interface', { |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 78 | getConfig() { return Promise.resolve({}); }, |
| 79 | getAccount() { return Promise.resolve({}); }, |
Wyatt Allen | 7076c1b | 2018-01-16 15:15:11 -0800 | [diff] [blame] | 80 | getChange() { return Promise.resolve({}); }, |
Kasper Nilsson | aa746bd | 2017-09-18 22:12:30 -0700 | [diff] [blame] | 81 | getChangeSuggestedReviewers() { return Promise.resolve([]); }, |
Andrew Bonventre | cfacb80 | 2016-03-29 14:06:39 -0400 | [diff] [blame] | 82 | }); |
Wyatt Allen | 4f4b3a7 | 2016-07-28 12:05:53 -0700 | [diff] [blame] | 83 | |
Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 84 | element = fixture('basic'); |
Kasper Nilsson | 352b68f | 2016-10-11 11:51:35 -0700 | [diff] [blame] | 85 | element.change = { |
| 86 | _number: changeNum, |
| 87 | labels: { |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 88 | 'Verified': { |
Kasper Nilsson | 352b68f | 2016-10-11 11:51:35 -0700 | [diff] [blame] | 89 | values: { |
| 90 | '-1': 'Fails', |
| 91 | ' 0': 'No score', |
| 92 | '+1': 'Verified', |
| 93 | }, |
| 94 | default_value: 0, |
Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 95 | }, |
Kasper Nilsson | 352b68f | 2016-10-11 11:51:35 -0700 | [diff] [blame] | 96 | 'Code-Review': { |
| 97 | values: { |
| 98 | '-2': 'Do not submit', |
| 99 | '-1': 'I would prefer that you didn\'t submit this', |
| 100 | ' 0': 'No score', |
| 101 | '+1': 'Looks good to me, but someone else must approve', |
| 102 | '+2': 'Looks good to me, approved', |
| 103 | }, |
| 104 | default_value: 0, |
| 105 | }, |
Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 106 | }, |
Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 107 | }; |
Kasper Nilsson | 352b68f | 2016-10-11 11:51:35 -0700 | [diff] [blame] | 108 | element.patchNum = patchNum; |
Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 109 | element.permittedLabels = { |
| 110 | 'Code-Review': [ |
| 111 | '-1', |
| 112 | ' 0', |
Kasper Nilsson | 352b68f | 2016-10-11 11:51:35 -0700 | [diff] [blame] | 113 | '+1', |
Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 114 | ], |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 115 | 'Verified': [ |
Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 116 | '-1', |
| 117 | ' 0', |
Kasper Nilsson | 352b68f | 2016-10-11 11:51:35 -0700 | [diff] [blame] | 118 | '+1', |
| 119 | ], |
Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 120 | }; |
| 121 | |
Wyatt Allen | 4f4b3a7 | 2016-07-28 12:05:53 -0700 | [diff] [blame] | 122 | getDraftCommentStub = sandbox.stub(element.$.storage, 'getDraftComment'); |
| 123 | setDraftCommentStub = sandbox.stub(element.$.storage, 'setDraftComment'); |
| 124 | eraseDraftCommentStub = sandbox.stub(element.$.storage, |
| 125 | 'eraseDraftComment'); |
| 126 | |
Wyatt Allen | ebfe8a7 | 2017-11-16 13:32:38 -0800 | [diff] [blame] | 127 | sandbox.stub(element, 'fetchChangeUpdates') |
Wyatt Allen | dc55496 | 2017-11-16 11:52:50 -0800 | [diff] [blame] | 128 | .returns(Promise.resolve({isLatest: true})); |
Wyatt Allen | 6cf5875 | 2017-04-24 16:59:07 +0200 | [diff] [blame] | 129 | |
Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 130 | // Allow the elements created by dom-repeat to be stamped. |
| 131 | flushAsynchronousOperations(); |
| 132 | }); |
| 133 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 134 | teardown(() => { |
Wyatt Allen | 4f4b3a7 | 2016-07-28 12:05:53 -0700 | [diff] [blame] | 135 | sandbox.restore(); |
| 136 | }); |
| 137 | |
Logan Hanks | 02c781e | 2017-07-18 14:18:01 -0700 | [diff] [blame] | 138 | function stubSaveReview(jsonResponseProducer) { |
| 139 | return sandbox.stub(element, '_saveReview', review => { |
Logan Hanks | 3e0917e | 2017-07-19 08:32:25 -0700 | [diff] [blame] | 140 | return new Promise((resolve, reject) => { |
| 141 | try { |
| 142 | const result = jsonResponseProducer(review) || {}; |
| 143 | const resultStr = |
| 144 | element.$.restAPI.JSON_PREFIX + JSON.stringify(result); |
| 145 | resolve({ |
| 146 | ok: true, |
| 147 | text() { |
| 148 | return Promise.resolve(resultStr); |
| 149 | }, |
| 150 | }); |
| 151 | } catch (err) { |
| 152 | reject(err); |
| 153 | } |
Logan Hanks | 02c781e | 2017-07-18 14:18:01 -0700 | [diff] [blame] | 154 | }); |
| 155 | }); |
| 156 | } |
| 157 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 158 | test('default to publishing drafts with reply', done => { |
Becky Siegel | 9efcd57 | 2017-03-23 08:28:03 -0700 | [diff] [blame] | 159 | // Async tick is needed because iron-selector content is distributed and |
| 160 | // distributed content requires an observer to be set up. |
| 161 | // Note: Double flush seems to be needed in Safari. {@see Issue 4963}. |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 162 | flush(() => { |
| 163 | flush(() => { |
Becky Siegel | 9efcd57 | 2017-03-23 08:28:03 -0700 | [diff] [blame] | 164 | element.draft = 'I wholeheartedly disapprove'; |
| 165 | |
Logan Hanks | 02c781e | 2017-07-18 14:18:01 -0700 | [diff] [blame] | 166 | stubSaveReview(review => { |
Becky Siegel | 9efcd57 | 2017-03-23 08:28:03 -0700 | [diff] [blame] | 167 | assert.deepEqual(review, { |
| 168 | drafts: 'PUBLISH_ALL_REVISIONS', |
Viktar Donich | 51bdb8d | 2017-07-14 11:39:24 -0700 | [diff] [blame] | 169 | labels: { |
| 170 | 'Code-Review': 0, |
| 171 | 'Verified': 0, |
| 172 | }, |
Becky Siegel | 9efcd57 | 2017-03-23 08:28:03 -0700 | [diff] [blame] | 173 | message: 'I wholeheartedly disapprove', |
| 174 | reviewers: [], |
| 175 | }); |
| 176 | assert.isFalse(element.$.commentList.hidden); |
| 177 | done(); |
Becky Siegel | 9efcd57 | 2017-03-23 08:28:03 -0700 | [diff] [blame] | 178 | }); |
| 179 | |
| 180 | // This is needed on non-Blink engines most likely due to the ways in |
| 181 | // which the dom-repeat elements are stamped. |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 182 | flush(() => { |
Becky Siegel | 9efcd57 | 2017-03-23 08:28:03 -0700 | [diff] [blame] | 183 | MockInteractions.tap(element.$$('.send')); |
| 184 | }); |
| 185 | }); |
| 186 | }); |
| 187 | }); |
| 188 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 189 | test('keep drafts with reply', done => { |
Becky Siegel | 9efcd57 | 2017-03-23 08:28:03 -0700 | [diff] [blame] | 190 | MockInteractions.tap(element.$$('#includeComments')); |
| 191 | assert.equal(element._includeComments, false); |
| 192 | |
| 193 | // Async tick is needed because iron-selector content is distributed and |
| 194 | // distributed content requires an observer to be set up. |
| 195 | // Note: Double flush seems to be needed in Safari. {@see Issue 4963}. |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 196 | flush(() => { |
| 197 | flush(() => { |
Becky Siegel | 9efcd57 | 2017-03-23 08:28:03 -0700 | [diff] [blame] | 198 | element.draft = 'I wholeheartedly disapprove'; |
| 199 | |
Logan Hanks | 02c781e | 2017-07-18 14:18:01 -0700 | [diff] [blame] | 200 | stubSaveReview(review => { |
Becky Siegel | 9efcd57 | 2017-03-23 08:28:03 -0700 | [diff] [blame] | 201 | assert.deepEqual(review, { |
| 202 | drafts: 'KEEP', |
Viktar Donich | 51bdb8d | 2017-07-14 11:39:24 -0700 | [diff] [blame] | 203 | labels: { |
| 204 | 'Code-Review': 0, |
| 205 | 'Verified': 0, |
| 206 | }, |
Becky Siegel | 9efcd57 | 2017-03-23 08:28:03 -0700 | [diff] [blame] | 207 | message: 'I wholeheartedly disapprove', |
| 208 | reviewers: [], |
| 209 | }); |
| 210 | assert.isTrue(element.$.commentList.hidden); |
| 211 | done(); |
Becky Siegel | 9efcd57 | 2017-03-23 08:28:03 -0700 | [diff] [blame] | 212 | }); |
| 213 | |
| 214 | // This is needed on non-Blink engines most likely due to the ways in |
| 215 | // which the dom-repeat elements are stamped. |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 216 | flush(() => { |
Becky Siegel | 9efcd57 | 2017-03-23 08:28:03 -0700 | [diff] [blame] | 217 | MockInteractions.tap(element.$$('.send')); |
| 218 | }); |
| 219 | }); |
| 220 | }); |
| 221 | }); |
| 222 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 223 | test('label picker', done => { |
Becky Siegel | a499e3d | 2017-04-06 16:57:13 -0700 | [diff] [blame] | 224 | element.draft = 'I wholeheartedly disapprove'; |
Logan Hanks | 02c781e | 2017-07-18 14:18:01 -0700 | [diff] [blame] | 225 | stubSaveReview(review => { |
Becky Siegel | a499e3d | 2017-04-06 16:57:13 -0700 | [diff] [blame] | 226 | assert.deepEqual(review, { |
| 227 | drafts: 'PUBLISH_ALL_REVISIONS', |
| 228 | labels: { |
| 229 | 'Code-Review': -1, |
| 230 | 'Verified': -1, |
| 231 | }, |
| 232 | message: 'I wholeheartedly disapprove', |
| 233 | reviewers: [], |
Urs Wolfer | b603694 | 2016-03-06 14:57:02 +0100 | [diff] [blame] | 234 | }); |
Becky Siegel | a499e3d | 2017-04-06 16:57:13 -0700 | [diff] [blame] | 235 | }); |
| 236 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 237 | sandbox.stub(element.$.labelScores, 'getLabelValues', () => { |
Becky Siegel | a499e3d | 2017-04-06 16:57:13 -0700 | [diff] [blame] | 238 | return { |
| 239 | 'Code-Review': -1, |
| 240 | 'Verified': -1, |
| 241 | }; |
| 242 | }); |
| 243 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 244 | element.addEventListener('send', () => { |
Logan Hanks | 3e0917e | 2017-07-19 08:32:25 -0700 | [diff] [blame] | 245 | // Flush to ensure properties are updated. |
| 246 | flush(() => { |
| 247 | assert.isFalse(element.disabled, |
| 248 | 'Element should be enabled when done sending reply.'); |
| 249 | assert.equal(element.draft.length, 0); |
| 250 | done(); |
| 251 | }); |
Becky Siegel | a499e3d | 2017-04-06 16:57:13 -0700 | [diff] [blame] | 252 | }); |
| 253 | |
| 254 | // This is needed on non-Blink engines most likely due to the ways in |
| 255 | // which the dom-repeat elements are stamped. |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 256 | flush(() => { |
Becky Siegel | a499e3d | 2017-04-06 16:57:13 -0700 | [diff] [blame] | 257 | MockInteractions.tap(element.$$('.send')); |
| 258 | assert.isTrue(element.disabled); |
Urs Wolfer | b603694 | 2016-03-06 14:57:02 +0100 | [diff] [blame] | 259 | }); |
Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 260 | }); |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 261 | |
Viktar Donich | 7d23f22 | 2017-05-17 09:25:06 -0700 | [diff] [blame] | 262 | test('getlabelValue returns value', done => { |
| 263 | flush(() => { |
Becky Siegel | 6161393 | 2017-05-30 15:09:20 -0700 | [diff] [blame] | 264 | element.$$('gr-label-scores').$$(`gr-label-score-row[name="Verified"]`) |
| 265 | .setSelectedValue(-1); |
Viktar Donich | 7d23f22 | 2017-05-17 09:25:06 -0700 | [diff] [blame] | 266 | assert.equal('-1', element.getLabelValue('Verified')); |
| 267 | done(); |
| 268 | }); |
| 269 | }); |
| 270 | |
| 271 | test('getlabelValue when no score is selected', done => { |
| 272 | flush(() => { |
Becky Siegel | 9799415 | 2017-12-19 14:31:26 -0800 | [diff] [blame] | 273 | element.$$('gr-label-scores') |
| 274 | .$$(`gr-label-score-row[name="Code-Review"]`).setSelectedValue(-1); |
Viktar Donich | 51bdb8d | 2017-07-14 11:39:24 -0700 | [diff] [blame] | 275 | assert.strictEqual(element.getLabelValue('Verified'), ' 0'); |
Viktar Donich | 7d23f22 | 2017-05-17 09:25:06 -0700 | [diff] [blame] | 276 | done(); |
| 277 | }); |
| 278 | }); |
| 279 | |
Dmitrii Filippov | 2b45976 | 2019-09-24 16:26:10 +0200 | [diff] [blame] | 280 | test('setlabelValue', done => { |
Becky Siegel | 452a5c6 | 2017-05-09 09:59:55 -0700 | [diff] [blame] | 281 | element._account = {_account_id: 1}; |
Dmitrii Filippov | 2b45976 | 2019-09-24 16:26:10 +0200 | [diff] [blame] | 282 | flush(() => { |
| 283 | const label = 'Verified'; |
| 284 | const value = '+1'; |
| 285 | element.setLabelValue(label, value); |
| 286 | |
| 287 | const labels = element.$.labelScores.getLabelValues(); |
| 288 | assert.deepEqual(labels, { |
| 289 | 'Code-Review': 0, |
| 290 | 'Verified': 1, |
| 291 | }); |
| 292 | done(); |
Viktar Donich | 51bdb8d | 2017-07-14 11:39:24 -0700 | [diff] [blame] | 293 | }); |
Becky Siegel | 452a5c6 | 2017-05-09 09:59:55 -0700 | [diff] [blame] | 294 | }); |
| 295 | |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 296 | function getActiveElement() { |
| 297 | return Polymer.IronOverlayManager.deepActiveElement; |
| 298 | } |
| 299 | |
| 300 | function isVisible(el) { |
| 301 | assert.ok(el); |
| 302 | return getComputedStyle(el).getPropertyValue('display') != 'none'; |
| 303 | } |
| 304 | |
| 305 | function overlayObserver(mode) { |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 306 | return new Promise(resolve => { |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 307 | function listener() { |
| 308 | element.removeEventListener('iron-overlay-' + mode, listener); |
| 309 | resolve(); |
| 310 | } |
| 311 | element.addEventListener('iron-overlay-' + mode, listener); |
| 312 | }); |
| 313 | } |
| 314 | |
Dmitrii Filippov | 2b45976 | 2019-09-24 16:26:10 +0200 | [diff] [blame] | 315 | function isFocusInsideElement(element) { |
| 316 | // In Polymer 2 focused element either <paper-input> or nested |
| 317 | // native input <input> element depending on the current focus |
| 318 | // in browser window. |
| 319 | // For example, the focus is changed if the developer console |
| 320 | // get a focus. |
| 321 | let activeElement = getActiveElement(); |
| 322 | while (activeElement) { |
| 323 | if (activeElement === element) { |
| 324 | return true; |
| 325 | } |
| 326 | if (activeElement.parentElement) { |
| 327 | activeElement = activeElement.parentElement; |
| 328 | } else { |
| 329 | activeElement = activeElement.getRootNode().host; |
| 330 | } |
| 331 | } |
| 332 | return false; |
| 333 | } |
| 334 | |
Logan Hanks | 43d4dbb | 2016-12-14 18:17:47 -0800 | [diff] [blame] | 335 | function testConfirmationDialog(done, cc) { |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 336 | const yesButton = |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 337 | element.$$('.reviewerConfirmationButtons gr-button:first-child'); |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 338 | const noButton = |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 339 | element.$$('.reviewerConfirmationButtons gr-button:last-child'); |
| 340 | |
Logan Hanks | 43d4dbb | 2016-12-14 18:17:47 -0800 | [diff] [blame] | 341 | element._ccPendingConfirmation = null; |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 342 | element._reviewerPendingConfirmation = null; |
| 343 | flushAsynchronousOperations(); |
| 344 | assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay)); |
| 345 | |
| 346 | // Cause the confirmation dialog to display. |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 347 | let observer = overlayObserver('opened'); |
| 348 | const group = { |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 349 | id: 'id', |
| 350 | name: 'name', |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 351 | }; |
Logan Hanks | 43d4dbb | 2016-12-14 18:17:47 -0800 | [diff] [blame] | 352 | if (cc) { |
| 353 | element._ccPendingConfirmation = { |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 354 | group, |
Logan Hanks | 43d4dbb | 2016-12-14 18:17:47 -0800 | [diff] [blame] | 355 | count: 10, |
| 356 | }; |
| 357 | } else { |
| 358 | element._reviewerPendingConfirmation = { |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 359 | group, |
Logan Hanks | 43d4dbb | 2016-12-14 18:17:47 -0800 | [diff] [blame] | 360 | count: 10, |
| 361 | }; |
| 362 | } |
| 363 | flushAsynchronousOperations(); |
| 364 | |
| 365 | if (cc) { |
| 366 | assert.deepEqual( |
| 367 | element._ccPendingConfirmation, |
| 368 | element._pendingConfirmationDetails); |
| 369 | } else { |
| 370 | assert.deepEqual( |
| 371 | element._reviewerPendingConfirmation, |
| 372 | element._pendingConfirmationDetails); |
| 373 | } |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 374 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 375 | observer.then(() => { |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 376 | assert.isTrue(isVisible(element.$.reviewerConfirmationOverlay)); |
| 377 | observer = overlayObserver('closed'); |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 378 | const expected = 'Group name has 10 members'; |
Logan Hanks | 43d4dbb | 2016-12-14 18:17:47 -0800 | [diff] [blame] | 379 | assert.notEqual( |
| 380 | element.$.reviewerConfirmationOverlay.innerText.indexOf(expected), |
| 381 | -1); |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 382 | MockInteractions.tap(noButton); // close the overlay |
| 383 | return observer; |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 384 | }).then(() => { |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 385 | assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay)); |
| 386 | |
| 387 | // We should be focused on account entry input. |
Dmitrii Filippov | 2b45976 | 2019-09-24 16:26:10 +0200 | [diff] [blame] | 388 | assert.isTrue( |
| 389 | isFocusInsideElement(element.$.reviewers.$.entry.$.input.$.input)); |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 390 | |
Logan Hanks | 43d4dbb | 2016-12-14 18:17:47 -0800 | [diff] [blame] | 391 | // No reviewer/CC should have been added. |
Tao Zhou | b5a5a3c | 2019-11-04 17:40:19 +0100 | [diff] [blame] | 392 | assert.equal(element.$.ccs.additions().length, 0); |
Logan Hanks | 43d4dbb | 2016-12-14 18:17:47 -0800 | [diff] [blame] | 393 | assert.equal(element.$.reviewers.additions().length, 0); |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 394 | |
| 395 | // Reopen confirmation dialog. |
| 396 | observer = overlayObserver('opened'); |
Logan Hanks | 43d4dbb | 2016-12-14 18:17:47 -0800 | [diff] [blame] | 397 | if (cc) { |
| 398 | element._ccPendingConfirmation = { |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 399 | group, |
Logan Hanks | 43d4dbb | 2016-12-14 18:17:47 -0800 | [diff] [blame] | 400 | count: 10, |
| 401 | }; |
| 402 | } else { |
| 403 | element._reviewerPendingConfirmation = { |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 404 | group, |
Logan Hanks | 43d4dbb | 2016-12-14 18:17:47 -0800 | [diff] [blame] | 405 | count: 10, |
| 406 | }; |
| 407 | } |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 408 | return observer; |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 409 | }).then(() => { |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 410 | assert.isTrue(isVisible(element.$.reviewerConfirmationOverlay)); |
| 411 | observer = overlayObserver('closed'); |
Becky Siegel | 8bb0934 | 2016-10-17 17:49:31 -0700 | [diff] [blame] | 412 | MockInteractions.tap(yesButton); // Confirm the group. |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 413 | return observer; |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 414 | }).then(() => { |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 415 | assert.isFalse(isVisible(element.$.reviewerConfirmationOverlay)); |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 416 | const additions = cc ? |
David Ostrovsky | 84b1a3a | 2020-01-04 13:41:34 +0100 | [diff] [blame] | 417 | element.$.ccs.additions() : |
Thomas Draebing | 6ff72df | 2019-12-27 10:58:03 +0100 | [diff] [blame] | 418 | element.$.reviewers.additions(); |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 419 | assert.deepEqual( |
Logan Hanks | 43d4dbb | 2016-12-14 18:17:47 -0800 | [diff] [blame] | 420 | additions, |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 421 | [ |
| 422 | { |
| 423 | group: { |
| 424 | id: 'id', |
| 425 | name: 'name', |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 426 | confirmed: true, |
| 427 | _group: true, |
| 428 | _pendingAdd: true, |
| 429 | }, |
| 430 | }, |
| 431 | ]); |
| 432 | |
| 433 | // We should be focused on account entry input. |
Dmitrii Filippov | 2b45976 | 2019-09-24 16:26:10 +0200 | [diff] [blame] | 434 | if (cc) { |
| 435 | assert.isTrue( |
| 436 | isFocusInsideElement(element.$.ccs.$.entry.$.input.$.input)); |
| 437 | } else { |
| 438 | assert.isTrue( |
| 439 | isFocusInsideElement(element.$.reviewers.$.entry.$.input.$.input)); |
| 440 | } |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 441 | }).then(done); |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 442 | } |
Logan Hanks | 43d4dbb | 2016-12-14 18:17:47 -0800 | [diff] [blame] | 443 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 444 | test('cc confirmation', done => { |
Logan Hanks | 43d4dbb | 2016-12-14 18:17:47 -0800 | [diff] [blame] | 445 | testConfirmationDialog(done, true); |
| 446 | }); |
| 447 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 448 | test('reviewer confirmation', done => { |
Logan Hanks | 43d4dbb | 2016-12-14 18:17:47 -0800 | [diff] [blame] | 449 | testConfirmationDialog(done, false); |
Logan Hanks | a008aa9 | 2016-07-22 10:31:12 -0700 | [diff] [blame] | 450 | }); |
Wyatt Allen | 4f4b3a7 | 2016-07-28 12:05:53 -0700 | [diff] [blame] | 451 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 452 | test('_getStorageLocation', () => { |
| 453 | const actual = element._getStorageLocation(); |
Wyatt Allen | 4f4b3a7 | 2016-07-28 12:05:53 -0700 | [diff] [blame] | 454 | assert.equal(actual.changeNum, changeNum); |
Wyatt Allen | e05392a | 2017-06-01 16:23:51 -0700 | [diff] [blame] | 455 | assert.equal(actual.patchNum, '@change'); |
Wyatt Allen | 4f4b3a7 | 2016-07-28 12:05:53 -0700 | [diff] [blame] | 456 | assert.equal(actual.path, '@change'); |
| 457 | }); |
| 458 | |
Becky Siegel | 9799415 | 2017-12-19 14:31:26 -0800 | [diff] [blame] | 459 | test('_reviewersMutated when account-text-change is fired from ccs', () => { |
Becky Siegel | 9799415 | 2017-12-19 14:31:26 -0800 | [diff] [blame] | 460 | flushAsynchronousOperations(); |
| 461 | assert.isFalse(element._reviewersMutated); |
Tao Zhou | b5a5a3c | 2019-11-04 17:40:19 +0100 | [diff] [blame] | 462 | assert.isTrue(element.$.ccs.allowAnyInput); |
Becky Siegel | 9799415 | 2017-12-19 14:31:26 -0800 | [diff] [blame] | 463 | assert.isFalse(element.$$('#reviewers').allowAnyInput); |
Tao Zhou | b5a5a3c | 2019-11-04 17:40:19 +0100 | [diff] [blame] | 464 | element.$.ccs.dispatchEvent(new CustomEvent('account-text-changed', |
Ole Rehmsen | c82baba | 2019-05-16 14:43:01 +0200 | [diff] [blame] | 465 | {bubbles: true, composed: true})); |
Becky Siegel | 9799415 | 2017-12-19 14:31:26 -0800 | [diff] [blame] | 466 | assert.isTrue(element._reviewersMutated); |
| 467 | }); |
| 468 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 469 | test('gets draft from storage on open', () => { |
| 470 | const storedDraft = 'hello world'; |
Wyatt Allen | 4f4b3a7 | 2016-07-28 12:05:53 -0700 | [diff] [blame] | 471 | getDraftCommentStub.returns({message: storedDraft}); |
| 472 | element.open(); |
| 473 | assert.isTrue(getDraftCommentStub.called); |
| 474 | assert.equal(element.draft, storedDraft); |
| 475 | }); |
| 476 | |
Wyatt Allen | 20592ec | 2017-11-15 14:26:57 -0800 | [diff] [blame] | 477 | test('gets draft from storage even when text is already present', () => { |
| 478 | const storedDraft = 'hello world'; |
| 479 | getDraftCommentStub.returns({message: storedDraft}); |
| 480 | element.draft = 'foo bar'; |
| 481 | element.open(); |
| 482 | assert.isTrue(getDraftCommentStub.called); |
| 483 | assert.equal(element.draft, storedDraft); |
| 484 | }); |
| 485 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 486 | test('blank if no stored draft', () => { |
Wyatt Allen | 4f4b3a7 | 2016-07-28 12:05:53 -0700 | [diff] [blame] | 487 | getDraftCommentStub.returns(null); |
Wyatt Allen | 20592ec | 2017-11-15 14:26:57 -0800 | [diff] [blame] | 488 | element.draft = 'foo bar'; |
Wyatt Allen | 4f4b3a7 | 2016-07-28 12:05:53 -0700 | [diff] [blame] | 489 | element.open(); |
| 490 | assert.isTrue(getDraftCommentStub.called); |
| 491 | assert.equal(element.draft, ''); |
| 492 | }); |
| 493 | |
Wyatt Allen | a77e851 | 2017-11-20 14:06:30 -0800 | [diff] [blame] | 494 | test('does not check stored draft when quote is present', () => { |
| 495 | const storedDraft = 'hello world'; |
| 496 | const quote = '> foo bar'; |
| 497 | getDraftCommentStub.returns({message: storedDraft}); |
| 498 | element.quote = quote; |
| 499 | element.open(); |
| 500 | assert.isFalse(getDraftCommentStub.called); |
| 501 | assert.equal(element.draft, quote); |
| 502 | assert.isNotOk(element.quote); |
| 503 | }); |
| 504 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 505 | test('updates stored draft on edits', () => { |
| 506 | const firstEdit = 'hello'; |
| 507 | const location = element._getStorageLocation(); |
Wyatt Allen | 4f4b3a7 | 2016-07-28 12:05:53 -0700 | [diff] [blame] | 508 | |
| 509 | element.draft = firstEdit; |
| 510 | element.flushDebouncer('store'); |
| 511 | |
| 512 | assert.isTrue(setDraftCommentStub.calledWith(location, firstEdit)); |
| 513 | |
| 514 | element.draft = ''; |
| 515 | element.flushDebouncer('store'); |
| 516 | |
| 517 | assert.isTrue(eraseDraftCommentStub.calledWith(location)); |
| 518 | }); |
Logan Hanks | f1063a2 | 2016-07-22 16:05:04 -0700 | [diff] [blame] | 519 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 520 | test('400 converts to human-readable server-error', done => { |
| 521 | sandbox.stub(window, 'fetch', () => { |
| 522 | const text = '....{"reviewers":{"id1":{"error":"first error"}},' + |
Logan Hanks | f1063a2 | 2016-07-22 16:05:04 -0700 | [diff] [blame] | 523 | '"ccs":{"id2":{"error":"second error"}}}'; |
Ben Rohlfs | 9bdbceb | 2019-07-03 17:06:52 +0200 | [diff] [blame] | 524 | return Promise.resolve(cloneableResponse(400, text)); |
Logan Hanks | f1063a2 | 2016-07-22 16:05:04 -0700 | [diff] [blame] | 525 | }); |
| 526 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 527 | element.addEventListener('server-error', event => { |
Logan Hanks | f1063a2 | 2016-07-22 16:05:04 -0700 | [diff] [blame] | 528 | if (event.target !== element) { |
| 529 | return; |
| 530 | } |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 531 | event.detail.response.text().then(body => { |
Logan Hanks | f1063a2 | 2016-07-22 16:05:04 -0700 | [diff] [blame] | 532 | assert.equal(body, 'first error, second error'); |
Wyatt Allen | e013aad | 2017-05-18 16:49:04 -0700 | [diff] [blame] | 533 | done(); |
Logan Hanks | f1063a2 | 2016-07-22 16:05:04 -0700 | [diff] [blame] | 534 | }); |
| 535 | }); |
Andrew Bonventre | efd0a53 | 2016-08-23 17:04:23 -0400 | [diff] [blame] | 536 | |
| 537 | // Async tick is needed because iron-selector content is distributed and |
| 538 | // distributed content requires an observer to be set up. |
Wyatt Allen | e013aad | 2017-05-18 16:49:04 -0700 | [diff] [blame] | 539 | flush(() => { element.send(); }); |
Logan Hanks | a75fb05 | 2016-08-01 13:23:38 -0700 | [diff] [blame] | 540 | }); |
Logan Hanks | f1063a2 | 2016-07-22 16:05:04 -0700 | [diff] [blame] | 541 | |
Ben Rohlfs | 9bdbceb | 2019-07-03 17:06:52 +0200 | [diff] [blame] | 542 | test('non-json 400 is treated as a normal server-error', done => { |
| 543 | sandbox.stub(window, 'fetch', () => { |
| 544 | const text = 'Comment validation error!'; |
| 545 | return Promise.resolve(cloneableResponse(400, text)); |
| 546 | }); |
| 547 | |
| 548 | element.addEventListener('server-error', event => { |
| 549 | if (event.target !== element) { |
| 550 | return; |
| 551 | } |
| 552 | event.detail.response.text().then(body => { |
| 553 | assert.equal(body, 'Comment validation error!'); |
| 554 | done(); |
| 555 | }); |
| 556 | }); |
| 557 | |
| 558 | // Async tick is needed because iron-selector content is distributed and |
| 559 | // distributed content requires an observer to be set up. |
| 560 | flush(() => { element.send(); }); |
| 561 | }); |
| 562 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 563 | test('filterReviewerSuggestion', () => { |
| 564 | const owner = makeAccount(); |
| 565 | const reviewer1 = makeAccount(); |
| 566 | const reviewer2 = makeGroup(); |
| 567 | const cc1 = makeAccount(); |
| 568 | const cc2 = makeGroup(); |
Kasper Nilsson | d589671 | 2017-06-01 17:59:02 -0700 | [diff] [blame] | 569 | let filter = element._filterReviewerSuggestionGenerator(false); |
Logan Hanks | a75fb05 | 2016-08-01 13:23:38 -0700 | [diff] [blame] | 570 | |
| 571 | element._owner = owner; |
| 572 | element._reviewers = [reviewer1, reviewer2]; |
| 573 | element._ccs = [cc1, cc2]; |
| 574 | |
Kasper Nilsson | d589671 | 2017-06-01 17:59:02 -0700 | [diff] [blame] | 575 | assert.isTrue(filter({account: makeAccount()})); |
| 576 | assert.isTrue(filter({group: makeGroup()})); |
Logan Hanks | a75fb05 | 2016-08-01 13:23:38 -0700 | [diff] [blame] | 577 | |
| 578 | // Owner should be excluded. |
Kasper Nilsson | d589671 | 2017-06-01 17:59:02 -0700 | [diff] [blame] | 579 | assert.isFalse(filter({account: owner})); |
Logan Hanks | a75fb05 | 2016-08-01 13:23:38 -0700 | [diff] [blame] | 580 | |
Kasper Nilsson | d589671 | 2017-06-01 17:59:02 -0700 | [diff] [blame] | 581 | // Existing and pending reviewers should be excluded when isCC = false. |
| 582 | assert.isFalse(filter({account: reviewer1})); |
| 583 | assert.isFalse(filter({group: reviewer2})); |
Logan Hanks | a75fb05 | 2016-08-01 13:23:38 -0700 | [diff] [blame] | 584 | |
Kasper Nilsson | d589671 | 2017-06-01 17:59:02 -0700 | [diff] [blame] | 585 | filter = element._filterReviewerSuggestionGenerator(true); |
| 586 | |
| 587 | // Existing and pending CCs should be excluded when isCC = true;. |
| 588 | assert.isFalse(filter({account: cc1})); |
| 589 | assert.isFalse(filter({group: cc2})); |
Logan Hanks | f1063a2 | 2016-07-22 16:05:04 -0700 | [diff] [blame] | 590 | }); |
Logan Hanks | fc57acc | 2016-08-05 13:54:50 -0700 | [diff] [blame] | 591 | |
Becky Siegel | b7b4145 | 2017-11-14 14:35:29 -0800 | [diff] [blame] | 592 | test('_focusOn', () => { |
Becky Siegel | afa8255 | 2017-11-17 15:59:39 -0800 | [diff] [blame] | 593 | sandbox.spy(element, '_chooseFocusTarget'); |
Becky Siegel | b7b4145 | 2017-11-14 14:35:29 -0800 | [diff] [blame] | 594 | flushAsynchronousOperations(); |
| 595 | const textareaStub = sandbox.stub(element.$.textarea, 'async'); |
| 596 | const reviewerEntryStub = sandbox.stub(element.$.reviewers.focusStart, |
| 597 | 'async'); |
Tao Zhou | b5a5a3c | 2019-11-04 17:40:19 +0100 | [diff] [blame] | 598 | const ccStub = sandbox.stub(element.$.ccs.focusStart, 'async'); |
Becky Siegel | b7b4145 | 2017-11-14 14:35:29 -0800 | [diff] [blame] | 599 | element._focusOn(); |
| 600 | assert.equal(element._chooseFocusTarget.callCount, 1); |
Becky Siegel | afa8255 | 2017-11-17 15:59:39 -0800 | [diff] [blame] | 601 | assert.deepEqual(textareaStub.callCount, 1); |
Becky Siegel | b7b4145 | 2017-11-14 14:35:29 -0800 | [diff] [blame] | 602 | assert.deepEqual(reviewerEntryStub.callCount, 0); |
| 603 | assert.deepEqual(ccStub.callCount, 0); |
| 604 | |
| 605 | element._focusOn(element.FocusTarget.ANY); |
| 606 | assert.equal(element._chooseFocusTarget.callCount, 2); |
Becky Siegel | afa8255 | 2017-11-17 15:59:39 -0800 | [diff] [blame] | 607 | assert.deepEqual(textareaStub.callCount, 2); |
Becky Siegel | b7b4145 | 2017-11-14 14:35:29 -0800 | [diff] [blame] | 608 | assert.deepEqual(reviewerEntryStub.callCount, 0); |
| 609 | assert.deepEqual(ccStub.callCount, 0); |
| 610 | |
| 611 | element._focusOn(element.FocusTarget.BODY); |
| 612 | assert.equal(element._chooseFocusTarget.callCount, 2); |
Becky Siegel | afa8255 | 2017-11-17 15:59:39 -0800 | [diff] [blame] | 613 | assert.deepEqual(textareaStub.callCount, 3); |
Becky Siegel | b7b4145 | 2017-11-14 14:35:29 -0800 | [diff] [blame] | 614 | assert.deepEqual(reviewerEntryStub.callCount, 0); |
| 615 | assert.deepEqual(ccStub.callCount, 0); |
| 616 | |
| 617 | element._focusOn(element.FocusTarget.REVIEWERS); |
| 618 | assert.equal(element._chooseFocusTarget.callCount, 2); |
Becky Siegel | afa8255 | 2017-11-17 15:59:39 -0800 | [diff] [blame] | 619 | assert.deepEqual(textareaStub.callCount, 3); |
Becky Siegel | b7b4145 | 2017-11-14 14:35:29 -0800 | [diff] [blame] | 620 | assert.deepEqual(reviewerEntryStub.callCount, 1); |
| 621 | assert.deepEqual(ccStub.callCount, 0); |
| 622 | |
| 623 | element._focusOn(element.FocusTarget.CCS); |
| 624 | assert.equal(element._chooseFocusTarget.callCount, 2); |
Becky Siegel | afa8255 | 2017-11-17 15:59:39 -0800 | [diff] [blame] | 625 | assert.deepEqual(textareaStub.callCount, 3); |
Becky Siegel | b7b4145 | 2017-11-14 14:35:29 -0800 | [diff] [blame] | 626 | assert.deepEqual(reviewerEntryStub.callCount, 1); |
| 627 | assert.deepEqual(ccStub.callCount, 1); |
| 628 | }); |
| 629 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 630 | test('_chooseFocusTarget', () => { |
Logan Hanks | fc57acc | 2016-08-05 13:54:50 -0700 | [diff] [blame] | 631 | element._account = null; |
| 632 | assert.strictEqual( |
| 633 | element._chooseFocusTarget(), element.FocusTarget.BODY); |
| 634 | |
| 635 | element._account = {_account_id: 1}; |
| 636 | assert.strictEqual( |
| 637 | element._chooseFocusTarget(), element.FocusTarget.BODY); |
| 638 | |
| 639 | element.change.owner = {_account_id: 2}; |
| 640 | assert.strictEqual( |
| 641 | element._chooseFocusTarget(), element.FocusTarget.BODY); |
| 642 | |
| 643 | element.change.owner._account_id = 1; |
| 644 | element.change._reviewers = null; |
| 645 | assert.strictEqual( |
| 646 | element._chooseFocusTarget(), element.FocusTarget.REVIEWERS); |
| 647 | |
| 648 | element._reviewers = []; |
| 649 | assert.strictEqual( |
| 650 | element._chooseFocusTarget(), element.FocusTarget.REVIEWERS); |
| 651 | |
| 652 | element._reviewers.push({}); |
| 653 | assert.strictEqual( |
| 654 | element._chooseFocusTarget(), element.FocusTarget.BODY); |
| 655 | }); |
Logan Hanks | ca3c497 | 2016-09-14 16:25:56 -0700 | [diff] [blame] | 656 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 657 | test('only send labels that have changed', done => { |
| 658 | flush(() => { |
Logan Hanks | 02c781e | 2017-07-18 14:18:01 -0700 | [diff] [blame] | 659 | stubSaveReview(review => { |
Viktar Donich | 51bdb8d | 2017-07-14 11:39:24 -0700 | [diff] [blame] | 660 | assert.deepEqual(review.labels, { |
| 661 | 'Code-Review': 0, |
| 662 | 'Verified': -1, |
| 663 | }); |
Kasper Nilsson | 4416acd | 2016-09-16 13:27:11 -0700 | [diff] [blame] | 664 | }); |
Logan Hanks | ca3c497 | 2016-09-14 16:25:56 -0700 | [diff] [blame] | 665 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 666 | element.addEventListener('send', () => { |
Kasper Nilsson | 4416acd | 2016-09-16 13:27:11 -0700 | [diff] [blame] | 667 | done(); |
| 668 | }); |
| 669 | // Without wrapping this test in flush(), the below two calls to |
| 670 | // MockInteractions.tap() cause a race in some situations in shadow DOM. |
| 671 | // The send button can be tapped before the others, causing the test to |
| 672 | // fail. |
Becky Siegel | a499e3d | 2017-04-06 16:57:13 -0700 | [diff] [blame] | 673 | |
Becky Siegel | 6161393 | 2017-05-30 15:09:20 -0700 | [diff] [blame] | 674 | element.$$('gr-label-scores').$$( |
| 675 | 'gr-label-score-row[name="Verified"]').setSelectedValue(-1); |
Kasper Nilsson | 4416acd | 2016-09-16 13:27:11 -0700 | [diff] [blame] | 676 | MockInteractions.tap(element.$$('.send')); |
Logan Hanks | ca3c497 | 2016-09-14 16:25:56 -0700 | [diff] [blame] | 677 | }); |
Logan Hanks | ca3c497 | 2016-09-14 16:25:56 -0700 | [diff] [blame] | 678 | }); |
Becky Siegel | 8bb0934 | 2016-10-17 17:49:31 -0700 | [diff] [blame] | 679 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 680 | test('_processReviewerChange', () => { |
| 681 | const mockIndexSplices = function(toRemove) { |
Kasper Nilsson | a827155 | 2017-01-17 11:54:40 -0800 | [diff] [blame] | 682 | return [{ |
| 683 | removed: [toRemove], |
| 684 | }]; |
| 685 | }; |
| 686 | |
| 687 | element._processReviewerChange( |
| 688 | mockIndexSplices(makeAccount()), 'REVIEWER'); |
| 689 | assert.equal(element._reviewersPendingRemove.REVIEWER.length, 1); |
| 690 | }); |
| 691 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 692 | test('_purgeReviewersPendingRemove', () => { |
| 693 | const removeStub = sandbox.stub(element, '_removeAccount'); |
| 694 | const mock = function() { |
Kasper Nilsson | a827155 | 2017-01-17 11:54:40 -0800 | [diff] [blame] | 695 | element._reviewersPendingRemove = { |
| 696 | test: [makeAccount()], |
| 697 | test2: [makeAccount(), makeAccount()], |
| 698 | }; |
| 699 | }; |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 700 | const checkObjEmpty = function(obj) { |
| 701 | for (const prop in obj) { |
Kasper Nilsson | a827155 | 2017-01-17 11:54:40 -0800 | [diff] [blame] | 702 | if (obj.hasOwnProperty(prop) && obj[prop].length) { return false; } |
| 703 | } |
| 704 | return true; |
| 705 | }; |
| 706 | mock(); |
| 707 | element._purgeReviewersPendingRemove(true); // Cancel |
| 708 | assert.isFalse(removeStub.called); |
| 709 | assert.isTrue(checkObjEmpty(element._reviewersPendingRemove)); |
| 710 | |
| 711 | mock(); |
| 712 | element._purgeReviewersPendingRemove(false); // Submit |
| 713 | assert.isTrue(removeStub.called); |
| 714 | assert.isTrue(checkObjEmpty(element._reviewersPendingRemove)); |
| 715 | }); |
| 716 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 717 | test('_removeAccount', done => { |
Kasper Nilsson | a827155 | 2017-01-17 11:54:40 -0800 | [diff] [blame] | 718 | sandbox.stub(element.$.restAPI, 'removeChangeReviewer') |
| 719 | .returns(Promise.resolve({ok: true})); |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 720 | const arr = [makeAccount(), makeAccount()]; |
Kasper Nilsson | a827155 | 2017-01-17 11:54:40 -0800 | [diff] [blame] | 721 | element.change.reviewers = { |
| 722 | REVIEWER: arr.slice(), |
| 723 | }; |
| 724 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 725 | element._removeAccount(arr[1], 'REVIEWER').then(() => { |
Kasper Nilsson | a827155 | 2017-01-17 11:54:40 -0800 | [diff] [blame] | 726 | assert.equal(element.change.reviewers.REVIEWER.length, 1); |
| 727 | assert.deepEqual(element.change.reviewers.REVIEWER, arr.slice(0, 1)); |
| 728 | done(); |
| 729 | }); |
| 730 | }); |
Logan Hanks | 64451c0 | 2017-03-22 13:39:40 -0700 | [diff] [blame] | 731 | |
Kasper Nilsson | d589671 | 2017-06-01 17:59:02 -0700 | [diff] [blame] | 732 | test('moving from cc to reviewer', () => { |
Kasper Nilsson | d589671 | 2017-06-01 17:59:02 -0700 | [diff] [blame] | 733 | element._reviewersPendingRemove = { |
| 734 | CC: [], |
| 735 | REVIEWER: [], |
| 736 | }; |
| 737 | flushAsynchronousOperations(); |
| 738 | |
| 739 | const reviewer1 = makeAccount(); |
| 740 | const reviewer2 = makeAccount(); |
| 741 | const reviewer3 = makeAccount(); |
| 742 | const cc1 = makeAccount(); |
| 743 | const cc2 = makeAccount(); |
| 744 | const cc3 = makeAccount(); |
| 745 | const cc4 = makeAccount(); |
| 746 | element._reviewers = [reviewer1, reviewer2, reviewer3]; |
| 747 | element._ccs = [cc1, cc2, cc3, cc4]; |
| 748 | element.push('_reviewers', cc1); |
| 749 | flushAsynchronousOperations(); |
| 750 | |
| 751 | assert.deepEqual(element._reviewers, |
| 752 | [reviewer1, reviewer2, reviewer3, cc1]); |
| 753 | assert.deepEqual(element._ccs, [cc2, cc3, cc4]); |
| 754 | assert.deepEqual(element._reviewersPendingRemove.CC, [cc1]); |
| 755 | |
| 756 | element.push('_reviewers', cc4, cc3); |
| 757 | flushAsynchronousOperations(); |
| 758 | |
| 759 | assert.deepEqual(element._reviewers, |
| 760 | [reviewer1, reviewer2, reviewer3, cc1, cc4, cc3]); |
| 761 | assert.deepEqual(element._ccs, [cc2]); |
| 762 | assert.deepEqual(element._reviewersPendingRemove.CC, [cc1, cc4, cc3]); |
| 763 | }); |
| 764 | |
Milutin Kristofic | f6ccd41 | 2019-09-16 14:29:27 +0200 | [diff] [blame] | 765 | test('moving from reviewer to cc', () => { |
| 766 | element._reviewersPendingRemove = { |
| 767 | CC: [], |
| 768 | REVIEWER: [], |
| 769 | }; |
| 770 | flushAsynchronousOperations(); |
| 771 | |
| 772 | const reviewer1 = makeAccount(); |
| 773 | const reviewer2 = makeAccount(); |
| 774 | const reviewer3 = makeAccount(); |
| 775 | const cc1 = makeAccount(); |
| 776 | const cc2 = makeAccount(); |
| 777 | const cc3 = makeAccount(); |
| 778 | const cc4 = makeAccount(); |
| 779 | element._reviewers = [reviewer1, reviewer2, reviewer3]; |
| 780 | element._ccs = [cc1, cc2, cc3, cc4]; |
| 781 | element.push('_ccs', reviewer1); |
| 782 | flushAsynchronousOperations(); |
| 783 | |
| 784 | assert.deepEqual(element._reviewers, |
| 785 | [reviewer2, reviewer3]); |
| 786 | assert.deepEqual(element._ccs, [cc1, cc2, cc3, cc4, reviewer1]); |
| 787 | assert.deepEqual(element._reviewersPendingRemove.REVIEWER, [reviewer1]); |
| 788 | |
| 789 | element.push('_ccs', reviewer3, reviewer2); |
| 790 | flushAsynchronousOperations(); |
| 791 | |
| 792 | assert.deepEqual(element._reviewers, []); |
| 793 | assert.deepEqual(element._ccs, |
| 794 | [cc1, cc2, cc3, cc4, reviewer1, reviewer3, reviewer2]); |
| 795 | assert.deepEqual(element._reviewersPendingRemove.REVIEWER, |
| 796 | [reviewer1, reviewer3, reviewer2]); |
| 797 | }); |
| 798 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 799 | test('migrate reviewers between states', done => { |
Logan Hanks | 64451c0 | 2017-03-22 13:39:40 -0700 | [diff] [blame] | 800 | element._reviewersPendingRemove = { |
| 801 | CC: [], |
| 802 | REVIEWER: [], |
| 803 | }; |
| 804 | flushAsynchronousOperations(); |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 805 | const reviewers = element.$.reviewers; |
Tao Zhou | b5a5a3c | 2019-11-04 17:40:19 +0100 | [diff] [blame] | 806 | const ccs = element.$.ccs; |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 807 | const reviewer1 = makeAccount(); |
| 808 | const reviewer2 = makeAccount(); |
| 809 | const cc1 = makeAccount(); |
| 810 | const cc2 = makeAccount(); |
Kasper Nilsson | 7591ceb | 2017-05-12 16:16:53 -0700 | [diff] [blame] | 811 | const cc3 = makeAccount(); |
Logan Hanks | 64451c0 | 2017-03-22 13:39:40 -0700 | [diff] [blame] | 812 | element._reviewers = [reviewer1, reviewer2]; |
Kasper Nilsson | 7591ceb | 2017-05-12 16:16:53 -0700 | [diff] [blame] | 813 | element._ccs = [cc1, cc2, cc3]; |
Logan Hanks | 64451c0 | 2017-03-22 13:39:40 -0700 | [diff] [blame] | 814 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 815 | const mutations = []; |
Logan Hanks | 64451c0 | 2017-03-22 13:39:40 -0700 | [diff] [blame] | 816 | |
Logan Hanks | 02c781e | 2017-07-18 14:18:01 -0700 | [diff] [blame] | 817 | stubSaveReview(review => mutations.push(...review.reviewers)); |
Logan Hanks | 64451c0 | 2017-03-22 13:39:40 -0700 | [diff] [blame] | 818 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 819 | sandbox.stub(element, '_removeAccount', (account, type) => { |
| 820 | mutations.push({state: 'REMOVED', account}); |
Logan Hanks | 64451c0 | 2017-03-22 13:39:40 -0700 | [diff] [blame] | 821 | return Promise.resolve(); |
| 822 | }); |
| 823 | |
| 824 | // Remove and add to other field. |
| 825 | reviewers.fire('remove', {account: reviewer1}); |
| 826 | ccs.$.entry.fire('add', {value: {account: reviewer1}}); |
| 827 | ccs.fire('remove', {account: cc1}); |
Kasper Nilsson | 7591ceb | 2017-05-12 16:16:53 -0700 | [diff] [blame] | 828 | ccs.fire('remove', {account: cc3}); |
Logan Hanks | 64451c0 | 2017-03-22 13:39:40 -0700 | [diff] [blame] | 829 | reviewers.$.entry.fire('add', {value: {account: cc1}}); |
| 830 | |
| 831 | // Add to other field without removing from former field. |
| 832 | // (Currently not possible in UI, but this is a good consistency check). |
| 833 | reviewers.$.entry.fire('add', {value: {account: cc2}}); |
| 834 | ccs.$.entry.fire('add', {value: {account: reviewer2}}); |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 835 | const mapReviewer = function(reviewer, opt_state) { |
| 836 | const result = {reviewer: reviewer._account_id, confirmed: undefined}; |
Logan Hanks | 64451c0 | 2017-03-22 13:39:40 -0700 | [diff] [blame] | 837 | if (opt_state) { |
| 838 | result.state = opt_state; |
| 839 | } |
| 840 | return result; |
| 841 | }; |
| 842 | |
Kasper Nilsson | 7591ceb | 2017-05-12 16:16:53 -0700 | [diff] [blame] | 843 | // Send and purge and verify moves, delete cc3. |
Logan Hanks | 64451c0 | 2017-03-22 13:39:40 -0700 | [diff] [blame] | 844 | element.send() |
Kasper Nilsson | 7591ceb | 2017-05-12 16:16:53 -0700 | [diff] [blame] | 845 | .then(keepReviewers => |
Thomas Draebing | 6ff72df | 2019-12-27 10:58:03 +0100 | [diff] [blame] | 846 | element._purgeReviewersPendingRemove(false, keepReviewers)) |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 847 | .then(() => { |
| 848 | assert.deepEqual( |
| 849 | mutations, [ |
| 850 | mapReviewer(cc1), |
| 851 | mapReviewer(cc2), |
| 852 | mapReviewer(reviewer1, 'CC'), |
| 853 | mapReviewer(reviewer2, 'CC'), |
Kasper Nilsson | 7591ceb | 2017-05-12 16:16:53 -0700 | [diff] [blame] | 854 | {account: cc3, state: 'REMOVED'}, |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 855 | ]); |
| 856 | done(); |
| 857 | }); |
Logan Hanks | 64451c0 | 2017-03-22 13:39:40 -0700 | [diff] [blame] | 858 | }); |
Kasper Nilsson | ff0745d | 2017-03-21 16:41:24 -0700 | [diff] [blame] | 859 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 860 | test('emits cancel on esc key', () => { |
| 861 | const cancelHandler = sandbox.spy(); |
Kasper Nilsson | ff0745d | 2017-03-21 16:41:24 -0700 | [diff] [blame] | 862 | element.addEventListener('cancel', cancelHandler); |
| 863 | MockInteractions.pressAndReleaseKeyOn(element, 27, null, 'esc'); |
| 864 | flushAsynchronousOperations(); |
| 865 | |
| 866 | assert.isTrue(cancelHandler.called); |
| 867 | }); |
Logan Hanks | dc65dde | 2017-04-27 11:45:23 +0200 | [diff] [blame] | 868 | |
Mike Frysinger | 81b90bc | 2017-07-25 18:24:32 -0400 | [diff] [blame] | 869 | test('should not send on enter key', () => { |
Logan Hanks | 3e0917e | 2017-07-19 08:32:25 -0700 | [diff] [blame] | 870 | stubSaveReview(() => undefined); |
Mike Frysinger | 81b90bc | 2017-07-25 18:24:32 -0400 | [diff] [blame] | 871 | element.addEventListener('send', () => assert.fail('wrongly called')); |
| 872 | MockInteractions.pressAndReleaseKeyOn(element, 13, null, 'enter'); |
| 873 | flushAsynchronousOperations(); |
| 874 | }); |
| 875 | |
| 876 | test('emit send on ctrl+enter key', done => { |
Logan Hanks | 3e0917e | 2017-07-19 08:32:25 -0700 | [diff] [blame] | 877 | stubSaveReview(() => undefined); |
Mike Frysinger | 81b90bc | 2017-07-25 18:24:32 -0400 | [diff] [blame] | 878 | element.addEventListener('send', () => done()); |
| 879 | MockInteractions.pressAndReleaseKeyOn(element, 13, 'ctrl', 'enter'); |
| 880 | flushAsynchronousOperations(); |
| 881 | }); |
| 882 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 883 | test('_computeMessagePlaceholder', () => { |
Logan Hanks | dc65dde | 2017-04-27 11:45:23 +0200 | [diff] [blame] | 884 | assert.equal( |
| 885 | element._computeMessagePlaceholder(false), |
| 886 | 'Say something nice...'); |
| 887 | assert.equal( |
| 888 | element._computeMessagePlaceholder(true), |
| 889 | 'Add a note for your reviewers...'); |
| 890 | }); |
| 891 | |
Kasper Nilsson | ad908b1 | 2017-05-11 11:26:10 -0700 | [diff] [blame] | 892 | test('_computeSendButtonLabel', () => { |
Logan Hanks | dc65dde | 2017-04-27 11:45:23 +0200 | [diff] [blame] | 893 | assert.equal( |
| 894 | element._computeSendButtonLabel(false), |
| 895 | 'Send'); |
| 896 | assert.equal( |
| 897 | element._computeSendButtonLabel(true), |
| 898 | 'Start review'); |
| 899 | }); |
Wyatt Allen | e013aad | 2017-05-18 16:49:04 -0700 | [diff] [blame] | 900 | |
| 901 | test('_handle400Error reviewrs and CCs', done => { |
| 902 | const error1 = 'error 1'; |
| 903 | const error2 = 'error 2'; |
| 904 | const error3 = 'error 3'; |
Ben Rohlfs | 9bdbceb | 2019-07-03 17:06:52 +0200 | [diff] [blame] | 905 | const text = ')]}\'' + JSON.stringify({ |
| 906 | reviewers: { |
| 907 | username1: { |
| 908 | input: 'user 1', |
| 909 | error: error1, |
| 910 | }, |
| 911 | username2: { |
| 912 | input: 'user 2', |
| 913 | error: error2, |
| 914 | }, |
Kasper Nilsson | 5a93dbd | 2017-05-19 10:43:02 -0700 | [diff] [blame] | 915 | }, |
Ben Rohlfs | 9bdbceb | 2019-07-03 17:06:52 +0200 | [diff] [blame] | 916 | ccs: { |
| 917 | username3: { |
| 918 | input: 'user 3', |
| 919 | error: error3, |
| 920 | }, |
| 921 | }, |
| 922 | }); |
Wyatt Allen | e013aad | 2017-05-18 16:49:04 -0700 | [diff] [blame] | 923 | element.addEventListener('server-error', e => { |
| 924 | e.detail.response.text().then(text => { |
| 925 | assert.equal(text, [error1, error2, error3].join(', ')); |
| 926 | done(); |
Kasper Nilsson | 5a93dbd | 2017-05-19 10:43:02 -0700 | [diff] [blame] | 927 | }); |
Wyatt Allen | e013aad | 2017-05-18 16:49:04 -0700 | [diff] [blame] | 928 | }); |
Ben Rohlfs | 9bdbceb | 2019-07-03 17:06:52 +0200 | [diff] [blame] | 929 | element._handle400Error(cloneableResponse(400, text)); |
Wyatt Allen | e013aad | 2017-05-18 16:49:04 -0700 | [diff] [blame] | 930 | }); |
| 931 | |
| 932 | test('_handle400Error CCs only', done => { |
| 933 | const error1 = 'error 1'; |
Ben Rohlfs | 9bdbceb | 2019-07-03 17:06:52 +0200 | [diff] [blame] | 934 | const text = ')]}\'' + JSON.stringify({ |
| 935 | ccs: { |
| 936 | username1: { |
| 937 | input: 'user 1', |
| 938 | error: error1, |
| 939 | }, |
Kasper Nilsson | 5a93dbd | 2017-05-19 10:43:02 -0700 | [diff] [blame] | 940 | }, |
Ben Rohlfs | 9bdbceb | 2019-07-03 17:06:52 +0200 | [diff] [blame] | 941 | }); |
Wyatt Allen | e013aad | 2017-05-18 16:49:04 -0700 | [diff] [blame] | 942 | element.addEventListener('server-error', e => { |
| 943 | e.detail.response.text().then(text => { |
| 944 | assert.equal(text, error1); |
| 945 | done(); |
Kasper Nilsson | 5a93dbd | 2017-05-19 10:43:02 -0700 | [diff] [blame] | 946 | }); |
Wyatt Allen | e013aad | 2017-05-18 16:49:04 -0700 | [diff] [blame] | 947 | }); |
Ben Rohlfs | 9bdbceb | 2019-07-03 17:06:52 +0200 | [diff] [blame] | 948 | element._handle400Error(cloneableResponse(400, text)); |
Wyatt Allen | e013aad | 2017-05-18 16:49:04 -0700 | [diff] [blame] | 949 | }); |
Logan Hanks | 68b082e | 2017-07-13 14:19:13 -0700 | [diff] [blame] | 950 | |
Wyatt Allen | f5d2d79 | 2017-08-14 11:53:19 -0700 | [diff] [blame] | 951 | test('fires height change when the drafts load', done => { |
| 952 | // Flush DOM operations before binding to the autogrow event so we don't |
| 953 | // catch the events fired from the initial layout. |
| 954 | flush(() => { |
| 955 | const autoGrowHandler = sinon.stub(); |
| 956 | element.addEventListener('autogrow', autoGrowHandler); |
| 957 | element.diffDrafts = {}; |
| 958 | flush(() => { |
| 959 | assert.isTrue(autoGrowHandler.called); |
| 960 | done(); |
| 961 | }); |
| 962 | }); |
| 963 | }); |
| 964 | |
Logan Hanks | 02c781e | 2017-07-18 14:18:01 -0700 | [diff] [blame] | 965 | suite('post review API', () => { |
| 966 | let startReviewStub; |
Logan Hanks | 68b082e | 2017-07-13 14:19:13 -0700 | [diff] [blame] | 967 | |
Logan Hanks | 02c781e | 2017-07-18 14:18:01 -0700 | [diff] [blame] | 968 | setup(() => { |
Logan Hanks | 3e0917e | 2017-07-19 08:32:25 -0700 | [diff] [blame] | 969 | startReviewStub = sandbox.stub(element.$.restAPI, 'startReview', () => { |
| 970 | return Promise.resolve(); |
| 971 | }); |
Logan Hanks | 02c781e | 2017-07-18 14:18:01 -0700 | [diff] [blame] | 972 | }); |
| 973 | |
| 974 | test('ready property in review input on start review', () => { |
| 975 | stubSaveReview(review => { |
| 976 | assert.isTrue(review.ready); |
| 977 | return {ready: true}; |
| 978 | }); |
| 979 | return element.send(true, true).then(() => { |
| 980 | assert.isFalse(startReviewStub.called); |
| 981 | }); |
| 982 | }); |
| 983 | |
| 984 | test('no ready property in review input on save review', () => { |
| 985 | stubSaveReview(review => { |
| 986 | assert.isUndefined(review.ready); |
Logan Hanks | 02c781e | 2017-07-18 14:18:01 -0700 | [diff] [blame] | 987 | }); |
| 988 | return element.send(true, false).then(() => { |
| 989 | assert.isFalse(startReviewStub.called); |
| 990 | }); |
| 991 | }); |
Logan Hanks | 68b082e | 2017-07-13 14:19:13 -0700 | [diff] [blame] | 992 | }); |
| 993 | |
Logan Hanks | 02c781e | 2017-07-18 14:18:01 -0700 | [diff] [blame] | 994 | suite('start review and save buttons', () => { |
| 995 | let sendStub; |
| 996 | |
Logan Hanks | 68b082e | 2017-07-13 14:19:13 -0700 | [diff] [blame] | 997 | setup(() => { |
Logan Hanks | 02c781e | 2017-07-18 14:18:01 -0700 | [diff] [blame] | 998 | sendStub = sandbox.stub(element, 'send', () => Promise.resolve()); |
Logan Hanks | 68b082e | 2017-07-13 14:19:13 -0700 | [diff] [blame] | 999 | element.canBeStarted = true; |
| 1000 | // Flush to make both Start/Save buttons appear in DOM. |
| 1001 | flushAsynchronousOperations(); |
| 1002 | }); |
| 1003 | |
| 1004 | test('start review sets ready', () => { |
| 1005 | MockInteractions.tap(element.$$('.send')); |
| 1006 | flushAsynchronousOperations(); |
Logan Hanks | 02c781e | 2017-07-18 14:18:01 -0700 | [diff] [blame] | 1007 | assert.isTrue(sendStub.calledWith(true, true)); |
Logan Hanks | 68b082e | 2017-07-13 14:19:13 -0700 | [diff] [blame] | 1008 | }); |
| 1009 | |
| 1010 | test('save review doesn\'t set ready', () => { |
| 1011 | MockInteractions.tap(element.$$('.save')); |
| 1012 | flushAsynchronousOperations(); |
Logan Hanks | 02c781e | 2017-07-18 14:18:01 -0700 | [diff] [blame] | 1013 | assert.isTrue(sendStub.calledWith(true, false)); |
Logan Hanks | 68b082e | 2017-07-13 14:19:13 -0700 | [diff] [blame] | 1014 | }); |
| 1015 | }); |
Logan Hanks | 3f1a6ff | 2017-07-25 11:05:23 -0700 | [diff] [blame] | 1016 | |
Logan Hanks | 3e0917e | 2017-07-19 08:32:25 -0700 | [diff] [blame] | 1017 | test('buttons disabled until all API calls are resolved', () => { |
| 1018 | stubSaveReview(review => { |
Tao Zhou | 9495320 | 2019-10-01 14:35:02 +0200 | [diff] [blame] | 1019 | return {ready: true}; |
Logan Hanks | 3e0917e | 2017-07-19 08:32:25 -0700 | [diff] [blame] | 1020 | }); |
| 1021 | return element.send(true, true).then(() => { |
| 1022 | assert.isFalse(element.disabled); |
| 1023 | }); |
| 1024 | }); |
| 1025 | |
| 1026 | suite('error handling', () => { |
| 1027 | const expectedDraft = 'draft'; |
| 1028 | const expectedError = new Error('test'); |
| 1029 | |
| 1030 | setup(() => { |
| 1031 | element.draft = expectedDraft; |
| 1032 | }); |
| 1033 | |
| 1034 | function assertDialogOpenAndEnabled() { |
| 1035 | assert.strictEqual(expectedDraft, element.draft); |
| 1036 | assert.isFalse(element.disabled); |
| 1037 | } |
| 1038 | |
Logan Hanks | 3e0917e | 2017-07-19 08:32:25 -0700 | [diff] [blame] | 1039 | test('error occurs in _saveReview', () => { |
| 1040 | stubSaveReview(review => { |
| 1041 | throw expectedError; |
| 1042 | }); |
| 1043 | return element.send(true, true).catch(err => { |
| 1044 | assert.strictEqual(expectedError, err); |
| 1045 | assertDialogOpenAndEnabled(); |
| 1046 | }); |
| 1047 | }); |
| 1048 | |
Kasper Nilsson | 6873549 | 2017-08-01 16:39:48 -0700 | [diff] [blame] | 1049 | suite('pending diff drafts?', () => { |
| 1050 | test('yes', () => { |
| 1051 | const promise = mockPromise(); |
| 1052 | const refreshHandler = sandbox.stub(); |
| 1053 | |
| 1054 | element.addEventListener('comment-refresh', refreshHandler); |
| 1055 | sandbox.stub(element.$.restAPI, 'hasPendingDiffDrafts').returns(true); |
| 1056 | element.$.restAPI._pendingRequests.sendDiffDraft = [promise]; |
| 1057 | element.open(); |
| 1058 | |
| 1059 | assert.isFalse(refreshHandler.called); |
| 1060 | assert.isTrue(element._savingComments); |
| 1061 | |
| 1062 | promise.resolve(); |
| 1063 | |
| 1064 | return element.$.restAPI.awaitPendingDiffDrafts().then(() => { |
| 1065 | assert.isTrue(refreshHandler.called); |
| 1066 | assert.isFalse(element._savingComments); |
| 1067 | }); |
| 1068 | }); |
| 1069 | |
| 1070 | test('no', () => { |
| 1071 | sandbox.stub(element.$.restAPI, 'hasPendingDiffDrafts').returns(false); |
| 1072 | element.open(); |
| 1073 | assert.notOk(element._savingComments); |
| 1074 | }); |
| 1075 | }); |
Logan Hanks | 3e0917e | 2017-07-19 08:32:25 -0700 | [diff] [blame] | 1076 | }); |
Kasper Nilsson | aa746bd | 2017-09-18 22:12:30 -0700 | [diff] [blame] | 1077 | |
| 1078 | test('_computeSendButtonDisabled', () => { |
| 1079 | const fn = element._computeSendButtonDisabled.bind(element); |
Tao Zhou | d2fca29 | 2019-08-12 18:53:02 +0200 | [diff] [blame] | 1080 | assert.isFalse(fn( |
| 1081 | /* buttonLabel= */ 'Start review', |
| 1082 | /* drafts= */ {}, |
| 1083 | /* text= */ '', |
| 1084 | /* reviewersMutated= */ false, |
| 1085 | /* labelsChanged= */ false, |
| 1086 | /* includeComments= */ false, |
David Pursehouse | 029bf46 | 2019-12-14 15:21:57 +0900 | [diff] [blame] | 1087 | /* disabled= */ false |
Tao Zhou | d2fca29 | 2019-08-12 18:53:02 +0200 | [diff] [blame] | 1088 | )); |
| 1089 | assert.isTrue(fn( |
| 1090 | /* buttonLabel= */ 'Send', |
| 1091 | /* drafts= */ {}, |
| 1092 | /* text= */ '', |
| 1093 | /* reviewersMutated= */ false, |
| 1094 | /* labelsChanged= */ false, |
| 1095 | /* includeComments= */ false, |
David Pursehouse | 029bf46 | 2019-12-14 15:21:57 +0900 | [diff] [blame] | 1096 | /* disabled= */ false |
Tao Zhou | d2fca29 | 2019-08-12 18:53:02 +0200 | [diff] [blame] | 1097 | )); |
Kasper Nilsson | 2eed3c3 | 2017-09-20 14:00:47 -0700 | [diff] [blame] | 1098 | // Mock nonempty comment draft array, with seding comments. |
Tao Zhou | d2fca29 | 2019-08-12 18:53:02 +0200 | [diff] [blame] | 1099 | assert.isFalse(fn( |
| 1100 | /* buttonLabel= */ 'Send', |
| 1101 | /* drafts= */ {file: ['draft']}, |
| 1102 | /* text= */ '', |
| 1103 | /* reviewersMutated= */ false, |
| 1104 | /* labelsChanged= */ false, |
| 1105 | /* includeComments= */ true, |
David Pursehouse | 029bf46 | 2019-12-14 15:21:57 +0900 | [diff] [blame] | 1106 | /* disabled= */ false |
Tao Zhou | d2fca29 | 2019-08-12 18:53:02 +0200 | [diff] [blame] | 1107 | )); |
Kasper Nilsson | 2eed3c3 | 2017-09-20 14:00:47 -0700 | [diff] [blame] | 1108 | // Mock nonempty comment draft array, without seding comments. |
Tao Zhou | d2fca29 | 2019-08-12 18:53:02 +0200 | [diff] [blame] | 1109 | assert.isTrue(fn( |
| 1110 | /* buttonLabel= */ 'Send', |
| 1111 | /* drafts= */ {file: ['draft']}, |
| 1112 | /* text= */ '', |
| 1113 | /* reviewersMutated= */ false, |
| 1114 | /* labelsChanged= */ false, |
| 1115 | /* includeComments= */ false, |
David Pursehouse | 029bf46 | 2019-12-14 15:21:57 +0900 | [diff] [blame] | 1116 | /* disabled= */ false |
Tao Zhou | d2fca29 | 2019-08-12 18:53:02 +0200 | [diff] [blame] | 1117 | )); |
Kasper Nilsson | aa746bd | 2017-09-18 22:12:30 -0700 | [diff] [blame] | 1118 | // Mock nonempty change message. |
Tao Zhou | d2fca29 | 2019-08-12 18:53:02 +0200 | [diff] [blame] | 1119 | assert.isFalse(fn( |
| 1120 | /* buttonLabel= */ 'Send', |
| 1121 | /* drafts= */ {}, |
| 1122 | /* text= */ 'test', |
| 1123 | /* reviewersMutated= */ false, |
| 1124 | /* labelsChanged= */ false, |
| 1125 | /* includeComments= */ false, |
David Pursehouse | 029bf46 | 2019-12-14 15:21:57 +0900 | [diff] [blame] | 1126 | /* disabled= */ false |
Tao Zhou | d2fca29 | 2019-08-12 18:53:02 +0200 | [diff] [blame] | 1127 | )); |
Kasper Nilsson | aa746bd | 2017-09-18 22:12:30 -0700 | [diff] [blame] | 1128 | // Mock reviewers mutated. |
Tao Zhou | d2fca29 | 2019-08-12 18:53:02 +0200 | [diff] [blame] | 1129 | assert.isFalse(fn( |
| 1130 | /* buttonLabel= */ 'Send', |
| 1131 | /* drafts= */ {}, |
| 1132 | /* text= */ '', |
| 1133 | /* reviewersMutated= */ true, |
| 1134 | /* labelsChanged= */ false, |
| 1135 | /* includeComments= */ false, |
David Pursehouse | 029bf46 | 2019-12-14 15:21:57 +0900 | [diff] [blame] | 1136 | /* disabled= */ false |
Tao Zhou | d2fca29 | 2019-08-12 18:53:02 +0200 | [diff] [blame] | 1137 | )); |
Kasper Nilsson | aa746bd | 2017-09-18 22:12:30 -0700 | [diff] [blame] | 1138 | // Mock labels changed. |
Tao Zhou | d2fca29 | 2019-08-12 18:53:02 +0200 | [diff] [blame] | 1139 | assert.isFalse(fn( |
| 1140 | /* buttonLabel= */ 'Send', |
| 1141 | /* drafts= */ {}, |
| 1142 | /* text= */ '', |
| 1143 | /* reviewersMutated= */ false, |
| 1144 | /* labelsChanged= */ true, |
| 1145 | /* includeComments= */ false, |
David Pursehouse | 029bf46 | 2019-12-14 15:21:57 +0900 | [diff] [blame] | 1146 | /* disabled= */ false |
Tao Zhou | d2fca29 | 2019-08-12 18:53:02 +0200 | [diff] [blame] | 1147 | )); |
Kasper Nilsson | 06864f0 | 2018-05-03 14:10:17 -0700 | [diff] [blame] | 1148 | // Whole dialog is disabled. |
Tao Zhou | d2fca29 | 2019-08-12 18:53:02 +0200 | [diff] [blame] | 1149 | assert.isTrue(fn( |
| 1150 | /* buttonLabel= */ 'Send', |
| 1151 | /* drafts= */ {}, |
| 1152 | /* text= */ '', |
| 1153 | /* reviewersMutated= */ false, |
| 1154 | /* labelsChanged= */ true, |
| 1155 | /* includeComments= */ false, |
David Pursehouse | 029bf46 | 2019-12-14 15:21:57 +0900 | [diff] [blame] | 1156 | /* disabled= */ true |
Tao Zhou | d2fca29 | 2019-08-12 18:53:02 +0200 | [diff] [blame] | 1157 | )); |
Kasper Nilsson | aa746bd | 2017-09-18 22:12:30 -0700 | [diff] [blame] | 1158 | }); |
Viktar Donich | 3ae72b3 | 2018-02-28 14:41:58 -0800 | [diff] [blame] | 1159 | |
Kasper Nilsson | fb54dc6 | 2018-03-26 13:57:57 -0700 | [diff] [blame] | 1160 | test('_submit blocked when no mutations exist', () => { |
| 1161 | const sendStub = sandbox.stub(element, 'send').returns(Promise.resolve()); |
| 1162 | // Stub the below function to avoid side effects from the send promise |
| 1163 | // resolving. |
| 1164 | sandbox.stub(element, '_purgeReviewersPendingRemove'); |
| 1165 | element.diffDrafts = {}; |
| 1166 | flushAsynchronousOperations(); |
| 1167 | |
| 1168 | MockInteractions.tap(element.$$('gr-button.send')); |
| 1169 | assert.isFalse(sendStub.called); |
| 1170 | |
Dmitrii Filippov | 0998cfa | 2019-11-12 10:47:06 +0100 | [diff] [blame] | 1171 | element.diffDrafts = {test: [{val: true}]}; |
Kasper Nilsson | fb54dc6 | 2018-03-26 13:57:57 -0700 | [diff] [blame] | 1172 | flushAsynchronousOperations(); |
| 1173 | |
| 1174 | MockInteractions.tap(element.$$('gr-button.send')); |
| 1175 | assert.isTrue(sendStub.called); |
| 1176 | }); |
| 1177 | |
| 1178 | test('getFocusStops', () => { |
| 1179 | // Setting diffDrafts to an empty object causes _sendDisabled to be |
| 1180 | // computed to false. |
| 1181 | element.diffDrafts = {}; |
| 1182 | assert.equal(element.getFocusStops().end, element.$.cancelButton); |
Dmitrii Filippov | 0998cfa | 2019-11-12 10:47:06 +0100 | [diff] [blame] | 1183 | element.diffDrafts = {test: [{val: true}]}; |
Kasper Nilsson | fb54dc6 | 2018-03-26 13:57:57 -0700 | [diff] [blame] | 1184 | assert.equal(element.getFocusStops().end, element.$.sendButton); |
| 1185 | }); |
| 1186 | |
Viktar Donich | 3ae72b3 | 2018-02-28 14:41:58 -0800 | [diff] [blame] | 1187 | test('setPluginMessage', () => { |
| 1188 | element.setPluginMessage('foo'); |
| 1189 | assert.equal(element.$.pluginMessage.textContent, 'foo'); |
| 1190 | }); |
Andrew Bonventre | f8b026d | 2015-12-09 17:55:54 -0500 | [diff] [blame] | 1191 | }); |
Dmitrii Filippov | 2b45976 | 2019-09-24 16:26:10 +0200 | [diff] [blame] | 1192 | </script> |