blob: b7dd6dc1f8bb8da26e2c835c934a08ddaf5673c8 [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.
4
5import {assert} from 'chai';
6import sinon from 'sinon';
7
8import {store, resetState} from 'reducers/base.js';
9import {hotlists} from 'reducers/hotlists.js';
10import * as sitewide from 'reducers/sitewide.js';
11
12import * as example from 'shared/test/constants-hotlists.js';
13import * as exampleUsers from 'shared/test/constants-users.js';
14
15import {MrHotlistPeoplePage} from './mr-hotlist-people-page.js';
16
17/** @type {MrHotlistPeoplePage} */
18let element;
19
20describe('mr-hotlist-people-page (unconnected)', () => {
21 beforeEach(() => {
22 // @ts-ignore
23 element = document.createElement('mr-hotlist-people-page-base');
24 document.body.appendChild(element);
25 });
26
27 afterEach(() => {
28 document.body.removeChild(element);
29 });
30
31 it('shows hotlist fetch error', async () => {
32 element._fetchError = new Error('This is an important error');
33 element._fetchError.description = 'This is an important error';
34 await element.updateComplete;
35 assert.include(element.shadowRoot.innerHTML, 'important error');
36 });
37
38 it('renders placeholders with no data', async () => {
39 await element.updateComplete;
40
41 const placeholders = element.shadowRoot.querySelectorAll('.placeholder');
42 assert.equal(placeholders.length, 2);
43 });
44
45 it('renders placeholders with editors list but no user data', async () => {
46 element._editors = [null, null];
47 await element.updateComplete;
48
49 const placeholders = element.shadowRoot.querySelectorAll('.placeholder');
50 assert.equal(placeholders.length, 3);
51 });
52
53 it('renders "No editors"', async () => {
54 element._editors = [];
55 await element.updateComplete;
56
57 assert.include(element.shadowRoot.innerHTML, 'No editors');
58 });
59
60 it('renders hotlist', async () => {
61 element._hotlist = example.HOTLIST;
62 element._owner = exampleUsers.USER;
63 element._editors = [exampleUsers.USER_2];
64 await element.updateComplete;
65 });
66
67 it('shows controls iff user has admin permissions', async () => {
68 element._editors = [exampleUsers.USER_2];
69 await element.updateComplete;
70
71 assert.equal(element.shadowRoot.querySelectorAll('button').length, 0);
72
73 element._permissions = [hotlists.ADMINISTER];
74 await element.updateComplete;
75
76 assert.equal(element.shadowRoot.querySelectorAll('button').length, 2);
77 });
78
79 it('shows remove button if user is editing themselves', async () => {
80 element._editors = [exampleUsers.USER, exampleUsers.USER_2];
81 element._currentUserName = exampleUsers.USER_2.name;
82 await element.updateComplete;
83
84 assert.equal(element.shadowRoot.querySelectorAll('button').length, 1);
85 });
86});
87
88describe('mr-hotlist-people-page (connected)', () => {
89 beforeEach(() => {
90 store.dispatch(resetState());
91
92 // @ts-ignore
93 element = document.createElement('mr-hotlist-people-page');
94 document.body.appendChild(element);
95
96 // Stop Redux from overriding values being tested.
97 sinon.stub(element, 'stateChanged');
98 });
99
100 afterEach(() => {
101 element.stateChanged.restore();
102 document.body.removeChild(element);
103 });
104
105 it('initializes', async () => {
106 assert.instanceOf(element, MrHotlistPeoplePage);
107 });
108
109 it('updates page title and header', async () => {
110 element._hotlist = {...example.HOTLIST, displayName: 'Hotlist-Name'};
111 await element.updateComplete;
112
113 const state = store.getState();
114 assert.deepEqual(sitewide.pageTitle(state), 'People - Hotlist-Name');
115 assert.deepEqual(sitewide.headerTitle(state), 'Hotlist Hotlist-Name');
116 });
117
118 it('adds editors', async () => {
119 element._hotlist = example.HOTLIST;
120 element._permissions = [hotlists.ADMINISTER];
121 await element.updateComplete;
122
123 const input = /** @type {HTMLInputElement} */
124 (element.shadowRoot.getElementById('add'));
125 input.value = 'test@example.com, test2@example.com';
126
127 const update = sinon.spy(hotlists, 'update');
128 try {
129 await element._onAddEditors(new Event('submit'));
130
131 const editors = ['users/test@example.com', 'users/test2@example.com'];
132 sinon.assert.calledWith(update, example.HOTLIST.name, {editors});
133 } finally {
134 update.restore();
135 }
136 });
137
138 it('_onAddEditors ignores empty input', async () => {
139 element._permissions = [hotlists.ADMINISTER];
140 await element.updateComplete;
141
142 const input = /** @type {HTMLInputElement} */
143 (element.shadowRoot.getElementById('add'));
144 input.value = ' ';
145
146 const update = sinon.spy(hotlists, 'update');
147 try {
148 await element._onAddEditors(new Event('submit'));
149 sinon.assert.notCalled(update);
150 } finally {
151 update.restore();
152 }
153 });
154
155 it('removes editors', async () => {
156 element._hotlist = example.HOTLIST;
157
158 const removeEditors = sinon.spy(hotlists, 'removeEditors');
159 try {
160 await element._removeEditor(exampleUsers.NAME_2);
161
162 sinon.assert.calledWith(
163 removeEditors, example.HOTLIST.name, [exampleUsers.NAME_2]);
164 } finally {
165 removeEditors.restore();
166 }
167 });
168});
169
170it('mr-hotlist-people-page (stateChanged)', () => {
171 // @ts-ignore
172 element = document.createElement('mr-hotlist-people-page');
173 document.body.appendChild(element);
174 assert.instanceOf(element, MrHotlistPeoplePage);
175 document.body.removeChild(element);
176});