blob: 34377231a54e9f2991aba2ef68d323c59b674211 [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 * as stars from './stars.js';
9import * as example from 'shared/test/constants-stars.js';
10
11import {prpcClient} from 'prpc-client-instance.js';
12
13let dispatch;
14
15
16describe('star reducers', () => {
17 it('root reducer initial state', () => {
18 const actual = stars.reducer(undefined, {type: null});
19 const expected = {
20 byName: {},
21 requests: {
22 listProjects: {error: null, requesting: false},
23 starProject: {},
24 unstarProject: {},
25 },
26 };
27 assert.deepEqual(actual, expected);
28 });
29
30 describe('byNameReducer', () => {
31 it('populated on LIST_PROJECTS_SUCCESS', () => {
32 const action = {type: stars.LIST_PROJECTS_SUCCESS, stars:
33 [example.PROJECT_STAR, example.PROJECT_STAR_2]};
34 const actual = stars.byNameReducer({}, action);
35
36 assert.deepEqual(actual, {
37 [example.PROJECT_STAR_NAME]: example.PROJECT_STAR,
38 [example.PROJECT_STAR_NAME_2]: example.PROJECT_STAR_2,
39 });
40 });
41
42 it('keeps original state on empty LIST_PROJECTS_SUCCESS', () => {
43 const originalState = {
44 [example.PROJECT_STAR_NAME]: example.PROJECT_STAR,
45 [example.PROJECT_STAR_NAME_2]: example.PROJECT_STAR_2,
46 };
47 const action = {type: stars.LIST_PROJECTS_SUCCESS, stars: []};
48 const actual = stars.byNameReducer(originalState, action);
49
50 assert.deepEqual(actual, originalState);
51 });
52
53 it('appends new stars to state on LIST_PROJECTS_SUCCESS', () => {
54 const originalState = {
55 [example.PROJECT_STAR_NAME]: example.PROJECT_STAR,
56 };
57 const action = {type: stars.LIST_PROJECTS_SUCCESS,
58 stars: [example.PROJECT_STAR_2]};
59 const actual = stars.byNameReducer(originalState, action);
60
61 const expected = {
62 [example.PROJECT_STAR_NAME]: example.PROJECT_STAR,
63 [example.PROJECT_STAR_NAME_2]: example.PROJECT_STAR_2,
64 };
65 assert.deepEqual(actual, expected);
66 });
67
68 it('adds star on STAR_PROJECT_SUCCESS', () => {
69 const originalState = {
70 [example.PROJECT_STAR_NAME]: example.PROJECT_STAR,
71 };
72 const action = {type: stars.STAR_PROJECT_SUCCESS,
73 projectStar: example.PROJECT_STAR_2};
74 const actual = stars.byNameReducer(originalState, action);
75
76 const expected = {
77 [example.PROJECT_STAR_NAME]: example.PROJECT_STAR,
78 [example.PROJECT_STAR_NAME_2]: example.PROJECT_STAR_2,
79 };
80 assert.deepEqual(actual, expected);
81 });
82
83 it('removes star on UNSTAR_PROJECT_SUCCESS', () => {
84 const originalState = {
85 [example.PROJECT_STAR_NAME]: example.PROJECT_STAR,
86 [example.PROJECT_STAR_NAME_2]: example.PROJECT_STAR_2,
87 };
88 const action = {type: stars.UNSTAR_PROJECT_SUCCESS,
89 starName: example.PROJECT_STAR_NAME};
90 const actual = stars.byNameReducer(originalState, action);
91
92 const expected = {
93 [example.PROJECT_STAR_NAME_2]: example.PROJECT_STAR_2,
94 };
95 assert.deepEqual(actual, expected);
96 });
97 });
98});
99
100describe('project selectors', () => {
101 it('byName', () => {
102 const normalizedStars = {
103 [example.PROJECT_STAR_NAME]: example.PROJECT_STAR,
104 };
105 const state = {stars: {
106 byName: normalizedStars,
107 }};
108 assert.deepEqual(stars.byName(state), normalizedStars);
109 });
110
111 it('requests', () => {
112 const state = {stars: {
113 requests: {
114 listProjects: {error: null, requesting: false},
115 starProject: {},
116 unstarProject: {},
117 },
118 }};
119 assert.deepEqual(stars.requests(state), {
120 listProjects: {error: null, requesting: false},
121 starProject: {},
122 unstarProject: {},
123 });
124 });
125});
126
127describe('star action creators', () => {
128 beforeEach(() => {
129 sinon.stub(prpcClient, 'call');
130 dispatch = sinon.stub();
131 });
132
133 afterEach(() => {
134 prpcClient.call.restore();
135 });
136
137 describe('listProjects', () => {
138 it('success', async () => {
139 const starsResponse = {
140 projectStars: [example.PROJECT_STAR, example.PROJECT_STAR_2],
141 };
142 prpcClient.call.returns(Promise.resolve(starsResponse));
143
144 await stars.listProjects('users/1234')(dispatch);
145
146 sinon.assert.calledWith(dispatch, {type: stars.LIST_PROJECTS_START});
147
148 sinon.assert.calledWith(
149 prpcClient.call, 'monorail.v3.Users', 'ListProjectStars',
150 {parent: 'users/1234'});
151
152 const successAction = {
153 type: stars.LIST_PROJECTS_SUCCESS,
154 stars: [example.PROJECT_STAR, example.PROJECT_STAR_2],
155 };
156 sinon.assert.calledWith(dispatch, successAction);
157 });
158
159 it('failure', async () => {
160 prpcClient.call.throws();
161
162 await stars.listProjects('users/1234')(dispatch);
163
164 const action = {
165 type: stars.LIST_PROJECTS_FAILURE,
166 error: sinon.match.any,
167 };
168 sinon.assert.calledWith(dispatch, action);
169 });
170 });
171
172 describe('starProject', () => {
173 it('success', async () => {
174 const starResponse = example.PROJECT_STAR;
175 prpcClient.call.returns(Promise.resolve(starResponse));
176
177 await stars.starProject('projects/monorail', 'users/1234')(dispatch);
178
179 sinon.assert.calledWith(dispatch, {
180 type: stars.STAR_PROJECT_START,
181 requestKey: example.PROJECT_STAR_NAME,
182 });
183
184 sinon.assert.calledWith(
185 prpcClient.call, 'monorail.v3.Users', 'StarProject',
186 {project: 'projects/monorail'});
187
188 const successAction = {
189 type: stars.STAR_PROJECT_SUCCESS,
190 requestKey: example.PROJECT_STAR_NAME,
191 projectStar: example.PROJECT_STAR,
192 };
193 sinon.assert.calledWith(dispatch, successAction);
194 });
195
196 it('failure', async () => {
197 prpcClient.call.throws();
198
199 await stars.starProject('projects/monorail', 'users/1234')(dispatch);
200
201 const action = {
202 type: stars.STAR_PROJECT_FAILURE,
203 requestKey: example.PROJECT_STAR_NAME,
204 error: sinon.match.any,
205 };
206 sinon.assert.calledWith(dispatch, action);
207 });
208 });
209
210 describe('unstarProject', () => {
211 it('success', async () => {
212 const starResponse = {};
213 prpcClient.call.returns(Promise.resolve(starResponse));
214
215 await stars.unstarProject('projects/monorail', 'users/1234')(dispatch);
216
217 sinon.assert.calledWith(dispatch, {
218 type: stars.UNSTAR_PROJECT_START,
219 requestKey: example.PROJECT_STAR_NAME,
220 });
221
222 sinon.assert.calledWith(
223 prpcClient.call, 'monorail.v3.Users', 'UnStarProject',
224 {project: 'projects/monorail'});
225
226 const successAction = {
227 type: stars.UNSTAR_PROJECT_SUCCESS,
228 requestKey: example.PROJECT_STAR_NAME,
229 starName: example.PROJECT_STAR_NAME,
230 };
231 sinon.assert.calledWith(dispatch, successAction);
232 });
233
234 it('failure', async () => {
235 prpcClient.call.throws();
236
237 await stars.unstarProject('projects/monorail', 'users/1234')(dispatch);
238
239 const action = {
240 type: stars.UNSTAR_PROJECT_FAILURE,
241 requestKey: example.PROJECT_STAR_NAME,
242 error: sinon.match.any,
243 };
244 sinon.assert.calledWith(dispatch, action);
245 });
246 });
247});