Skip to content
Snippets Groups Projects
Commit 653ac1c1 authored by Xiao Gui's avatar Xiao Gui
Browse files

bugfix: navigateTo region

parent 287f55bc
No related branches found
No related tags found
No related merge requests found
export const IDS = {
ATLAES: {
HUMAN: "juelich/iav/atlas/v1.0.0/1"
},
TEMPLATES: {
BIG_BRAIN: "minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588",
MNI152: "minds/core/referencespace/v1.0.0/dafcffc5-4826-4bf1-8ff6-46b8a31ff8e2",
......
import { HttpClientTestingModule, HttpTestingController } from "@angular/common/http/testing"
import { TestBed } from "@angular/core/testing"
import { provideMockActions } from "@ngrx/effects/testing"
import { Action } from "@ngrx/store"
import { MockStore, provideMockStore } from "@ngrx/store/testing"
import { hot } from "jasmine-marbles"
import { Observable, of, throwError } from "rxjs"
import { SAPI, SAPIModule, SapiRegionModel, SAPIParcellation, SapiAtlasModel, SapiSpaceModel, SapiParcellationModel } from "src/atlasComponents/sapi"
import { IDS } from "src/atlasComponents/sapi/constants"
import { actions, selectors } from "."
import { Effect } from "./effects"
import * as mainActions from "../actions"
import { take } from "rxjs/operators"
describe("> effects.ts", () => {
describe("> Effect", () => {
let actions$ = new Observable<Action>()
let hoc1left: SapiRegionModel
let hoc1leftCentroid: SapiRegionModel
let hoc1leftCentroidWrongSpc: SapiRegionModel
beforeEach(async () => {
TestBed.configureTestingModule({
imports: [
// HttpClientTestingModule,
SAPIModule
],
providers: [
Effect,
provideMockStore(),
provideMockActions(() => actions$)
]
})
/**
* only need to populate hoc1 left once
*/
if (!hoc1left) {
const sapisvc = TestBed.inject(SAPI)
const regions = await sapisvc.getParcRegions(IDS.ATLAES.HUMAN, IDS.PARCELLATION.JBA29, IDS.TEMPLATES.MNI152).toPromise()
hoc1left = regions.find(r => /hoc1/i.test(r.name) && /left/i.test(r.name))
if (!hoc1left) throw new Error(`cannot find hoc1 left`)
hoc1leftCentroid = JSON.parse(JSON.stringify(hoc1left))
hoc1leftCentroid.hasAnnotation.bestViewPoint = {
coordinateSpace: {
'@id': IDS.TEMPLATES.BIG_BRAIN
},
coordinates: [{
value: 1
}, {
value: 2
}, {
value: 3
}]
}
hoc1leftCentroidWrongSpc = JSON.parse(JSON.stringify(hoc1leftCentroid))
hoc1leftCentroidWrongSpc.hasAnnotation.bestViewPoint.coordinateSpace['@id'] = IDS.TEMPLATES.COLIN27
}
})
it('> can be init', () => {
const effects = TestBed.inject(Effect)
expect(effects).toBeTruthy()
})
describe('> selectTemplate$', () => {
describe('> when transiting from template A to template B', () => {
......@@ -77,61 +142,167 @@ describe("> effects.ts", () => {
})
describe('> onNavigateToRegion', () => {
beforeEach(async () => {
actions$ = hot('a', {
a: actions.navigateToRegion({
region: hoc1left
})
})
const mockStore = TestBed.inject(MockStore)
mockStore.overrideSelector(selectors.selectedAtlas, {
"@id": IDS.ATLAES.HUMAN
} as SapiAtlasModel)
mockStore.overrideSelector(selectors.selectedTemplate, {
"@id": IDS.TEMPLATES.MNI152
} as SapiSpaceModel)
mockStore.overrideSelector(selectors.selectedParcellation, {
"@id": IDS.PARCELLATION.JBA29
} as SapiParcellationModel)
})
describe('> if atlas, template, parc is not set', () => {
const atp = [{
name: 'atlas',
atpSelector: selectors.selectedAtlas
},{
name: 'template',
atpSelector: selectors.selectedTemplate
},{
name: 'parcellation',
atpSelector: selectors.selectedParcellation
}]
for (const { name, atpSelector } of atp) {
describe(`> if ${name} is unset`, () => {
describe('> if atlas is unset', () => {
it('> returns general error', () => {
})
})
describe('> if template is unset', () => {
it('> returns general error', () => {
})
})
describe('> if parc is unset', () => {
it('> returns general error', () => {
beforeEach(() => {
const mockStore = TestBed.inject(MockStore)
mockStore.overrideSelector(atpSelector, null)
})
it('> returns general error', () => {
const effect = TestBed.inject(Effect)
expect(effect.onNavigateToRegion).toBeObservable(
hot('a', {
a: mainActions.generalActionError({
message: `atlas, template, parcellation or region not set`
})
})
)
})
})
})
}
})
describe('> if atlas, template, parc is set, but region unset', () => {
beforeEach(() => {
actions$ = hot('a', {
a: actions.navigateToRegion({
region: null
})
})
})
it('> returns general error', () => {
const effect = TestBed.inject(Effect)
expect(effect.onNavigateToRegion).toBeObservable(
hot('a', {
a: mainActions.generalActionError({
message: `atlas, template, parcellation or region not set`
})
})
)
})
})
describe('> if inputs are fine', () => {
it('> getRegionDetailSpy is called', () => {
let getRegionSpy: jasmine.Spy
let regionGetDetailSpy: jasmine.Spy = jasmine.createSpy()
beforeEach(() => {
const sapi = TestBed.inject(SAPI)
getRegionSpy = spyOn(sapi, 'getRegion')
getRegionSpy.and.returnValue({
getDetail: regionGetDetailSpy
})
regionGetDetailSpy.and.returnValue(
of(hoc1leftCentroid)
)
})
afterEach(() => {
if (getRegionSpy) getRegionSpy.calls.reset()
if (regionGetDetailSpy) regionGetDetailSpy.calls.reset()
})
it('> getRegionDetailSpy is called, and calls navigateTo', () => {
const eff = TestBed.inject(Effect)
expect(eff.onNavigateToRegion).toBeObservable(
hot(`a`, {
a: actions.navigateTo({
navigation: {
position: [1e6, 2e6, 3e6]
},
animation: true
})
})
)
expect(getRegionSpy).toHaveBeenCalledTimes(1)
expect(getRegionSpy).toHaveBeenCalledWith(IDS.ATLAES.HUMAN, IDS.PARCELLATION.JBA29, hoc1left["@id"])
})
describe('> mal formed return', () => {
describe('> returns null', () => {
beforeEach(() => {
regionGetDetailSpy.and.returnValue(
of(null)
)
})
it('> generalactionerror', () => {
const eff = TestBed.inject(Effect)
expect(eff.onNavigateToRegion).toBeObservable(
hot(`a`, {
a: mainActions.generalActionError({
message: `getting region detail error! cannot get coordinates`
})
})
)
})
})
describe('> general throw', () => {
it('> generalactionerror', () => {
beforeEach(() => {
regionGetDetailSpy.and.returnValue(
throwError(`oh noes`)
)
})
})
describe('> does not contain props attr', () => {
it('> generalactionerror', () => {
})
})
describe('> does not contain props.length === 0', () => {
it('> generalactionerror', () => {
const eff = TestBed.inject(Effect)
expect(eff.onNavigateToRegion).toBeObservable(
hot(`a`, {
a: mainActions.generalActionError({
message: `Error getting region centroid`
})
})
)
})
})
})
describe('> wellformed response', () => {
beforeEach(() => {
})
describe('> does not contain props attr', () => {
beforeEach(() => {
regionGetDetailSpy.and.returnValue(
of(hoc1left)
)
})
it('> generalactionerror', () => {
it('> emits navigateTo', () => {
const eff = TestBed.inject(Effect)
expect(eff.onNavigateToRegion).toBeObservable(
hot(`a`, {
a: mainActions.generalActionError({
message: `getting region detail error! cannot get coordinates`
})
})
)
})
})
})
......
import { Injectable } from "@angular/core";
import { Actions, createEffect, ofType } from "@ngrx/effects";
import { concat, forkJoin, merge, Observable, of } from "rxjs";
import { filter, map, mapTo, switchMap, switchMapTo, take, tap, withLatestFrom } from "rxjs/operators";
import { catchError, filter, map, mapTo, switchMap, switchMapTo, take, withLatestFrom } from "rxjs/operators";
import { SAPI, SapiAtlasModel, SapiParcellationModel, SAPIRegion, SapiRegionModel, SapiSpaceModel } from "src/atlasComponents/sapi";
import * as mainActions from "../actions"
import { select, Store } from "@ngrx/store";
......@@ -337,9 +337,59 @@ export class Effect {
onNavigateToRegion = createEffect(() => this.action.pipe(
ofType(actions.navigateToRegion),
mapTo(mainActions.generalActionError({
message: `NYI onNavigateToRegion`
}))
withLatestFrom(
this.store.pipe(
select(selectors.selectedTemplate)
),
this.store.pipe(
select(selectors.selectedAtlas)
),
this.store.pipe(
select(selectors.selectedParcellation)
)
),
switchMap(([{ region }, selectedTemplate, selectedAtlas, selectedParcellation]) => {
if (!selectedAtlas || !selectedTemplate || !selectedParcellation || !region) {
return of(
mainActions.generalActionError({
message: `atlas, template, parcellation or region not set`
})
)
}
if (region.hasAnnotation?.bestViewPoint && region.hasAnnotation.bestViewPoint.coordinateSpace['@id'] === selectedTemplate["@id"]) {
return of(
actions.navigateTo({
animation: true,
navigation: {
position: region.hasAnnotation.bestViewPoint.coordinates.map(v => v.value * 1e6)
}
})
)
}
console.log('bla2?')
return this.sapiSvc.getRegion(selectedAtlas['@id'], selectedParcellation['@id'], region["@id"]).getDetail(selectedTemplate["@id"]).pipe(
map(detailedRegion => {
if (!detailedRegion?.hasAnnotation?.bestViewPoint?.coordinates) {
return mainActions.generalActionError({
message: `getting region detail error! cannot get coordinates`
})
}
return actions.navigateTo({
animation: true,
navigation: {
position: detailedRegion.hasAnnotation.bestViewPoint.coordinates.map(v => v.value * 1e6)
}
})
}),
catchError((_err, _obs) => of(
mainActions.generalActionError({
message: `Error getting region centroid`
})
))
)
})
))
onSelAtlasTmplParcClearRegion = createEffect(() => merge(
......
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