1 | describe('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 |
|
82 |
|
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 | });
|