blob: fa9643f826ea48c8902b1c689b97fff73e5d4f41 [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001// Copyright 2020 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.
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
12describe('chops-announcement', () => {
13 beforeEach(() => {
14 element = document.createElement('chops-announcement');
15 document.body.appendChild(element);
16
17 clock = sinon.useFakeTimers({
18 now: new Date(0),
19 shouldAdvanceTime: false,
20 });
21
22 sinon.stub(window, 'fetch');
23 });
24
25 afterEach(() => {
26 if (document.body.contains(element)) {
27 document.body.removeChild(element);
28 }
29
30 clock.restore();
31
32 window.fetch.restore();
33 });
34
35 it('initializes', () => {
36 assert.instanceOf(element, ChopsAnnouncement);
37 });
38
39 it('does not request announcements when no service specified', async () => {
40 sinon.stub(element, 'fetch');
41
42 element.service = '';
43
44 await element.updateComplete;
45
46 sinon.assert.notCalled(element.fetch);
47 });
48
49 it('requests announcements when service is specified', async () => {
50 sinon.stub(element, 'fetch');
51
52 element.service = 'monorail';
53
54 await element.updateComplete;
55
56 sinon.assert.calledOnce(element.fetch);
57 });
58
59 it('refreshes announcements regularly', async () => {
60 sinon.stub(element, 'fetch');
61
62 element.service = 'monorail';
63
64 await element.updateComplete;
65
66 sinon.assert.calledOnce(element.fetch);
67
68 clock.tick(REFRESH_TIME_MS);
69
70 await element.updateComplete;
71
72 sinon.assert.calledTwice(element.fetch);
73 });
74
75 it('stops refreshing when service removed', async () => {
76 sinon.stub(element, 'fetch');
77
78 element.service = 'monorail';
79
80 await element.updateComplete;
81
82 sinon.assert.calledOnce(element.fetch);
83
84 element.service = '';
85
86 await element.updateComplete;
87 clock.tick(REFRESH_TIME_MS);
88 await element.updateComplete;
89
90 sinon.assert.calledOnce(element.fetch);
91 });
92
93 it('stops refreshing when element is disconnected', async () => {
94 sinon.stub(element, 'fetch');
95
96 element.service = 'monorail';
97
98 await element.updateComplete;
99
100 sinon.assert.calledOnce(element.fetch);
101
102 document.body.removeChild(element);
103
104 await element.updateComplete;
105 clock.tick(REFRESH_TIME_MS);
106 await element.updateComplete;
107
108 sinon.assert.calledOnce(element.fetch);
109 });
110
111 it('renders error when thrown', async () => {
112 sinon.stub(element, 'fetch');
113 element.fetch.throws(() => Error('Something went wrong'));
114
115 element.service = 'monorail';
116
117 await element.updateComplete;
118
119 // Fetch runs here.
120
121 await element.updateComplete;
122
123 assert.equal(element._error, 'Something went wrong');
124 assert.include(element.shadowRoot.textContent, 'Something went wrong');
125 });
126
127 it('renders fetched announcement', async () => {
128 sinon.stub(element, 'fetch');
129 element.fetch.returns(
130 {announcements: [{id: '1234', messageContent: 'test thing'}]});
131
132 element.service = 'monorail';
133
134 await element.updateComplete;
135
136 // Fetch runs here.
137
138 await element.updateComplete;
139
140 assert.deepEqual(element._announcements,
141 [{id: '1234', messageContent: 'test thing'}]);
142 assert.include(element.shadowRoot.textContent, 'test thing');
143 });
144
145 it('renders empty on empty announcement', async () => {
146 sinon.stub(element, 'fetch');
147 element.fetch.returns({});
148 element.service = 'monorail';
149
150 await element.updateComplete;
151
152 // Fetch runs here.
153
154 await element.updateComplete;
155
156 assert.deepEqual(element._announcements, []);
157 assert.equal(0, element.shadowRoot.children.length);
158 });
159
160 it('fetch returns response data', async () => {
161 const json = {announcements: [{id: '1234', messageContent: 'test thing'}]};
162 const fakeResponse = XSSI_PREFIX + JSON.stringify(json);
163 window.fetch.returns(new window.Response(fakeResponse));
164
165 const resp = await element.fetch('monorail');
166
167 assert.deepEqual(resp, json);
168 });
169
170 it('fetch errors when no XSSI prefix', async () => {
171 const json = {announcements: [{id: '1234', messageContent: 'test thing'}]};
172 const fakeResponse = JSON.stringify(json);
173 window.fetch.returns(new window.Response(fakeResponse));
174
175 try {
176 await element.fetch('monorail');
177 } catch (e) {
178 assert.include(e.message, 'No XSSI prefix in announce response:');
179 }
180 });
181
182 it('fetch errors when response is not okay', async () => {
183 const json = {announcements: [{id: '1234', messageContent: 'test thing'}]};
184 const fakeResponse = XSSI_PREFIX + JSON.stringify(json);
185 window.fetch.returns(new window.Response(fakeResponse, {status: 500}));
186
187 try {
188 await element.fetch('monorail');
189 } catch (e) {
190 assert.include(e.message,
191 'Something went wrong while fetching announcements');
192 }
193 });
194});