blob: 4db7877f53c6cffc4b81a619a237bb901f3ea60e [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.
4import sinon from 'sinon';
5import {assert} from 'chai';
6
7import {MrStar} from './mr-star.js';
8
9let element;
10
11describe('mr-star', () => {
12 beforeEach(() => {
13 element = document.createElement('mr-star');
14 document.body.appendChild(element);
15 });
16
17 afterEach(() => {
18 if (document.body.contains(element)) {
19 document.body.removeChild(element);
20 }
21 });
22
23 it('initializes', () => {
24 assert.instanceOf(element, MrStar);
25 });
26
27 it('unimplemented methods throw errors', () => {
28 assert.throws(element.star, 'Method not implemented.');
29 assert.throws(element.unstar, 'Method not implemented.');
30 });
31
32 describe('clicking star toggles star state', () => {
33 beforeEach(() => {
34 sinon.stub(element, 'star');
35 sinon.stub(element, 'unstar');
36 element._isLoggedIn = true;
37 element._canStar = true;
38 });
39
40 it('unstarred star', async () => {
41 element._isStarred = false;
42
43 await element.updateComplete;
44
45 sinon.assert.notCalled(element.star);
46 sinon.assert.notCalled(element.unstar);
47
48 element.shadowRoot.querySelector('button').click();
49
50 sinon.assert.calledOnce(element.star);
51 sinon.assert.notCalled(element.unstar);
52 });
53
54 it('starred star', async () => {
55 element._isStarred = true;
56
57 await element.updateComplete;
58
59 sinon.assert.notCalled(element.star);
60 sinon.assert.notCalled(element.unstar);
61
62 element.shadowRoot.querySelector('button').click();
63
64 sinon.assert.notCalled(element.star);
65 sinon.assert.calledOnce(element.unstar);
66 });
67 });
68
69 it('clicking while logged out logs you in', async () => {
70 sinon.stub(element, 'login');
71 element._isLoggedIn = false;
72 element._canStar = true;
73
74 await element.updateComplete;
75
76 sinon.assert.notCalled(element.login);
77
78 element.shadowRoot.querySelector('button').click();
79
80 sinon.assert.calledOnce(element.login);
81 });
82
83 describe('toggleStar', () => {
84 beforeEach(() => {
85 sinon.stub(element, 'star');
86 sinon.stub(element, 'unstar');
87 });
88
89 it('stars when unstarred', () => {
90 element._isLoggedIn = true;
91 element._canStar = true;
92 element._isStarred = false;
93
94 element.toggleStar();
95
96 sinon.assert.calledOnce(element.star);
97 sinon.assert.notCalled(element.unstar);
98 });
99
100 it('unstars when starred', () => {
101 element._isLoggedIn = true;
102 element._canStar = true;
103 element._isStarred = true;
104
105 element.toggleStar();
106
107 sinon.assert.calledOnce(element.unstar);
108 sinon.assert.notCalled(element.star);
109 });
110
111 it('does nothing when user is not logged in', () => {
112 element._isLoggedIn = false;
113 element._canStar = true;
114 element._isStarred = true;
115
116 element.toggleStar();
117
118 sinon.assert.notCalled(element.unstar);
119 sinon.assert.notCalled(element.star);
120 });
121
122 it('does nothing when user does not have permission', () => {
123 element._isLoggedIn = true;
124 element._canStar = false;
125 element._isStarred = true;
126
127 element.toggleStar();
128
129 sinon.assert.notCalled(element.unstar);
130 sinon.assert.notCalled(element.star);
131 });
132
133 it('does nothing when stars are being fetched', () => {
134 element._isLoggedIn = true;
135 element._canStar = true;
136 element._isStarred = true;
137 element._requesting = true;
138
139 element.toggleStar();
140
141 sinon.assert.notCalled(element.unstar);
142 sinon.assert.notCalled(element.star);
143 });
144 });
145
146 describe('_starringEnabled', () => {
147 it('enabled when user is logged in and has permission', () => {
148 element._isLoggedIn = true;
149 element._canStar = true;
150 element._isStarred = true;
151 element._requesting = false;
152
153 assert.isTrue(element._starringEnabled);
154 });
155
156 it('disabled when user is logged out', () => {
157 element._isLoggedIn = false;
158 element._canStar = false;
159 element._isStarred = false;
160 element._requesting = false;
161
162 assert.isFalse(element._starringEnabled);
163 });
164
165 it('disabled when user has no permission', () => {
166 element._isLoggedIn = true;
167 element._canStar = false;
168 element._isStarred = true;
169 element._requesting = false;
170
171 assert.isFalse(element._starringEnabled);
172 });
173
174 it('disabled when requesting star', () => {
175 element._isLoggedIn = true;
176 element._canStar = true;
177 element._isStarred = true;
178 element._requesting = true;
179
180 assert.isFalse(element._starringEnabled);
181 });
182 });
183
184 it('loading state shown when requesting', async () => {
185 element._requesting = true;
186 await element.updateComplete;
187
188 const star = element.shadowRoot.querySelector('button');
189
190 assert.isTrue(star.classList.contains('loading'));
191
192 element._requesting = false;
193 await element.updateComplete;
194
195 assert.isFalse(star.classList.contains('loading'));
196 });
197
198 it('isStarred changes displayed icon', async () => {
199 element._isStarred = true;
200 await element.updateComplete;
201
202 const star = element.shadowRoot.querySelector('button');
203 assert.equal(star.textContent.trim(), 'star');
204
205 element._isStarred = false;
206 await element.updateComplete;
207
208 assert.equal(star.textContent.trim(), 'star_border');
209 });
210
211 describe('mr-star nested inside a link', () => {
212 let parent;
213 let oldHash;
214
215 beforeEach(() => {
216 parent = document.createElement('a');
217 parent.setAttribute('href', '#test-hash');
218 parent.appendChild(element);
219
220 oldHash = window.location.hash;
221
222 sinon.stub(element, 'star');
223 sinon.stub(element, 'unstar');
224 });
225
226 afterEach(() => {
227 window.location.hash = oldHash;
228 });
229
230 it('clicking to star does not cause navigation', async () => {
231 sinon.spy(element, 'toggleStar');
232 element._isLoggedIn = true;
233 element._canStar = true;
234 await element.updateComplete;
235
236 element.shadowRoot.querySelector('button').click();
237
238 assert.notEqual(window.location.hash, '#test-hash');
239 sinon.assert.calledOnce(element.toggleStar);
240 });
241
242 it('clicking on disabled star does not cause navigation', async () => {
243 element._isLoggedIn = true;
244 element._canStar = false;
245 await element.updateComplete;
246
247 element.shadowRoot.querySelector('button').click();
248
249 assert.notEqual(window.location.hash, '#test-hash');
250 });
251
252 it('clicking on link still navigates', async () => {
253 element._isLoggedIn = true;
254 element._canStar = true;
255 await element.updateComplete;
256
257 parent.click();
258
259 assert.equal(window.location.hash, '#test-hash');
260 });
261 });
262
263 describe('_starToolTip', () => {
264 it('not logged in', () => {
265 element._isLoggedIn = false;
266 element._canStar = false;
267 assert.equal(element._starToolTip,
268 `Login to star this resource.`);
269 });
270
271 it('no permission to star', () => {
272 element._isLoggedIn = true;
273 element._canStar = false;
274 assert.equal(element._starToolTip,
275 `You don't have permission to star this resource.`);
276 });
277
278 it('star is loading', () => {
279 element._isLoggedIn = true;
280 element._canStar = true;
281 element._requesting = true;
282 assert.equal(element._starToolTip,
283 `Loading star state for this resource.`);
284 });
285
286 it('issue is not starred', () => {
287 element._isLoggedIn = true;
288 element._canStar = true;
289 element._isStarred = false;
290 assert.equal(element._starToolTip,
291 `Star this resource.`);
292 });
293
294 it('issue is starred', () => {
295 element._isLoggedIn = true;
296 element._canStar = true;
297 element._isStarred = true;
298 assert.equal(element._starToolTip,
299 `Unstar this resource.`);
300 });
301 });
302});