blob: d9dcd254c07fc4f251f1a464df93d439ae69d69b [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001// Copyright 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import {assert} from 'chai';
6import {MrMetadata} from './mr-metadata.js';
7
8import {EMPTY_FIELD_VALUE} from 'shared/issue-fields.js';
9
10let element;
11
12describe('mr-metadata', () => {
13 beforeEach(() => {
14 element = document.createElement('mr-metadata');
15 document.body.appendChild(element);
16
17 element.issueRef = {projectName: 'proj'};
18 });
19
20 afterEach(() => {
21 document.body.removeChild(element);
22 });
23
24 it('initializes', () => {
25 assert.instanceOf(element, MrMetadata);
26 });
27
28 it('has table role set', () => {
29 assert.equal(element.getAttribute('role'), 'table');
30 });
31
32 describe('default issue fields', () => {
33 it('renders empty Owner', async () => {
34 await element.updateComplete;
35
36 const tr = element.shadowRoot.querySelector('tr.row-owner');
37 const labelElement = tr.querySelector('th');
38 const dataElement = tr.querySelector('td');
39
40 assert.equal(labelElement.textContent, 'Owner:');
41 assert.equal(dataElement.textContent.trim(), EMPTY_FIELD_VALUE);
42 });
43
44 it('renders populated Owner', async () => {
45 element.owner = {displayName: 'test@example.com'};
46
47 await element.updateComplete;
48
49 const tr = element.shadowRoot.querySelector('tr.row-owner');
50 const labelElement = tr.querySelector('th');
51 const dataElement = tr.querySelector('mr-user-link');
52
53 assert.equal(labelElement.textContent, 'Owner:');
54 assert.include(dataElement.shadowRoot.textContent.trim(),
55 'test@example.com');
56 });
57
58 it('renders empty CC', async () => {
59 await element.updateComplete;
60
61 const tr = element.shadowRoot.querySelector('tr.row-cc');
62 const labelElement = tr.querySelector('th');
63 const dataElement = tr.querySelector('td');
64
65 assert.equal(labelElement.textContent, 'CC:');
66 assert.equal(dataElement.textContent.trim(), EMPTY_FIELD_VALUE);
67 });
68
69 it('renders multiple CCed users', async () => {
70 element.cc = [
71 {displayName: 'test@example.com'},
72 {displayName: 'hello@example.com'},
73 ];
74
75 await element.updateComplete;
76
77 const tr = element.shadowRoot.querySelector('tr.row-cc');
78 const labelElement = tr.querySelector('th');
79 const dataElements = tr.querySelectorAll('mr-user-link');
80
81 assert.equal(labelElement.textContent, 'CC:');
82 assert.include(dataElements[0].shadowRoot.textContent.trim(),
83 'test@example.com');
84 assert.include(dataElements[1].shadowRoot.textContent.trim(),
85 'hello@example.com');
86 });
87
88 it('renders empty Status', async () => {
89 await element.updateComplete;
90
91 const tr = element.shadowRoot.querySelector('tr.row-status');
92 const labelElement = tr.querySelector('th');
93 const dataElement = tr.querySelector('td');
94
95 assert.equal(labelElement.textContent, 'Status:');
96 assert.equal(dataElement.textContent.trim(), EMPTY_FIELD_VALUE);
97 });
98
99 it('renders populated Status', async () => {
100 element.issueStatus = {status: 'Fixed', meansOpen: false};
101
102 await element.updateComplete;
103
104 const tr = element.shadowRoot.querySelector('tr.row-status');
105 const labelElement = tr.querySelector('th');
106 const dataElement = tr.querySelector('td');
107
108 assert.equal(labelElement.textContent, 'Status:');
109 assert.equal(dataElement.textContent.trim(), 'Fixed (Closed)');
110 });
111
112 it('hides empty MergedInto', async () => {
113 await element.updateComplete;
114
115 const tr = element.shadowRoot.querySelector('tr.row-mergedinto');
116 assert.isNull(tr);
117 });
118
119 it('hides MergedInto when Status is not Duplicate', async () => {
120 element.issueStatus = {status: 'test'};
121 element.mergedInto = {projectName: 'chromium', localId: 22};
122
123 await element.updateComplete;
124
125 const tr = element.shadowRoot.querySelector('tr.row-mergedinto');
126 assert.isNull(tr);
127 });
128
129 it('shows MergedInto when Status is Duplicate', async () => {
130 element.issueStatus = {status: 'Duplicate'};
131 element.mergedInto = {projectName: 'chromium', localId: 22};
132
133 await element.updateComplete;
134
135 const tr = element.shadowRoot.querySelector('tr.row-mergedinto');
136 const labelElement = tr.querySelector('th');
137 const dataElement = tr.querySelector('mr-issue-link');
138
139 assert.equal(labelElement.textContent, 'MergedInto:');
140 assert.equal(dataElement.shadowRoot.textContent.trim(),
141 'Issue chromium:22');
142 });
143
144 it('renders empty Components', async () => {
145 await element.updateComplete;
146
147 const tr = element.shadowRoot.querySelector('tr.row-components');
148 const labelElement = tr.querySelector('th');
149 const dataElement = tr.querySelector('td');
150
151 assert.equal(labelElement.textContent, 'Components:');
152 assert.equal(dataElement.textContent.trim(), EMPTY_FIELD_VALUE);
153 });
154
155 it('renders multiple Components', async () => {
156 element.components = [
157 {path: 'Test', docstring: 'i got docs'},
158 {path: 'Test>Nothing'},
159 ];
160
161 await element.updateComplete;
162
163 const tr = element.shadowRoot.querySelector('tr.row-components');
164 const labelElement = tr.querySelector('th');
165 const dataElements = tr.querySelectorAll('td > a');
166
167 assert.equal(labelElement.textContent, 'Components:');
168
169 assert.equal(dataElements[0].textContent.trim(), 'Test');
170 assert.equal(dataElements[0].title, 'Test = i got docs');
171
172 assert.equal(dataElements[1].textContent.trim(), 'Test>Nothing');
173 assert.equal(dataElements[1].title, 'Test>Nothing');
174 });
175
176 it('renders empty Modified', async () => {
177 await element.updateComplete;
178
179 const tr = element.shadowRoot.querySelector('tr.row-modified');
180 const labelElement = tr.querySelector('th');
181 const dataElement = tr.querySelector('td');
182
183 assert.equal(labelElement.textContent, 'Modified:');
184 assert.equal(dataElement.textContent.trim(), EMPTY_FIELD_VALUE);
185 });
186
187 it('renders populated Modified', async () => {
188 element.modifiedTimestamp = 1234;
189
190 await element.updateComplete;
191
192 const tr = element.shadowRoot.querySelector('tr.row-modified');
193 const labelElement = tr.querySelector('th');
194 const dataElement = tr.querySelector('chops-timestamp');
195
196 assert.equal(labelElement.textContent, 'Modified:');
197 assert.equal(dataElement.timestamp, 1234);
198 });
199
200 it('does not render SLO if user not in experiment', async () => {
201 await element.updateComplete;
202
203 const tr = element.shadowRoot.querySelector('tr.row-slo');
204 assert.isNull(tr);
205 });
206
207 it('renders SLO if user in experiment', async () => {
208 element.currentUser = {displayName: 'jessan@google.com'};
209 await element.updateComplete;
210
211 const tr = element.shadowRoot.querySelector('tr.row-slo');
212 const labelElement = tr.querySelector('th');
213 const dataElement = tr.querySelector('mr-issue-slo');
214
215 assert.equal(labelElement.textContent, 'SLO:');
216 assert.equal(dataElement.shadowRoot.textContent.trim(), 'N/A');
217 });
218 });
219
220 describe('approval fields', () => {
221 beforeEach(() => {
222 element.builtInFieldSpec = ['ApprovalStatus', 'Approvers', 'Setter',
223 'cue.availability_msgs'];
224 });
225
226 it('renders empty ApprovalStatus', async () => {
227 await element.updateComplete;
228
229 const tr = element.shadowRoot.querySelector('tr.row-approvalstatus');
230 const labelElement = tr.querySelector('th');
231 const dataElement = tr.querySelector('td');
232
233 assert.equal(labelElement.textContent, 'Status:');
234 assert.equal(dataElement.textContent.trim(), EMPTY_FIELD_VALUE);
235 });
236
237 it('renders populated ApprovalStatus', async () => {
238 element.approvalStatus = 'Approved';
239
240 await element.updateComplete;
241
242 const tr = element.shadowRoot.querySelector('tr.row-approvalstatus');
243 const labelElement = tr.querySelector('th');
244 const dataElement = tr.querySelector('td');
245
246 assert.equal(labelElement.textContent, 'Status:');
247 assert.equal(dataElement.textContent.trim(), 'Approved');
248 });
249
250 it('renders empty Approvers', async () => {
251 await element.updateComplete;
252
253 const tr = element.shadowRoot.querySelector('tr.row-approvers');
254 const labelElement = tr.querySelector('th');
255 const dataElement = tr.querySelector('td');
256
257 assert.equal(labelElement.textContent, 'Approvers:');
258 assert.equal(dataElement.textContent.trim(), EMPTY_FIELD_VALUE);
259 });
260
261 it('renders multiple Approvers', async () => {
262 element.approvers = [
263 {displayName: 'test@example.com'},
264 {displayName: 'hello@example.com'},
265 ];
266
267 await element.updateComplete;
268
269 const tr = element.shadowRoot.querySelector('tr.row-approvers');
270 const labelElement = tr.querySelector('th');
271 const dataElements = tr.querySelectorAll('mr-user-link');
272
273 assert.equal(labelElement.textContent, 'Approvers:');
274 assert.include(dataElements[0].shadowRoot.textContent.trim(),
275 'test@example.com');
276 assert.include(dataElements[1].shadowRoot.textContent.trim(),
277 'hello@example.com');
278 });
279
280 it('hides empty Setter', async () => {
281 await element.updateComplete;
282
283 const tr = element.shadowRoot.querySelector('tr.row-setter');
284
285 assert.isNull(tr);
286 });
287
288 it('renders populated Setter', async () => {
289 element.setter = {displayName: 'test@example.com'};
290
291 await element.updateComplete;
292
293 const tr = element.shadowRoot.querySelector('tr.row-setter');
294 const labelElement = tr.querySelector('th');
295 const dataElement = tr.querySelector('mr-user-link');
296
297 assert.equal(labelElement.textContent, 'Setter:');
298 assert.include(dataElement.shadowRoot.textContent.trim(),
299 'test@example.com');
300 });
301
302 it('renders cue.availability_msgs', async () => {
303 await element.updateComplete;
304
305 const tr = element.shadowRoot.querySelector(
306 'tr.cue-availability_msgs');
307 const cueElement = tr.querySelector('mr-cue');
308
309 assert.isDefined(cueElement);
310 });
311 });
312
313 describe('custom config', () => {
314 beforeEach(() => {
315 element.builtInFieldSpec = ['owner', 'fakefield'];
316 });
317
318 it('owner still renders when lowercase', async () => {
319 await element.updateComplete;
320
321 const tr = element.shadowRoot.querySelector('tr.row-owner');
322 const labelElement = tr.querySelector('th');
323 const dataElement = tr.querySelector('td');
324
325 assert.equal(labelElement.textContent, 'owner:');
326 assert.equal(dataElement.textContent.trim(), EMPTY_FIELD_VALUE);
327 });
328
329 it('fakefield does not render', async () => {
330 await element.updateComplete;
331
332 const tr = element.shadowRoot.querySelector('tr.row-fakefield');
333
334 assert.isNull(tr);
335 });
336
337 it('cue.availability_msgs does not render when not configured', async () => {
338 await element.updateComplete;
339
340 const tr = element.shadowRoot.querySelector('tr.cue-availability_msgs');
341
342 assert.isNull(tr);
343 });
344 });
345});