import {async, fakeAsync, TestBed, tick} from '@angular/core/testing'; import {ChallengeService} from './challenge.service'; // import {UtilsOxService} from 'ox-core'; import {GameActionsService} from './game-actions.service'; import {ExerciseMetricsBonusTime, randomBetween} from 'ox-core'; import {HttpClientModule} from '@angular/common/http'; import {ResourceOx} from 'ox-core'; import {PreloaderOxService, ResourceType, ScreenTypeOx} from 'ox-core'; import {timer} from 'rxjs'; describe('ChallengeService', () => { let challengeService: ChallengeService; // let utils: UtilsOxService; let gameActionsService: GameActionsService; beforeEach(() => { TestBed.configureTestingModule({ providers: [PostMessageBridgeFactory, GameActionsService, ChallengeService, PreloaderOxService], imports: [HttpClientModule] }); gameActionsService = TestBed.get(GameActionsService); // utils = TestBed.get(UtilsOxService); challengeService = TestBed.get(ChallengeService); challengeService['generateNextChallenge'] = subLevel => new ExerciseOx(randomBetween(0, 1000), subLevel, new ExerciseMetricsBonusTime(10, 20)); challengeService['equalsExerciseData'] = (a, b) => a === b; } ); it('should be created', () => { expect(challengeService).toBeTruthy(); }); it('it should pre-generate one exercise of the next and previous sublevels, and PregeneratedCount of current sublevel', () => { const generates = (current, max, pregenerate) => challengeService['getPossibleNextSubLevels'](current, max, [], pregenerate); expect(generates(2, 3, 2)).toEqual([1, 2, 2, 3]); expect(generates(1, 3, 2)).toEqual([1, 1, 2]); expect(generates(3, 3, 2)).toEqual([2, 3, 3]); }); it('it should fill the cache with at least one exercise of the current sublevel after next challenge', () => { challengeService['getCurrentSubLevel'] = () => 2; challengeService['getMaxSubLevel'] = () => 3; challengeService['currentSubLevelPregeneratedExercisesNeeded'] = 2; // gameActionsService.showNextChallenge.emit(); challengeService.nextChallenge(); expect(challengeService['cachedExercises'].length).toEqual(4); }); it('must send undefined to current exercise and clean cache after restart game', () => { gameActionsService.restartGame.emit(); cleanCacheAndEmitUndefinedToCurrentExercise(); }); it('must send undefined to current exercise and clean cache after microLessonCompleted', () => { gameActionsService.microLessonCompleted.emit(); cleanCacheAndEmitUndefinedToCurrentExercise(); }); it('must send undefined to current exercise and clean cache after exitFromGame', () => { gameActionsService.exitFromGame.emit(); cleanCacheAndEmitUndefinedToCurrentExercise(); }); // it('After show next challenge there is one exercise assigned to cache', () => { // challengeService['getCurrentSubLevel'] = () => 2; // gameActionsService.showNextChallenge.emit(); // expect(challengeService.currentExercise.value.subLevel).toBe(2); // expect(challengeService.currentExercise.value.exerciseData).toBeGreaterThan(-1); // }); it('Next challenge throws error if the can not find a non repeted exercise.', () => { challengeService['usedDataExercises'] = [new ExerciseOx(1, 2, new ExerciseMetricsBonusTime(10, 20)).exerciseData]; challengeService['generateNextChallenge'] = subLevel => new ExerciseOx(1, subLevel, new ExerciseMetricsBonusTime(10, 20)); expect(function () { challengeService.assignCurrentExerciseFromCache(); challengeService.nextChallenge(); }).toThrow(); }); it('Used exercise can not be reduced to less than 1 element', () => { const aux = []; challengeService['getCurrentSubLevel'] = () => 2; for (let i = 0; i < 150; i++) { aux.push(new ExerciseOx(1, 2, new ExerciseMetricsBonusTime(10, 20)).exerciseData); } challengeService['usedDataExercises'] = aux; challengeService['generateNextChallenge'] = subLevel => new ExerciseOx(1, subLevel, new ExerciseMetricsBonusTime(10, 20)); expect(function () { challengeService.assignCurrentExerciseFromCache(); challengeService.nextChallenge(); }).toThrow(); expect(challengeService['usedDataExercises'].length).toEqual(1); }); it('assignCurrentExerciseFromCache emits a valid exercise, remove that exercise from cache, ' + 'add that exercise to used list.', () => { challengeService['getCurrentSubLevel'] = () => 1; const toCall = new ExerciseOx(1, 1, new ExerciseMetricsBonusTime(10, 20)); const toCall2 = new ExerciseOx(2, 1, new ExerciseMetricsBonusTime(10, 20)); challengeService['cachedExercises'] = [toCall, toCall2, new ExerciseOx(3, 2, new ExerciseMetricsBonusTime(10, 20))]; challengeService.assignCurrentExerciseFromCache(); const selectedExercise = [toCall, toCall2].find(x => x.exerciseData === challengeService.currentExercise.value.exerciseData); expect(selectedExercise).toBeTruthy(); expect(challengeService['cachedExercises'].some(x => x.exerciseData === selectedExercise.exerciseData)).toBeFalsy(); expect(challengeService['usedDataExercises'].some(x => x === selectedExercise.exerciseData)).toBeTruthy(); expect(challengeService['cachedExercises'].length).toBe(2); }); it('assignCurrentExerciseFromCache waits for resources loaded to emit current exercise', async((() => { challengeService['getCurrentSubLevel'] = () => 1; TestBed.get(PreloaderOxService).basePath = 'assets'; const resources: ResourceOx[] = [ new ResourceOx('__Elementos.svg', ResourceType.Audio, [ScreenTypeOx.Game], true), ]; const toCall = new ExerciseOx(1, 1, new ExerciseMetricsBonusTime(10, 20), resources); const toCall2 = new ExerciseOx(2, 1, new ExerciseMetricsBonusTime(10, 20), resources); challengeService['cachedExercises'] = [toCall, toCall2, new ExerciseOx(3, 2, new ExerciseMetricsBonusTime(10, 20))]; challengeService['loadExerciseResources'](); challengeService.assignCurrentExerciseFromCache(); // const selectedExercise = [toCall, toCall2].find(x => x.exerciseData === challengeService.currentExercise.value.exerciseData); // expect(selectedExercise).toBeTruthy(); expect(challengeService.currentExercise.value).toBeUndefined(); timer(3000).subscribe(x => { expect(challengeService.currentExercise.value).toBeTruthy(); }); // expect(challengeService['cachedExercises'].some(x => x.exerciseData === selectedExercise.exerciseData)).toBeFalsy(); // expect(challengeService['usedDataExercises'].some(x => x === selectedExercise.exerciseData)).toBeTruthy(); // expect(challengeService['cachedExercises'].length).toBe(2); }))); // it('assignCurrentExerciseFromCache emits a valid exercise, remove that exercise from cache, ' + // 'add that exercise to used list.', () => { // challengeService['getCurrentSubLevel'] = () => 1; // const toCall = new ExerciseOx(1, 1, new ExerciseMetricsBonusTime(10, 20)); // const toCall2 = new ExerciseOx(2, 1, new ExerciseMetricsBonusTime(10, 20)); // challengeService['cachedExercises'] = [toCall, toCall2, new ExerciseOx(3, 2, new ExerciseMetricsBonusTime(10, 20))]; // challengeService.assignCurrentExerciseFromCache(); // const selectedExercise = [toCall, toCall2].find(x => x.exerciseData === challengeService.currentExercise.value.exerciseData); // expect(selectedExercise).toBeTruthy(); // expect(challengeService['cachedExercises'].some(x => x.exerciseData === selectedExercise.exerciseData)).toBeFalsy(); // expect(challengeService['usedDataExercises'].some(x => x === selectedExercise.exerciseData)).toBeTruthy(); // expect(challengeService['cachedExercises'].length).toBe(2); // }); function cleanCacheAndEmitUndefinedToCurrentExercise() { spyOn(challengeService.currentExercise, 'next'); expect(challengeService['cachedExercises'].length).toEqual(0); expect(challengeService.currentExercise.value).toBe(undefined); } });