UNPKG

11.3 kBJavaScriptView Raw
1describe('ng-scores',function() {
2 "use strict";
3 var ngServices = factory('services/ng-services');
4 var module = factory('services/ng-scores',{
5 'services/ng-services': ngServices,
6 'services/log': logMock
7 });
8
9 var $scores;
10 var $score;
11 var $q;
12
13 var stagesMock = createStagesMock();
14 var teamsMock = createTeamsMock([
15 { number: 132 },
16 { number: 2581 },
17 { number: 445 }
18 ]);
19 var messageMock = createMessageMock();
20 var independenceMock = createIndependenceMock();
21 var validationMock = createValidationMock();
22 var mockScore = {
23 file: 'somescore.json',
24 team: teamsMock.teams[0].number,
25 stage: stagesMock.stages[0].id,
26 round: 1,
27 score: 150,
28 originalScore: 150
29 };
30 var fakeRankingEntry = [
31 {
32 rank: 1,
33 team: {number: 123, name: "bla"},
34 scores: [mockScore],
35 highest: mockScore
36 }
37 ];
38 var fakeRankings = {};
39 fakeRankings[stagesMock.stages[0].id] = fakeRankingEntry;
40 var rankingsMock = createRankingsMock(fakeRankings);
41
42 var rawScore = {
43 id: 'asd23d',
44 file: 'somescore.json',
45 teamNumber: teamsMock.teams[0].number,
46 stageId: stagesMock.stages[0].id,
47 round: 1,
48 score: 150,
49 originalScore: 150,
50 published: false,
51 edited: undefined,
52 table: undefined
53 };
54
55 var mockScores = { version: 3, scores: [rawScore] };
56
57 var fsMock= createFsMock({
58 "scores.json": mockScores,
59 });
60 var settingsMock = createSettingsMock(Q, {});
61
62 beforeEach(function() {
63 angular.mock.module(module.name);
64 angular.mock.module(function($provide) {
65 $provide.value('$fs', fsMock);
66 $provide.value('$stages', stagesMock);
67 $provide.value('$teams', teamsMock);
68 $provide.value('$message', messageMock);
69 $provide.value('$independence', independenceMock);
70 $provide.value('$rankings', rankingsMock);
71 $provide.value('$validation', validationMock);
72 $provide.value('$settings', settingsMock);
73 });
74 angular.mock.inject(["$scores", "$score", "$q", function(_$scores_, _$score_,_$q_) {
75 $scores = _$scores_;
76 $score = _$score_;
77 $q = _$q_;
78 }]);
79 });
80
81 // Strip autogenerated properties to (hopefully ;)) arrive at the same
82 // object as what was used as input to $scores.add().
83 function filteredScores() {
84 return $scores.scores.map(function(score) {
85 return {
86 file: score.file,
87 team: score.teamNumber,
88 stage: score.stageId,
89 round: score.round,
90 score: score.score,
91 originalScore: score.originalScore
92 };
93 });
94 }
95
96 describe('clear',function() {
97 it('should clear the scores',function() {
98 $scores.load().then(function() {
99 expect(filteredScores()).toEqual([mockScore]);
100 $scores.clear();
101 expect(filteredScores()).toEqual([]);
102 });
103 });
104 });
105
106 describe('load',function() {
107 it('should load from scores.json',function() {
108 return $scores.load().then(function() {
109 expect(fsMock.read).toHaveBeenCalledWith('scores.json');
110 });
111 });
112
113 it('should log an error if loading fails',function() {
114 fsMock.read.and.returnValue(Q.reject('read err'));
115 return $scores.load().then(function() {
116 expect(logMock).toHaveBeenCalledWith('scores read error','read err');
117 });
118 });
119
120 it('is called when recieving a load message', function(){
121 $scores.load = jasmine.createSpy('scoresLoad');
122 messageMock.mockSend('scores:reload');
123 expect($scores.load).toHaveBeenCalled();
124 });
125
126 it('throws an error if it revcieves an unkown version', function(){
127 expect(() => $scores.load({ version: 4 })).toThrow(new Error('unsupported scores version 4, (expected 3)'));
128 });
129 });
130
131 describe('_update',function() {
132 it('throws an error if endupdate is called before beginupdate', function() {
133 expect(() => $scores.endupdate()).toThrow(new Error('beginupdate()/endupdate() calls mismatched'));
134 });
135
136 it('doesn\'t run if currently updating', function() {
137 $scores.getRankings = jasmine.createSpy('getRankingsSpy').and.returnValue(Q.when());
138 $scores._updating = 1;
139 $scores._update();
140 expect($scores.getRankings).not.toHaveBeenCalled()
141 });
142 });
143
144 describe('broadcastRanking', function () {
145 it('should send a message describing the correct rankings', function () {
146 var broadcastStage = stagesMock.stages[0];
147 $scores.broadcastRanking(broadcastStage);
148 var rankingTopic = 'scores:ranking';
149 var rankingMessage = {
150 stage: {
151 id: broadcastStage.id,
152 name: broadcastStage.name,
153 rounds: broadcastStage.rounds,
154 },
155 ranking: [{
156 rank: fakeRankingEntry[0].rank,
157 team: fakeRankingEntry[0].team,
158 scores: [mockScore.score],
159 highest: fakeRankingEntry[0].highest.score
160 }]
161 };
162 $scores.getRankings().then(() => expect(messageMock.send).toHaveBeenCalledWith(rankingTopic, rankingMessage));
163 })
164 });
165
166 describe('acceptScores', function() {
167 beforeEach(function() {
168 $scores.load = jasmine.createSpy('loadSpy');
169 });
170
171 it('loads the new data', function() {
172 $scores.acceptScores({ data: mockScores });
173 expect($scores.load).toHaveBeenCalledWith(mockScores);
174 });
175
176 it('sends the reload message', function() {
177 $scores.acceptScores([mockScore]);
178 expect(messageMock.send).toHaveBeenCalledWith('scores:reload');
179 });
180
181 it('should try to auto-broadcast if call and settings permit', function () {
182 $scores.broadcastRanking = jasmine.createSpy('broadcastRankingSpy');
183 settingsMock.settings.autoBroadcast = true;
184 var autoBroadcastStage = stagesMock.stages[0];
185 settingsMock.settings.currentStage = autoBroadcastStage.id;
186 $scores.acceptScores({data: mockScores}, true);
187 expect($scores.broadcastRanking).toHaveBeenCalledWith(autoBroadcastStage)
188 });
189
190 it('should not try to auto-broadcast if call permits and settings do not', function () {
191 $scores.broadcastRanking = jasmine.createSpy('broadcastRankingSpy');
192 settingsMock.settings.autoBroadcast = false;
193 var autoBroadcastStage = stagesMock.stages[0];
194 settingsMock.settings.currentStage = autoBroadcastStage.id;
195 $scores.acceptScores({data: mockScores}, true);
196 expect($scores.broadcastRanking).not.toHaveBeenCalled();
197
198 settingsMock.settings.currentStage = undefined;
199 settingsMock.settings.autoBroadcast = true;
200 expect($scores.broadcastRanking).not.toHaveBeenCalled();
201 })
202
203 it('should not try to auto-broadcast if call does not permit and settings do', function () {
204 $scores.broadcastRanking = jasmine.createSpy('broadcastRankingSpy');
205 settingsMock.settings.autoBroadcast = true;
206 var autoBroadcastStage = stagesMock.stages[0];
207 settingsMock.settings.currentStage = autoBroadcastStage.id;
208 $scores.acceptScores({data: mockScores}, false);
209 expect($scores.broadcastRanking).not.toHaveBeenCalled();
210 })
211 });
212
213 describe('create', function() {
214 it('calls ng-independence act', function() {
215 $scores.create({ scoreEntry: {} });
216 expect(independenceMock.act).toHaveBeenCalled();
217 });
218
219 it('adds a score to scores upon failure', function() {
220 var inititalLength = $scores.scores.length;
221 independenceMock.act = jasmine.createSpy('independenceAct').and.callFake(function(url, data, fallback) {
222 fallback();
223 return new Promise(function(res, rej) {
224 res();
225 });
226 });
227 $scores.create({ scoreEntry: {} }).then(function() {
228 expect($scores.scores.length - inititalLength).toBe(1);
229 });
230 });
231 });
232
233 describe('delete', function() {
234 it('calls ng-independence act', function() {
235 $scores.delete({ id: 'asdfg' });
236 expect(independenceMock.act).toHaveBeenCalled();
237 });
238
239 it('removes a score from scores upon failure', function() {
240 var inititalLength = $scores.scores.length;
241 independenceMock.act = jasmine.createSpy('independenceAct').and.callFake(function(url, data, fallback) {
242 fallback();
243 return new Promise(function(res, rej) {
244 res();
245 });
246 });
247 $scores.delete({ id: 'asd23d' }).then(function() {
248 expect(inititalLength - $scores.scores.length).toBe(1);
249 });
250 });
251 });
252
253 describe('getRankings',function() {
254 it('calls ng-validation validate', function() {
255 $scores.getRankings();
256 expect(validationMock.validate).toHaveBeenCalled();
257 });
258
259 it('calls ng-rankings calculate if there are no errors', function() {
260 $scores.getRankings();
261 expect(rankingsMock.calculate).toHaveBeenCalled();
262 });
263
264 it('doesn\'t calls ng-rankings calculate if there are errors', function() {
265 validationMock.validate = jasmine.createSpy('validation').and.returnValue([{ name: 'DuplicateScoreError' }]);
266 rankingsMock.calculate = jasmine.createSpy('calculate');
267 $scores.getRankings();
268 expect($scores.validationErrors.length).toBe(1);
269 expect(rankingsMock.calculate).not.toHaveBeenCalled();
270 });
271 });
272
273 describe('pendingActions',function() {
274 it('calls ng-independence pendingActions', function() {
275 $scores.pendingActions();
276 expect(independenceMock.pendingActions).toHaveBeenCalled();
277 });
278 });
279
280 describe('update', function() {
281 it('calls ng-independence act', function() {
282 $scores.update({ id: 'asdfg' });
283 expect(independenceMock.act).toHaveBeenCalled();
284 });
285
286 it('updates a score in scores upon failure', function() {
287 var newScore = { id: 'asdfg' };
288 independenceMock.act = jasmine.createSpy('independenceAct').and.callFake(function(url, data, fallback) {
289 fallback();
290 return new Promise(function(res, rej) {
291 res();
292 });
293 });
294 $scores.update(newScore).then(function() {
295 expect($scores.scores.filter(score => score.id === newScore.id)).toBe(newScore);
296 });
297 });
298 });
299
300});