Commit bd16be14 authored by Konstantin Schulz's avatar Konstantin Schulz

fixed a bug in the test page where local exercises would not load in test mode

parent 73b1e38a
Pipeline #15562 passed with stages
in 2 minutes and 48 seconds
......@@ -17871,6 +17871,14 @@ Heluios
Heluium
Heluius
Heluorum
Helvetia
Helvetiae
Helvetico
Helvetii
Helvetiis
Helvetiorum
Helvetios
Helvetium
Helymi
Helymum
Helymus
......
......@@ -129,7 +129,6 @@ describe('ExerciseService', () => {
let callCount = 0;
getSpy.and.callFake(() => {
callCount += 1;
console.log(callCount);
return callCount === 1 ? Promise.resolve({}) : Promise.reject();
});
exerciseService.downloadLocalH5PExercise().then(() => {
......@@ -336,7 +335,8 @@ describe('ExerciseService', () => {
result: new Result(),
verb: new Verb({id: configMC.xAPIverbIDanswered})
})
}
},
type: EventMC.xAPI.toString()
}));
iframe.parentNode.removeChild(iframe);
expect(postSpy).toHaveBeenCalledTimes(1);
......
......@@ -246,12 +246,13 @@ export class ExerciseService {
});
} else {
let etp: ExerciseTypePath = params.type as ExerciseTypePath;
etp = etp === ExerciseTypePath.VocList ? ExerciseTypePath.FillBlanks : etp;
this.currentExerciseParams.libraryPath = [this.helperService.baseUrl, this.h5pPathLocal, etp]
.join('/');
this.currentExerciseParams.filePath =
[this.currentExerciseParams.libraryPath, 'content', params.author, params.fileID]
.join('/') + `_${this.currentExerciseParams.language}.json`;
// do this AFTER the URL / file path was constructed
etp = etp === ExerciseTypePath.VocList ? ExerciseTypePath.FillBlanks : etp;
this.initH5P(etp, this.currentExerciseParams.filePath,
params.showActions ? params.showActions : true).then(() => {
return resolve();
......@@ -290,7 +291,7 @@ export class ExerciseService {
this.helperService.makePostRequest(this.http, this.toastCtrl, fileUrl, formData, '').then(() => {
return resolve();
}, () => {
console.log('ERROR: COULD NOT SEND EXERCISE RESULTS TO SERVER.');
console.error('Network error: Could not send exercise results to server.');
return reject();
});
});
......@@ -335,19 +336,22 @@ export class ExerciseService {
}
setXAPIeventHandler(): void {
this.helperService.getH5P().externalDispatcher.off(EventMC.xAPI);
this.helperService.getH5P().externalDispatcher.on(EventMC.xAPI, (event: XAPIevent) => {
// results are only available when a task has been completed/answered, not in the "attempted" or "interacted" stages
if (event.data.statement.verb.id === configMC.xAPIverbIDanswered && event.data.statement.result) {
const iframe: HTMLIFrameElement = this.getH5PIframe();
if (iframe) {
const iframeDoc: Document = iframe.contentWindow.document;
const inner: string = iframeDoc.documentElement.innerHTML;
const result: TestResultMC = new TestResultMC({
statement: event.data.statement,
innerHTML: inner
});
this.sendData(result).then();
this.helperService.getH5P().externalDispatcher.off(EventMC.any);
this.helperService.getH5P().externalDispatcher.on(EventMC.any, (event: XAPIevent) => {
if (event.type === EventMC.xAPI.toString()) {
this.helperService.events.trigger(EventMC.xAPI, event);
// results are only available when a task has been completed/answered, not in the "attempted" or "interacted" stages
if (event.data.statement.verb.id === configMC.xAPIverbIDanswered && event.data.statement.result) {
const iframe: HTMLIFrameElement = this.getH5PIframe();
if (iframe) {
const iframeDoc: Document = iframe.contentWindow.document;
const inner: string = iframeDoc.documentElement.innerHTML;
const result: TestResultMC = new TestResultMC({
statement: event.data.statement,
innerHTML: inner
});
this.sendData(result).then();
}
}
}
});
......
......@@ -91,6 +91,7 @@ export enum DependencyTranslation {
}
export enum EventMC {
any = '*' as any,
h5pCreated = 'h5pCreated' as any,
xAPI = 'xAPI' as any,
}
......
......@@ -4,14 +4,23 @@ export default class EventRegistry {
listeners: { [eventName: string]: any[] } = {};
public off(eventName: EventMC): void {
if (eventName === EventMC.any) {
[EventMC.h5pCreated, EventMC.xAPI].forEach(value => this.off(value));
return;
}
this.listeners[eventName] = [];
}
public on(eventName: EventMC, callback: any): void {
if (!this.listeners[eventName]) {
this.listeners[eventName] = [];
if (eventName === EventMC.any) {
[EventMC.h5pCreated, EventMC.xAPI].forEach(value => this.on(value, callback));
return;
} else {
if (!this.listeners[eventName]) {
this.listeners[eventName] = [];
}
this.listeners[eventName].push(callback);
}
this.listeners[eventName].push(callback);
}
public trigger(eventName: EventMC, event: any): void {
......
......@@ -156,7 +156,7 @@ describe('PreviewPage', () => {
it('should send data', (done) => {
const requestSpy: Spy = spyOn(previewPage.helperService, 'makePostRequest').and.returnValue(Promise.resolve());
const consoleSpy: Spy = spyOn(console, 'log');
const consoleSpy: Spy = spyOn(console, 'error');
previewPage.exerciseService.sendData(new TestResultMC()).then(() => {
expect(consoleSpy).toHaveBeenCalledTimes(0);
requestSpy.and.callFake(() => Promise.reject());
......
......@@ -14,7 +14,6 @@ import Score from '../models/xAPI/Score';
import {EventMC, TestModuleState} from '../models/enum';
import MockMC from '../models/mockMC';
import {XAPIevent} from '../models/xAPIevent';
import EventRegistry from '../models/eventRegistry';
import Verb from '../models/xAPI/Verb';
import configMC from '../../configMC';
import Context from '../models/xAPI/Context';
......@@ -29,8 +28,6 @@ import {ExerciseTypePath} from '../../../openapi';
describe('TestPage', () => {
let testPage: TestPage;
let fixture: ComponentFixture<TestPage>;
let newDispatcher: EventRegistry;
let getH5Pspy: Spy;
beforeEach(async(() => {
TestBed.configureTestingModule({
......@@ -52,8 +49,6 @@ describe('TestPage', () => {
beforeEach(() => {
fixture = TestBed.createComponent(TestPage);
testPage = fixture.componentInstance;
newDispatcher = new EventRegistry();
getH5Pspy = spyOn(testPage.helperService, 'getH5P').and.returnValue({externalDispatcher: newDispatcher});
fixture.detectChanges();
});
......@@ -232,10 +227,10 @@ describe('TestPage', () => {
statement: new StatementBase({result: new Result(), verb: new Verb({id: configMC.xAPIverbIDanswered})})
}
});
newDispatcher.trigger(EventMC.xAPI, xapiEvent);
testPage.helperService.events.trigger(EventMC.xAPI, xapiEvent);
expect(finishSpy).toHaveBeenCalledTimes(0);
testPage.currentState = TestModuleState.inProgress;
newDispatcher.trigger(EventMC.xAPI, xapiEvent);
testPage.helperService.events.trigger(EventMC.xAPI, xapiEvent);
expect(finishSpy).toHaveBeenCalledTimes(1);
const inputEventSpy: Spy = spyOn(testPage, 'setInputEventHandler');
const solutionsEventSpy: Spy = spyOn(testPage, 'handleSolutionsEvent');
......
......@@ -17,8 +17,7 @@ import {ExerciseService} from 'src/app/exercise.service';
import configMC from '../../configMC';
import {Storage} from '@ionic/storage';
import {CorpusService} from '../corpus.service';
import {ExerciseTypePath} from '../../../openapi';
import {ExerciseAuthor} from '../../../openapi';
import {ExerciseAuthor, ExerciseTypePath} from '../../../openapi';
@Component({
selector: 'app-test',
......@@ -316,7 +315,7 @@ export class TestPage implements OnDestroy, OnInit {
ngOnDestroy(): void {
this.removeTimer(false);
this.helperService.getH5P().externalDispatcher.off(EventMC.xAPI);
this.helperService.events.off(EventMC.xAPI);
this.helperService.events.off(EventMC.h5pCreated);
}
......@@ -401,12 +400,13 @@ export class TestPage implements OnDestroy, OnInit {
}
setH5PeventHandlers(): void {
this.helperService.getH5P().externalDispatcher.on(EventMC.xAPI, (event: XAPIevent) => {
this.helperService.events.on(EventMC.xAPI, (event: XAPIevent) => {
if (this.currentState !== TestModuleState.inProgress) {
return;
}
// results are only available when a task has been completed/answered, not in the "attempted" or "interacted" stages
if (event.data.statement.verb.id === configMC.xAPIverbIDanswered && event.data.statement.result) {
// results are only available when a task has been completed/answered, not just "attempted" or "interacted"
if (event.data && event.data.statement &&
event.data.statement.verb.id === configMC.xAPIverbIDanswered && event.data.statement.result) {
this.finishCurrentExercise(event).then();
}
});
......@@ -470,7 +470,7 @@ export class TestPage implements OnDestroy, OnInit {
}
}
const fileName: string = this.exerciseService.currentExerciseName.split('_').slice(-1)[0];
let exerciseType = this.exerciseService.currentExerciseName.split('_').slice(0, 2).join('_');
let exerciseType: string = this.exerciseService.currentExerciseName.split('_').slice(0, 2).join('_');
this.exerciseService.loadExercise({
showActions: false,
author: ExerciseAuthor.Callidus,
......
......@@ -15,7 +15,7 @@ export default {
backendBaseUrl: '',
bambergCoreVocabularyUrl: 'https://www.ccbuchner.de/reihe-0-0/adeo-53/',
callidusProjectUrl: 'https://www.projekte.hu-berlin.de/de/callidus',
developerMailTo: 'mailto:sulzkons@hu-berlin.de?subject=[CALLIDUS-Software]',
developerMailTo: 'mailto:schulzkx@hu-berlin.de?subject=[CALLIDUS-Software]',
frontendBaseUrl: '',
intervalCorporaUpdate: 1209600000,
localStorageKeyApplicationState: 'mc/applicationState',
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment