blob: bed36f50f0edd6a0f2932d76687d553cd8b0a066 [file] [log] [blame]
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +01001// Copyright 2020 The Chromium Authors
Copybara854996b2021-09-07 19:36:02 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4import {assert} from 'chai';
5import {ChopsAnnouncement, REFRESH_TIME_MS,
6 XSSI_PREFIX} from './chops-announcement.js';
7import sinon from 'sinon';
8
9let element;
10let clock;
11
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010012function assertRendersMessage(message) {
13 const messageContainer = element.shadowRoot.querySelector('mr-comment-content');
14 assert.include(messageContainer.content, message);
15}
16
17function assertDoesNotRender() {
18 assert.equal(0, element.shadowRoot.children.length);
19}
20
Copybara854996b2021-09-07 19:36:02 +000021describe('chops-announcement', () => {
22 beforeEach(() => {
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010023 element = document.createElement('chops-announcement-base');
Copybara854996b2021-09-07 19:36:02 +000024 document.body.appendChild(element);
25
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010026 element.additionalAnnouncements = [];
27
Copybara854996b2021-09-07 19:36:02 +000028 clock = sinon.useFakeTimers({
29 now: new Date(0),
30 shouldAdvanceTime: false,
31 });
32
33 sinon.stub(window, 'fetch');
34 });
35
36 afterEach(() => {
37 if (document.body.contains(element)) {
38 document.body.removeChild(element);
39 }
40
41 clock.restore();
42
43 window.fetch.restore();
44 });
45
Copybara854996b2021-09-07 19:36:02 +000046 it('does not request announcements when no service specified', async () => {
47 sinon.stub(element, 'fetch');
48
49 element.service = '';
50
51 await element.updateComplete;
52
53 sinon.assert.notCalled(element.fetch);
54 });
55
56 it('requests announcements when service is specified', async () => {
57 sinon.stub(element, 'fetch');
58
59 element.service = 'monorail';
60
61 await element.updateComplete;
62
63 sinon.assert.calledOnce(element.fetch);
64 });
65
66 it('refreshes announcements regularly', async () => {
67 sinon.stub(element, 'fetch');
68
69 element.service = 'monorail';
70
71 await element.updateComplete;
72
73 sinon.assert.calledOnce(element.fetch);
74
75 clock.tick(REFRESH_TIME_MS);
76
77 await element.updateComplete;
78
79 sinon.assert.calledTwice(element.fetch);
80 });
81
82 it('stops refreshing when service removed', async () => {
83 sinon.stub(element, 'fetch');
84
85 element.service = 'monorail';
86
87 await element.updateComplete;
88
89 sinon.assert.calledOnce(element.fetch);
90
91 element.service = '';
92
93 await element.updateComplete;
94 clock.tick(REFRESH_TIME_MS);
95 await element.updateComplete;
96
97 sinon.assert.calledOnce(element.fetch);
98 });
99
100 it('stops refreshing when element is disconnected', async () => {
101 sinon.stub(element, 'fetch');
102
103 element.service = 'monorail';
104
105 await element.updateComplete;
106
107 sinon.assert.calledOnce(element.fetch);
108
109 document.body.removeChild(element);
110
111 await element.updateComplete;
112 clock.tick(REFRESH_TIME_MS);
113 await element.updateComplete;
114
115 sinon.assert.calledOnce(element.fetch);
116 });
117
118 it('renders error when thrown', async () => {
119 sinon.stub(element, 'fetch');
120 element.fetch.throws(() => Error('Something went wrong'));
121
122 element.service = 'monorail';
123
124 await element.updateComplete;
125
126 // Fetch runs here.
127
128 await element.updateComplete;
129
130 assert.equal(element._error, 'Something went wrong');
131 assert.include(element.shadowRoot.textContent, 'Something went wrong');
132 });
133
134 it('renders fetched announcement', async () => {
135 sinon.stub(element, 'fetch');
136 element.fetch.returns(
137 {announcements: [{id: '1234', messageContent: 'test thing'}]});
138
139 element.service = 'monorail';
140
141 await element.updateComplete;
142
143 // Fetch runs here.
144
145 await element.updateComplete;
146
147 assert.deepEqual(element._announcements,
148 [{id: '1234', messageContent: 'test thing'}]);
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100149
150 assertRendersMessage('test thing');
Copybara854996b2021-09-07 19:36:02 +0000151 });
152
153 it('renders empty on empty announcement', async () => {
154 sinon.stub(element, 'fetch');
155 element.fetch.returns({});
156 element.service = 'monorail';
157
158 await element.updateComplete;
159
160 // Fetch runs here.
161
162 await element.updateComplete;
163
164 assert.deepEqual(element._announcements, []);
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100165 assertDoesNotRender()
Copybara854996b2021-09-07 19:36:02 +0000166 });
167
168 it('fetch returns response data', async () => {
169 const json = {announcements: [{id: '1234', messageContent: 'test thing'}]};
170 const fakeResponse = XSSI_PREFIX + JSON.stringify(json);
171 window.fetch.returns(new window.Response(fakeResponse));
172
173 const resp = await element.fetch('monorail');
174
175 assert.deepEqual(resp, json);
176 });
177
178 it('fetch errors when no XSSI prefix', async () => {
179 const json = {announcements: [{id: '1234', messageContent: 'test thing'}]};
180 const fakeResponse = JSON.stringify(json);
181 window.fetch.returns(new window.Response(fakeResponse));
182
183 try {
184 await element.fetch('monorail');
185 } catch (e) {
186 assert.include(e.message, 'No XSSI prefix in announce response:');
187 }
188 });
189
190 it('fetch errors when response is not okay', async () => {
191 const json = {announcements: [{id: '1234', messageContent: 'test thing'}]};
192 const fakeResponse = XSSI_PREFIX + JSON.stringify(json);
193 window.fetch.returns(new window.Response(fakeResponse, {status: 500}));
194
195 try {
196 await element.fetch('monorail');
197 } catch (e) {
198 assert.include(e.message,
199 'Something went wrong while fetching announcements');
200 }
201 });
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100202
203 describe('additional announcement handlings', () => {
204 beforeEach(() => {
205 sinon.stub(element, 'fetch');
206 element.fetch.returns({});
207 element.service = 'monorail';
208 });
209
210 it('renders additional announcement', async () => {
211 element.additionalAnnouncements = [{'messageContent': 'test thing'}];
212 await element.updateComplete;
213
214 assertRendersMessage('test thing');
215 });
216
217 it('renders when user is in group', async () => {
218 element.additionalAnnouncements = [
219 {'messageContent': 'test thing', 'groups': ['hello@group.com']}
220 ];
221 element.userGroups = [
222 {"userId": "12344", "displayName": "hello@group.com"}];
223 await element.updateComplete;
224
225 assertRendersMessage('test thing');
226 });
227
228 it('does not render when user is not in group', async () => {
229 element.additionalAnnouncements = [
230 {'messageContent': 'test thing', 'groups': ['hello@group.com']}
231 ];
232 element.userGroups = [
233 {"userId": "12344", "displayName": "hello@othergroup.com"}];
234 await element.updateComplete;
235
236 assertDoesNotRender();
237 });
238
239 it('renders when user is in everyone@ group', async () => {
240 element.additionalAnnouncements = [
241 {'messageContent': 'test thing', 'groups': ['everyone@world.com']}
242 ];
243 element.userGroups = [
244 {"userId": "12344", "displayName": "hello@group.com"}];
245 element.currentUserName = "hello@world.com";
246 await element.updateComplete;
247
248 assertRendersMessage('test thing');
249 });
250
251 it('does not renders when user is not in everyone@ group', async () => {
252 element.additionalAnnouncements = [
253 {'messageContent': 'test thing', 'groups': ['everyone@word.com']}
254 ];
255 element.userGroups = [
256 {"userId": "12344", "displayName": "hello@world.com"}];
257 element.currentUserName = "hello@world.com";
258 await element.updateComplete;
259
260 assertDoesNotRender();
261 });
262
263 it('renders when viewing referenced project', async () => {
264 element.additionalAnnouncements = [
265 {'messageContent': 'test thing', 'projects': ['chromium']}];
266 element.currentProject = 'chromium';
267
268 await element.updateComplete;
269
270 assertRendersMessage('test thing');
271 });
272
273 it('does not render when not viewing referenced project', async () => {
274 element.additionalAnnouncements = [
275 {'messageContent': 'test thing', 'projects': ['chromium']}];
276 element.currentProject = 'chrome';
277
278 await element.updateComplete;
279
280 assertDoesNotRender();
281 });
282 });
Copybara854996b2021-09-07 19:36:02 +0000283});