blob: 987fff21b775d576b618753328e33cc5926dbddb [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 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 {MrHotlistSettingsPage} from './mr-hotlist-settings-page.js';
16
17/** @type {MrHotlistSettingsPage} */
18let element;
19
20describe('mr-hotlist-settings-page (unconnected)', () => {
21 beforeEach(() => {
22 // @ts-ignore
23 element = document.createElement('mr-hotlist-settings-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('shows loading message with null hotlist', async () => {
39 await element.updateComplete;
40 assert.include(element.shadowRoot.innerHTML, 'Loading');
41 });
42
43 it('renders hotlist', async () => {
44 element._hotlist = example.HOTLIST;
45 await element.updateComplete;
46 });
47
48 it('renders a view only hotlist if no permissions', async () => {
49 element._hotlist = {...example.HOTLIST};
50 await element.updateComplete;
51 assert.notInclude(element.shadowRoot.innerHTML, 'form');
52 });
53
54 it('renders an editable hotlist if permission to administer', async () => {
55 element._hotlist = {...example.HOTLIST};
56 element._permissions = [hotlists.ADMINISTER];
57 await element.updateComplete;
58 assert.include(element.shadowRoot.innerHTML, 'form');
59 });
60
61 it('renders private hotlist', async () => {
62 element._hotlist = {...example.HOTLIST, hotlistPrivacy: 'PRIVATE'};
63 await element.updateComplete;
64 assert.include(element.shadowRoot.innerHTML, 'Members only');
65 });
66});
67
68describe('mr-hotlist-settings-page (connected)', () => {
69 beforeEach(() => {
70 store.dispatch(resetState());
71
72 // @ts-ignore
73 element = document.createElement('mr-hotlist-settings-page');
74 document.body.appendChild(element);
75
76 // Stop Redux from overriding values being tested.
77 sinon.stub(element, 'stateChanged');
78 });
79
80 afterEach(() => {
81 element.stateChanged.restore();
82 document.body.removeChild(element);
83 });
84
85 it('updates page title and header', async () => {
86 element._hotlist = {...example.HOTLIST, displayName: 'Hotlist-Name'};
87 await element.updateComplete;
88
89 const state = store.getState();
90 assert.deepEqual(sitewide.pageTitle(state), 'Settings - Hotlist-Name');
91 assert.deepEqual(sitewide.headerTitle(state), 'Hotlist Hotlist-Name');
92 });
93
94 it('deletes hotlist', async () => {
95 element._hotlist = example.HOTLIST;
96 element._permissions = [hotlists.ADMINISTER];
97 element._currentUser = exampleUsers.USER;
98 await element.updateComplete;
99
100 const deleteButton = element.shadowRoot.getElementById('delete-hotlist');
101 assert.isNotNull(deleteButton);
102
103 // Auto confirm deletion of hotlist.
104 const confirmStub = sinon.stub(window, 'confirm');
105 confirmStub.returns(true);
106
107 const pageStub = sinon.stub(element, 'page');
108
109 const deleteHotlist = sinon.spy(hotlists, 'deleteHotlist');
110
111 try {
112 await element._delete();
113
114 sinon.assert.calledWith(deleteHotlist, example.NAME);
115 sinon.assert.calledWith(
116 element.page, `/u/${exampleUsers.DISPLAY_NAME}/hotlists`);
117 } finally {
118 deleteHotlist.restore();
119 pageStub.restore();
120 confirmStub.restore();
121 }
122 });
123
124 it('updates hotlist when there are changes', async () => {
125 element._hotlist = {...example.HOTLIST};
126 element._permissions = [hotlists.ADMINISTER];
127 await element.updateComplete;
128
129 const saveButton = element.shadowRoot.getElementById('save-hotlist');
130 assert.isNotNull(saveButton);
131 assert.isTrue(saveButton.hasAttribute('disabled'));
132
133 const hlist = {
134 displayName: element._hotlist.displayName + 'foo',
135 summary: element._hotlist.summary + 'abc',
136 };
137
138 const summaryInput = element.shadowRoot.getElementById('summary');
139 /** @type {HTMLInputElement} */ (summaryInput).value += 'abc';
140 const nameInput =
141 element.shadowRoot.getElementById('displayName');
142 /** @type {HTMLInputElement} */ (nameInput).value += 'foo';
143
144 await element.shadowRoot.getElementById('settingsForm').dispatchEvent(
145 new Event('change'));
146 assert.isFalse(saveButton.hasAttribute('disabled'));
147
148 const snackbarStub = sinon.stub(element, '_showHotlistSavedSnackbar');
149 const update = sinon.stub(hotlists, 'update').returns(async () => {});
150 try {
151 await element._save();
152 sinon.assert.calledWith(update, example.HOTLIST.name, hlist);
153 sinon.assert.calledOnce(snackbarStub);
154 } finally {
155 update.restore();
156 snackbarStub.restore();
157 }
158 });
159});
160
161it('mr-hotlist-settings-page (stateChanged)', () => {
162 // @ts-ignore
163 element = document.createElement('mr-hotlist-settings-page');
164 document.body.appendChild(element);
165 assert.instanceOf(element, MrHotlistSettingsPage);
166 document.body.removeChild(element);
167});