diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4d31798be711a9682bd5363bf7187fd644973ea7..47df1bb53233eb8ff5c3a70cebe7c9425c2eeb59 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,6 +37,11 @@ jobs: node-version: 16.x - run: npm i - run: | + if [[ "$GITHUB_REF" = *hotfix* ]] || [[ "$GITHUB_REF" = refs/heads/staging ]] + then + export SIIBRA_API_ENDPOINTS=https://siibra-api-rc.apps.hbp.eu/v2_0 + node src/environments/parseEnv.js ./environment.common.ts + fi npm run test-ci backend: diff --git a/src/atlasComponents/sapi/features/sapiFeature.ts b/src/atlasComponents/sapi/features/sapiFeature.ts index 5abaa0040f6cb71046c70bf57e7a77a57f2794a8..8290da0cad9b4c8e057845258980ff5091579272 100644 --- a/src/atlasComponents/sapi/features/sapiFeature.ts +++ b/src/atlasComponents/sapi/features/sapiFeature.ts @@ -7,7 +7,7 @@ export class SAPIFeature { } public detail$ = this.sapi.httpGet<SapiFeatureModel>( - `${SAPI.bsEndpoint}/features/${this.id}`, + `${SAPI.BsEndpoint}/features/${this.id}`, this.opts ) } diff --git a/src/atlasComponents/sapi/sapi.service.spec.ts b/src/atlasComponents/sapi/sapi.service.spec.ts index 297105f3fc148a1b6a1f3fb01f39d88ec0983cfb..0448de0ccf6c7c2fcb3d5cd587e996db861a7bf2 100644 --- a/src/atlasComponents/sapi/sapi.service.spec.ts +++ b/src/atlasComponents/sapi/sapi.service.spec.ts @@ -1,3 +1,4 @@ +import { NEVER } from "rxjs" import * as env from "src/environments/environment" import { SAPI } from "./sapi.service" @@ -7,16 +8,24 @@ describe("> sapi.service.ts", () => { let fetchSpy: jasmine.Spy let environmentSpy: jasmine.Spy - const endpt1 = 'foo-bar' - const endpt2 = 'buzz-bizz' + const endpt1 = 'http://foo-bar' + const endpt2 = 'http://buzz-bizz' const atlas1 = 'foo' const atlas2 = 'bar' - + let originalBsEndpoint: string + beforeAll(() => { + originalBsEndpoint = SAPI.BsEndpoint + }) + + afterAll(() => { + SAPI.BsEndpoint = originalBsEndpoint + }) + beforeEach(() => { fetchSpy = spyOn(window, 'fetch') - fetchSpy.and.rejectWith("foo-bar") + fetchSpy.and.callThrough() environmentSpy = spyOnProperty(env, 'environment') environmentSpy.and.returnValue({ @@ -42,7 +51,7 @@ describe("> sapi.service.ts", () => { it("> endpoint should be set", async () => { await SAPI.SetBsEndPoint() - expect(SAPI.bsEndpoint).toBe(endpt1) + expect(SAPI.BsEndpoint).toBe(endpt1) }) }) @@ -70,7 +79,17 @@ describe("> sapi.service.ts", () => { it('> should set endpt2', async () => { await SAPI.SetBsEndPoint() - expect(SAPI.bsEndpoint).toBe(endpt2) + expect(SAPI.BsEndpoint).toBe(endpt2) + }) + + it("> instances bsendpoint should be the updated version", async () => { + await SAPI.SetBsEndPoint() + const mockHttpClient = { + get: jasmine.createSpy() + } + mockHttpClient.get.and.returnValue(NEVER) + const sapi = new SAPI(mockHttpClient as any, null, null) + expect(sapi.bsEndpoint).toBe(endpt2) }) }) }) diff --git a/src/atlasComponents/sapi/sapi.service.ts b/src/atlasComponents/sapi/sapi.service.ts index a3b20176f9aabd68c948d811c6582178d7b2a261..394acc033c64d0b3567024c4f65f1ddc53dfc3c1 100644 --- a/src/atlasComponents/sapi/sapi.service.ts +++ b/src/atlasComponents/sapi/sapi.service.ts @@ -41,7 +41,7 @@ export class SAPI{ const resp = await fetch(`${url}/atlases`) const atlases = await resp.json() if (atlases.length > 0) { - SAPI.bsEndpoint = url + SAPI.BsEndpoint = url return } } catch (e) { @@ -52,8 +52,11 @@ export class SAPI{ } static ErrorMessage = null - static bsEndpoint = `https://siibra-api-stable.apps.hbp.eu/v2_0` - public bsEndpoint = SAPI.bsEndpoint + static BsEndpoint = `https://siibra-api-rc.apps.hbp.eu/v2_0` + + get bsEndpoint() { + return SAPI.BsEndpoint + } registry = { _map: {} as Record<string, { @@ -113,7 +116,7 @@ export class SAPI{ } getModalities(): Observable<SapiModalityModel[]> { - return this.http.get<SapiModalityModel[]>(`${SAPI.bsEndpoint}/modalities`) + return this.http.get<SapiModalityModel[]>(`${SAPI.BsEndpoint}/modalities`) } httpGet<T>(url: string, params?: Record<string, string>, sapiParam?: SapiQueryPriorityArg){ diff --git a/src/atlasComponents/sapi/stories.base.ts b/src/atlasComponents/sapi/stories.base.ts index 51fde4f0cd5695f6055398e8bd9ec39ed469c541..1fa58bef89b562d5be3ad8ef5383c302bb335649 100644 --- a/src/atlasComponents/sapi/stories.base.ts +++ b/src/atlasComponents/sapi/stories.base.ts @@ -67,22 +67,22 @@ export const parcId = { } export async function getAtlases(): Promise<SapiAtlasModel[]> { - return await (await fetch(`${SAPI.bsEndpoint}/atlases`)).json() as SapiAtlasModel[] + return await (await fetch(`${SAPI.BsEndpoint}/atlases`)).json() as SapiAtlasModel[] } export async function getAtlas(id: string): Promise<SapiAtlasModel>{ - return await (await fetch(`${SAPI.bsEndpoint}/atlases/${id}`)).json() + return await (await fetch(`${SAPI.BsEndpoint}/atlases/${id}`)).json() } export async function getParc(atlasId: string, id: string): Promise<SapiParcellationModel>{ - return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId}/parcellations/${id}`)).json() + return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId}/parcellations/${id}`)).json() } export async function getParcRegions(atlasId: string, id: string, spaceId: string): Promise<SapiRegionModel[]>{ - return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId}/parcellations/${id}/regions?space_id=${encodeURIComponent(spaceId)}`)).json() + return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId}/parcellations/${id}/regions?space_id=${encodeURIComponent(spaceId)}`)).json() } export async function getSpace(atlasId: string, id: string): Promise<SapiSpaceModel> { - return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId}/spaces/${id}`)).json() + return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId}/spaces/${id}`)).json() } export async function getHumanAtlas(): Promise<SapiAtlasModel> { @@ -90,7 +90,7 @@ export async function getHumanAtlas(): Promise<SapiAtlasModel> { } export async function getMni152(): Promise<SapiSpaceModel> { - return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/spaces/${spaceId.human.mni152}`)).json() + return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/spaces/${spaceId.human.mni152}`)).json() } export async function getJba29(): Promise<SapiParcellationModel> { @@ -103,33 +103,33 @@ export async function getJba29Regions(): Promise<SapiRegionModel[]> { export async function getHoc1Right(spaceId=null): Promise<SapiRegionModel> { if (!spaceId) { - return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20right`)).json() + return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20right`)).json() } - return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20right?space_id=${encodeURIComponent(spaceId)}`)).json() + return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20right?space_id=${encodeURIComponent(spaceId)}`)).json() } export async function get44Left(spaceId=null): Promise<SapiRegionModel> { if (!spaceId) { - return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/area%2044%20left`)).json() + return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/area%2044%20left`)).json() } - return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/area%2044%20left?space_id=${encodeURIComponent(spaceId)}`)).json() + return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/area%2044%20left?space_id=${encodeURIComponent(spaceId)}`)).json() } export async function getHoc1RightSpatialFeatures(): Promise<SxplrCleanedFeatureModel[]> { - const json: SapiSpatialFeatureModel[] = await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/spaces/${spaceId.human.mni152}/features?parcellation_id=2.9®ion=hoc1%20right`)).json() + const json: SapiSpatialFeatureModel[] = await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/spaces/${spaceId.human.mni152}/features?parcellation_id=2.9®ion=hoc1%20right`)).json() return cleanIeegSessionDatasets(json.filter(it => it['@type'] === "siibra/features/ieegSession")) } export async function getHoc1RightFeatures(): Promise<SapiRegionalFeatureModel[]> { - return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20right/features`)).json() + return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20right/features`)).json() } export async function getHoc1RightFeatureDetail(featId: string): Promise<SapiRegionalFeatureModel>{ - return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20right/features/${encodeURIComponent(featId)}`)).json() + return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20right/features/${encodeURIComponent(featId)}`)).json() } export async function getJba29Features(): Promise<SapiParcellationFeatureModel[]> { - return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/features`)).json() + return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/features`)).json() } export async function getBigbrainSpatialFeatures(): Promise<SapiSpatialFeatureModel[]>{ @@ -137,14 +137,14 @@ export async function getBigbrainSpatialFeatures(): Promise<SapiSpatialFeatureMo [-1000, -1000, -1000], [1000, 1000, 1000] ] - const url = new URL(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/spaces/${spaceId.human.bigbrain}/features`) + const url = new URL(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/spaces/${spaceId.human.bigbrain}/features`) url.searchParams.set(`bbox`, JSON.stringify(bbox)) return await (await fetch(url.toString())).json() } export async function getMni152SpatialFeatureHoc1Right(): Promise<SapiSpatialFeatureModel[]>{ - const url = new URL(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/spaces/${spaceId.human.mni152}/features`) + const url = new URL(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/spaces/${spaceId.human.mni152}/features`) url.searchParams.set(`parcellation_id`, parcId.human.jba29) url.searchParams.set("region", 'hoc1 right') return await (await fetch(url.toString())).json() diff --git a/src/atlasComponents/sapiViews/core/parcellation/parcellationVersion.pipe.spec.ts b/src/atlasComponents/sapiViews/core/parcellation/parcellationVersion.pipe.spec.ts index 77df043bb37ed7ffb87cad72d422dda777db33d0..972e411795a3ac9e3a862a3cb61bc7d403f1a105 100644 --- a/src/atlasComponents/sapiViews/core/parcellation/parcellationVersion.pipe.spec.ts +++ b/src/atlasComponents/sapiViews/core/parcellation/parcellationVersion.pipe.spec.ts @@ -3,11 +3,11 @@ import { SAPI } from "src/atlasComponents/sapi/sapi.service" import { SapiParcellationModel } from "src/atlasComponents/sapi/type" import { getTraverseFunctions } from "./parcellationVersion.pipe" -describe(`parcellationVersion.pipe.ts (endpoint at ${SAPI.bsEndpoint})`, () => { +describe(`parcellationVersion.pipe.ts (endpoint at ${SAPI.BsEndpoint})`, () => { describe("getTraverseFunctions", () => { let julichBrainParcellations: SapiParcellationModel[] = [] beforeAll(async () => { - const res = await fetch(`${SAPI.bsEndpoint}/atlases/${encodeURIComponent(IDS.ATLAES.HUMAN)}/parcellations`) + const res = await fetch(`${SAPI.BsEndpoint}/atlases/${encodeURIComponent(IDS.ATLAES.HUMAN)}/parcellations`) const arr: SapiParcellationModel[] = await res.json() julichBrainParcellations = arr.filter(it => /Julich-Brain Cytoarchitectonic Maps/.test(it.name)) }) diff --git a/src/environments/parseEnv.js b/src/environments/parseEnv.js index 7b23070ca889aae07002b73c51f1549050fa369c..9533d341158797f5da8a604929d9327e8980545f 100644 --- a/src/environments/parseEnv.js +++ b/src/environments/parseEnv.js @@ -2,9 +2,11 @@ const fs = require('fs') const path = require('path') const { promisify } = require('util') const asyncWrite = promisify(fs.writeFile) +const process = require("process") const main = async () => { - const pathToEnvFile = path.join(__dirname, './environment.prod.ts') + const target = process.argv[2] || './environment.prod.ts' + const pathToEnvFile = path.join(__dirname, target) const { BACKEND_URL, STRICT_LOCAL, diff --git a/src/share/saneUrl/saneUrl.component.spec.ts b/src/share/saneUrl/saneUrl.component.spec.ts index 5ab173950c92148144b7b3025f63cddf95205a30..982ecb76fb47ca954a5da6c9f5c792c69f3118ba 100644 --- a/src/share/saneUrl/saneUrl.component.spec.ts +++ b/src/share/saneUrl/saneUrl.component.spec.ts @@ -1,14 +1,13 @@ -import { TestBed, fakeAsync, tick, flush } from '@angular/core/testing' -import { ShareModule } from '../share.module' +import { TestBed, fakeAsync, tick, flush, ComponentFixture } from '@angular/core/testing' import { SaneUrl } from './saneUrl.component' -import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing' import { By } from '@angular/platform-browser' import { BACKENDURL } from 'src/util/constants' import { NoopAnimationsModule } from '@angular/platform-browser/animations' import { SaneUrlSvc } from './saneUrl.service' import { AngularMaterialModule } from 'src/sharedModules' import { CUSTOM_ELEMENTS_SCHEMA, Directive } from '@angular/core' -import { of } from 'rxjs' +import { of, throwError } from 'rxjs' +import { NotFoundError } from '../type' const inputCss = `input[aria-label="Custom link"]` const submitCss = `button[aria-label="Create custom link"]` @@ -25,15 +24,22 @@ class AuthStateDummy { describe('> saneUrl.component.ts', () => { describe('> SaneUrl', () => { + const mockSaneUrlSvc = { + saneUrlroot: 'saneUrlroot', + getKeyVal: jasmine.createSpy('getKeyVal'), + setKeyVal: jasmine.createSpy('setKeyVal'), + } beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ - HttpClientTestingModule, NoopAnimationsModule, AngularMaterialModule, ], providers: [ - SaneUrlSvc, + { + provide: SaneUrlSvc, + useValue: mockSaneUrlSvc + } ], declarations: [ SaneUrl, @@ -43,11 +49,18 @@ describe('> saneUrl.component.ts', () => { CUSTOM_ELEMENTS_SCHEMA ] }).compileComponents() + + mockSaneUrlSvc.getKeyVal.and.returnValue( + of('foo-bar') + ) + mockSaneUrlSvc.setKeyVal.and.returnValue( + of('OK') + ) }) afterEach(() => { - const ctrl = TestBed.inject(HttpTestingController) - ctrl.verify() + mockSaneUrlSvc.getKeyVal.calls.reset() + mockSaneUrlSvc.setKeyVal.calls.reset() }) it('> can be created', () => { @@ -112,215 +125,188 @@ describe('> saneUrl.component.ts', () => { const input = fixture.debugElement.query( By.css( inputCss ) ) }) - it('> on entering string in input, makes debounced GET request', fakeAsync(() => { - - const value = 'test_1' - - const httpTestingController = TestBed.inject(HttpTestingController) - - // Necessary to detectChanges, or formControl will not initialise properly - // See https://stackoverflow.com/a/56600762/6059235 - const fixture = TestBed.createComponent(SaneUrl) - fixture.detectChanges() - - // Set value - fixture.componentInstance.customUrl.setValue(value) - - tick(500) - - const req = httpTestingController.expectOne(`${BACKENDURL}saneUrl/${value}`) - req.flush(200) - })) - - it('> on 200 response, show error', fakeAsync(() => { - - const value = 'test_1' - - const httpTestingController = TestBed.inject(HttpTestingController) - - // Necessary to detectChanges, or formControl will not initialise properly - // See https://stackoverflow.com/a/56600762/6059235 - const fixture = TestBed.createComponent(SaneUrl) - fixture.detectChanges() - - // Set value - fixture.componentInstance.customUrl.setValue(value) - - tick(500) - - const req = httpTestingController.expectOne(`${BACKENDURL}saneUrl/${value}`) - req.flush('OK') - - // Expect validator to fail catch it - expect(fixture.componentInstance.customUrl.invalid).toEqual(true) - - // on change detection, UI should catch it - fixture.detectChanges() - - const input = fixture.debugElement.query( By.css( inputCss ) ) - - const submit = fixture.debugElement.query( By.css( submitCss ) ) - const disabled = !!submit.attributes['disabled'] - expect(disabled.toString()).toEqual('true') - })) - - it('> on 404 response, show available', fakeAsync(() => { - - const value = 'test_1' - - const httpTestingController = TestBed.inject(HttpTestingController) - - // Necessary to detectChanges, or formControl will not initialise properly - // See https://stackoverflow.com/a/56600762/6059235 - const fixture = TestBed.createComponent(SaneUrl) - fixture.detectChanges() - - // Set value - fixture.componentInstance.customUrl.setValue(value) - - tick(500) - - const req = httpTestingController.expectOne(`${BACKENDURL}saneUrl/${value}`) - req.flush('some reason', { status: 404, statusText: 'Not Found.' }) - - // Expect validator to fail catch it - expect(fixture.componentInstance.customUrl.invalid).toEqual(false) - - // on change detection, UI should catch it - fixture.detectChanges() - - const input = fixture.debugElement.query( By.css( inputCss ) ) - - const submit = fixture.debugElement.query( By.css( submitCss ) ) - const disabled = !!submit.attributes['disabled'] - expect(disabled.toString()).toEqual('false') - })) - - it('> on other error codes, show invalid', fakeAsync(() => { - - const value = 'test_1' - - const httpTestingController = TestBed.inject(HttpTestingController) - - // Necessary to detectChanges, or formControl will not initialise properly - // See https://stackoverflow.com/a/56600762/6059235 - const fixture = TestBed.createComponent(SaneUrl) - fixture.detectChanges() - - // Set value - fixture.componentInstance.customUrl.setValue(value) - - tick(500) - - const req = httpTestingController.expectOne(`${BACKENDURL}saneUrl/${value}`) - req.flush('some reason', { status: 401, statusText: 'Unauthorised.' }) - - // Expect validator to fail catch it - expect(fixture.componentInstance.customUrl.invalid).toEqual(true) - - // on change detection, UI should catch it - fixture.detectChanges() - - const input = fixture.debugElement.query( By.css( inputCss ) ) - - const submit = fixture.debugElement.query( By.css( submitCss ) ) - const disabled = !!submit.attributes['disabled'] - expect(disabled.toString()).toEqual('true') - })) - - it('> on click create link btn calls correct API', fakeAsync(() => { - - const value = 'test_1' - - const httpTestingController = TestBed.inject(HttpTestingController) - - // Necessary to detectChanges, or formControl will not initialise properly - // See https://stackoverflow.com/a/56600762/6059235 - const fixture = TestBed.createComponent(SaneUrl) - fixture.detectChanges() - - // Set value - fixture.componentInstance.customUrl.setValue(value) - - tick(500) - - const req = httpTestingController.expectOne(`${BACKENDURL}saneUrl/${value}`) - req.flush('some reason', { status: 404, statusText: 'Not Found.' }) - - fixture.detectChanges() - flush() - - const submit = fixture.debugElement.query( By.css( submitCss ) ) - const disabled = !!submit.attributes['disabled'] - expect(disabled.toString()).toEqual('false') - - submit.triggerEventHandler('click', {}) - - fixture.detectChanges() - - const disabledInProgress = !!submit.attributes['disabled'] - expect(disabledInProgress.toString()).toEqual('true') - - const req2 = httpTestingController.expectOne({ - method: 'POST', - url: `${BACKENDURL}saneUrl/${value}` + describe("> on valid input", () => { + let saneUrlCmp: SaneUrl + let fixture: ComponentFixture<SaneUrl> + const stateTobeSaved = 'foo-bar' + beforeEach(() => { + // Necessary to detectChanges, or formControl will not initialise properly + // See https://stackoverflow.com/a/56600762/6059235 + fixture = TestBed.createComponent(SaneUrl) + saneUrlCmp = fixture.componentInstance + saneUrlCmp.stateTobeSaved = stateTobeSaved + fixture.detectChanges() }) - - req2.flush({}) - - fixture.detectChanges() - - const disabledAfterComplete = !!submit.attributes['disabled'] - expect(disabledAfterComplete.toString()).toEqual('true') - - const cpyBtn = fixture.debugElement.query( By.css( copyBtnCss ) ) - expect(cpyBtn).toBeTruthy() - })) - - it('> on click create link btn fails show result', fakeAsync(() => { - - const value = 'test_1' - - const httpTestingController = TestBed.inject(HttpTestingController) - - // Necessary to detectChanges, or formControl will not initialise properly - // See https://stackoverflow.com/a/56600762/6059235 - const fixture = TestBed.createComponent(SaneUrl) - fixture.detectChanges() - - // Set value - fixture.componentInstance.customUrl.setValue(value) - - tick(500) - - const req = httpTestingController.expectOne(`${BACKENDURL}saneUrl/${value}`) - req.flush('some reason', { status: 404, statusText: 'Not Found.' }) - - fixture.detectChanges() - flush() - - const submit = fixture.debugElement.query( By.css( submitCss ) ) - const disabled = !!submit.attributes['disabled'] - expect(disabled.toString()).toEqual('false') - - submit.triggerEventHandler('click', {}) - - fixture.detectChanges() - - const disabledInProgress = !!submit.attributes['disabled'] - expect(disabledInProgress.toString()).toEqual('true') - - const req2 = httpTestingController.expectOne({ - method: 'POST', - url: `${BACKENDURL}saneUrl/${value}` + it('> on entering string in input, makes debounced GET request', fakeAsync(() => { + + const value = 'test_1' + + // Set value + fixture.componentInstance.customUrl.setValue(value) + + tick(500) + + expect(mockSaneUrlSvc.getKeyVal).toHaveBeenCalledOnceWith(value) + })) + + describe("> on 200", () => { + it("> show error", fakeAsync(() => { + + const value = 'test_1' + + // Set value + fixture.componentInstance.customUrl.setValue(value) + + tick(500) + + // Expect validator to fail catch it + expect(fixture.componentInstance.customUrl.invalid).toEqual(true) + + // on change detection, UI should catch it + fixture.detectChanges() + + const input = fixture.debugElement.query( By.css( inputCss ) ) + + const submit = fixture.debugElement.query( By.css( submitCss ) ) + const disabled = !!submit.attributes['disabled'] + expect(disabled.toString()).toEqual('true') + })) + }) + + describe('> on 404', () => { + beforeEach(() => { + mockSaneUrlSvc.getKeyVal.and.returnValue( + throwError(new NotFoundError('not found')) + ) + }) + it("> should available", fakeAsync(() => { + + const value = 'test_1' + + // Set value + fixture.componentInstance.customUrl.setValue(value) + + tick(500) + + // Expect validator to fail catch it + expect(fixture.componentInstance.customUrl.invalid).toEqual(false) + + // on change detection, UI should catch it + fixture.detectChanges() + + const input = fixture.debugElement.query( By.css( inputCss ) ) + + const submit = fixture.debugElement.query( By.css( submitCss ) ) + const disabled = !!submit.attributes['disabled'] + expect(disabled.toString()).toEqual('false') + })) }) + + describe("> on other error", () => { + beforeEach(() => { + + mockSaneUrlSvc.getKeyVal.and.returnValue( + throwError(new Error('other errors')) + ) + }) + it("> show invalid", fakeAsync(() => { + const value = 'test_1' + + // Set value + fixture.componentInstance.customUrl.setValue(value) + + tick(500) + + // Expect validator to fail catch it + expect(fixture.componentInstance.customUrl.invalid).toEqual(true) + + // on change detection, UI should catch it + fixture.detectChanges() + + const input = fixture.debugElement.query( By.css( inputCss ) ) + + const submit = fixture.debugElement.query( By.css( submitCss ) ) + const disabled = !!submit.attributes['disabled'] + expect(disabled.toString()).toEqual('true') + })) + }) + + describe("> on click create link", () => { + beforeEach(() => { + mockSaneUrlSvc.getKeyVal.and.returnValue( + throwError(new NotFoundError('not found')) + ) + }) + it("> calls correct service function", fakeAsync(() => { + + const value = 'test_1' + + // Set value + fixture.componentInstance.customUrl.setValue(value) + + tick(500) + + fixture.detectChanges() + flush() + + const submit = fixture.debugElement.query( By.css( submitCss ) ) + const disabled = !!submit.attributes['disabled'] + expect(disabled.toString()).toEqual('false') + + submit.triggerEventHandler('click', {}) + + fixture.detectChanges() + + const disabledInProgress = !!submit.attributes['disabled'] + expect(disabledInProgress.toString()).toEqual('true') + + fixture.detectChanges() + + const disabledAfterComplete = !!submit.attributes['disabled'] + expect(disabledAfterComplete.toString()).toEqual('true') + + const cpyBtn = fixture.debugElement.query( By.css( copyBtnCss ) ) + expect(cpyBtn).toBeTruthy() + })) + + describe("> on fail", () => { + beforeEach(() => { + mockSaneUrlSvc.setKeyVal.and.returnValue( + throwError(new Error(`some error`)) + ) + }) + it("> show result", fakeAsync(() => { + + const value = 'test_1' - req2.flush('Something went wrong', { statusText: 'Wrong status text', status: 500 }) - - fixture.detectChanges() - - const input = fixture.debugElement.query( By.css( inputCss ) ) - - })) + // Set value + fixture.componentInstance.customUrl.setValue(value) + + tick(500) + + fixture.detectChanges() + + const submit = fixture.debugElement.query( By.css( submitCss ) ) + const disabled = !!submit.attributes['disabled'] + expect(disabled.toString()).toEqual('false') + + submit.triggerEventHandler('click', {}) + + fixture.detectChanges() + + const disabledInProgress = !!submit.attributes['disabled'] + expect(disabledInProgress.toString()).toEqual('true') + + expect(mockSaneUrlSvc.setKeyVal).toHaveBeenCalledOnceWith(value, stateTobeSaved) + + fixture.detectChanges() + + const input = fixture.debugElement.query( By.css( inputCss ) ) + + })) + }) + }) + + }) }) }) diff --git a/src/viewerModule/nehuba/statusCard/statusCard.component.spec.ts b/src/viewerModule/nehuba/statusCard/statusCard.component.spec.ts index ce0afa8fa8632b433b5998eed1107654fdc4dfa2..ab6ac511153553a1bc50365bd2b85c4a239c94f4 100644 --- a/src/viewerModule/nehuba/statusCard/statusCard.component.spec.ts +++ b/src/viewerModule/nehuba/statusCard/statusCard.component.spec.ts @@ -146,8 +146,8 @@ describe('> statusCard.component.ts', () => { initialNgState: { navigation: { pose: { - orientation: [0,0,0,1], - position: [10, 20, 30] + orientation: [0, 0, 0, 1], + position: [0, 0, 0] }, zoomFactor: 1e6 }