blob: aab798955c0a358c30a2ba4c7059bcea12f97859 [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';
7import * as userV0 from './userV0.js';
8import {prpcClient} from 'prpc-client-instance.js';
9
10
11let dispatch;
12
13describe('userV0', () => {
14 describe('reducers', () => {
15 it('SET_PREFS_SUCCESS updates existing prefs with new prefs', () => {
16 const state = {prefs: {
17 testPref: 'true',
18 anotherPref: 'hello-world',
19 }};
20
21 const newPrefs = [
22 {name: 'anotherPref', value: 'override'},
23 {name: 'newPref', value: 'test-me'},
24 ];
25
26 const newState = userV0.currentUserReducer(state,
27 {type: userV0.SET_PREFS_SUCCESS, newPrefs});
28
29 assert.deepEqual(newState, {prefs: {
30 testPref: 'true',
31 anotherPref: 'override',
32 newPref: 'test-me',
33 }});
34 });
35
36 it('FETCH_PROJECTS_SUCCESS overrides existing entry in usersById', () => {
37 const state = {
38 ['123']: {
39 projects: {
40 ownerOf: [],
41 memberOf: [],
42 contributorTo: [],
43 starredProjects: [],
44 },
45 },
46 };
47
48 const usersProjects = [
49 {
50 userRef: {userId: '123'},
51 ownerOf: ['chromium'],
52 },
53 ];
54
55 const newState = userV0.usersByIdReducer(state,
56 {type: userV0.FETCH_PROJECTS_SUCCESS, usersProjects});
57
58 assert.deepEqual(newState, {
59 ['123']: {
60 projects: {
61 ownerOf: ['chromium'],
62 memberOf: [],
63 contributorTo: [],
64 starredProjects: [],
65 },
66 },
67 });
68 });
69
70 it('FETCH_PROJECTS_SUCCESS adds new entry to usersById', () => {
71 const state = {
72 ['123']: {
73 projects: {
74 ownerOf: [],
75 memberOf: [],
76 contributorTo: [],
77 starredProjects: [],
78 },
79 },
80 };
81
82 const usersProjects = [
83 {
84 userRef: {userId: '543'},
85 ownerOf: ['chromium'],
86 },
87 {
88 userRef: {userId: '789'},
89 memberOf: ['v8'],
90 },
91 ];
92
93 const newState = userV0.usersByIdReducer(state,
94 {type: userV0.FETCH_PROJECTS_SUCCESS, usersProjects});
95
96 assert.deepEqual(newState, {
97 ['123']: {
98 projects: {
99 ownerOf: [],
100 memberOf: [],
101 contributorTo: [],
102 starredProjects: [],
103 },
104 },
105 ['543']: {
106 projects: {
107 ownerOf: ['chromium'],
108 memberOf: [],
109 contributorTo: [],
110 starredProjects: [],
111 },
112 },
113 ['789']: {
114 projects: {
115 ownerOf: [],
116 memberOf: ['v8'],
117 contributorTo: [],
118 starredProjects: [],
119 },
120 },
121 });
122 });
123
124 describe('GAPI_LOGIN_SUCCESS', () => {
125 it('sets currentUser.gapiEmail', () => {
126 const newState = userV0.currentUserReducer({}, {
127 type: userV0.GAPI_LOGIN_SUCCESS,
128 email: 'rutabaga@rutabaga.com',
129 });
130 assert.deepEqual(newState, {
131 gapiEmail: 'rutabaga@rutabaga.com',
132 });
133 });
134
135 it('defaults to an empty string', () => {
136 const newState = userV0.currentUserReducer({}, {
137 type: userV0.GAPI_LOGIN_SUCCESS,
138 });
139 assert.deepEqual(newState, {
140 gapiEmail: '',
141 });
142 });
143 });
144
145 describe('GAPI_LOGOUT_SUCCESS', () => {
146 it('sets currentUser.gapiEmail', () => {
147 const newState = userV0.currentUserReducer({}, {
148 type: userV0.GAPI_LOGOUT_SUCCESS,
149 email: '',
150 });
151 assert.deepEqual(newState, {
152 gapiEmail: '',
153 });
154 });
155
156 it('defaults to an empty string', () => {
157 const state = {};
158 const newState = userV0.currentUserReducer(state, {
159 type: userV0.GAPI_LOGOUT_SUCCESS,
160 });
161 assert.deepEqual(newState, {
162 gapiEmail: '',
163 });
164 });
165 });
166 });
167
168 describe('selectors', () => {
169 it('prefs', () => {
170 const state = wrapCurrentUser({prefs: {
171 testPref: 'true',
172 test_non_bool: 'hello-world',
173 }});
174
175 assert.deepEqual(userV0.prefs(state), new Map([
176 ['render_markdown', false],
177 ['testPref', true],
178 ['test_non_bool', 'hello-world'],
179 ]));
180 });
181
182 it('prefs is set with the correct type', async () =>{
183 // When setting prefs it's important that they are set as their
184 // String value.
185 const state = wrapCurrentUser({prefs: {
186 render_markdown : 'true',
187 }});
188 const markdownPref = userV0.prefs(state).get('render_markdown');
189 assert.isTrue(markdownPref);
190 });
191
192 it('prefs is NOT set with the correct type', async () =>{
193 // Here the value is a boolean so when it gets set it would
194 // appear as false because it's compared with a String.
195 const state = wrapCurrentUser({prefs: {
196 render_markdown : true,
197 }});
198 const markdownPref = userV0.prefs(state).get('render_markdown');
199 // Thus this is false when it was meant to be true.
200 assert.isFalse(markdownPref);
201 });
202
203 it('projects', () => {
204 assert.deepEqual(userV0.projects(wrapUser({})), {});
205
206 const state = wrapUser({
207 currentUser: {userId: '123'},
208 usersById: {
209 ['123']: {
210 projects: {
211 ownerOf: ['chromium'],
212 memberOf: ['v8'],
213 contributorTo: [],
214 starredProjects: [],
215 },
216 },
217 },
218 });
219
220 assert.deepEqual(userV0.projects(state), {
221 ownerOf: ['chromium'],
222 memberOf: ['v8'],
223 contributorTo: [],
224 starredProjects: [],
225 });
226 });
227
228 it('projectPerUser', () => {
229 assert.deepEqual(userV0.projectsPerUser(wrapUser({})), new Map());
230
231 const state = wrapUser({
232 usersById: {
233 ['123']: {
234 projects: {
235 ownerOf: ['chromium'],
236 memberOf: ['v8'],
237 contributorTo: [],
238 starredProjects: [],
239 },
240 },
241 },
242 });
243
244 assert.deepEqual(userV0.projectsPerUser(state), new Map([
245 ['123', {
246 ownerOf: ['chromium'],
247 memberOf: ['v8'],
248 contributorTo: [],
249 starredProjects: [],
250 }],
251 ]));
252 });
253 });
254
255 describe('action creators', () => {
256 beforeEach(() => {
257 sinon.stub(prpcClient, 'call');
258
259 dispatch = sinon.stub();
260 });
261
262 afterEach(() => {
263 prpcClient.call.restore();
264 });
265
266 it('fetchProjects succeeds', async () => {
267 const action = userV0.fetchProjects([{userId: '123'}]);
268
269 prpcClient.call.returns(Promise.resolve({
270 usersProjects: [
271 {
272 userRef: {
273 userId: '123',
274 },
275 ownerOf: ['chromium'],
276 },
277 ],
278 }));
279
280 await action(dispatch);
281
282 sinon.assert.calledWith(dispatch, {type: userV0.FETCH_PROJECTS_START});
283
284 sinon.assert.calledWith(
285 prpcClient.call,
286 'monorail.Users',
287 'GetUsersProjects',
288 {userRefs: [{userId: '123'}]});
289
290 sinon.assert.calledWith(dispatch, {
291 type: userV0.FETCH_PROJECTS_SUCCESS,
292 usersProjects: [
293 {
294 userRef: {
295 userId: '123',
296 },
297 ownerOf: ['chromium'],
298 },
299 ],
300 });
301 });
302
303 it('fetchProjects fails', async () => {
304 const action = userV0.fetchProjects([{userId: '123'}]);
305
306 const error = new Error('mistakes were made');
307 prpcClient.call.returns(Promise.reject(error));
308
309 await action(dispatch);
310
311 sinon.assert.calledWith(dispatch, {type: userV0.FETCH_PROJECTS_START});
312
313 sinon.assert.calledWith(
314 prpcClient.call,
315 'monorail.Users',
316 'GetUsersProjects',
317 {userRefs: [{userId: '123'}]});
318
319 sinon.assert.calledWith(dispatch, {
320 type: userV0.FETCH_PROJECTS_FAILURE,
321 error,
322 });
323 });
324
325 it('setPrefs', async () => {
326 const action = userV0.setPrefs([{name: 'pref_name', value: 'true'}]);
327
328 prpcClient.call.returns(Promise.resolve({}));
329
330 await action(dispatch);
331
332 sinon.assert.calledWith(dispatch, {type: userV0.SET_PREFS_START});
333
334 sinon.assert.calledWith(
335 prpcClient.call,
336 'monorail.Users',
337 'SetUserPrefs',
338 {prefs: [{name: 'pref_name', value: 'true'}]});
339
340 sinon.assert.calledWith(dispatch, {
341 type: userV0.SET_PREFS_SUCCESS,
342 newPrefs: [{name: 'pref_name', value: 'true'}],
343 });
344 });
345
346 it('setPrefs fails', async () => {
347 const action = userV0.setPrefs([{name: 'pref_name', value: 'true'}]);
348
349 const error = new Error('mistakes were made');
350 prpcClient.call.returns(Promise.reject(error));
351
352 await action(dispatch);
353
354 sinon.assert.calledWith(dispatch, {type: userV0.SET_PREFS_START});
355
356 sinon.assert.calledWith(
357 prpcClient.call,
358 'monorail.Users',
359 'SetUserPrefs',
360 {prefs: [{name: 'pref_name', value: 'true'}]});
361
362 sinon.assert.calledWith(dispatch, {
363 type: userV0.SET_PREFS_FAILURE,
364 error,
365 });
366 });
367 });
368});
369
370
371const wrapCurrentUser = (currentUser = {}) => ({userV0: {currentUser}});
372const wrapUser = (user) => ({userV0: user});