blob: 66ef3abf542d326905ca23644e67e01ee150b8af [file] [log] [blame]
Dmitrii Filippovacd39a22020-04-02 10:31:43 +02001/**
2 * @license
Ben Rohlfs94fcbbc2022-05-27 10:45:03 +02003 * Copyright 2015 Google LLC
4 * SPDX-License-Identifier: Apache-2.0
Dmitrii Filippovacd39a22020-04-02 10:31:43 +02005 */
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01006import '../../../test/common-test-setup-karma';
7import '../../edit/gr-edit-constants';
Dhruv Srivastavab213a1f2021-11-19 14:45:40 +01008import '../gr-thread-list/gr-thread-list';
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01009import './gr-change-view';
Dmitrii Filippov0695d402020-10-22 16:57:57 +020010import {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +010011 ChangeStatus,
12 CommentSide,
13 DefaultBase,
14 DiffViewMode,
15 HttpMethod,
Dhruv Srivastava69a51732021-04-14 18:23:00 +020016 MessageTag,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +010017 PrimaryTab,
Dhruv Srivastava80d34f42021-10-18 16:45:02 +020018 createDefaultPreferences,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +010019} from '../../../constants/constants';
20import {GrEditConstants} from '../../edit/gr-edit-constants';
21import {_testOnly_resetEndpoints} from '../../shared/gr-js-api-interface/gr-plugin-endpoints';
Ben Rohlfsebe4acc2020-12-11 21:16:10 +010022import {GerritNav} from '../../core/gr-navigation/gr-navigation';
Dmitrii Filippov78448cd2020-10-26 17:39:11 +010023import {getPluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader';
Ben Rohlfsa7ab9502021-02-15 17:45:45 +010024import {EventType, PluginApi} from '../../../api/plugin';
Ben Rohlfs00049652021-10-25 16:40:38 +020025import {
26 mockPromise,
27 queryAndAssert,
28 stubRestApi,
29 stubUsers,
30 waitQueryAndAssert,
31 waitUntil,
32} from '../../../test/test-utils';
Dmitrii Filippov78448cd2020-10-26 17:39:11 +010033import {
34 createAppElementChangeViewParams,
35 createApproval,
Dmitrii Filippov0695d402020-10-22 16:57:57 +020036 createChange,
37 createChangeMessages,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +010038 createCommit,
39 createMergeable,
40 createPreferences,
41 createRevision,
Dmitrii Filippov0695d402020-10-22 16:57:57 +020042 createRevisions,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +010043 createServerInfo,
44 createUserConfig,
45 TEST_NUMERIC_CHANGE_ID,
46 TEST_PROJECT_NAME,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +010047 createEditRevision,
48 createAccountWithIdNameAndEmail,
Dhruv Srivastavada276592021-04-07 14:51:51 +020049 createChangeViewChange,
Milutin Kristofice9ddfa42021-04-20 23:34:45 +020050 createRelatedChangeAndCommitInfo,
Dhruv Srivastava8e1e2b22021-09-30 12:17:55 +010051 createAccountDetailWithId,
Ben Rohlfsa16c51a2021-11-22 12:50:55 +010052 createParsedChange,
Chris Poucet973ecc92022-06-13 10:44:07 +020053 createDraft,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +010054} from '../../../test/test-data-generators';
Chris Poucet973ecc92022-06-13 10:44:07 +020055import {GrChangeView} from './gr-change-view';
Dmitrii Filippov78448cd2020-10-26 17:39:11 +010056import {
57 AccountId,
58 ApprovalInfo,
Dhruv Srivastava591b4902021-03-10 11:48:12 +010059 BasePatchSetNum,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +010060 ChangeId,
61 ChangeInfo,
62 CommitId,
Ben Rohlfsef043172022-05-27 16:07:27 +020063 EDIT,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +010064 NumericChangeId,
Ben Rohlfs58267b72022-05-27 15:59:18 +020065 PARENT,
Milutin Kristofice9ddfa42021-04-20 23:34:45 +020066 RelatedChangeAndCommitInfo,
Dhruv Srivastava69a51732021-04-14 18:23:00 +020067 ReviewInputTag,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +010068 RevisionInfo,
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +010069 RevisionPatchSetNum,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +010070 RobotId,
Ben Rohlfs05750b92021-10-29 08:23:08 +020071 RobotCommentInfo,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +010072 Timestamp,
73 UrlEncodedCommentId,
Chris Poucet973ecc92022-06-13 10:44:07 +020074 DetailedLabelInfo,
75 RepoName,
76 QuickLabelInfo,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +010077} from '../../../types/common';
78import {
79 pressAndReleaseKeyOn,
80 tap,
81} from '@polymer/iron-test-helpers/mock-interactions';
82import {GrEditControls} from '../../edit/gr-edit-controls/gr-edit-controls';
83import {AppElementChangeViewParams} from '../../gr-app-types';
Ben Rohlfs8e28ad82021-09-20 14:48:33 +020084import {SinonFakeTimers, SinonStubbedMember} from 'sinon';
Ben Rohlfsa9d2cff2021-01-22 21:33:58 +010085import {RestApiService} from '../../../services/gr-rest-api/gr-rest-api';
Ben Rohlfs05750b92021-10-29 08:23:08 +020086import {CommentThread} from '../../../utils/comment-util';
Ben Rohlfsebe4acc2020-12-11 21:16:10 +010087import {GerritView} from '../../../services/router/router-model';
Ben Rohlfsa00ef282021-01-22 21:45:53 +010088import {ParsedChangeInfo} from '../../../types/types';
Milutin Kristofic8803ea02020-12-09 23:34:39 +010089import {GrRelatedChangesList} from '../gr-related-changes-list/gr-related-changes-list';
Dhruv Srivastava69a51732021-04-14 18:23:00 +020090import {ChangeStates} from '../../shared/gr-change-status/gr-change-status';
Chris Poucetbf65b8f2022-01-18 21:18:12 +000091import {LoadingStatus} from '../../../models/change/change-model';
Ben Rohlfs00049652021-10-25 16:40:38 +020092import {FocusTarget, GrReplyDialog} from '../gr-reply-dialog/gr-reply-dialog';
93import {GrOverlay} from '../../shared/gr-overlay/gr-overlay';
Paladox none70efbef2021-08-12 05:21:59 +000094import {GrChangeStar} from '../../shared/gr-change-star/gr-change-star';
Dhruv Srivastavab213a1f2021-11-19 14:45:40 +010095import {GrThreadList} from '../gr-thread-list/gr-thread-list';
Chris Poucetdd2d0102022-05-13 14:09:39 +020096import {assertIsDefined} from '../../../utils/common-util';
Dhruv47c21d12022-06-07 16:37:52 +020097import {DEFAULT_NUM_FILES_SHOWN} from '../gr-file-list/gr-file-list';
Chris Poucet973ecc92022-06-13 10:44:07 +020098import {fixture, html} from '@open-wc/testing-helpers';
99import {deepClone} from '../../../utils/deep-util';
Dmitrii Filippov0028b582020-03-24 11:58:55 +0100100
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100101suite('gr-change-view tests', () => {
102 let element: GrChangeView;
103
Frank Borden6988bdf2021-04-07 14:42:00 +0200104 let navigateToChangeStub: SinonStubbedMember<
105 typeof GerritNav.navigateToChange
106 >;
Dmitrii Filippov06117e82020-06-25 13:26:55 +0200107
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100108 const ROBOT_COMMENTS_LIMIT = 10;
109
Tao Zhou18738b92020-05-04 19:44:51 +0200110 // TODO: should have a mock service to generate VALID fake data
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100111 const THREADS: CommentThread[] = [
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100112 {
113 comments: [
114 {
Dhruv Srivastava3dfaf362020-12-01 21:53:59 +0100115 path: '/COMMIT_MSG',
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100116 author: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100117 _account_id: 1000000 as AccountId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100118 name: 'user',
119 username: 'user',
120 },
Ben Rohlfsabaeacf2022-05-27 15:24:22 +0200121 patch_set: 2 as RevisionPatchSetNum,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100122 robot_id: 'rb1' as RobotId,
123 id: 'ecf0b9fa_fe1a5f62' as UrlEncodedCommentId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100124 line: 5,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100125 updated: '2018-02-08 18:49:18.000000000' as Timestamp,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100126 message: 'test',
127 unresolved: true,
128 },
129 {
Dhruv Srivastava3dfaf362020-12-01 21:53:59 +0100130 path: '/COMMIT_MSG',
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100131 author: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100132 _account_id: 1000000 as AccountId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100133 name: 'user',
134 username: 'user',
135 },
Ben Rohlfsabaeacf2022-05-27 15:24:22 +0200136 patch_set: 4 as RevisionPatchSetNum,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100137 id: 'ecf0b9fa_fe1a5f62_1' as UrlEncodedCommentId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100138 line: 5,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100139 updated: '2018-02-08 18:49:18.000000000' as Timestamp,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100140 message: 'test',
141 unresolved: true,
142 },
143 {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100144 id: '503008e2_0ab203ee' as UrlEncodedCommentId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100145 path: '/COMMIT_MSG',
146 line: 5,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100147 in_reply_to: 'ecf0b9fa_fe1a5f62' as UrlEncodedCommentId,
148 updated: '2018-02-13 22:48:48.018000000' as Timestamp,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100149 message: 'draft',
150 unresolved: false,
151 __draft: true,
Ben Rohlfsabaeacf2022-05-27 15:24:22 +0200152 patch_set: 2 as RevisionPatchSetNum,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100153 },
154 ],
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +0100155 patchNum: 4 as RevisionPatchSetNum,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100156 path: '/COMMIT_MSG',
157 line: 5,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100158 rootId: 'ecf0b9fa_fe1a5f62' as UrlEncodedCommentId,
Dhruv Srivastava794db3a2020-11-11 11:28:08 +0100159 commentSide: CommentSide.REVISION,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100160 },
161 {
162 comments: [
163 {
Dhruv Srivastava3dfaf362020-12-01 21:53:59 +0100164 path: '/COMMIT_MSG',
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100165 author: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100166 _account_id: 1000000 as AccountId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100167 name: 'user',
168 username: 'user',
169 },
Ben Rohlfsabaeacf2022-05-27 15:24:22 +0200170 patch_set: 3 as RevisionPatchSetNum,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100171 id: 'ecf0b9fa_fe5f62' as UrlEncodedCommentId,
172 robot_id: 'rb2' as RobotId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100173 line: 5,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100174 updated: '2018-02-08 18:49:18.000000000' as Timestamp,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100175 message: 'test',
176 unresolved: true,
177 },
178 {
Dhruv Srivastava3dfaf362020-12-01 21:53:59 +0100179 path: 'test.txt',
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100180 author: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100181 _account_id: 1000000 as AccountId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100182 name: 'user',
183 username: 'user',
184 },
Ben Rohlfsabaeacf2022-05-27 15:24:22 +0200185 patch_set: 3 as RevisionPatchSetNum,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100186 id: '09a9fb0a_1484e6cf' as UrlEncodedCommentId,
187 side: CommentSide.PARENT,
188 updated: '2018-02-13 22:47:19.000000000' as Timestamp,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100189 message: 'Some comment on another patchset.',
190 unresolved: false,
191 },
192 ],
Ben Rohlfsabaeacf2022-05-27 15:24:22 +0200193 patchNum: 3 as RevisionPatchSetNum,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100194 path: 'test.txt',
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100195 rootId: '09a9fb0a_1484e6cf' as UrlEncodedCommentId,
196 commentSide: CommentSide.PARENT,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100197 },
198 {
199 comments: [
200 {
Dhruv Srivastava3dfaf362020-12-01 21:53:59 +0100201 path: '/COMMIT_MSG',
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100202 author: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100203 _account_id: 1000000 as AccountId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100204 name: 'user',
205 username: 'user',
206 },
Ben Rohlfsabaeacf2022-05-27 15:24:22 +0200207 patch_set: 2 as RevisionPatchSetNum,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100208 id: '8caddf38_44770ec1' as UrlEncodedCommentId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100209 line: 4,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100210 updated: '2018-02-13 22:48:40.000000000' as Timestamp,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100211 message: 'Another unresolved comment',
212 unresolved: true,
213 },
214 ],
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +0100215 patchNum: 2 as RevisionPatchSetNum,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100216 path: '/COMMIT_MSG',
217 line: 4,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100218 rootId: '8caddf38_44770ec1' as UrlEncodedCommentId,
Dhruv Srivastava794db3a2020-11-11 11:28:08 +0100219 commentSide: CommentSide.REVISION,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100220 },
221 {
222 comments: [
223 {
Dhruv Srivastava3dfaf362020-12-01 21:53:59 +0100224 path: '/COMMIT_MSG',
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100225 author: {
Ben Rohlfs3f279682022-02-25 12:07:27 +0100226 // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100227 _account_id: 1000000 as AccountId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100228 name: 'user',
229 username: 'user',
230 },
Ben Rohlfsabaeacf2022-05-27 15:24:22 +0200231 patch_set: 2 as RevisionPatchSetNum,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100232 id: 'scaddf38_44770ec1' as UrlEncodedCommentId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100233 line: 4,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100234 updated: '2018-02-14 22:48:40.000000000' as Timestamp,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100235 message: 'Yet another unresolved comment',
236 unresolved: true,
237 },
238 ],
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +0100239 patchNum: 2 as RevisionPatchSetNum,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100240 path: '/COMMIT_MSG',
241 line: 4,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100242 rootId: 'scaddf38_44770ec1' as UrlEncodedCommentId,
Dhruv Srivastava794db3a2020-11-11 11:28:08 +0100243 commentSide: CommentSide.REVISION,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100244 },
245 {
246 comments: [
247 {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100248 id: 'zcf0b9fa_fe1a5f62' as UrlEncodedCommentId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100249 path: '/COMMIT_MSG',
250 line: 6,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100251 updated: '2018-02-15 22:48:48.018000000' as Timestamp,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100252 message: 'resolved draft',
253 unresolved: false,
254 __draft: true,
Ben Rohlfsabaeacf2022-05-27 15:24:22 +0200255 patch_set: 2 as RevisionPatchSetNum,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100256 },
257 ],
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +0100258 patchNum: 4 as RevisionPatchSetNum,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100259 path: '/COMMIT_MSG',
260 line: 6,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100261 rootId: 'zcf0b9fa_fe1a5f62' as UrlEncodedCommentId,
Dhruv Srivastava794db3a2020-11-11 11:28:08 +0100262 commentSide: CommentSide.REVISION,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100263 },
264 {
265 comments: [
266 {
Dhruv Srivastava3dfaf362020-12-01 21:53:59 +0100267 path: '/COMMIT_MSG',
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100268 author: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100269 _account_id: 1000000 as AccountId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100270 name: 'user',
271 username: 'user',
272 },
Ben Rohlfsabaeacf2022-05-27 15:24:22 +0200273 patch_set: 4 as RevisionPatchSetNum,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100274 id: 'rc1' as UrlEncodedCommentId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100275 line: 5,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100276 updated: '2019-02-08 18:49:18.000000000' as Timestamp,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100277 message: 'test',
278 unresolved: true,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100279 robot_id: 'rc1' as RobotId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100280 },
281 ],
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +0100282 patchNum: 4 as RevisionPatchSetNum,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100283 path: '/COMMIT_MSG',
284 line: 5,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100285 rootId: 'rc1' as UrlEncodedCommentId,
Dhruv Srivastava794db3a2020-11-11 11:28:08 +0100286 commentSide: CommentSide.REVISION,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100287 },
288 {
289 comments: [
290 {
Dhruv Srivastava3dfaf362020-12-01 21:53:59 +0100291 path: '/COMMIT_MSG',
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100292 author: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100293 _account_id: 1000000 as AccountId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100294 name: 'user',
295 username: 'user',
296 },
Ben Rohlfsabaeacf2022-05-27 15:24:22 +0200297 patch_set: 4 as RevisionPatchSetNum,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100298 id: 'rc2' as UrlEncodedCommentId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100299 line: 5,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100300 updated: '2019-03-08 18:49:18.000000000' as Timestamp,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100301 message: 'test',
302 unresolved: true,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100303 robot_id: 'rc2' as RobotId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100304 },
305 {
Dhruv Srivastava3dfaf362020-12-01 21:53:59 +0100306 path: '/COMMIT_MSG',
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100307 author: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100308 _account_id: 1000000 as AccountId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100309 name: 'user',
310 username: 'user',
311 },
Ben Rohlfsabaeacf2022-05-27 15:24:22 +0200312 patch_set: 4 as RevisionPatchSetNum,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100313 id: 'c2_1' as UrlEncodedCommentId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100314 line: 5,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100315 updated: '2019-03-08 18:49:18.000000000' as Timestamp,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100316 message: 'test',
317 unresolved: true,
318 },
319 ],
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +0100320 patchNum: 4 as RevisionPatchSetNum,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100321 path: '/COMMIT_MSG',
322 line: 5,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100323 rootId: 'rc2' as UrlEncodedCommentId,
Dhruv Srivastava794db3a2020-11-11 11:28:08 +0100324 commentSide: CommentSide.REVISION,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100325 },
326 ];
327
Chris Poucet973ecc92022-06-13 10:44:07 +0200328 setup(async () => {
Dmitrii Filippovf97fc6e2020-04-07 09:59:22 +0200329 // Since pluginEndpoints are global, must reset state.
330 _testOnly_resetEndpoints();
Dmitrii Filippov7d4f2f32020-06-28 23:14:26 +0200331 navigateToChangeStub = sinon.stub(GerritNav, 'navigateToChange');
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100332
Ben Rohlfs3a6ff7e2021-01-18 14:08:39 +0100333 stubRestApi('getConfig').returns(
334 Promise.resolve({
335 ...createServerInfo(),
336 user: {
337 ...createUserConfig(),
338 anonymous_coward_name: 'test coward name',
339 },
340 })
341 );
Dhruv Srivastava8e1e2b22021-09-30 12:17:55 +0100342 stubRestApi('getAccount').returns(
343 Promise.resolve(createAccountDetailWithId(5))
344 );
Ben Rohlfs3a6ff7e2021-01-18 14:08:39 +0100345 stubRestApi('getDiffComments').returns(Promise.resolve({}));
346 stubRestApi('getDiffRobotComments').returns(Promise.resolve({}));
347 stubRestApi('getDiffDrafts').returns(Promise.resolve({}));
Chris Poucet973ecc92022-06-13 10:44:07 +0200348
Dhruv Srivastava12e2c992020-09-01 16:40:21 +0200349 getPluginLoader().loadPlugins([]);
Chris Poucetd3f52fd2021-11-29 23:16:39 +0100350 window.Gerrit.install(
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100351 plugin => {
352 plugin.registerDynamicCustomComponent(
353 'change-view-tab-header',
354 'gr-checks-change-view-tab-header-view'
355 );
356 plugin.registerDynamicCustomComponent(
357 'change-view-tab-content',
358 'gr-checks-view'
359 );
360 },
361 '0.1',
Ben Rohlfsef1dd592021-03-09 10:58:29 +0100362 'http://some/plugins/url.js'
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100363 );
Chris Poucet973ecc92022-06-13 10:44:07 +0200364 element = await fixture<GrChangeView>(
365 html`<gr-change-view></gr-change-view>`
366 );
367 element.params = {
368 view: GerritView.CHANGE,
369 changeNum: TEST_NUMERIC_CHANGE_ID,
370 project: 'gerrit' as RepoName,
371 };
Frank Borden610556a2022-07-15 15:34:10 +0200372 // Do this asynchronously as some tests don't expect the element to have
Chris Poucet973ecc92022-06-13 10:44:07 +0200373 // rendered yet.
374 element.updateComplete.then(() => {
375 assertIsDefined(element.actions);
376 sinon.stub(element.actions, 'reload').returns(Promise.resolve());
377 });
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100378 });
379
Chris Pouceta2e173e2021-08-31 01:04:04 +0000380 teardown(async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +0200381 await element.updateComplete;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100382 });
383
Frank Borden610556a2022-07-15 15:34:10 +0200384 test('render', () => {
385 expect(element).shadowDom.to.equal(/* HTML */ `
386 <div class="container loading">Loading...</div>
387 <div aria-hidden="false" class="container" hidden="" id="mainContent">
388 <section class="changeInfoSection">
389 <div class="header">
390 <h1 class="assistive-tech-only">Change :</h1>
391 <div class="headerTitle">
392 <div class="changeStatuses"></div>
393 <gr-change-star id="changeStar"> </gr-change-star>
394 <a aria-label="Change undefined" class="changeNumber"> </a>
395 <span class="changeNumberColon"> : </span>
396 <span class="headerSubject"> </span>
397 <gr-copy-clipboard
398 class="changeCopyClipboard"
399 hideinput=""
400 text="undefined: undefined | http://localhost:9876undefined"
401 >
402 </gr-copy-clipboard>
403 </div>
404 <div class="commitActions">
405 <gr-change-actions hidden="" id="actions"> </gr-change-actions>
406 </div>
407 </div>
408 <h2 class="assistive-tech-only">Change metadata</h2>
409 <div class="changeInfo">
410 <div class="changeInfo-column changeMetadata hideOnMobileOverlay">
411 <gr-change-metadata id="metadata"> </gr-change-metadata>
412 </div>
413 <div class="changeInfo-column mainChangeInfo" id="mainChangeInfo">
414 <div class="hideOnMobileOverlay" id="commitAndRelated">
415 <div class="commitContainer">
416 <h3 class="assistive-tech-only">Commit Message</h3>
417 <div>
418 <gr-button
419 aria-disabled="false"
420 class="reply"
421 id="replyBtn"
422 primary=""
423 role="button"
424 tabindex="0"
425 title="Open reply dialog to publish comments and add reviewers (shortcut: a)"
426 >
427 Reply
428 </gr-button>
429 </div>
430 <div class="commitMessage" id="commitMessage">
431 <gr-editable-content
432 id="commitMessageEditor"
433 remove-zero-width-space=""
434 >
435 <gr-linked-text pre="" remove-zero-width-space="">
436 <span id="output" slot="insert"> </span>
437 </gr-linked-text>
438 </gr-editable-content>
439 </div>
440 <h3 class="assistive-tech-only">
441 Comments and Checks Summary
442 </h3>
443 <gr-change-summary> </gr-change-summary>
444 <gr-endpoint-decorator name="commit-container">
445 <gr-endpoint-param name="change"> </gr-endpoint-param>
446 <gr-endpoint-param name="revision"> </gr-endpoint-param>
447 </gr-endpoint-decorator>
448 </div>
449 <div class="relatedChanges">
450 <gr-related-changes-list id="relatedChanges">
451 </gr-related-changes-list>
452 </div>
453 <div class="emptySpace"></div>
454 </div>
455 </div>
456 </div>
457 </section>
458 <h2 class="assistive-tech-only">Files and Comments tabs</h2>
459 <paper-tabs dir="null" id="primaryTabs" role="tablist" tabindex="0">
460 <paper-tab
461 aria-disabled="false"
462 aria-selected="true"
463 class="iron-selected"
464 data-name="files"
465 role="tab"
466 tabindex="0"
467 >
468 <span> Files </span>
469 </paper-tab>
470 <paper-tab
471 aria-disabled="false"
472 aria-selected="false"
473 class="commentThreads"
474 data-name="comments"
475 role="tab"
476 tabindex="-1"
477 >
478 <gr-tooltip-content has-tooltip="" title="">
479 <span> Comments </span>
480 </gr-tooltip-content>
481 </paper-tab>
482 <paper-tab
483 aria-disabled="false"
484 aria-selected="false"
485 data-name="change-view-tab-header-url"
486 role="tab"
487 tabindex="-1"
488 >
489 <gr-endpoint-decorator name="change-view-tab-header-url">
490 <gr-endpoint-param name="change"> </gr-endpoint-param>
491 <gr-endpoint-param name="revision"> </gr-endpoint-param>
492 </gr-endpoint-decorator>
493 </paper-tab>
494 </paper-tabs>
495 <section class="patchInfo">
496 <div>
497 <gr-file-list-header id="fileListHeader"> </gr-file-list-header>
498 <gr-file-list class="hideOnMobileOverlay" id="fileList">
499 </gr-file-list>
500 </div>
501 </section>
502 <gr-endpoint-decorator name="change-view-integration">
503 <gr-endpoint-param name="change"> </gr-endpoint-param>
504 <gr-endpoint-param name="revision"> </gr-endpoint-param>
505 </gr-endpoint-decorator>
506 <paper-tabs dir="null" id="secondaryTabs" role="tablist" tabindex="0">
507 <paper-tab
508 aria-disabled="false"
509 aria-selected="false"
510 class="changeLog"
511 data-name="_changeLog"
512 role="tab"
513 tabindex="-1"
514 >
515 Change Log
516 </paper-tab>
517 </paper-tabs>
518 <section class="changeLog">
519 <h2 class="assistive-tech-only">Change Log</h2>
520 <gr-messages-list class="hideOnMobileOverlay"> </gr-messages-list>
521 </section>
522 </div>
523 <gr-apply-fix-dialog id="applyFixDialog"> </gr-apply-fix-dialog>
524 <gr-overlay
525 aria-hidden="true"
526 id="downloadOverlay"
527 style="outline: none; display: none;"
528 tabindex="-1"
529 with-backdrop=""
530 >
531 <gr-download-dialog id="downloadDialog" role="dialog">
532 </gr-download-dialog>
533 </gr-overlay>
534 <gr-overlay
535 aria-hidden="true"
536 id="includedInOverlay"
537 style="outline: none; display: none;"
538 tabindex="-1"
539 with-backdrop=""
540 >
541 <gr-included-in-dialog id="includedInDialog"> </gr-included-in-dialog>
542 </gr-overlay>
543 <gr-overlay
544 aria-hidden="true"
545 class="scrollable"
546 id="replyOverlay"
547 no-cancel-on-esc-key=""
548 no-cancel-on-outside-click=""
549 scroll-action="lock"
550 style="outline: none; display: none;"
551 tabindex="-1"
552 with-backdrop=""
553 >
554 </gr-overlay>
555 `);
556 });
557
Chris Poucet973ecc92022-06-13 10:44:07 +0200558 test('handleMessageAnchorTap', async () => {
559 element.changeNum = 1 as NumericChangeId;
560 element.patchRange = {
Ben Rohlfs58267b72022-05-27 15:59:18 +0200561 basePatchNum: PARENT,
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +0100562 patchNum: 1 as RevisionPatchSetNum,
Dhruv Srivastava163de6f2020-06-04 09:40:28 +0000563 };
Chris Poucet973ecc92022-06-13 10:44:07 +0200564 element.change = createChangeViewChange();
565 await element.updateComplete;
Dmitrii Filippov7d4f2f32020-06-28 23:14:26 +0200566 const getUrlStub = sinon.stub(GerritNav, 'getUrlForChange');
567 const replaceStateStub = sinon.stub(history, 'replaceState');
Chris Poucet973ecc92022-06-13 10:44:07 +0200568 element.handleMessageAnchorTap(
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100569 new CustomEvent('message-anchor-tap', {detail: {id: 'a12345'}})
570 );
Dhruv Srivastava163de6f2020-06-04 09:40:28 +0000571
Dhruv Srivastavac9d12bc2021-11-12 11:32:40 +0100572 assert.equal(getUrlStub.lastCall.args[1]!.messageHash, '#message-a12345');
Dhruv Srivastava163de6f2020-06-04 09:40:28 +0000573 assert.isTrue(replaceStateStub.called);
574 });
575
Chris Poucet973ecc92022-06-13 10:44:07 +0200576 test('handleDiffAgainstBase', () => {
577 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +0200578 ...createChangeViewChange(),
Dmitrii Filippov0695d402020-10-22 16:57:57 +0200579 revisions: createRevisions(10),
580 };
Chris Poucet973ecc92022-06-13 10:44:07 +0200581 element.patchRange = {
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +0100582 patchNum: 3 as RevisionPatchSetNum,
Dhruv Srivastava591b4902021-03-10 11:48:12 +0100583 basePatchNum: 1 as BasePatchSetNum,
Dhruv Srivastava4757b352020-06-12 15:41:42 +0200584 };
Chris Poucet973ecc92022-06-13 10:44:07 +0200585 element.handleDiffAgainstBase();
Dhruv Srivastava4757b352020-06-12 15:41:42 +0200586 assert(navigateToChangeStub.called);
587 const args = navigateToChangeStub.getCall(0).args;
Chris Poucet973ecc92022-06-13 10:44:07 +0200588 assert.equal(args[0], element.change);
Ben Rohlfsabaeacf2022-05-27 15:24:22 +0200589 assert.equal(args[1]!.patchNum, 3 as RevisionPatchSetNum);
Dhruv Srivastava4757b352020-06-12 15:41:42 +0200590 });
591
Chris Poucet973ecc92022-06-13 10:44:07 +0200592 test('handleDiffAgainstLatest', () => {
593 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +0200594 ...createChangeViewChange(),
Dmitrii Filippov0695d402020-10-22 16:57:57 +0200595 revisions: createRevisions(10),
596 };
Chris Poucet973ecc92022-06-13 10:44:07 +0200597 element.patchRange = {
Dhruv Srivastava591b4902021-03-10 11:48:12 +0100598 basePatchNum: 1 as BasePatchSetNum,
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +0100599 patchNum: 3 as RevisionPatchSetNum,
Dhruv Srivastava4757b352020-06-12 15:41:42 +0200600 };
Chris Poucet973ecc92022-06-13 10:44:07 +0200601 element.handleDiffAgainstLatest();
Dhruv Srivastava4757b352020-06-12 15:41:42 +0200602 assert(navigateToChangeStub.called);
603 const args = navigateToChangeStub.getCall(0).args;
Chris Poucet973ecc92022-06-13 10:44:07 +0200604 assert.equal(args[0], element.change);
Ben Rohlfsabaeacf2022-05-27 15:24:22 +0200605 assert.equal(args[1]!.patchNum, 10 as RevisionPatchSetNum);
Dhruv Srivastava0633ae12021-11-11 15:16:47 +0100606 assert.equal(args[1]!.basePatchNum, 1 as BasePatchSetNum);
Dhruv Srivastava4757b352020-06-12 15:41:42 +0200607 });
608
Chris Poucet973ecc92022-06-13 10:44:07 +0200609 test('handleDiffBaseAgainstLeft', () => {
610 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +0200611 ...createChangeViewChange(),
Dmitrii Filippov0695d402020-10-22 16:57:57 +0200612 revisions: createRevisions(10),
613 };
Chris Poucet973ecc92022-06-13 10:44:07 +0200614 element.patchRange = {
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +0100615 patchNum: 3 as RevisionPatchSetNum,
Dhruv Srivastava591b4902021-03-10 11:48:12 +0100616 basePatchNum: 1 as BasePatchSetNum,
Dhruv Srivastava4757b352020-06-12 15:41:42 +0200617 };
Chris Poucet973ecc92022-06-13 10:44:07 +0200618 element.handleDiffBaseAgainstLeft();
Dhruv Srivastava4757b352020-06-12 15:41:42 +0200619 assert(navigateToChangeStub.called);
620 const args = navigateToChangeStub.getCall(0).args;
Chris Poucet973ecc92022-06-13 10:44:07 +0200621 assert.equal(args[0], element.change);
Ben Rohlfsabaeacf2022-05-27 15:24:22 +0200622 assert.equal(args[1]!.patchNum, 1 as RevisionPatchSetNum);
Dhruv Srivastava4757b352020-06-12 15:41:42 +0200623 });
624
Chris Poucet973ecc92022-06-13 10:44:07 +0200625 test('handleDiffRightAgainstLatest', () => {
626 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +0200627 ...createChangeViewChange(),
Dmitrii Filippov0695d402020-10-22 16:57:57 +0200628 revisions: createRevisions(10),
629 };
Chris Poucet973ecc92022-06-13 10:44:07 +0200630 element.patchRange = {
Dhruv Srivastava591b4902021-03-10 11:48:12 +0100631 basePatchNum: 1 as BasePatchSetNum,
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +0100632 patchNum: 3 as RevisionPatchSetNum,
Dhruv Srivastava4757b352020-06-12 15:41:42 +0200633 };
Chris Poucet973ecc92022-06-13 10:44:07 +0200634 element.handleDiffRightAgainstLatest();
Dhruv Srivastava4757b352020-06-12 15:41:42 +0200635 assert(navigateToChangeStub.called);
636 const args = navigateToChangeStub.getCall(0).args;
Ben Rohlfsabaeacf2022-05-27 15:24:22 +0200637 assert.equal(args[1]!.patchNum, 10 as RevisionPatchSetNum);
Dhruv Srivastava0633ae12021-11-11 15:16:47 +0100638 assert.equal(args[1]!.basePatchNum, 3 as BasePatchSetNum);
Dhruv Srivastava4757b352020-06-12 15:41:42 +0200639 });
640
Chris Poucet973ecc92022-06-13 10:44:07 +0200641 test('handleDiffBaseAgainstLatest', () => {
642 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +0200643 ...createChangeViewChange(),
Dmitrii Filippov0695d402020-10-22 16:57:57 +0200644 revisions: createRevisions(10),
645 };
Chris Poucet973ecc92022-06-13 10:44:07 +0200646 element.patchRange = {
Dhruv Srivastava591b4902021-03-10 11:48:12 +0100647 basePatchNum: 1 as BasePatchSetNum,
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +0100648 patchNum: 3 as RevisionPatchSetNum,
Dhruv Srivastava4757b352020-06-12 15:41:42 +0200649 };
Chris Poucet973ecc92022-06-13 10:44:07 +0200650 element.handleDiffBaseAgainstLatest();
Dhruv Srivastava4757b352020-06-12 15:41:42 +0200651 assert(navigateToChangeStub.called);
652 const args = navigateToChangeStub.getCall(0).args;
Ben Rohlfsabaeacf2022-05-27 15:24:22 +0200653 assert.equal(args[1]!.patchNum, 10 as RevisionPatchSetNum);
Dhruv Srivastava0633ae12021-11-11 15:16:47 +0100654 assert.isNotOk(args[1]!.basePatchNum);
Dhruv Srivastava4757b352020-06-12 15:41:42 +0200655 });
656
Dhruv Srivastava8e1e2b22021-09-30 12:17:55 +0100657 test('toggle attention set status', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +0200658 element.change = {
Dhruv Srivastava8e1e2b22021-09-30 12:17:55 +0100659 ...createChangeViewChange(),
660 revisions: createRevisions(10),
661 };
662 const addToAttentionSetStub = stubRestApi('addToAttentionSet').returns(
663 Promise.resolve(new Response())
664 );
665
666 const removeFromAttentionSetStub = stubRestApi(
667 'removeFromAttentionSet'
668 ).returns(Promise.resolve(new Response()));
Chris Poucet973ecc92022-06-13 10:44:07 +0200669 element.patchRange = {
Dhruv Srivastava8e1e2b22021-09-30 12:17:55 +0100670 basePatchNum: 1 as BasePatchSetNum,
671 patchNum: 3 as RevisionPatchSetNum,
672 };
Chris Poucet973ecc92022-06-13 10:44:07 +0200673 await element.updateComplete;
674 assert.isNotOk(element.change.attention_set);
675 element.handleToggleAttentionSet();
Dhruv Srivastava8e1e2b22021-09-30 12:17:55 +0100676 assert.isTrue(addToAttentionSetStub.called);
677 assert.isFalse(removeFromAttentionSetStub.called);
678
Chris Poucet973ecc92022-06-13 10:44:07 +0200679 element.handleToggleAttentionSet();
Dhruv Srivastava8e1e2b22021-09-30 12:17:55 +0100680 assert.isTrue(removeFromAttentionSetStub.called);
681 });
682
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100683 suite('plugins adding to file tab', () => {
Chris Pouceta2e173e2021-08-31 01:04:04 +0000684 setup(async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +0200685 element.changeNum = TEST_NUMERIC_CHANGE_ID;
686 await element.updateComplete;
Andrew Bonventre547b8ab2015-12-01 01:02:00 -0500687 });
688
Chris Poucet973ecc92022-06-13 10:44:07 +0200689 test('plugin added tab shows up as a dynamic endpoint', async () => {
690 await flush();
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100691 assert(
Chris Poucet973ecc92022-06-13 10:44:07 +0200692 element.dynamicTabHeaderEndpoints.includes('change-view-tab-header-url')
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100693 );
694 const primaryTabs = element.shadowRoot!.querySelector('#primaryTabs')!;
695 const paperTabs = primaryTabs.querySelectorAll<HTMLElement>('paper-tab');
Ben Rohlfs36be36d2022-06-24 18:10:45 +0200696 // 4 Tabs are : Files, Comment Threads, Plugin
697 assert.equal(primaryTabs.querySelectorAll('paper-tab').length, 3);
698 assert.equal(paperTabs[0].dataset.name, 'files');
699 assert.equal(paperTabs[1].dataset.name, 'comments');
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100700 assert.equal(paperTabs[2].dataset.name, 'change-view-tab-header-url');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100701 });
702
Chris Poucet973ecc92022-06-13 10:44:07 +0200703 test('setActivePrimaryTab switched tab correctly', async () => {
704 element.setActivePrimaryTab(
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100705 new CustomEvent('', {
706 detail: {tab: 'change-view-tab-header-url'},
707 })
708 );
Chris Poucet973ecc92022-06-13 10:44:07 +0200709 await element.updateComplete;
710 assert.equal(element.activeTabs[0], 'change-view-tab-header-url');
Tao Zhou4fd32d52020-04-06 17:23:10 +0200711 });
712
Chris Pouceta2e173e2021-08-31 01:04:04 +0000713 test('show-primary-tab switched primary tab correctly', async () => {
Paladox none6b055dc2020-06-28 14:53:18 +0000714 element.dispatchEvent(
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100715 new CustomEvent('show-primary-tab', {
716 composed: true,
717 bubbles: true,
718 detail: {
719 tab: 'change-view-tab-header-url',
720 },
721 })
722 );
Chris Poucet973ecc92022-06-13 10:44:07 +0200723 await element.updateComplete;
724 assert.equal(element.activeTabs[0], 'change-view-tab-header-url');
Tao Zhou4fd32d52020-04-06 17:23:10 +0200725 });
726
Chris Pouceta2e173e2021-08-31 01:04:04 +0000727 test('param change should switch primary tab correctly', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +0200728 assert.equal(element.activeTabs[0], PrimaryTab.FILES);
Tao Zhou4fd32d52020-04-06 17:23:10 +0200729 // view is required
Chris Poucet973ecc92022-06-13 10:44:07 +0200730 element.changeNum = undefined;
Tao Zhou4cd35cb2020-07-22 11:28:22 +0200731 element.params = {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100732 ...createAppElementChangeViewParams(),
733 ...element.params,
Ben Rohlfs36be36d2022-06-24 18:10:45 +0200734 tab: PrimaryTab.COMMENT_THREADS,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100735 };
Chris Poucet973ecc92022-06-13 10:44:07 +0200736 await element.updateComplete;
Ben Rohlfs36be36d2022-06-24 18:10:45 +0200737 assert.equal(element.activeTabs[0], PrimaryTab.COMMENT_THREADS);
Tao Zhou4fd32d52020-04-06 17:23:10 +0200738 });
739
Chris Pouceta2e173e2021-08-31 01:04:04 +0000740 test('invalid param change should not switch primary tab', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +0200741 assert.equal(element.activeTabs[0], PrimaryTab.FILES);
Tao Zhou4fd32d52020-04-06 17:23:10 +0200742 // view is required
Tao Zhou4cd35cb2020-07-22 11:28:22 +0200743 element.params = {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100744 ...createAppElementChangeViewParams(),
745 ...element.params,
Dhruv Srivastava49f0a7a2021-10-06 12:03:01 +0100746 tab: 'random',
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100747 };
Chris Poucet973ecc92022-06-13 10:44:07 +0200748 await element.updateComplete;
749 assert.equal(element.activeTabs[0], PrimaryTab.FILES);
Kasper Nilssonf0743732016-10-18 13:01:10 -0700750 });
751
Chris Pouceta2e173e2021-08-31 01:04:04 +0000752 test('switching tab sets _selectedTabPluginEndpoint', async () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100753 const paperTabs = element.shadowRoot!.querySelector('#primaryTabs')!;
754 tap(paperTabs.querySelectorAll('paper-tab')[2]);
Chris Poucet973ecc92022-06-13 10:44:07 +0200755 await element.updateComplete;
Chris Pouceta2e173e2021-08-31 01:04:04 +0000756 assert.equal(
Chris Poucet973ecc92022-06-13 10:44:07 +0200757 element.selectedTabPluginEndpoint,
Chris Pouceta2e173e2021-08-31 01:04:04 +0000758 'change-view-tab-content-url'
759 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100760 });
761 });
Paladox none7acb7ac2017-11-09 18:06:18 +0000762
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100763 suite('keyboard shortcuts', () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100764 let clock: SinonFakeTimers;
Dhruv Srivastava4caf0842020-09-18 11:50:33 +0200765 setup(() => {
766 clock = sinon.useFakeTimers();
767 });
768
769 teardown(() => {
770 clock.restore();
771 sinon.restore();
772 });
773
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100774 test('t to add topic', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +0200775 assertIsDefined(element.metadata);
776 const editStub = sinon.stub(element.metadata, 'editTopic');
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100777 pressAndReleaseKeyOn(element, 83, null, 't');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100778 assert(editStub.called);
779 });
780
781 test('S should toggle the CL star', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +0200782 assertIsDefined(element.changeStar);
783 const starStub = sinon.stub(element.changeStar, 'toggleStar');
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100784 pressAndReleaseKeyOn(element, 83, null, 's');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100785 assert(starStub.called);
786 });
787
Dhruv Srivastava4caf0842020-09-18 11:50:33 +0200788 test('toggle star is throttled', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +0200789 assertIsDefined(element.changeStar);
790 const starStub = sinon.stub(element.changeStar, 'toggleStar');
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100791 pressAndReleaseKeyOn(element, 83, null, 's');
Dhruv Srivastava4caf0842020-09-18 11:50:33 +0200792 assert(starStub.called);
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100793 pressAndReleaseKeyOn(element, 83, null, 's');
Dhruv Srivastava4caf0842020-09-18 11:50:33 +0200794 assert.equal(starStub.callCount, 1);
795 clock.tick(1000);
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100796 pressAndReleaseKeyOn(element, 83, null, 's');
Dhruv Srivastava4caf0842020-09-18 11:50:33 +0200797 assert.equal(starStub.callCount, 2);
798 });
799
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100800 test('U should navigate to root if no backPage set', () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100801 const relativeNavStub = sinon.stub(GerritNav, 'navigateToRelativeUrl');
802 pressAndReleaseKeyOn(element, 85, null, 'u');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100803 assert.isTrue(relativeNavStub.called);
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100804 assert.isTrue(
805 relativeNavStub.lastCall.calledWithExactly(GerritNav.getUrlForRoot())
806 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100807 });
808
809 test('U should navigate to backPage if set', () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100810 const relativeNavStub = sinon.stub(GerritNav, 'navigateToRelativeUrl');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100811 element.backPage = '/dashboard/self';
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100812 pressAndReleaseKeyOn(element, 85, null, 'u');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100813 assert.isTrue(relativeNavStub.called);
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100814 assert.isTrue(
815 relativeNavStub.lastCall.calledWithExactly('/dashboard/self')
816 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100817 });
818
Chris Pouceta2e173e2021-08-31 01:04:04 +0000819 test('A fires an error event when not logged in', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +0200820 element.userModel.setAccount(undefined);
Dmitrii Filippov7d4f2f32020-06-28 23:14:26 +0200821 const loggedInErrorSpy = sinon.spy();
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100822 element.addEventListener('show-auth-required', loggedInErrorSpy);
Ben Rohlfs410f5222021-10-19 23:44:02 +0200823 pressAndReleaseKeyOn(element, 65, null, 'a');
Chris Poucet973ecc92022-06-13 10:44:07 +0200824 await element.updateComplete;
825 assertIsDefined(element.replyOverlay);
826 assert.isFalse(element.replyOverlay.opened);
Chris Pouceta2e173e2021-08-31 01:04:04 +0000827 assert.isTrue(loggedInErrorSpy.called);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100828 });
829
Chris Pouceta2e173e2021-08-31 01:04:04 +0000830 test('shift A does not open reply overlay', async () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100831 pressAndReleaseKeyOn(element, 65, 'shift', 'a');
Chris Poucet973ecc92022-06-13 10:44:07 +0200832 await element.updateComplete;
833 assertIsDefined(element.replyOverlay);
834 assert.isFalse(element.replyOverlay.opened);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100835 });
836
Chris Pouceta2e173e2021-08-31 01:04:04 +0000837 test('A toggles overlay when logged in', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +0200838 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +0200839 ...createChangeViewChange(),
Dmitrii Filippov0695d402020-10-22 16:57:57 +0200840 revisions: createRevisions(1),
841 messages: createChangeMessages(1),
842 };
Chris Poucet973ecc92022-06-13 10:44:07 +0200843 element.change.labels = {};
844 await element.updateComplete;
Dmitrii Filippov77e5f7f2020-07-10 18:39:45 +0200845
Chris Poucet973ecc92022-06-13 10:44:07 +0200846 const openSpy = sinon.spy(element, 'openReplyDialog');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100847
Ben Rohlfs410f5222021-10-19 23:44:02 +0200848 pressAndReleaseKeyOn(element, 65, null, 'a');
Chris Poucet973ecc92022-06-13 10:44:07 +0200849 await element.updateComplete;
850 assertIsDefined(element.replyOverlay);
851 assert.isTrue(element.replyOverlay.opened);
852 element.replyOverlay.close();
853 assert.isFalse(element.replyOverlay.opened);
Chris Pouceta2e173e2021-08-31 01:04:04 +0000854 assert(
Ben Rohlfs00049652021-10-25 16:40:38 +0200855 openSpy.lastCall.calledWithExactly(FocusTarget.ANY),
Chris Poucet973ecc92022-06-13 10:44:07 +0200856 'openReplyDialog should have been passed ANY'
Chris Pouceta2e173e2021-08-31 01:04:04 +0000857 );
858 assert.equal(openSpy.callCount, 1);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100859 });
860
Chris Poucet973ecc92022-06-13 10:44:07 +0200861 test('fullscreen-overlay-opened hides content', async () => {
862 element.loggedIn = true;
863 element.loading = false;
864 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +0200865 ...createChangeViewChange(),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100866 labels: {},
867 actions: {
868 abandon: {
869 enabled: true,
870 label: 'Abandon',
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100871 method: HttpMethod.POST,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100872 title: 'Abandon',
873 },
874 },
875 };
Chris Poucet973ecc92022-06-13 10:44:07 +0200876 await element.updateComplete;
877 const handlerSpy = sinon.spy(element, 'handleHideBackgroundContent');
Ben Rohlfs00049652021-10-25 16:40:38 +0200878 const overlay = queryAndAssert<GrOverlay>(element, '#replyOverlay');
879 overlay.dispatchEvent(
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100880 new CustomEvent('fullscreen-overlay-opened', {
881 composed: true,
882 bubbles: true,
883 })
884 );
Chris Poucet973ecc92022-06-13 10:44:07 +0200885 await element.updateComplete;
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100886 assert.isTrue(handlerSpy.called);
Chris Poucet973ecc92022-06-13 10:44:07 +0200887 assertIsDefined(element.mainContent);
888 assertIsDefined(element.actions);
889 assert.isTrue(element.mainContent.classList.contains('overlayOpen'));
890 assert.equal(getComputedStyle(element.actions).display, 'flex');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100891 });
892
Chris Poucet973ecc92022-06-13 10:44:07 +0200893 test('fullscreen-overlay-closed shows content', async () => {
894 element.loggedIn = true;
895 element.loading = false;
896 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +0200897 ...createChangeViewChange(),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100898 labels: {},
899 actions: {
900 abandon: {
901 enabled: true,
902 label: 'Abandon',
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100903 method: HttpMethod.POST,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100904 title: 'Abandon',
905 },
906 },
907 };
Chris Poucet973ecc92022-06-13 10:44:07 +0200908 await element.updateComplete;
909 const handlerSpy = sinon.spy(element, 'handleShowBackgroundContent');
Ben Rohlfs00049652021-10-25 16:40:38 +0200910 const overlay = queryAndAssert<GrOverlay>(element, '#replyOverlay');
911 overlay.dispatchEvent(
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100912 new CustomEvent('fullscreen-overlay-closed', {
913 composed: true,
914 bubbles: true,
915 })
916 );
Chris Poucet973ecc92022-06-13 10:44:07 +0200917 await element.updateComplete;
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100918 assert.isTrue(handlerSpy.called);
Chris Poucet973ecc92022-06-13 10:44:07 +0200919 assertIsDefined(element.mainContent);
920 assert.isFalse(element.mainContent.classList.contains('overlayOpen'));
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100921 });
922
923 test('expand all messages when expand-diffs fired', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +0200924 assertIsDefined(element.fileList);
925 assertIsDefined(element.fileListHeader);
926 const handleExpand = sinon.stub(element.fileList, 'expandAllDiffs');
927 element.fileListHeader.dispatchEvent(
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100928 new CustomEvent('expand-diffs', {
929 composed: true,
930 bubbles: true,
931 })
932 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100933 assert.isTrue(handleExpand.called);
934 });
935
936 test('collapse all messages when collapse-diffs fired', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +0200937 assertIsDefined(element.fileList);
938 assertIsDefined(element.fileListHeader);
939 const handleCollapse = sinon.stub(element.fileList, 'collapseAllDiffs');
940 element.fileListHeader.dispatchEvent(
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100941 new CustomEvent('collapse-diffs', {
942 composed: true,
943 bubbles: true,
944 })
945 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100946 assert.isTrue(handleCollapse.called);
947 });
948
Chris Pouceta2e173e2021-08-31 01:04:04 +0000949 test('X should expand all messages', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +0200950 await element.updateComplete;
Chris Pouceta2e173e2021-08-31 01:04:04 +0000951 const handleExpand = sinon.stub(
952 element.messagesList!,
953 'handleExpandCollapse'
954 );
955 pressAndReleaseKeyOn(element, 88, null, 'x');
956 assert(handleExpand.calledWith(true));
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100957 });
958
Chris Pouceta2e173e2021-08-31 01:04:04 +0000959 test('Z should collapse all messages', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +0200960 await element.updateComplete;
Chris Pouceta2e173e2021-08-31 01:04:04 +0000961 const handleExpand = sinon.stub(
962 element.messagesList!,
963 'handleExpandCollapse'
964 );
965 pressAndReleaseKeyOn(element, 90, null, 'z');
966 assert(handleExpand.calledWith(false));
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100967 });
968
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100969 test('d should open download overlay', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +0200970 assertIsDefined(element.downloadOverlay);
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100971 const stub = sinon
Chris Poucet973ecc92022-06-13 10:44:07 +0200972 .stub(element.downloadOverlay, 'open')
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100973 .returns(Promise.resolve());
Ben Rohlfs410f5222021-10-19 23:44:02 +0200974 pressAndReleaseKeyOn(element, 68, null, 'd');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100975 assert.isTrue(stub.called);
976 });
977
Chris Poucetdd2d0102022-05-13 14:09:39 +0200978 test(', should open diff preferences', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +0200979 assertIsDefined(element.fileList);
980 await element.fileList.updateComplete;
981 assertIsDefined(element.fileList.diffPreferencesDialog);
982 const stub = sinon.stub(element.fileList.diffPreferencesDialog, 'open');
983 element.loggedIn = false;
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100984 pressAndReleaseKeyOn(element, 188, null, ',');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100985 assert.isFalse(stub.called);
986
Chris Poucet973ecc92022-06-13 10:44:07 +0200987 element.loggedIn = true;
Dmitrii Filippov78448cd2020-10-26 17:39:11 +0100988 pressAndReleaseKeyOn(element, 188, null, ',');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +0100989 assert.isTrue(stub.called);
990 });
991
Dhruv Srivastava80d34f42021-10-18 16:45:02 +0200992 test('m should toggle diff mode', async () => {
993 const updatePreferencesStub = stubUsers('updatePreferences');
Chris Poucet973ecc92022-06-13 10:44:07 +0200994 await element.updateComplete;
Dhruv Srivastava80d34f42021-10-18 16:45:02 +0200995
996 const prefs = {
997 ...createDefaultPreferences(),
998 diff_view: DiffViewMode.SIDE_BY_SIDE,
999 };
Chris Poucetefcdb202021-11-22 23:54:26 +01001000 element.userModel.setPreferences(prefs);
Chris Poucet973ecc92022-06-13 10:44:07 +02001001 element.handleToggleDiffMode();
Dhruv Srivastava80d34f42021-10-18 16:45:02 +02001002 assert.isTrue(
1003 updatePreferencesStub.calledWith({diff_view: DiffViewMode.UNIFIED})
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001004 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001005
Dhruv Srivastava80d34f42021-10-18 16:45:02 +02001006 const newPrefs = {
1007 ...createDefaultPreferences(),
1008 diff_view: DiffViewMode.UNIFIED,
1009 };
Chris Poucetefcdb202021-11-22 23:54:26 +01001010 element.userModel.setPreferences(newPrefs);
Chris Poucet973ecc92022-06-13 10:44:07 +02001011 await element.updateComplete;
1012 element.handleToggleDiffMode();
Dhruv Srivastava80d34f42021-10-18 16:45:02 +02001013 assert.isTrue(
1014 updatePreferencesStub.calledWith({diff_view: DiffViewMode.SIDE_BY_SIDE})
1015 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001016 });
1017 });
1018
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001019 suite('thread list and change log tabs', () => {
1020 setup(() => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001021 element.changeNum = TEST_NUMERIC_CHANGE_ID;
1022 element.patchRange = {
Ben Rohlfs58267b72022-05-27 15:59:18 +02001023 basePatchNum: PARENT,
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +01001024 patchNum: 1 as RevisionPatchSetNum,
Kasper Nilsson9c1a3db2018-10-19 15:11:07 -07001025 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001026 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +02001027 ...createChangeViewChange(),
Becky Siegel9b03dd22017-10-26 14:57:32 -07001028 revisions: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001029 rev2: createRevision(2),
1030 rev1: createRevision(1),
1031 rev13: createRevision(13),
1032 rev3: createRevision(3),
Kasper Nilssonf0743732016-10-18 13:01:10 -07001033 },
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001034 current_revision: 'rev3' as CommitId,
1035 status: ChangeStatus.NEW,
Kasper Nilssonf0743732016-10-18 13:01:10 -07001036 labels: {
1037 test: {
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001038 all: [],
Kasper Nilssonf0743732016-10-18 13:01:10 -07001039 default_value: 0,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001040 values: {},
Kasper Nilssonf0743732016-10-18 13:01:10 -07001041 approved: {},
1042 },
1043 },
1044 };
Milutin Kristofic8803ea02020-12-09 23:34:39 +01001045 const relatedChanges = element.shadowRoot!.querySelector(
1046 '#relatedChanges'
1047 ) as GrRelatedChangesList;
1048 sinon.stub(relatedChanges, 'reload');
Han-Wen Nienhuys577ce0a2021-08-11 12:11:17 +02001049 sinon.stub(element, 'loadData').returns(Promise.resolve());
Chris Poucet973ecc92022-06-13 10:44:07 +02001050 sinon.spy(element, 'paramsChanged');
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001051 element.params = createAppElementChangeViewParams();
Kasper Nilsson34a5d892018-04-11 11:10:53 -07001052 });
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001053 });
1054
Dhruv Srivastavab213a1f2021-11-19 14:45:40 +01001055 suite('Comments tab', () => {
1056 setup(async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001057 element.changeNum = TEST_NUMERIC_CHANGE_ID;
1058 element.change = {
Dhruv Srivastavab213a1f2021-11-19 14:45:40 +01001059 ...createChangeViewChange(),
1060 revisions: {
1061 rev2: createRevision(2),
1062 rev1: createRevision(1),
1063 rev13: createRevision(13),
1064 rev3: createRevision(3),
1065 rev4: createRevision(4),
1066 },
1067 current_revision: 'rev4' as CommitId,
1068 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001069 element.commentThreads = THREADS;
1070 await element.updateComplete;
Dhruv Srivastavab213a1f2021-11-19 14:45:40 +01001071 const paperTabs = element.shadowRoot!.querySelector('#primaryTabs')!;
Ben Rohlfs36be36d2022-06-24 18:10:45 +02001072 const tabs = paperTabs.querySelectorAll('paper-tab');
1073 assert.isTrue(tabs.length > 1);
1074 assert.equal(tabs[1].dataset.name, 'comments');
1075 tap(tabs[1]);
Chris Poucet973ecc92022-06-13 10:44:07 +02001076 await element.updateComplete;
Dhruv Srivastavab213a1f2021-11-19 14:45:40 +01001077 });
1078
1079 test('commentId overrides unresolveOnly default', async () => {
1080 const threadList = queryAndAssert<GrThreadList>(
1081 element,
1082 'gr-thread-list'
1083 );
1084 assert.isTrue(element.unresolvedOnly);
1085 assert.isNotOk(element.scrollCommentId);
1086 assert.isTrue(threadList.unresolvedOnly);
1087
1088 element.scrollCommentId = 'abcd' as UrlEncodedCommentId;
Chris Poucet973ecc92022-06-13 10:44:07 +02001089 await element.updateComplete;
Dhruv Srivastavab213a1f2021-11-19 14:45:40 +01001090 assert.isFalse(threadList.unresolvedOnly);
1091 });
1092 });
1093
1094 suite('Findings robot-comment tab', () => {
Frank Borden0a05fa12021-08-09 13:50:52 +02001095 setup(async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001096 element.changeNum = TEST_NUMERIC_CHANGE_ID;
1097 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +02001098 ...createChangeViewChange(),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001099 revisions: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001100 rev2: createRevision(2),
1101 rev1: createRevision(1),
1102 rev13: createRevision(13),
1103 rev3: createRevision(3),
1104 rev4: createRevision(4),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001105 },
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001106 current_revision: 'rev4' as CommitId,
Kasper Nilssonbbd28672018-08-01 10:23:23 -07001107 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001108 element.commentThreads = THREADS;
Ben Rohlfs36be36d2022-06-24 18:10:45 +02001109 element.showFindingsTab = true;
Chris Poucet973ecc92022-06-13 10:44:07 +02001110 await element.updateComplete;
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001111 const paperTabs = element.shadowRoot!.querySelector('#primaryTabs')!;
Ben Rohlfs36be36d2022-06-24 18:10:45 +02001112 const tabs = paperTabs.querySelectorAll('paper-tab');
1113 assert.isTrue(tabs.length > 3);
1114 assert.equal(tabs[3].dataset.name, 'findings');
1115 tap(tabs[3]);
Chris Poucet973ecc92022-06-13 10:44:07 +02001116 await element.updateComplete;
Kasper Nilssonbbd28672018-08-01 10:23:23 -07001117 });
Milutin Kristofic7a86db12019-08-07 15:26:13 +02001118
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001119 test('robot comments count per patchset', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001120 const count = element.robotCommentCountPerPatchSet(THREADS);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001121 const expectedCount = {
1122 2: 1,
1123 3: 1,
1124 4: 2,
1125 };
1126 assert.deepEqual(count, expectedCount);
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001127 assert.equal(
Chris Poucet973ecc92022-06-13 10:44:07 +02001128 element.computeText(createRevision(2), THREADS),
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001129 'Patchset 2 (1 finding)'
1130 );
1131 assert.equal(
Chris Poucet973ecc92022-06-13 10:44:07 +02001132 element.computeText(createRevision(4), THREADS),
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001133 'Patchset 4 (2 findings)'
1134 );
1135 assert.equal(
Chris Poucet973ecc92022-06-13 10:44:07 +02001136 element.computeText(createRevision(5), THREADS),
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001137 'Patchset 5'
1138 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001139 });
Milutin Kristofic7a86db12019-08-07 15:26:13 +02001140
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001141 test('only robot comments are rendered', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001142 assert.equal(element.computeRobotCommentThreads().length, 2);
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001143 assert.equal(
Chris Poucet973ecc92022-06-13 10:44:07 +02001144 (
1145 element.computeRobotCommentThreads()[0]
1146 .comments[0] as RobotCommentInfo
1147 ).robot_id,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001148 'rc1'
1149 );
1150 assert.equal(
Chris Poucet973ecc92022-06-13 10:44:07 +02001151 (
1152 element.computeRobotCommentThreads()[1]
1153 .comments[0] as RobotCommentInfo
1154 ).robot_id,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001155 'rc2'
1156 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001157 });
1158
Chris Pouceta2e173e2021-08-31 01:04:04 +00001159 test('changing patchsets resets robot comments', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001160 assertIsDefined(element.change);
1161 const newChange = {...element.change};
1162 newChange.current_revision = 'rev3' as CommitId;
1163 element.change = newChange;
1164 await element.updateComplete;
1165 assert.equal(element.computeRobotCommentThreads().length, 1);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001166 });
1167
1168 test('Show more button is hidden', () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001169 assert.isNull(element.shadowRoot!.querySelector('.show-robot-comments'));
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001170 });
1171
1172 suite('robot comments show more button', () => {
Chris Pouceta2e173e2021-08-31 01:04:04 +00001173 setup(async () => {
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001174 const arr = [];
1175 for (let i = 0; i <= 30; i++) {
1176 arr.push(...THREADS);
1177 }
Chris Poucet973ecc92022-06-13 10:44:07 +02001178 element.commentThreads = arr;
1179 await element.updateComplete;
Milutin Kristofic7a86db12019-08-07 15:26:13 +02001180 });
1181
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001182 test('Show more button is rendered', () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001183 assert.isOk(element.shadowRoot!.querySelector('.show-robot-comments'));
1184 assert.equal(
Chris Poucet973ecc92022-06-13 10:44:07 +02001185 element.computeRobotCommentThreads().length,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001186 ROBOT_COMMENTS_LIMIT
1187 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001188 });
1189
Chris Pouceta2e173e2021-08-31 01:04:04 +00001190 test('Clicking show more button renders all comments', async () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001191 tap(element.shadowRoot!.querySelector('.show-robot-comments')!);
Chris Poucet973ecc92022-06-13 10:44:07 +02001192 await element.updateComplete;
1193 assert.equal(element.computeRobotCommentThreads().length, 62);
Milutin Kristofic7a86db12019-08-07 15:26:13 +02001194 });
1195 });
Andrew Bonventre547b8ab2015-12-01 01:02:00 -05001196 });
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001197
Chris Poucet973ecc92022-06-13 10:44:07 +02001198 test('reply button is not visible when logged out', async () => {
1199 assertIsDefined(element.replyBtn);
1200 element.loggedIn = false;
1201 await element.updateComplete;
1202 assert.equal(getComputedStyle(element.replyBtn).display, 'none');
1203 element.loggedIn = true;
1204 await element.updateComplete;
1205 assert.notEqual(getComputedStyle(element.replyBtn).display, 'none');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001206 });
1207
Chris Poucet973ecc92022-06-13 10:44:07 +02001208 test('download tap calls handleOpenDownloadDialog', () => {
1209 assertIsDefined(element.actions);
1210 const openDialogStub = sinon.stub(element, 'handleOpenDownloadDialog');
1211 element.actions.dispatchEvent(
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001212 new CustomEvent('download-tap', {
1213 composed: true,
1214 bubbles: true,
1215 })
1216 );
1217 assert.isTrue(openDialogStub.called);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001218 });
1219
Chris Pouceta2e173e2021-08-31 01:04:04 +00001220 test('fetches the server config on attached', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001221 await element.updateComplete;
Chris Pouceta2e173e2021-08-31 01:04:04 +00001222 assert.equal(
Chris Poucet973ecc92022-06-13 10:44:07 +02001223 element.serverConfig!.user.anonymous_coward_name,
Chris Pouceta2e173e2021-08-31 01:04:04 +00001224 'test coward name'
1225 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001226 });
1227
Chris Poucet973ecc92022-06-13 10:44:07 +02001228 test('changeStatuses', async () => {
1229 element.loading = false;
1230 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +02001231 ...createChangeViewChange(),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001232 revisions: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001233 rev2: createRevision(2),
1234 rev1: createRevision(1),
1235 rev13: createRevision(13),
1236 rev3: createRevision(3),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001237 },
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001238 current_revision: 'rev3' as CommitId,
Dmitrii Filippov3bf68892020-07-12 00:19:10 +02001239 status: ChangeStatus.MERGED,
1240 work_in_progress: true,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001241 labels: {
1242 test: {
1243 all: [],
1244 default_value: 0,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001245 values: {},
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001246 approved: {},
1247 },
1248 },
1249 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001250 element.mergeable = true;
1251 await element.updateComplete;
Frank Borden88603372021-06-02 16:50:51 +02001252 const expectedStatuses = [ChangeStates.MERGED, ChangeStates.WIP];
Chris Poucet973ecc92022-06-13 10:44:07 +02001253 assert.deepEqual(element.changeStatuses, expectedStatuses);
Chris Poucetcaeea1b2021-08-19 22:12:56 +00001254 const statusChips =
1255 element.shadowRoot!.querySelectorAll('gr-change-status');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001256 assert.equal(statusChips.length, 2);
1257 });
1258
Dhruv Srivastava69a51732021-04-14 18:23:00 +02001259 suite('ChangeStatus revert', () => {
Chris Pouceta2e173e2021-08-31 01:04:04 +00001260 test('do not show any chip if no revert created', async () => {
Dhruv Srivastava4b634ac2021-04-19 12:18:53 +02001261 const change = {
Ben Rohlfsa16c51a2021-11-22 12:50:55 +01001262 ...createParsedChange(),
Dhruv Srivastava4b634ac2021-04-19 12:18:53 +02001263 messages: createChangeMessages(2),
1264 };
1265 const getChangeStub = stubRestApi('getChange');
1266 getChangeStub.onFirstCall().returns(
1267 Promise.resolve({
1268 ...createChange(),
1269 })
1270 );
1271 getChangeStub.onSecondCall().returns(
1272 Promise.resolve({
1273 ...createChange(),
1274 })
1275 );
Chris Poucet973ecc92022-06-13 10:44:07 +02001276 element.change = change;
1277 element.mergeable = true;
1278 element.currentRevisionActions = {submit: {enabled: true}};
1279 assert.isTrue(element.isSubmitEnabled());
1280 await element.updateComplete;
1281 element.computeRevertSubmitted(element.change);
1282 await element.updateComplete;
Chris Pouceta2e173e2021-08-31 01:04:04 +00001283 assert.isFalse(
Chris Poucet973ecc92022-06-13 10:44:07 +02001284 element.changeStatuses?.includes(ChangeStates.REVERT_SUBMITTED)
Chris Pouceta2e173e2021-08-31 01:04:04 +00001285 );
1286 assert.isFalse(
Chris Poucet973ecc92022-06-13 10:44:07 +02001287 element.changeStatuses?.includes(ChangeStates.REVERT_CREATED)
Chris Pouceta2e173e2021-08-31 01:04:04 +00001288 );
Dhruv Srivastava4b634ac2021-04-19 12:18:53 +02001289 });
1290
Chris Pouceta2e173e2021-08-31 01:04:04 +00001291 test('do not show any chip if all reverts are abandoned', async () => {
Dhruv Srivastava4a557f22021-04-21 14:10:09 +02001292 const change = {
Ben Rohlfsa16c51a2021-11-22 12:50:55 +01001293 ...createParsedChange(),
Dhruv Srivastava4a557f22021-04-21 14:10:09 +02001294 messages: createChangeMessages(2),
1295 };
1296 change.messages[0].message = 'Created a revert of this change as 12345';
1297 change.messages[0].tag = MessageTag.TAG_REVERT as ReviewInputTag;
1298
1299 change.messages[1].message = 'Created a revert of this change as 23456';
1300 change.messages[1].tag = MessageTag.TAG_REVERT as ReviewInputTag;
1301
1302 const getChangeStub = stubRestApi('getChange');
1303 getChangeStub.onFirstCall().returns(
1304 Promise.resolve({
1305 ...createChange(),
1306 status: ChangeStatus.ABANDONED,
1307 })
1308 );
1309 getChangeStub.onSecondCall().returns(
1310 Promise.resolve({
1311 ...createChange(),
1312 status: ChangeStatus.ABANDONED,
1313 })
1314 );
Chris Poucet973ecc92022-06-13 10:44:07 +02001315 element.change = change;
1316 element.mergeable = true;
1317 element.currentRevisionActions = {submit: {enabled: true}};
1318 assert.isTrue(element.isSubmitEnabled());
1319 await element.updateComplete;
1320 element.computeRevertSubmitted(element.change);
1321 await element.updateComplete;
Chris Pouceta2e173e2021-08-31 01:04:04 +00001322 assert.isFalse(
Chris Poucet973ecc92022-06-13 10:44:07 +02001323 element.changeStatuses?.includes(ChangeStates.REVERT_SUBMITTED)
Chris Pouceta2e173e2021-08-31 01:04:04 +00001324 );
1325 assert.isFalse(
Chris Poucet973ecc92022-06-13 10:44:07 +02001326 element.changeStatuses?.includes(ChangeStates.REVERT_CREATED)
Chris Pouceta2e173e2021-08-31 01:04:04 +00001327 );
Dhruv Srivastava4a557f22021-04-21 14:10:09 +02001328 });
1329
Chris Pouceta2e173e2021-08-31 01:04:04 +00001330 test('show revert created if no revert is merged', async () => {
Dhruv Srivastava69a51732021-04-14 18:23:00 +02001331 const change = {
Ben Rohlfsa16c51a2021-11-22 12:50:55 +01001332 ...createParsedChange(),
Dhruv Srivastava69a51732021-04-14 18:23:00 +02001333 messages: createChangeMessages(2),
1334 };
1335 change.messages[0].message = 'Created a revert of this change as 12345';
1336 change.messages[0].tag = MessageTag.TAG_REVERT as ReviewInputTag;
Dhruv Srivastava4a557f22021-04-21 14:10:09 +02001337
1338 change.messages[1].message = 'Created a revert of this change as 23456';
1339 change.messages[1].tag = MessageTag.TAG_REVERT as ReviewInputTag;
1340
Dhruv Srivastava69a51732021-04-14 18:23:00 +02001341 const getChangeStub = stubRestApi('getChange');
1342 getChangeStub.onFirstCall().returns(
1343 Promise.resolve({
1344 ...createChange(),
1345 })
1346 );
1347 getChangeStub.onSecondCall().returns(
1348 Promise.resolve({
1349 ...createChange(),
1350 })
1351 );
Chris Poucet973ecc92022-06-13 10:44:07 +02001352 element.change = change;
1353 element.mergeable = true;
1354 element.currentRevisionActions = {submit: {enabled: true}};
1355 assert.isTrue(element.isSubmitEnabled());
1356 await element.updateComplete;
1357 element.computeRevertSubmitted(element.change);
1358 // Wait for promises to settle.
Chris Pouceta2e173e2021-08-31 01:04:04 +00001359 await flush();
Chris Poucet973ecc92022-06-13 10:44:07 +02001360 await element.updateComplete;
Chris Pouceta2e173e2021-08-31 01:04:04 +00001361 assert.isFalse(
Chris Poucet973ecc92022-06-13 10:44:07 +02001362 element.changeStatuses?.includes(ChangeStates.REVERT_SUBMITTED)
Chris Pouceta2e173e2021-08-31 01:04:04 +00001363 );
1364 assert.isTrue(
Chris Poucet973ecc92022-06-13 10:44:07 +02001365 element.changeStatuses?.includes(ChangeStates.REVERT_CREATED)
Chris Pouceta2e173e2021-08-31 01:04:04 +00001366 );
Dhruv Srivastava69a51732021-04-14 18:23:00 +02001367 });
1368
Chris Pouceta2e173e2021-08-31 01:04:04 +00001369 test('show revert submitted if revert is merged', async () => {
Dhruv Srivastava69a51732021-04-14 18:23:00 +02001370 const change = {
Ben Rohlfsa16c51a2021-11-22 12:50:55 +01001371 ...createParsedChange(),
Dhruv Srivastava69a51732021-04-14 18:23:00 +02001372 messages: createChangeMessages(2),
1373 };
1374 change.messages[0].message = 'Created a revert of this change as 12345';
1375 change.messages[0].tag = MessageTag.TAG_REVERT as ReviewInputTag;
1376 const getChangeStub = stubRestApi('getChange');
1377 getChangeStub.onFirstCall().returns(
1378 Promise.resolve({
1379 ...createChange(),
1380 status: ChangeStatus.MERGED,
1381 })
1382 );
1383 getChangeStub.onSecondCall().returns(
1384 Promise.resolve({
1385 ...createChange(),
1386 })
1387 );
Chris Poucet973ecc92022-06-13 10:44:07 +02001388 element.change = change;
1389 element.mergeable = true;
1390 element.currentRevisionActions = {submit: {enabled: true}};
1391 assert.isTrue(element.isSubmitEnabled());
1392 await element.updateComplete;
1393 element.computeRevertSubmitted(element.change);
1394 // Wait for promises to settle.
Chris Pouceta2e173e2021-08-31 01:04:04 +00001395 await flush();
Chris Poucet973ecc92022-06-13 10:44:07 +02001396 await element.updateComplete;
Chris Pouceta2e173e2021-08-31 01:04:04 +00001397 assert.isFalse(
Chris Poucet973ecc92022-06-13 10:44:07 +02001398 element.changeStatuses?.includes(ChangeStates.REVERT_CREATED)
Chris Pouceta2e173e2021-08-31 01:04:04 +00001399 );
1400 assert.isTrue(
Chris Poucet973ecc92022-06-13 10:44:07 +02001401 element.changeStatuses?.includes(ChangeStates.REVERT_SUBMITTED)
Chris Pouceta2e173e2021-08-31 01:04:04 +00001402 );
Dhruv Srivastava69a51732021-04-14 18:23:00 +02001403 });
1404 });
1405
Chris Poucetdd2d0102022-05-13 14:09:39 +02001406 test('diff preferences open when open-diff-prefs is fired', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001407 await element.updateComplete;
1408 assertIsDefined(element.fileList);
1409 assertIsDefined(element.fileListHeader);
1410 await element.fileList.updateComplete;
1411 const overlayOpenStub = sinon.stub(element.fileList, 'openDiffPrefs');
1412 element.fileListHeader.dispatchEvent(
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001413 new CustomEvent('open-diff-prefs', {
1414 composed: true,
1415 bubbles: true,
1416 })
1417 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001418 assert.isTrue(overlayOpenStub.called);
1419 });
1420
Chris Poucet973ecc92022-06-13 10:44:07 +02001421 test('prepareCommitMsgForLinkify', () => {
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001422 let commitMessage = 'R=test@google.com';
Chris Poucet973ecc92022-06-13 10:44:07 +02001423 let result = element.prepareCommitMsgForLinkify(commitMessage);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001424 assert.equal(result, 'R=\u200Btest@google.com');
1425
1426 commitMessage = 'R=test@google.com\nR=test@google.com';
Chris Poucet973ecc92022-06-13 10:44:07 +02001427 result = element.prepareCommitMsgForLinkify(commitMessage);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001428 assert.equal(result, 'R=\u200Btest@google.com\nR=\u200Btest@google.com');
1429
1430 commitMessage = 'CC=test@google.com';
Chris Poucet973ecc92022-06-13 10:44:07 +02001431 result = element.prepareCommitMsgForLinkify(commitMessage);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001432 assert.equal(result, 'CC=\u200Btest@google.com');
David Ostrovskya2401c12020-05-03 19:29:26 +02001433 });
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001434
1435 test('_isSubmitEnabled', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001436 assert.isFalse(element.isSubmitEnabled());
1437 element.currentRevisionActions = {submit: {}};
1438 assert.isFalse(element.isSubmitEnabled());
1439 element.currentRevisionActions = {submit: {enabled: true}};
1440 assert.isTrue(element.isSubmitEnabled());
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001441 });
1442
Chris Poucet973ecc92022-06-13 10:44:07 +02001443 test('reload is called when an approved label is removed', async () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001444 const vote: ApprovalInfo = {
1445 ...createApproval(),
1446 _account_id: 1 as AccountId,
1447 name: 'bojack',
1448 value: 1,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001449 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001450 element.changeNum = TEST_NUMERIC_CHANGE_ID;
1451 element.patchRange = {
Ben Rohlfs58267b72022-05-27 15:59:18 +02001452 basePatchNum: PARENT,
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +01001453 patchNum: 1 as RevisionPatchSetNum,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001454 };
1455 const change = {
Chris Poucet973ecc92022-06-13 10:44:07 +02001456 ...createParsedChange(),
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001457 owner: createAccountWithIdNameAndEmail(),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001458 revisions: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001459 rev2: createRevision(2),
1460 rev1: createRevision(1),
1461 rev13: createRevision(13),
1462 rev3: createRevision(3),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001463 },
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001464 current_revision: 'rev3' as CommitId,
1465 status: ChangeStatus.NEW,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001466 labels: {
1467 test: {
1468 all: [vote],
1469 default_value: 0,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001470 values: {},
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001471 approved: {},
1472 },
1473 },
1474 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001475 element.change = change;
1476 await element.updateComplete;
Ben Rohlfs66367b62021-04-30 10:06:32 +02001477 const reloadStub = sinon.stub(element, 'loadData');
Chris Poucet973ecc92022-06-13 10:44:07 +02001478 const newChange = {...element.change};
1479 (newChange.labels!.test! as DetailedLabelInfo).all = [];
1480 element.change = deepClone(newChange);
1481 await element.updateComplete;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001482 assert.isFalse(reloadStub.called);
Chris Poucet973ecc92022-06-13 10:44:07 +02001483
1484 assert.isDefined(element.change);
1485 const testLabels: DetailedLabelInfo & QuickLabelInfo =
1486 newChange.labels!.test;
1487 assertIsDefined(testLabels);
1488 testLabels.all!.push(vote);
1489 testLabels.all!.push(vote);
1490 testLabels.approved = vote;
1491 element.change = deepClone(newChange);
1492 await element.updateComplete;
1493 assert.isFalse(reloadStub.called);
1494
1495 assert.isDefined(element.change);
1496 (newChange.labels!.test! as DetailedLabelInfo).all = [];
1497 element.change = deepClone(newChange);
1498 await element.updateComplete;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001499 assert.isTrue(reloadStub.called);
1500 assert.isTrue(reloadStub.calledOnce);
1501 });
1502
1503 test('reply button has updated count when there are drafts', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001504 const getLabel = (canReview: boolean) => {
1505 element.change!.actions!.ready = {enabled: canReview};
1506 return element.computeReplyButtonLabel();
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001507 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001508 element.change = createParsedChange();
1509 element.change.actions = {};
1510 element.diffDrafts = undefined;
1511 assert.equal(getLabel(false), 'Reply');
1512 assert.equal(getLabel(true), 'Reply');
1513
1514 element.diffDrafts = {};
1515 assert.equal(getLabel(false), 'Reply');
1516 assert.equal(getLabel(true), 'Start Review');
1517
1518 element.diffDrafts = {
1519 'file1.txt': [createDraft()],
1520 'file2.txt': [createDraft(), createDraft()],
1521 };
1522 assert.equal(getLabel(false), 'Reply (3)');
1523 assert.equal(getLabel(true), 'Start Review (3)');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001524 });
1525
Chris Poucet973ecc92022-06-13 10:44:07 +02001526 test('change num change', async () => {
Ben Rohlfs3a6ff7e2021-01-18 14:08:39 +01001527 const change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +02001528 ...createChangeViewChange(),
Ben Rohlfs3a6ff7e2021-01-18 14:08:39 +01001529 labels: {},
1530 } as ParsedChangeInfo;
Chris Poucet973ecc92022-06-13 10:44:07 +02001531 element.changeNum = undefined;
1532 element.patchRange = {
Ben Rohlfs58267b72022-05-27 15:59:18 +02001533 basePatchNum: PARENT,
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +01001534 patchNum: 2 as RevisionPatchSetNum,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001535 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001536 element.change = change;
1537 assertIsDefined(element.fileList);
1538 assert.equal(element.fileList.numFilesShown, DEFAULT_NUM_FILES_SHOWN);
1539 element.fileList.numFilesShown = 150;
Dhruv65b97262022-06-13 15:05:05 +02001540 element.fileList.selectedIndex = 15;
Chris Poucet973ecc92022-06-13 10:44:07 +02001541 await element.updateComplete;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001542
Chris Poucet973ecc92022-06-13 10:44:07 +02001543 element.changeNum = 2 as NumericChangeId;
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001544 element.params = {
1545 ...createAppElementChangeViewParams(),
1546 changeNum: 2 as NumericChangeId,
1547 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001548 await element.updateComplete;
1549 assert.equal(element.fileList.numFilesShown, DEFAULT_NUM_FILES_SHOWN);
Dhruv65b97262022-06-13 15:05:05 +02001550 assert.equal(element.fileList.selectedIndex, 0);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001551 });
1552
Ben Rohlfs71a8dee2021-06-22 10:06:15 +02001553 test('don’t reload entire page when patchRange changes', async () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001554 const reloadStub = sinon
Ben Rohlfs66367b62021-04-30 10:06:32 +02001555 .stub(element, 'loadData')
Han-Wen Nienhuys577ce0a2021-08-11 12:11:17 +02001556 .callsFake(() => Promise.resolve());
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001557 const reloadPatchDependentStub = sinon
Chris Poucet973ecc92022-06-13 10:44:07 +02001558 .stub(element, 'reloadPatchNumDependentResources')
Dhruv Srivastava09a1b5a2021-01-20 09:28:15 +01001559 .callsFake(() => Promise.resolve([undefined, undefined, undefined]));
Chris Poucet973ecc92022-06-13 10:44:07 +02001560 assertIsDefined(element.fileList);
1561 await element.fileList.updateComplete;
1562 const collapseStub = sinon.stub(element.fileList, 'collapseAllDiffs');
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001563 const value: AppElementChangeViewParams = {
1564 ...createAppElementChangeViewParams(),
1565 view: GerritView.CHANGE,
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +01001566 patchNum: 1 as RevisionPatchSetNum,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001567 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001568 element.changeNum = undefined;
Ben Rohlfs71a8dee2021-06-22 10:06:15 +02001569 element.params = value;
Chris Poucet973ecc92022-06-13 10:44:07 +02001570 await element.updateComplete;
Dhruv Srivastava105fa212021-09-03 12:16:30 +00001571 assert.isTrue(reloadStub.calledOnce);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001572
Chris Poucet973ecc92022-06-13 10:44:07 +02001573 element.initialLoadComplete = true;
Dhruv65b97262022-06-13 15:05:05 +02001574 element.fileList.selectedIndex = 15;
Chris Poucet973ecc92022-06-13 10:44:07 +02001575 element.change = {
Ben Rohlfsd03b9b12021-05-12 12:04:50 +02001576 ...createChangeViewChange(),
1577 revisions: {
1578 rev1: createRevision(1),
1579 rev2: createRevision(2),
1580 },
1581 };
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001582
Dhruv Srivastava591b4902021-03-10 11:48:12 +01001583 value.basePatchNum = 1 as BasePatchSetNum;
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +01001584 value.patchNum = 2 as RevisionPatchSetNum;
Ben Rohlfs71a8dee2021-06-22 10:06:15 +02001585 element.params = {...value};
Chris Poucet973ecc92022-06-13 10:44:07 +02001586 await element.updateComplete;
Ben Rohlfs71a8dee2021-06-22 10:06:15 +02001587 await flush();
Dhruv65b97262022-06-13 15:05:05 +02001588 assert.equal(element.fileList.selectedIndex, 0);
Dhruv Srivastava105fa212021-09-03 12:16:30 +00001589 assert.isFalse(reloadStub.calledTwice);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001590 assert.isTrue(reloadPatchDependentStub.calledOnce);
Dhruv Srivastava105fa212021-09-03 12:16:30 +00001591 assert.isTrue(collapseStub.calledTwice);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001592 });
1593
Ben Rohlfs71a8dee2021-06-22 10:06:15 +02001594 test('reload ported comments when patchNum changes', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001595 assertIsDefined(element.fileList);
Han-Wen Nienhuys577ce0a2021-08-11 12:11:17 +02001596 sinon.stub(element, 'loadData').callsFake(() => Promise.resolve());
Ben Rohlfs1fe7f4d2021-12-06 11:21:49 +01001597 sinon.stub(element, 'loadAndSetCommitInfo');
Chris Poucet973ecc92022-06-13 10:44:07 +02001598 await element.updateComplete;
Chris Poucet6c6b54f2021-12-09 02:53:13 +01001599 const reloadPortedCommentsStub = sinon.stub(
1600 element.getCommentsModel(),
1601 'reloadPortedComments'
1602 );
1603 const reloadPortedDraftsStub = sinon.stub(
1604 element.getCommentsModel(),
1605 'reloadPortedDrafts'
1606 );
Chris Poucet973ecc92022-06-13 10:44:07 +02001607 sinon.stub(element.fileList, 'collapseAllDiffs');
Dhruv Srivastava09a1b5a2021-01-20 09:28:15 +01001608
1609 const value: AppElementChangeViewParams = {
1610 ...createAppElementChangeViewParams(),
1611 view: GerritView.CHANGE,
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +01001612 patchNum: 1 as RevisionPatchSetNum,
Dhruv Srivastava09a1b5a2021-01-20 09:28:15 +01001613 };
Ben Rohlfs71a8dee2021-06-22 10:06:15 +02001614 element.params = value;
Chris Poucet973ecc92022-06-13 10:44:07 +02001615 await element.updateComplete;
Dhruv Srivastava09a1b5a2021-01-20 09:28:15 +01001616
Chris Poucet973ecc92022-06-13 10:44:07 +02001617 element.initialLoadComplete = true;
1618 element.change = {
Ben Rohlfsd03b9b12021-05-12 12:04:50 +02001619 ...createChangeViewChange(),
1620 revisions: {
1621 rev1: createRevision(1),
1622 rev2: createRevision(2),
1623 },
1624 };
Dhruv Srivastava09a1b5a2021-01-20 09:28:15 +01001625
Dhruv Srivastava591b4902021-03-10 11:48:12 +01001626 value.basePatchNum = 1 as BasePatchSetNum;
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +01001627 value.patchNum = 2 as RevisionPatchSetNum;
Ben Rohlfs71a8dee2021-06-22 10:06:15 +02001628 element.params = {...value};
Chris Poucet973ecc92022-06-13 10:44:07 +02001629 await element.updateComplete;
Dhruv Srivastava09a1b5a2021-01-20 09:28:15 +01001630 assert.isTrue(reloadPortedCommentsStub.calledOnce);
Ben Rohlfs718cec02021-11-03 09:04:15 +01001631 assert.isTrue(reloadPortedDraftsStub.calledOnce);
Dhruv Srivastava09a1b5a2021-01-20 09:28:15 +01001632 });
1633
Dhruv Srivastava49f0a7a2021-10-06 12:03:01 +01001634 test('do not reload entire page when patchRange doesnt change', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001635 assertIsDefined(element.fileList);
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001636 const reloadStub = sinon
Ben Rohlfs66367b62021-04-30 10:06:32 +02001637 .stub(element, 'loadData')
Han-Wen Nienhuys577ce0a2021-08-11 12:11:17 +02001638 .callsFake(() => Promise.resolve());
Chris Poucet973ecc92022-06-13 10:44:07 +02001639 const collapseStub = sinon.stub(element.fileList, 'collapseAllDiffs');
Chris Poucetcaeea1b2021-08-19 22:12:56 +00001640 const value: AppElementChangeViewParams =
1641 createAppElementChangeViewParams();
Ben Rohlfs71a8dee2021-06-22 10:06:15 +02001642 element.params = value;
Dhruv Srivastava49f0a7a2021-10-06 12:03:01 +01001643 // change already loaded
Chris Poucet973ecc92022-06-13 10:44:07 +02001644 assert.isOk(element.changeNum);
1645 await element.updateComplete;
Dhruv Srivastava49f0a7a2021-10-06 12:03:01 +01001646 assert.isFalse(reloadStub.calledOnce);
Chris Poucet973ecc92022-06-13 10:44:07 +02001647 element.initialLoadComplete = true;
Ben Rohlfs71a8dee2021-06-22 10:06:15 +02001648 element.params = {...value};
Chris Poucet973ecc92022-06-13 10:44:07 +02001649 await element.updateComplete;
Dhruv Srivastava49f0a7a2021-10-06 12:03:01 +01001650 assert.isFalse(reloadStub.calledTwice);
1651 assert.isFalse(collapseStub.calledTwice);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001652 });
1653
Ben Rohlfsc04f61a2021-12-02 14:36:54 +01001654 test('forceReload updates the change', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001655 assertIsDefined(element.fileList);
Ben Rohlfsc04f61a2021-12-02 14:36:54 +01001656 const getChangeStub = stubRestApi('getChangeDetail').returns(
1657 Promise.resolve(createParsedChange())
1658 );
1659 const loadDataStub = sinon
1660 .stub(element, 'loadData')
1661 .callsFake(() => Promise.resolve());
Chris Poucet973ecc92022-06-13 10:44:07 +02001662 const collapseStub = sinon.stub(element.fileList, 'collapseAllDiffs');
Ben Rohlfsc04f61a2021-12-02 14:36:54 +01001663 element.params = {...createAppElementChangeViewParams(), forceReload: true};
Chris Poucet973ecc92022-06-13 10:44:07 +02001664 await element.updateComplete;
Ben Rohlfsc04f61a2021-12-02 14:36:54 +01001665 assert.isTrue(getChangeStub.called);
1666 assert.isTrue(loadDataStub.called);
1667 assert.isTrue(collapseStub.called);
Chris Poucet973ecc92022-06-13 10:44:07 +02001668 // patchNum is set by changeChanged, so this verifies that change was set.
1669 assert.isOk(element.patchRange?.patchNum);
Ben Rohlfsc04f61a2021-12-02 14:36:54 +01001670 });
1671
Ben Rohlfs71a8dee2021-06-22 10:06:15 +02001672 test('do not handle new change numbers', async () => {
1673 const recreateSpy = sinon.spy();
1674 element.addEventListener('recreate-change-view', recreateSpy);
1675
Chris Poucetcaeea1b2021-08-19 22:12:56 +00001676 const value: AppElementChangeViewParams =
1677 createAppElementChangeViewParams();
Ben Rohlfs71a8dee2021-06-22 10:06:15 +02001678 element.params = value;
Chris Poucet973ecc92022-06-13 10:44:07 +02001679 await element.updateComplete;
Ben Rohlfs71a8dee2021-06-22 10:06:15 +02001680 assert.isFalse(recreateSpy.calledOnce);
1681
1682 value.changeNum = 555111333 as NumericChangeId;
1683 element.params = {...value};
Chris Poucet973ecc92022-06-13 10:44:07 +02001684 await element.updateComplete;
Ben Rohlfs71a8dee2021-06-22 10:06:15 +02001685 assert.isTrue(recreateSpy.calledOnce);
1686 });
1687
Ben Rohlfsbdf135d2021-12-20 15:09:02 +01001688 test('related changes are updated when loadData is called', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001689 await element.updateComplete;
Milutin Kristofic8803ea02020-12-09 23:34:39 +01001690 const relatedChanges = element.shadowRoot!.querySelector(
1691 '#relatedChanges'
1692 ) as GrRelatedChangesList;
Ben Rohlfsbdf135d2021-12-20 15:09:02 +01001693 const reloadStub = sinon.stub(relatedChanges, 'reload');
1694 stubRestApi('getMergeable').returns(
1695 Promise.resolve({...createMergeable(), mergeable: true})
1696 );
1697
1698 element.params = createAppElementChangeViewParams();
Chris Poucetbf65b8f2022-01-18 21:18:12 +00001699 element.getChangeModel().setState({
Ben Rohlfsbdf135d2021-12-20 15:09:02 +01001700 loadingStatus: LoadingStatus.LOADED,
1701 change: {
1702 ...createChangeViewChange(),
1703 },
1704 });
1705
Chris Pouceta2e173e2021-08-31 01:04:04 +00001706 await element.loadData(true);
1707 assert.isFalse(navigateToChangeStub.called);
Ben Rohlfsbdf135d2021-12-20 15:09:02 +01001708 assert.isTrue(reloadStub.called);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001709 });
1710
Chris Poucet973ecc92022-06-13 10:44:07 +02001711 test('computeCopyTextForTitle', () => {
1712 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +02001713 ...createChangeViewChange(),
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001714 _number: 123 as NumericChangeId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001715 subject: 'test subject',
1716 revisions: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001717 rev1: createRevision(1),
1718 rev3: createRevision(3),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001719 },
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001720 current_revision: 'rev3' as CommitId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001721 };
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001722 sinon.stub(GerritNav, 'getUrlForChange').returns('/change/123');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001723 assert.equal(
Chris Poucet973ecc92022-06-13 10:44:07 +02001724 element.computeCopyTextForTitle(),
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001725 `123: test subject | http://${location.host}/change/123`
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001726 );
1727 });
1728
1729 test('get latest revision', () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001730 let change: ChangeInfo = {
1731 ...createChange(),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001732 revisions: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001733 rev1: createRevision(1),
1734 rev3: createRevision(3),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001735 },
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001736 current_revision: 'rev3' as CommitId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001737 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001738 assert.equal(element.getLatestRevisionSHA(change), 'rev3');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001739 change = {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001740 ...createChange(),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001741 revisions: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001742 rev1: createRevision(1),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001743 },
Dhruv Srivastavada276592021-04-07 14:51:51 +02001744 current_revision: undefined,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001745 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001746 assert.equal(element.getLatestRevisionSHA(change), 'rev1');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001747 });
1748
1749 test('show commit message edit button', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001750 const change = createParsedChange();
1751 const mergedChanged: ParsedChangeInfo = {
1752 ...createParsedChange(),
Dmitrii Filippov4e4522e2020-05-06 12:50:49 +02001753 status: ChangeStatus.MERGED,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001754 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001755 assert.isTrue(element.computeHideEditCommitMessage(false, false, change));
1756 assert.isTrue(element.computeHideEditCommitMessage(true, true, change));
1757 assert.isTrue(element.computeHideEditCommitMessage(false, true, change));
1758 assert.isFalse(element.computeHideEditCommitMessage(true, false, change));
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001759 assert.isTrue(
Chris Poucet973ecc92022-06-13 10:44:07 +02001760 element.computeHideEditCommitMessage(true, false, mergedChanged)
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001761 );
1762 assert.isTrue(
Chris Poucet973ecc92022-06-13 10:44:07 +02001763 element.computeHideEditCommitMessage(true, false, change, true)
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001764 );
1765 assert.isFalse(
Chris Poucet973ecc92022-06-13 10:44:07 +02001766 element.computeHideEditCommitMessage(true, false, change, false)
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001767 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001768 });
1769
Chris Poucet973ecc92022-06-13 10:44:07 +02001770 test('handleCommitMessageSave trims trailing whitespace', async () => {
1771 element.change = createChangeViewChange();
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001772 // Response code is 500, because we want to avoid window reloading
Ben Rohlfs3a6ff7e2021-01-18 14:08:39 +01001773 const putStub = stubRestApi('putChangeCommitMessage').returns(
1774 Promise.resolve(new Response(null, {status: 500}))
1775 );
Chris Poucet973ecc92022-06-13 10:44:07 +02001776 await element.updateComplete;
Frank Borden6988bdf2021-04-07 14:42:00 +02001777 const mockEvent = (content: string) =>
1778 new CustomEvent('', {detail: {content}});
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001779
Chris Poucet973ecc92022-06-13 10:44:07 +02001780 assertIsDefined(element.commitMessageEditor);
1781 element.handleCommitMessageSave(mockEvent('test \n test '));
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001782 assert.equal(putStub.lastCall.args[1], 'test\n test');
Chris Poucet973ecc92022-06-13 10:44:07 +02001783 element.commitMessageEditor.disabled = false;
1784 element.handleCommitMessageSave(mockEvent(' test\ntest'));
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001785 assert.equal(putStub.lastCall.args[1], ' test\ntest');
Chris Poucet973ecc92022-06-13 10:44:07 +02001786 element.commitMessageEditor.disabled = false;
1787 element.handleCommitMessageSave(mockEvent('\n\n\n\n\n\n\n\n'));
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001788 assert.equal(putStub.lastCall.args[1], '\n\n\n\n\n\n\n\n');
1789 });
1790
Chris Pouceta2e173e2021-08-31 01:04:04 +00001791 test('topic is coalesced to null', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001792 sinon.stub(element, 'changeChanged');
Chris Poucetbf65b8f2022-01-18 21:18:12 +00001793 element.getChangeModel().setState({
Ben Rohlfs61bafc22021-11-29 10:40:08 +01001794 loadingStatus: LoadingStatus.LOADED,
Ben Rohlfsa16c51a2021-11-22 12:50:55 +01001795 change: {
Dhruv Srivastavada276592021-04-07 14:51:51 +02001796 ...createChangeViewChange(),
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001797 labels: {},
1798 current_revision: 'foo' as CommitId,
1799 revisions: {foo: createRevision()},
Ben Rohlfsa16c51a2021-11-22 12:50:55 +01001800 },
1801 });
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001802
Dhruv Srivastava21129812021-12-02 15:48:03 +01001803 await element.performPostChangeLoadTasks();
Chris Poucet973ecc92022-06-13 10:44:07 +02001804 assert.isNull(element.change!.topic);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001805 });
1806
Chris Pouceta2e173e2021-08-31 01:04:04 +00001807 test('commit sha is populated from getChangeDetail', async () => {
Chris Poucetbf65b8f2022-01-18 21:18:12 +00001808 element.getChangeModel().setState({
Ben Rohlfs61bafc22021-11-29 10:40:08 +01001809 loadingStatus: LoadingStatus.LOADED,
Ben Rohlfsa16c51a2021-11-22 12:50:55 +01001810 change: {
Dhruv Srivastavada276592021-04-07 14:51:51 +02001811 ...createChangeViewChange(),
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001812 labels: {},
1813 current_revision: 'foo' as CommitId,
1814 revisions: {foo: createRevision()},
Ben Rohlfsa16c51a2021-11-22 12:50:55 +01001815 },
1816 });
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001817
Dhruv Srivastava21129812021-12-02 15:48:03 +01001818 await element.performPostChangeLoadTasks();
Chris Poucet973ecc92022-06-13 10:44:07 +02001819 assert.equal('foo', element.commitInfo!.commit);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001820 });
1821
Chris Poucet973ecc92022-06-13 10:44:07 +02001822 test('getBasePatchNum', async () => {
1823 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +02001824 ...createChangeViewChange(),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001825 revisions: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001826 '98da160735fb81604b4c40e93c368f380539dd0e': createRevision(),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001827 },
1828 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001829 element.patchRange = {
Ben Rohlfs58267b72022-05-27 15:59:18 +02001830 basePatchNum: PARENT,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001831 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001832 await element.updateComplete;
1833 assert.equal(element.getBasePatchNum(), PARENT);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001834
Chris Poucet973ecc92022-06-13 10:44:07 +02001835 element.prefs = {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001836 ...createPreferences(),
1837 default_base_for_merges: DefaultBase.FIRST_PARENT,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001838 };
1839
Chris Poucet973ecc92022-06-13 10:44:07 +02001840 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +02001841 ...createChangeViewChange(),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001842 revisions: {
1843 '98da160735fb81604b4c40e93c368f380539dd0e': {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001844 ...createRevision(1),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001845 commit: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001846 ...createCommit(),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001847 parents: [
1848 {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001849 commit: '6e12bdf1176eb4ab24d8491ba3b6d0704409cde8' as CommitId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001850 subject: 'test',
1851 },
1852 {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001853 commit: '22f7db4754b5d9816fc581f3d9a6c0ef8429c841' as CommitId,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001854 subject: 'test3',
1855 },
1856 ],
1857 },
1858 },
1859 },
1860 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001861 await element.updateComplete;
1862 assert.equal(element.getBasePatchNum(), -1 as BasePatchSetNum);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001863
Chris Poucet973ecc92022-06-13 10:44:07 +02001864 element.patchRange.basePatchNum = PARENT;
1865 element.patchRange.patchNum = 1 as RevisionPatchSetNum;
1866 await element.updateComplete;
1867 assert.equal(element.getBasePatchNum(), PARENT);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001868 });
1869
Chris Poucet973ecc92022-06-13 10:44:07 +02001870 test('openReplyDialog called with `ANY` when coming from tap event', async () => {
1871 await element.updateComplete;
1872 assertIsDefined(element.replyBtn);
1873 const openStub = sinon.stub(element, 'openReplyDialog');
1874 tap(element.replyBtn);
Chris Pouceta2e173e2021-08-31 01:04:04 +00001875 assert(
Ben Rohlfs00049652021-10-25 16:40:38 +02001876 openStub.lastCall.calledWithExactly(FocusTarget.ANY),
Chris Poucet973ecc92022-06-13 10:44:07 +02001877 'openReplyDialog should have been passed ANY'
Chris Pouceta2e173e2021-08-31 01:04:04 +00001878 );
1879 assert.equal(openStub.callCount, 1);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001880 });
1881
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001882 test(
Chris Poucet973ecc92022-06-13 10:44:07 +02001883 'openReplyDialog called with `BODY` when coming from message reply' +
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001884 'event',
Chris Pouceta2e173e2021-08-31 01:04:04 +00001885 async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001886 await element.updateComplete;
1887 const openStub = sinon.stub(element, 'openReplyDialog');
Chris Pouceta2e173e2021-08-31 01:04:04 +00001888 element.messagesList!.dispatchEvent(
1889 new CustomEvent('reply', {
1890 detail: {message: {message: 'text'}},
1891 composed: true,
1892 bubbles: true,
1893 })
1894 );
Ben Rohlfs00049652021-10-25 16:40:38 +02001895 assert.isTrue(openStub.calledOnce);
1896 assert.equal(openStub.lastCall.args[0], FocusTarget.BODY);
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001897 }
1898 );
1899
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001900 test('reply dialog focus can be controlled', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001901 const openStub = sinon.stub(element, 'openReplyDialog');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001902
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001903 const e = new CustomEvent('show-reply-dialog', {
1904 detail: {value: {ccsOnly: false}},
1905 });
Chris Poucet973ecc92022-06-13 10:44:07 +02001906 element.handleShowReplyDialog(e);
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001907 assert(
1908 openStub.lastCall.calledWithExactly(FocusTarget.REVIEWERS),
Chris Poucet973ecc92022-06-13 10:44:07 +02001909 'openReplyDialog should have been passed REVIEWERS'
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001910 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001911 assert.equal(openStub.callCount, 1);
1912
1913 e.detail.value = {ccsOnly: true};
Chris Poucet973ecc92022-06-13 10:44:07 +02001914 element.handleShowReplyDialog(e);
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001915 assert(
1916 openStub.lastCall.calledWithExactly(FocusTarget.CCS),
Chris Poucet973ecc92022-06-13 10:44:07 +02001917 'openReplyDialog should have been passed CCS'
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001918 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001919 assert.equal(openStub.callCount, 2);
1920 });
1921
1922 test('getUrlParameter functionality', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001923 const locationStub = sinon.stub(element, 'getLocationSearch');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001924 locationStub.returns('?test');
1925 assert.equal(element._getUrlParameter('test'), 'test');
1926 locationStub.returns('?test2=12&test=3');
1927 assert.equal(element._getUrlParameter('test'), 'test');
1928 locationStub.returns('');
1929 assert.isNull(element._getUrlParameter('test'));
1930 locationStub.returns('?');
1931 assert.isNull(element._getUrlParameter('test'));
1932 locationStub.returns('?test2');
1933 assert.isNull(element._getUrlParameter('test'));
1934 });
1935
Chris Pouceta2e173e2021-08-31 01:04:04 +00001936 test('revert dialog opened with revert param', async () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001937 const awaitPluginsLoadedStub = sinon
1938 .stub(getPluginLoader(), 'awaitPluginsLoaded')
1939 .callsFake(() => Promise.resolve());
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001940
Chris Poucet973ecc92022-06-13 10:44:07 +02001941 element.patchRange = {
Ben Rohlfs58267b72022-05-27 15:59:18 +02001942 basePatchNum: PARENT,
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +01001943 patchNum: 2 as RevisionPatchSetNum,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001944 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001945 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +02001946 ...createChangeViewChange(),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001947 revisions: {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001948 rev1: createRevision(1),
1949 rev2: createRevision(2),
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001950 },
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001951 current_revision: 'rev1' as CommitId,
Dmitrii Filippov4e4522e2020-05-06 12:50:49 +02001952 status: ChangeStatus.MERGED,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001953 labels: {},
1954 actions: {},
1955 };
1956
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001957 sinon.stub(element, '_getUrlParameter').callsFake(param => {
1958 assert.equal(param, 'revert');
1959 return param;
1960 });
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001961
Chris Pouceta2e173e2021-08-31 01:04:04 +00001962 const promise = mockPromise();
Chris Poucet973ecc92022-06-13 10:44:07 +02001963 assertIsDefined(element.actions);
Chris Pouceta2e173e2021-08-31 01:04:04 +00001964 sinon
Chris Poucet973ecc92022-06-13 10:44:07 +02001965 .stub(element.actions, 'showRevertDialog')
Chris Pouceta2e173e2021-08-31 01:04:04 +00001966 .callsFake(() => promise.resolve());
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001967
Chris Poucet973ecc92022-06-13 10:44:07 +02001968 element.maybeShowRevertDialog();
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001969 assert.isTrue(awaitPluginsLoadedStub.called);
Chris Pouceta2e173e2021-08-31 01:04:04 +00001970 await promise;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001971 });
1972
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001973 suite('reply dialog tests', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001974 setup(async () => {
1975 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +02001976 ...createChangeViewChange(),
Ben Rohlfsa16c51a2021-11-22 12:50:55 +01001977 // element has latest info
1978 revisions: {rev1: createRevision()},
Dmitrii Filippov0695d402020-10-22 16:57:57 +02001979 messages: createChangeMessages(1),
Ben Rohlfsa16c51a2021-11-22 12:50:55 +01001980 current_revision: 'rev1' as CommitId,
1981 labels: {},
Dmitrii Filippov0695d402020-10-22 16:57:57 +02001982 };
Chris Poucet973ecc92022-06-13 10:44:07 +02001983 await element.updateComplete;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01001984 });
1985
Chris Pouceta2e173e2021-08-31 01:04:04 +00001986 test('show reply dialog on open-reply-dialog event', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02001987 const openReplyDialogStub = sinon.stub(element, 'openReplyDialog');
Tao Zhouda7463c2020-07-14 11:17:20 +02001988 element.dispatchEvent(
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01001989 new CustomEvent('open-reply-dialog', {
1990 composed: true,
1991 bubbles: true,
1992 detail: {},
1993 })
1994 );
Chris Poucet973ecc92022-06-13 10:44:07 +02001995 await element.updateComplete;
Chris Pouceta2e173e2021-08-31 01:04:04 +00001996 assert.isTrue(openReplyDialogStub.calledOnce);
Tao Zhouda7463c2020-07-14 11:17:20 +02001997 });
1998
Ben Rohlfs00049652021-10-25 16:40:38 +02001999 test('reply from comment adds quote text', async () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002000 const e = new CustomEvent('', {
2001 detail: {message: {message: 'quote text'}},
2002 });
Chris Poucet973ecc92022-06-13 10:44:07 +02002003 element.handleMessageReply(e);
Ben Rohlfs00049652021-10-25 16:40:38 +02002004 const dialog = await waitQueryAndAssert<GrReplyDialog>(
2005 element,
2006 '#replyDialog'
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002007 );
Ben Rohlfs00049652021-10-25 16:40:38 +02002008 const openSpy = sinon.spy(dialog, 'open');
Chris Poucet973ecc92022-06-13 10:44:07 +02002009 await element.updateComplete;
Ben Rohlfs00049652021-10-25 16:40:38 +02002010 await waitUntil(() => openSpy.called && !!openSpy.lastCall.args[1]);
2011 assert.equal(openSpy.lastCall.args[1], '> quote text\n\n');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002012 });
2013 });
2014
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002015 test('header class computation', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02002016 assert.equal(element.computeHeaderClass(), 'header');
2017 assertIsDefined(element.params);
2018 element.params.edit = true;
2019 assert.equal(element.computeHeaderClass(), 'header editMode');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002020 });
2021
Chris Poucet973ecc92022-06-13 10:44:07 +02002022 test('maybeScrollToMessage', async () => {
2023 await element.updateComplete;
Chris Pouceta2e173e2021-08-31 01:04:04 +00002024 const scrollStub = sinon.stub(element.messagesList!, 'scrollToMessage');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002025
Chris Poucet973ecc92022-06-13 10:44:07 +02002026 element.maybeScrollToMessage('');
Chris Pouceta2e173e2021-08-31 01:04:04 +00002027 assert.isFalse(scrollStub.called);
Chris Poucet973ecc92022-06-13 10:44:07 +02002028 element.maybeScrollToMessage('message');
Chris Pouceta2e173e2021-08-31 01:04:04 +00002029 assert.isFalse(scrollStub.called);
Chris Poucet973ecc92022-06-13 10:44:07 +02002030 element.maybeScrollToMessage('#message-TEST');
Chris Pouceta2e173e2021-08-31 01:04:04 +00002031 assert.isTrue(scrollStub.called);
2032 assert.equal(scrollStub.lastCall.args[0], 'TEST');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002033 });
2034
2035 test('topic update reloads related changes', () => {
Milutin Kristofic8803ea02020-12-09 23:34:39 +01002036 flush();
2037 const relatedChanges = element.shadowRoot!.querySelector(
2038 '#relatedChanges'
2039 ) as GrRelatedChangesList;
2040 const reloadStub = sinon.stub(relatedChanges, 'reload');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002041 element.dispatchEvent(new CustomEvent('topic-changed'));
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002042 assert.isTrue(reloadStub.calledOnce);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002043 });
2044
Chris Poucet973ecc92022-06-13 10:44:07 +02002045 test('computeEditMode', async () => {
2046 const callCompute = async (params: AppElementChangeViewParams) => {
2047 element.params = params;
2048 await element.updateComplete;
2049 return element.getEditMode();
2050 };
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002051 assert.isTrue(
Chris Poucet973ecc92022-06-13 10:44:07 +02002052 await callCompute({
2053 ...createAppElementChangeViewParams(),
2054 edit: true,
2055 basePatchNum: PARENT,
2056 patchNum: 1 as RevisionPatchSetNum,
2057 })
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002058 );
2059 assert.isFalse(
Chris Poucet973ecc92022-06-13 10:44:07 +02002060 await callCompute({
2061 ...createAppElementChangeViewParams(),
2062 basePatchNum: PARENT,
2063 patchNum: 1 as RevisionPatchSetNum,
2064 })
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002065 );
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002066 assert.isTrue(
Chris Poucet973ecc92022-06-13 10:44:07 +02002067 await callCompute({
2068 ...createAppElementChangeViewParams(),
2069 basePatchNum: 1 as BasePatchSetNum,
2070 patchNum: EDIT,
2071 })
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002072 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002073 });
2074
Chris Poucet973ecc92022-06-13 10:44:07 +02002075 test('processEdit', () => {
2076 element.patchRange = {};
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002077 const change: ParsedChangeInfo = {
Dhruv Srivastavada276592021-04-07 14:51:51 +02002078 ...createChangeViewChange(),
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002079 current_revision: 'foo' as CommitId,
2080 revisions: {
Ben Rohlfs5e167022021-12-06 11:48:22 +01002081 foo: {...createRevision()},
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002082 },
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002083 };
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002084
Ben Rohlfs1fe7f4d2021-12-06 11:21:49 +01002085 // With no edit, nothing happens.
Chris Poucet973ecc92022-06-13 10:44:07 +02002086 element.processEdit(change);
2087 assert.equal(element.patchRange.patchNum, undefined);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002088
Ben Rohlfs1fe7f4d2021-12-06 11:21:49 +01002089 change.revisions['bar'] = {
Ben Rohlfsef043172022-05-27 16:07:27 +02002090 _number: EDIT,
Ben Rohlfs1fe7f4d2021-12-06 11:21:49 +01002091 basePatchNum: 1 as BasePatchSetNum,
2092 commit: {
2093 ...createCommit(),
2094 commit: 'bar' as CommitId,
2095 },
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002096 fetch: {},
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002097 };
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002098
Ben Rohlfs1fe7f4d2021-12-06 11:21:49 +01002099 // When edit is set, but not patchNum, then switch to edit ps.
Chris Poucet973ecc92022-06-13 10:44:07 +02002100 element.processEdit(change);
2101 assert.equal(element.patchRange.patchNum, EDIT);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002102
Ben Rohlfs1fe7f4d2021-12-06 11:21:49 +01002103 // When edit is set, but patchNum as well, then keep patchNum.
Chris Poucet973ecc92022-06-13 10:44:07 +02002104 element.patchRange.patchNum = 5 as RevisionPatchSetNum;
Ben Rohlfs8ccb2d42021-12-08 11:22:20 +01002105 element.routerPatchNum = 5 as RevisionPatchSetNum;
Chris Poucet973ecc92022-06-13 10:44:07 +02002106 element.processEdit(change);
2107 assert.equal(element.patchRange.patchNum, 5 as RevisionPatchSetNum);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002108 });
2109
Frank Borden8198a832022-04-11 17:31:15 +02002110 test('file-action-tap handling', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02002111 element.patchRange = {
Ben Rohlfs58267b72022-05-27 15:59:18 +02002112 basePatchNum: PARENT,
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +01002113 patchNum: 1 as RevisionPatchSetNum,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002114 };
Chris Poucet973ecc92022-06-13 10:44:07 +02002115 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +02002116 ...createChangeViewChange(),
Milutin Kristoficbec88f12020-10-13 16:53:28 +02002117 };
Chris Poucet973ecc92022-06-13 10:44:07 +02002118 assertIsDefined(element.fileList);
2119 assertIsDefined(element.fileListHeader);
2120 const fileList = element.fileList;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002121 const Actions = GrEditConstants.Actions;
Chris Poucet973ecc92022-06-13 10:44:07 +02002122 element.fileListHeader.editMode = true;
2123 await element.fileListHeader.updateComplete;
2124 await element.updateComplete;
Frank Borden8198a832022-04-11 17:31:15 +02002125 const controls = queryAndAssert<GrEditControls>(
Chris Poucet973ecc92022-06-13 10:44:07 +02002126 element.fileListHeader,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002127 '#editControls'
Frank Borden8198a832022-04-11 17:31:15 +02002128 );
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002129 const openDeleteDialogStub = sinon.stub(controls, 'openDeleteDialog');
2130 const openRenameDialogStub = sinon.stub(controls, 'openRenameDialog');
2131 const openRestoreDialogStub = sinon.stub(controls, 'openRestoreDialog');
2132 const getEditUrlForDiffStub = sinon.stub(GerritNav, 'getEditUrlForDiff');
2133 const navigateToRelativeUrlStub = sinon.stub(
2134 GerritNav,
2135 'navigateToRelativeUrl'
2136 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002137
2138 // Delete
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002139 fileList.dispatchEvent(
2140 new CustomEvent('file-action-tap', {
2141 detail: {action: Actions.DELETE.id, path: 'foo'},
2142 bubbles: true,
2143 composed: true,
2144 })
2145 );
Chris Poucet973ecc92022-06-13 10:44:07 +02002146 await element.updateComplete;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002147
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002148 assert.isTrue(openDeleteDialogStub.called);
2149 assert.equal(openDeleteDialogStub.lastCall.args[0], 'foo');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002150
2151 // Restore
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002152 fileList.dispatchEvent(
2153 new CustomEvent('file-action-tap', {
2154 detail: {action: Actions.RESTORE.id, path: 'foo'},
2155 bubbles: true,
2156 composed: true,
2157 })
2158 );
Chris Poucet973ecc92022-06-13 10:44:07 +02002159 await element.updateComplete;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002160
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002161 assert.isTrue(openRestoreDialogStub.called);
2162 assert.equal(openRestoreDialogStub.lastCall.args[0], 'foo');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002163
2164 // Rename
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002165 fileList.dispatchEvent(
2166 new CustomEvent('file-action-tap', {
2167 detail: {action: Actions.RENAME.id, path: 'foo'},
2168 bubbles: true,
2169 composed: true,
2170 })
2171 );
Chris Poucet973ecc92022-06-13 10:44:07 +02002172 await element.updateComplete;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002173
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002174 assert.isTrue(openRenameDialogStub.called);
2175 assert.equal(openRenameDialogStub.lastCall.args[0], 'foo');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002176
2177 // Open
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002178 fileList.dispatchEvent(
2179 new CustomEvent('file-action-tap', {
2180 detail: {action: Actions.OPEN.id, path: 'foo'},
2181 bubbles: true,
2182 composed: true,
2183 })
2184 );
Chris Poucet973ecc92022-06-13 10:44:07 +02002185 await element.updateComplete;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002186
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002187 assert.isTrue(getEditUrlForDiffStub.called);
2188 assert.equal(getEditUrlForDiffStub.lastCall.args[1], 'foo');
Ben Rohlfsabaeacf2022-05-27 15:24:22 +02002189 assert.equal(
2190 getEditUrlForDiffStub.lastCall.args[2],
2191 1 as RevisionPatchSetNum
2192 );
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002193 assert.isTrue(navigateToRelativeUrlStub.called);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002194 });
2195
Chris Poucet973ecc92022-06-13 10:44:07 +02002196 test('selectedRevision updates when patchNum is changed', async () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002197 const revision1: RevisionInfo = createRevision(1);
2198 const revision2: RevisionInfo = createRevision(2);
Chris Poucetbf65b8f2022-01-18 21:18:12 +00002199 element.getChangeModel().setState({
Ben Rohlfs61bafc22021-11-29 10:40:08 +01002200 loadingStatus: LoadingStatus.LOADED,
Ben Rohlfsa16c51a2021-11-22 12:50:55 +01002201 change: {
Dhruv Srivastavada276592021-04-07 14:51:51 +02002202 ...createChangeViewChange(),
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002203 revisions: {
2204 aaa: revision1,
2205 bbb: revision2,
2206 },
2207 labels: {},
2208 actions: {},
2209 current_revision: 'bbb' as CommitId,
Ben Rohlfsa16c51a2021-11-22 12:50:55 +01002210 },
2211 });
Chris Poucet973ecc92022-06-13 10:44:07 +02002212 element.userModel.setPreferences(createPreferences());
Ben Rohlfsa16c51a2021-11-22 12:50:55 +01002213
Chris Poucet973ecc92022-06-13 10:44:07 +02002214 element.patchRange = {patchNum: 2 as RevisionPatchSetNum};
2215 await element.performPostChangeLoadTasks();
2216 assert.strictEqual(element.selectedRevision, revision2);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002217
Chris Poucet973ecc92022-06-13 10:44:07 +02002218 element.patchRange = {patchNum: 1 as RevisionPatchSetNum};
2219 await element.updateComplete;
2220 assert.strictEqual(element.selectedRevision, revision1);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002221 });
2222
Chris Poucet973ecc92022-06-13 10:44:07 +02002223 test('selectedRevision is assigned when patchNum is edit', async () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002224 const revision1 = createRevision(1);
2225 const revision2 = createRevision(2);
2226 const revision3 = createEditRevision();
Chris Poucetbf65b8f2022-01-18 21:18:12 +00002227 element.getChangeModel().setState({
Ben Rohlfs61bafc22021-11-29 10:40:08 +01002228 loadingStatus: LoadingStatus.LOADED,
Ben Rohlfsa16c51a2021-11-22 12:50:55 +01002229 change: {
Dhruv Srivastavada276592021-04-07 14:51:51 +02002230 ...createChangeViewChange(),
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002231 revisions: {
2232 aaa: revision1,
2233 bbb: revision2,
2234 ccc: revision3,
2235 },
2236 labels: {},
2237 actions: {},
2238 current_revision: 'ccc' as CommitId,
Ben Rohlfsa16c51a2021-11-22 12:50:55 +01002239 },
2240 });
Chris Poucet973ecc92022-06-13 10:44:07 +02002241 stubRestApi('getPreferences').returns(Promise.resolve(createPreferences()));
2242
2243 element.patchRange = {patchNum: EDIT};
Ben Rohlfs1fe7f4d2021-12-06 11:21:49 +01002244 await element.performPostChangeLoadTasks();
Chris Poucet973ecc92022-06-13 10:44:07 +02002245 assert.strictEqual(element.selectedRevision, revision3);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002246 });
2247
Chris Poucet973ecc92022-06-13 10:44:07 +02002248 test('sendShowChangeEvent', () => {
Dhruv Srivastavada276592021-04-07 14:51:51 +02002249 const change = {...createChangeViewChange(), labels: {}};
Chris Poucet973ecc92022-06-13 10:44:07 +02002250 element.change = {...change};
2251 element.patchRange = {patchNum: 4 as RevisionPatchSetNum};
2252 element.mergeable = true;
Chris Poucetc6e880b2021-11-15 19:57:06 +01002253 const showStub = sinon.stub(element.jsAPI, 'handleEvent');
Chris Poucet973ecc92022-06-13 10:44:07 +02002254 element.sendShowChangeEvent();
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002255 assert.isTrue(showStub.calledOnce);
Ben Rohlfsa47355d2020-08-30 15:56:13 +02002256 assert.equal(showStub.lastCall.args[0], EventType.SHOW_CHANGE);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002257 assert.deepEqual(showStub.lastCall.args[1], {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002258 change,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002259 patchNum: 4,
2260 info: {mergeable: true},
2261 });
2262 });
2263
Dhruv Srivastava254b1da2021-10-27 12:32:44 +02002264 test('patch range changed', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02002265 element.patchRange = undefined;
2266 element.change = createChangeViewChange();
2267 element.change.revisions = createRevisions(4);
2268 element.change.current_revision = '1' as CommitId;
2269 element.change = {...element.change};
Dhruv Srivastava254b1da2021-10-27 12:32:44 +02002270
2271 const params = createAppElementChangeViewParams();
2272
2273 assert.isFalse(element.hasPatchRangeChanged(params));
2274 assert.isFalse(element.hasPatchNumChanged(params));
2275
Ben Rohlfs58267b72022-05-27 15:59:18 +02002276 params.basePatchNum = PARENT;
Dhruv Srivastava254b1da2021-10-27 12:32:44 +02002277 // undefined means navigate to latest patchset
2278 params.patchNum = undefined;
2279
Chris Poucet973ecc92022-06-13 10:44:07 +02002280 element.patchRange = {
Dhruv Srivastava254b1da2021-10-27 12:32:44 +02002281 patchNum: 2 as RevisionPatchSetNum,
Ben Rohlfs58267b72022-05-27 15:59:18 +02002282 basePatchNum: PARENT,
Dhruv Srivastava254b1da2021-10-27 12:32:44 +02002283 };
2284
2285 assert.isTrue(element.hasPatchRangeChanged(params));
2286 assert.isTrue(element.hasPatchNumChanged(params));
2287
Chris Poucet973ecc92022-06-13 10:44:07 +02002288 element.patchRange = {
Dhruv Srivastava254b1da2021-10-27 12:32:44 +02002289 patchNum: 4 as RevisionPatchSetNum,
Ben Rohlfs58267b72022-05-27 15:59:18 +02002290 basePatchNum: PARENT,
Dhruv Srivastava254b1da2021-10-27 12:32:44 +02002291 };
2292
2293 assert.isFalse(element.hasPatchRangeChanged(params));
2294 assert.isFalse(element.hasPatchNumChanged(params));
2295 });
2296
Chris Poucet973ecc92022-06-13 10:44:07 +02002297 suite('handleEditTap', () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002298 let fireEdit: () => void;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002299
2300 setup(() => {
2301 fireEdit = () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02002302 assertIsDefined(element.actions);
2303 element.actions.dispatchEvent(new CustomEvent('edit-tap'));
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002304 };
2305 navigateToChangeStub.restore();
2306
Chris Poucet973ecc92022-06-13 10:44:07 +02002307 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +02002308 ...createChangeViewChange(),
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002309 revisions: {rev1: createRevision()},
2310 };
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002311 });
2312
Chris Pouceta2e173e2021-08-31 01:04:04 +00002313 test('edit exists in revisions', async () => {
2314 const promise = mockPromise();
Dmitrii Filippov7d4f2f32020-06-28 23:14:26 +02002315 sinon.stub(GerritNav, 'navigateToChange').callsFake((...args) => {
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002316 assert.equal(args.length, 2);
Ben Rohlfsef043172022-05-27 16:07:27 +02002317 assert.equal(args[1]!.patchNum, EDIT); // patchNum
Chris Pouceta2e173e2021-08-31 01:04:04 +00002318 promise.resolve();
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002319 });
2320
Chris Poucet973ecc92022-06-13 10:44:07 +02002321 assertIsDefined(element.change);
2322 const newChange = {...element.change};
2323 newChange.revisions.rev2 = createRevision(EDIT);
2324 element.change = newChange;
2325 await element.updateComplete;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002326
2327 fireEdit();
Chris Pouceta2e173e2021-08-31 01:04:04 +00002328 await promise;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002329 });
2330
Chris Pouceta2e173e2021-08-31 01:04:04 +00002331 test('no edit exists in revisions, non-latest patchset', async () => {
2332 const promise = mockPromise();
Dmitrii Filippov7d4f2f32020-06-28 23:14:26 +02002333 sinon.stub(GerritNav, 'navigateToChange').callsFake((...args) => {
Dhruv Srivastava0633ae12021-11-11 15:16:47 +01002334 assert.equal(args.length, 2);
Ben Rohlfsabaeacf2022-05-27 15:24:22 +02002335 assert.equal(args[1]!.patchNum, 1 as RevisionPatchSetNum); // patchNum
Dhruv Srivastava0633ae12021-11-11 15:16:47 +01002336 assert.equal(args[1]!.isEdit, true); // opt_isEdit
Chris Pouceta2e173e2021-08-31 01:04:04 +00002337 promise.resolve();
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002338 });
2339
Chris Poucet973ecc92022-06-13 10:44:07 +02002340 assertIsDefined(element.change);
2341 const newChange = {...element.change};
2342 newChange.revisions.rev2 = createRevision(2);
2343 element.change = newChange;
2344 element.patchRange = {patchNum: 1 as RevisionPatchSetNum};
2345 await element.updateComplete;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002346
2347 fireEdit();
Chris Pouceta2e173e2021-08-31 01:04:04 +00002348 await promise;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002349 });
2350
Chris Pouceta2e173e2021-08-31 01:04:04 +00002351 test('no edit exists in revisions, latest patchset', async () => {
2352 const promise = mockPromise();
Dmitrii Filippov7d4f2f32020-06-28 23:14:26 +02002353 sinon.stub(GerritNav, 'navigateToChange').callsFake((...args) => {
Dhruv Srivastava0633ae12021-11-11 15:16:47 +01002354 assert.equal(args.length, 2);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002355 // No patch should be specified when patchNum == latest.
Dhruv Srivastava0633ae12021-11-11 15:16:47 +01002356 assert.isNotOk(args[1]!.patchNum); // patchNum
2357 assert.equal(args[1]!.isEdit, true); // opt_isEdit
Chris Pouceta2e173e2021-08-31 01:04:04 +00002358 promise.resolve();
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002359 });
2360
Chris Poucet973ecc92022-06-13 10:44:07 +02002361 assertIsDefined(element.change);
2362 const newChange = {...element.change};
2363 newChange.revisions.rev2 = createRevision(2);
2364 element.change = newChange;
2365 element.patchRange = {patchNum: 2 as RevisionPatchSetNum};
2366 await element.updateComplete;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002367
2368 fireEdit();
Chris Pouceta2e173e2021-08-31 01:04:04 +00002369 await promise;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002370 });
2371 });
2372
Chris Poucet973ecc92022-06-13 10:44:07 +02002373 test('handleStopEditTap', async () => {
2374 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +02002375 ...createChangeViewChange(),
Milutin Kristoficbec88f12020-10-13 16:53:28 +02002376 };
Chris Poucet973ecc92022-06-13 10:44:07 +02002377 await element.updateComplete;
2378 assertIsDefined(element.metadata);
2379 assertIsDefined(element.actions);
2380 sinon.stub(element.metadata, 'computeLabelNames');
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002381 navigateToChangeStub.restore();
Chris Pouceta2e173e2021-08-31 01:04:04 +00002382 const promise = mockPromise();
Dmitrii Filippov7d4f2f32020-06-28 23:14:26 +02002383 sinon.stub(GerritNav, 'navigateToChange').callsFake((...args) => {
Dhruv Srivastava0633ae12021-11-11 15:16:47 +01002384 assert.equal(args.length, 2);
Ben Rohlfsabaeacf2022-05-27 15:24:22 +02002385 assert.equal(args[1]!.patchNum, 1 as RevisionPatchSetNum); // patchNum
Chris Pouceta2e173e2021-08-31 01:04:04 +00002386 promise.resolve();
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002387 });
2388
Chris Poucet973ecc92022-06-13 10:44:07 +02002389 element.patchRange = {patchNum: 1 as RevisionPatchSetNum};
2390 element.actions.dispatchEvent(
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002391 new CustomEvent('stop-edit-tap', {bubbles: false})
2392 );
Chris Pouceta2e173e2021-08-31 01:04:04 +00002393 await promise;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002394 });
2395
2396 suite('plugin endpoints', () => {
Chris Pouceta2e173e2021-08-31 01:04:04 +00002397 test('endpoint params', async () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02002398 element.change = {...createChangeViewChange(), labels: {}};
2399 element.selectedRevision = createRevision();
Chris Pouceta2e173e2021-08-31 01:04:04 +00002400 const promise = mockPromise();
Chris Poucetd3f52fd2021-11-29 23:16:39 +01002401 window.Gerrit.install(
2402 promise.resolve,
2403 '0.1',
2404 'http://some/plugins/url.js'
2405 );
Chris Poucet973ecc92022-06-13 10:44:07 +02002406 await element.updateComplete;
Chris Pouceta2e173e2021-08-31 01:04:04 +00002407 const plugin: PluginApi = (await promise) as PluginApi;
2408 const hookEl = await plugin
2409 .hook('change-view-integration')
2410 .getLastAttached();
2411 assert.strictEqual((hookEl as any).plugin, plugin);
Chris Poucet973ecc92022-06-13 10:44:07 +02002412 assert.strictEqual((hookEl as any).change, element.change);
2413 assert.strictEqual((hookEl as any).revision, element.selectedRevision);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002414 });
2415 });
2416
Chris Poucet973ecc92022-06-13 10:44:07 +02002417 suite('getMergeability', () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002418 let getMergeableStub: SinonStubbedMember<RestApiService['getMergeable']>;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002419 setup(() => {
Chris Poucet973ecc92022-06-13 10:44:07 +02002420 element.change = {...createChangeViewChange(), labels: {}};
Ben Rohlfs3a6ff7e2021-01-18 14:08:39 +01002421 getMergeableStub = stubRestApi('getMergeable').returns(
2422 Promise.resolve({...createMergeable(), mergeable: true})
2423 );
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002424 });
2425
2426 test('merged change', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02002427 element.mergeable = null;
2428 element.change!.status = ChangeStatus.MERGED;
2429 return element.getMergeability().then(() => {
2430 assert.isFalse(element.mergeable);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002431 assert.isFalse(getMergeableStub.called);
2432 });
2433 });
2434
2435 test('abandoned change', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02002436 element.mergeable = null;
2437 element.change!.status = ChangeStatus.ABANDONED;
2438 return element.getMergeability().then(() => {
2439 assert.isFalse(element.mergeable);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002440 assert.isFalse(getMergeableStub.called);
2441 });
2442 });
2443
2444 test('open change', () => {
Chris Poucet973ecc92022-06-13 10:44:07 +02002445 element.mergeable = null;
2446 return element.getMergeability().then(() => {
2447 assert.isTrue(element.mergeable);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002448 assert.isTrue(getMergeableStub.called);
2449 });
2450 });
2451 });
2452
Chris Poucet973ecc92022-06-13 10:44:07 +02002453 test('handleToggleStar called when star is tapped', async () => {
2454 element.change = {
Dhruv Srivastavada276592021-04-07 14:51:51 +02002455 ...createChangeViewChange(),
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002456 owner: {_account_id: 1 as AccountId},
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002457 starred: false,
2458 };
Chris Poucet973ecc92022-06-13 10:44:07 +02002459 element.loggedIn = true;
2460 await element.updateComplete;
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002461
Chris Poucet973ecc92022-06-13 10:44:07 +02002462 const stub = sinon.stub(element, 'handleToggleStar');
Paladox none70efbef2021-08-12 05:21:59 +00002463
2464 const changeStar = queryAndAssert<GrChangeStar>(element, '#changeStar');
2465 tap(queryAndAssert<HTMLButtonElement>(changeStar, 'button')!);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002466 assert.isTrue(stub.called);
2467 });
2468
2469 suite('gr-reporting tests', () => {
2470 setup(() => {
Chris Poucet973ecc92022-06-13 10:44:07 +02002471 element.patchRange = {
Ben Rohlfs58267b72022-05-27 15:59:18 +02002472 basePatchNum: PARENT,
Dhruv Srivastava1c41a1b72021-03-11 16:24:53 +01002473 patchNum: 1 as RevisionPatchSetNum,
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002474 };
Dhruv Srivastava21129812021-12-02 15:48:03 +01002475 sinon
2476 .stub(element, 'performPostChangeLoadTasks')
2477 .returns(Promise.resolve(false));
Chris Poucet973ecc92022-06-13 10:44:07 +02002478 sinon.stub(element, 'getMergeability').returns(Promise.resolve());
2479 sinon.stub(element, 'getLatestCommitMessage').returns(Promise.resolve());
Ben Rohlfs3a6ff7e2021-01-18 14:08:39 +01002480 sinon
Chris Poucet973ecc92022-06-13 10:44:07 +02002481 .stub(element, 'reloadPatchNumDependentResources')
Dhruv Srivastava09a1b5a2021-01-20 09:28:15 +01002482 .returns(Promise.resolve([undefined, undefined, undefined]));
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002483 });
2484
Chris Pouceta2e173e2021-08-31 01:04:04 +00002485 test("don't report changeDisplayed on reply", async () => {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002486 const changeDisplayStub = sinon.stub(
Chris Poucetc6e880b2021-11-15 19:57:06 +01002487 element.reporting,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002488 'changeDisplayed'
2489 );
2490 const changeFullyLoadedStub = sinon.stub(
Chris Poucetc6e880b2021-11-15 19:57:06 +01002491 element.reporting,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002492 'changeFullyLoaded'
2493 );
Chris Poucet973ecc92022-06-13 10:44:07 +02002494 element.handleReplySent();
2495 await element.updateComplete;
Chris Pouceta2e173e2021-08-31 01:04:04 +00002496 assert.isFalse(changeDisplayStub.called);
2497 assert.isFalse(changeFullyLoadedStub.called);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002498 });
2499
Chris Poucet973ecc92022-06-13 10:44:07 +02002500 test('report changeDisplayed on paramsChanged', async () => {
Ben Rohlfsb7ef7f72022-06-10 12:17:28 +02002501 stubRestApi('getChangeOrEditFiles').resolves({
2502 'a-file.js': {},
2503 });
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002504 const changeDisplayStub = sinon.stub(
Chris Poucetc6e880b2021-11-15 19:57:06 +01002505 element.reporting,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002506 'changeDisplayed'
2507 );
2508 const changeFullyLoadedStub = sinon.stub(
Chris Poucetc6e880b2021-11-15 19:57:06 +01002509 element.reporting,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002510 'changeFullyLoaded'
2511 );
Dhruv Srivastava49f0a7a2021-10-06 12:03:01 +01002512 // reset so reload is triggered
Chris Poucet973ecc92022-06-13 10:44:07 +02002513 element.changeNum = undefined;
Ben Rohlfs71a8dee2021-06-22 10:06:15 +02002514 element.params = {
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002515 ...createAppElementChangeViewParams(),
Ben Rohlfsa5356e92021-05-07 11:06:17 +02002516 changeNum: TEST_NUMERIC_CHANGE_ID,
Dmitrii Filippov78448cd2020-10-26 17:39:11 +01002517 project: TEST_PROJECT_NAME,
Ben Rohlfs71a8dee2021-06-22 10:06:15 +02002518 };
Chris Poucetbf65b8f2022-01-18 21:18:12 +00002519 element.getChangeModel().setState({
Dhruv Srivastava21129812021-12-02 15:48:03 +01002520 loadingStatus: LoadingStatus.LOADED,
2521 change: {
2522 ...createChangeViewChange(),
2523 labels: {},
2524 current_revision: 'foo' as CommitId,
2525 revisions: {foo: createRevision()},
2526 },
2527 });
Chris Poucet973ecc92022-06-13 10:44:07 +02002528 await element.updateComplete;
Ben Rohlfs71a8dee2021-06-22 10:06:15 +02002529 await flush();
2530 assert.isTrue(changeDisplayStub.called);
2531 assert.isTrue(changeFullyLoadedStub.called);
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002532 });
2533 });
Milutin Kristofice9ddfa42021-04-20 23:34:45 +02002534
Chris Poucet973ecc92022-06-13 10:44:07 +02002535 test('calculateHasParent', () => {
Milutin Kristofice9ddfa42021-04-20 23:34:45 +02002536 const changeId = '123' as ChangeId;
2537 const relatedChanges: RelatedChangeAndCommitInfo[] = [];
2538
Chris Poucet973ecc92022-06-13 10:44:07 +02002539 assert.equal(element.calculateHasParent(changeId, relatedChanges), false);
Milutin Kristofice9ddfa42021-04-20 23:34:45 +02002540
2541 relatedChanges.push({
2542 ...createRelatedChangeAndCommitInfo(),
2543 change_id: '123' as ChangeId,
2544 });
Chris Poucet973ecc92022-06-13 10:44:07 +02002545 assert.equal(element.calculateHasParent(changeId, relatedChanges), false);
Milutin Kristofice9ddfa42021-04-20 23:34:45 +02002546
2547 relatedChanges.push({
2548 ...createRelatedChangeAndCommitInfo(),
2549 change_id: '234' as ChangeId,
2550 });
Chris Poucet973ecc92022-06-13 10:44:07 +02002551 assert.equal(element.calculateHasParent(changeId, relatedChanges), true);
Milutin Kristofice9ddfa42021-04-20 23:34:45 +02002552 });
Dmitrii Filippovdaf0ec92020-03-17 11:27:28 +01002553});