Commit 7de52892 authored by Konstantin Schulz's avatar Konstantin Schulz

the pages for exercise list and authors may now be accessed using deep links

parent 1b7ffc26
Pipeline #13975 passed with stages
in 3 minutes and 45 seconds
......@@ -33,7 +33,10 @@ To generate class structures for this project automatically:
## Documentation
### API
To view the API documentation, visit https://korpling.org/mc-service/mc/api/v1.0/ui/ .
To view the official API documentation, visit https://korpling.org/mc-service/mc/api/v1.0/ui/ .
If you make local changes to the source code, your own API documentation will be published at http://localhost:5000/mc/api/v1.0/ui/ .
The port (5000) and API path (/mc/api/v1.0/) may change depending on your configuration.
### Changelog
To update the changelog, use: `git log --oneline --decorate > CHANGELOG`
......
......@@ -16,7 +16,7 @@ import {
TranslateTestingModule
} from './translate-testing/translate-testing.module';
import {APP_BASE_HREF} from '@angular/common';
import {Subscription} from 'rxjs';
import {ReplaySubject, Subscription} from 'rxjs';
import {HelperService} from './helper.service';
import {CorpusService} from './corpus.service';
import Spy = jasmine.Spy;
......@@ -63,7 +63,10 @@ describe('AppComponent', () => {
{provide: Platform, useClass: PlatformStub},
{provide: APP_BASE_HREF, useValue: '/'},
{provide: MenuController},
{provide: CorpusService, useValue: {initCorpusService: () => Promise.resolve()}},
{
provide: CorpusService,
useValue: {initCorpusService: () => Promise.resolve(), isInitialized: new ReplaySubject<boolean>(1)}
},
{
provide: HelperService,
useValue: {makeGetRequest: () => Promise.resolve(MockMC.apiResponseCorporaGet)}
......
......@@ -24,8 +24,10 @@ export class AppComponent {
public menuCtrl: MenuController,
public corpusService: CorpusService,
) {
platform.ready().then(() => {
this.corpusService.initCorpusService().then();
platform.ready().then(async () => {
this.corpusService.initCorpusService().then(() => {
this.corpusService.isInitialized.next(true);
});
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
this.statusBar.styleDefault();
......
......@@ -11,6 +11,7 @@ import {APP_BASE_HREF} from '@angular/common';
import {Author} from '../models/author';
import Spy = jasmine.Spy;
import MockMC from '../models/mockMC';
import {CorpusService} from '../corpus.service';
describe('AuthorPage', () => {
let authorPage: AuthorPage;
......@@ -30,10 +31,19 @@ describe('AuthorPage', () => {
],
providers: [
{provide: APP_BASE_HREF, useValue: '/'},
{
provide: CorpusService,
useValue: {
availableAuthors: [],
getCorpora: () => Promise.resolve(),
isTreebank: () => true,
restoreLastCorpus: () => Promise.resolve()
}
}
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
.compileComponents();
.compileComponents().then();
}));
beforeEach(() => {
......@@ -63,13 +73,19 @@ describe('AuthorPage', () => {
expect(authorPage.authorsDisplayed.length).toBe(1);
});
it('should be initialized', () => {
authorPage.corpusService.availableAuthors = [new Author({
corpora: [{source_urn: 'proiel'}],
name: 'name'
})];
authorPage.ngOnInit();
expect(authorPage.baseAuthorList.length).toBe(1);
it('should be initialized', (done) => {
const storageSpy: Spy = spyOn(authorPage.storage, 'get').and.returnValue(Promise.resolve(null));
authorPage.ngOnInit().then(async () => {
expect(storageSpy).toHaveBeenCalledTimes(1);
authorPage.corpusService.availableAuthors = [new Author({
corpora: [{source_urn: 'proiel'}],
name: 'name'
})];
await authorPage.ngOnInit();
expect(storageSpy).toHaveBeenCalledTimes(1);
expect(authorPage.baseAuthorList.length).toBe(1);
done();
});
});
it('should restore the last setup', (done) => {
......@@ -100,4 +116,11 @@ describe('AuthorPage', () => {
authorPage.showCorpora(author);
expect(authorPage.corpusService.currentAuthor).toBe(author);
});
it('should toggle treebank authors', () => {
authorPage.showOnlyTreebanks = false;
authorPage.corpusService.availableAuthors = [{corpora: [], name: ''}];
authorPage.toggleTreebankAuthors();
expect(authorPage.baseAuthorList.length).toBe(1);
});
});
......@@ -9,6 +9,8 @@ import {ExerciseService} from '../exercise.service';
import {ApplicationState} from '../models/applicationState';
import {take} from 'rxjs/operators';
import configMC from '../../configMC';
import {UpdateInfo} from '../models/updateInfo';
import {Storage} from '@ionic/storage';
/**
* Generated class for the AuthorPage page.
......@@ -28,7 +30,8 @@ export class AuthorPage implements OnInit {
public corpusService: CorpusService,
public http: HttpClient,
public exerciseService: ExerciseService,
public helperService: HelperService) {
public helperService: HelperService,
public storage: Storage) {
}
public authorsDisplayed: Author[];
......@@ -55,14 +58,22 @@ export class AuthorPage implements OnInit {
return this.corpusService.availableAuthors.filter(author => author.corpora.some(corpus => this.corpusService.isTreebank(corpus)));
}
ngOnInit(): void {
if (!this.corpusService.availableAuthors.length) {
this.corpusService.loadCorporaFromLocalStorage().then(() => {
ngOnInit(): Promise<void> {
return new Promise<void>(resolve => {
if (!this.corpusService.availableAuthors.length) {
this.storage.get(configMC.localStorageKeyUpdateInfo).then((jsonString: string) => {
// check local storage for necessary updates
const updateInfo: UpdateInfo = JSON.parse(jsonString) as UpdateInfo;
this.corpusService.getCorpora(updateInfo ? updateInfo.corpora : 0).then(() => {
this.toggleTreebankAuthors();
return resolve();
});
});
} else {
this.toggleTreebankAuthors();
});
} else {
this.toggleTreebankAuthors();
}
return resolve();
}
});
}
restoreLastSetup(): Promise<void> {
......
......@@ -238,7 +238,7 @@ describe('CorpusService', () => {
it('should initialize the corpus service', (done) => {
const annisRespSpy: Spy = spyOn(corpusService, 'checkAnnisResponse').and.callFake(() => Promise.reject());
const restoreSpy: Spy = spyOn(corpusService, 'restoreLastCorpus').and.returnValue(Promise.resolve());
const updateInfoSpy: Spy = spyOn(corpusService, 'initUpdateInfo').and.callFake(() => Promise.reject());
const updateInfoSpy: Spy = spyOn(corpusService.helperService, 'initUpdateInfo').and.callFake(() => Promise.reject());
helperService.applicationState.next(helperService.deepCopy(MockMC.applicationState) as ApplicationState);
corpusService.initCorpusService().then(() => {
}, () => {
......@@ -286,23 +286,6 @@ describe('CorpusService', () => {
expect(corpus).toBeTruthy();
}));
it('should initialize the update information', (done) => {
const updateInfoSpy: Spy = spyOn(corpusService.storage, 'get').withArgs(configMC.localStorageKeyUpdateInfo);
updateInfoSpy.and.returnValue(Promise.resolve(''));
corpusService.initUpdateInfo().then(() => {
updateInfoSpy.and.callThrough();
corpusService.storage.get(configMC.localStorageKeyUpdateInfo).then((jsonString: string) => {
const updateInfo: UpdateInfo = JSON.parse(jsonString) as UpdateInfo;
expect(updateInfo.corpora).toBe(1);
const setSpy: Spy = spyOn(corpusService.storage, 'set').and.returnValue(Promise.resolve());
corpusService.initUpdateInfo().then(() => {
expect(setSpy).toHaveBeenCalledTimes(0);
done();
});
});
});
});
it('should load corpora from local storage', (done) => {
corpusService.availableCorpora = [];
spyOn(corpusService.storage, 'get').withArgs(configMC.localStorageKeyCorpora).and.returnValue(
......
......@@ -66,6 +66,7 @@ export class CorpusService {
public invalidQueryCorpusString: string;
public invalidSentenceCountString: string;
public invalidTextRangeString: string;
public isInitialized: ReplaySubject<boolean>;
public isTextRangeCorrect = false;
public phenomenonMap: PhenomenonMap = new PhenomenonMap({
dependency: new PhenomenonMapContent({translationObject: DependencyTranslation}),
......@@ -305,9 +306,10 @@ export class CorpusService {
initCorpusService(): Promise<void> {
return new Promise<void>((resolve, reject) => {
this.isInitialized = new ReplaySubject<boolean>(1);
this.initCurrentCorpus().then();
this.initCurrentTextRange();
this.initUpdateInfo().then(() => {
this.helperService.initUpdateInfo().then(() => {
this.checkForUpdates().finally(() => {
this.checkAnnisResponse().then(() => {
this.restoreLastCorpus().then(() => {
......@@ -370,23 +372,6 @@ export class CorpusService {
});
}
initUpdateInfo(): Promise<void> {
return new Promise<void>(resolve => {
this.storage.get(configMC.localStorageKeyUpdateInfo).then((jsonString: string) => {
if (jsonString) {
return resolve();
}
const ui: UpdateInfo = new UpdateInfo({
corpora: 1,
exerciseList: 1
});
this.storage.set(configMC.localStorageKeyUpdateInfo, JSON.stringify(ui)).then(() => {
return resolve();
});
});
});
}
isTreebank(corpus: CorpusMC): boolean {
return corpus.source_urn.includes('proiel');
}
......
......@@ -17,6 +17,7 @@ import Spy = jasmine.Spy;
import configMC from '../../configMC';
import {UpdateInfo} from '../models/updateInfo';
import {VocabularyMC} from '../../../openapi';
import {ReplaySubject} from 'rxjs';
describe('ExerciseListPage', () => {
let exerciseListPage: ExerciseListPage;
......@@ -46,6 +47,8 @@ describe('ExerciseListPage', () => {
fixture = TestBed.createComponent(ExerciseListPage);
exerciseListPage = fixture.componentInstance;
getExerciseListSpy = spyOn(exerciseListPage, 'getExerciseList').and.returnValue(Promise.resolve());
exerciseListPage.corpusService.isInitialized = new ReplaySubject<boolean>(1);
exerciseListPage.corpusService.isInitialized.next(true);
fixture.detectChanges();
});
......
......@@ -124,10 +124,12 @@ export class ExerciseListPage implements OnInit {
ngOnInit(): Promise<void> {
return new Promise<void>(((resolve, reject) => {
this.vocService.currentReferenceVocabulary = null;
this.getExerciseList().then(() => {
return resolve();
}, () => {
return resolve();
this.corpusService.isInitialized.pipe(take(1)).subscribe(() => {
this.getExerciseList().then(() => {
return resolve();
}, () => {
return resolve();
});
});
}));
}
......
......@@ -16,6 +16,7 @@ import {ApplicationState} from './models/applicationState';
import {take} from 'rxjs/operators';
import {HttpErrorResponse, HttpParams} from '@angular/common/http';
import MockMC from './models/mockMC';
import {UpdateInfo} from './models/updateInfo';
describe('HelperService', () => {
let helperService: HelperService;
......@@ -157,6 +158,22 @@ describe('HelperService', () => {
});
});
});
it('should initialize the update information', (done) => {
const updateInfoSpy: Spy = spyOn(helperService.storage, 'get').withArgs(configMC.localStorageKeyUpdateInfo);
updateInfoSpy.and.returnValue(Promise.resolve(''));
helperService.initUpdateInfo().then(() => {
updateInfoSpy.and.callThrough();
helperService.storage.get(configMC.localStorageKeyUpdateInfo).then((jsonString: string) => {
const updateInfo: UpdateInfo = JSON.parse(jsonString) as UpdateInfo;
expect(updateInfo.corpora).toBe(1);
const setSpy: Spy = spyOn(helperService.storage, 'set').and.returnValue(Promise.resolve());
helperService.initUpdateInfo().then(() => {
expect(setSpy).toHaveBeenCalledTimes(0);
done();
});
});
});
});
it('should make a get request', (done) => {
const toastCtrl: ToastController = TestBed.inject(ToastController);
......
......@@ -12,6 +12,7 @@ import {ReplaySubject} from 'rxjs';
import {TextData} from './models/textData';
import configMC from '../configMC';
import EventRegistry from './models/eventRegistry';
import {UpdateInfo} from './models/updateInfo';
declare var H5P: any;
// dirty hack to prevent H5P access errors after resize events
......@@ -271,6 +272,23 @@ export class HelperService {
});
}
initUpdateInfo(): Promise<void> {
return new Promise<void>(resolve => {
this.storage.get(configMC.localStorageKeyUpdateInfo).then((jsonString: string) => {
if (jsonString) {
return resolve();
}
const ui: UpdateInfo = new UpdateInfo({
corpora: 1,
exerciseList: 1
});
this.storage.set(configMC.localStorageKeyUpdateInfo, JSON.stringify(ui)).then(() => {
return resolve();
});
});
});
}
loadTranslations(translate: TranslateService): void {
// dirty hack to wait until the translation loader is initialized in IE11
this.getDelayedTranslation(translate, 'CORPUS_UPDATE_COMPLETED').then((value: string) => {
......
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