Skip to content
Snippets Groups Projects
nehubaViewer.component.spec.ts 11.34 KiB
import { TestBed, fakeAsync, tick, ComponentFixture } from "@angular/core/testing"
import { CommonModule } from "@angular/common"
import { NehubaViewerUnit, scanFn } from "./nehubaViewer.component"
import { LoggingModule, LoggingService } from "src/logging"
import { IMeshesToLoad, SET_MESHES_TO_LOAD } from "../constants"
import { Subject } from "rxjs"
import { IColorMap, SET_COLORMAP_OBS, SET_LAYER_VISIBILITY } from "../layerCtrl.service"
import { rgbToHex } from 'common/util'

describe('> nehubaViewer.component.ts', () => {
  describe('> #scanFn', () => {

    const curr = {
      layer: {
        name: 'foo-bar'
      },
      labelIndicies: [1,2,3]
    }

    describe('> insert OP', () => {
      describe('> if incoming is empty arr', () => {
        const acc = []
        it('> should insert', () => {
          expect(
            scanFn(acc, curr)
          ).toEqual([curr])
        })
      })

      describe('> if incoming has other key', () => {
        it('> should insert', () => {
          const acc = [{
            layer: {
              name: 'hello-world'
            },
            labelIndicies: [4,5,6]
          }]
          expect(
            scanFn(acc, curr)
          ).toEqual([
            ...acc,
            curr
          ])
        })
      })
    })

    describe('> update OP', () => {
      const acc = [{
        layer: {
          name: 'hello-world'
        },
        labelIndicies: [4,5,6]
      }, {
        layer: {
          name: 'foo-bar',
        },
        labelIndicies: [1]
      }]
      it('> should update with same key', () => {
        expect(
          scanFn(acc, curr)
        ).toEqual([{
          layer: {
            name: 'hello-world'
          },
          labelIndicies: [4,5,6]
        }, {
          layer: {
            name: 'foo-bar',
          },
          labelIndicies: [1,2,3]
        }])
      })
    })
  })

  describe('> NehubaViewerUnit', () => {
    const setMeshToLoadCtl$ = new Subject<IMeshesToLoad>()
    let setLayerVisibility$: Subject<string[]> = new Subject()
    let setcolorMap$: Subject<IColorMap> = new Subject()
    let fixture: ComponentFixture<NehubaViewerUnit>
    beforeEach(async () => {
      await TestBed.configureTestingModule({
        imports: [
          CommonModule,
          LoggingModule
        ],
        declarations: [
          NehubaViewerUnit
        ],
        providers:[
          {
            provide: SET_MESHES_TO_LOAD,
            useFactory: () => setMeshToLoadCtl$
          },
          {
            provide: SET_LAYER_VISIBILITY,
            useValue: setLayerVisibility$
          },
          {
            provide: SET_COLORMAP_OBS,
            useValue: setcolorMap$
          },
          LoggingService,
        ]
      }).compileComponents()
    })

    it('> creates component', () => {
      fixture = TestBed.createComponent(NehubaViewerUnit)
      expect(fixture.componentInstance).toBeTruthy()
    })

    describe('> loading meshes', () => {
      beforeEach(() => {
        fixture = TestBed.createComponent(NehubaViewerUnit)
        fixture.componentInstance.nehubaViewer = {
          setMeshesToLoad: jasmine.createSpy('setMeshesToLoad').and.returnValue(null),
          dispose: () => {}
        }
        fixture.componentInstance['_nehubaReady'] = true
      })

      describe('> injecting SET_MESHES_TO_LOAD', () => {

        it('> when injected obs emits, will trigger loadMesh call', fakeAsync(() => {

          fixture.detectChanges()
          setMeshToLoadCtl$.next({
            labelIndicies: [1,2,3],
            layer: {
              name: 'foo-bar'
            }
          })
          tick(400)
          expect(fixture.componentInstance.nehubaViewer.setMeshesToLoad).toHaveBeenCalledWith([1,2,3], { name: 'foo-bar' })
        }))
      })
    })

    describe('> layer visibility', () => {
      let nehubaViewerSpy: any
      let managedLayersSpy: jasmine.Spy
      let getLayerByNameSpy: jasmine.Spy
      let managedLayer = {
        setVisible: jasmine.createSpy()
      }
      let layerManager = {
        get managedLayers() {
          return []
        },
        getLayerByName(layerName: string){

        }
      }

      afterEach(() => {
        managedLayer.setVisible.calls.reset()
      })
      beforeEach(() => {
        managedLayersSpy = spyOnProperty(layerManager, 'managedLayers')
        managedLayersSpy.and.returnValue([ managedLayer ])
        getLayerByNameSpy = spyOn(layerManager, 'getLayerByName')
        getLayerByNameSpy.and.callThrough()
        
        nehubaViewerSpy = {
          ngviewer: {
            layerManager
          },
          dispose: () => {}
        }

        fixture = TestBed.createComponent(NehubaViewerUnit)
        fixture.componentInstance.nehubaViewer = nehubaViewerSpy
        fixture.componentInstance['_nehubaReady'] = true
      })

      it('> if provided obs does not emit, does not call manage layers', fakeAsync(() => {
        fixture.detectChanges()
        tick(320)
        expect(managedLayersSpy).not.toHaveBeenCalled()
      }))

      describe('> if provided obs does emit', () => {

        const setup = (emit = []) => {
          setLayerVisibility$.next(emit)
          fixture.detectChanges()
          tick(640)
        }
        describe('> emits []', () => {
          beforeEach(fakeAsync(() => {
            setup()
          }))
          it('> call manage layers', () => {
            expect(managedLayersSpy).toHaveBeenCalled() 
          })
          it('> layers have visibility set off', fakeAsync(() => {
            expect(managedLayer.setVisible).toHaveBeenCalledWith(false)
          }))
        })

        describe('> emits ["something"]', () => {
          let layerSetVisibleSpy: jasmine.Spy
          beforeEach(fakeAsync(() => {
            layerSetVisibleSpy = jasmine.createSpy()
            const layer = {
              setVisible: layerSetVisibleSpy
            }
            getLayerByNameSpy.and.returnValue(layer)
            setup(['something'])
          }))
          it('> calls getLayerByname', () => {
            expect(layerManager.getLayerByName).toHaveBeenCalledWith('something')
          })

          it('> getLayerByNameSpy called', () => {
            expect(getLayerByNameSpy).toHaveBeenCalled()
          })
          it('> if returns layer, expects setVisible to be called', () => {
            expect(layerSetVisibleSpy).toHaveBeenCalledWith(true)
          })
        })
      })
    })

    describe('> colorMap obs', () => {

      let prvSetCMSpy: jasmine.Spy
      const setup = () => {

        fixture = TestBed.createComponent(NehubaViewerUnit)
        fixture.componentInstance['_nehubaReady'] = true

        /**
         * set nehubaViewer, since some methods check viewer is loaded
         */
        fixture.componentInstance.nehubaViewer = {
           ngviewer: {},
           dispose: () => {}
         }
        fixture.detectChanges()
        prvSetCMSpy = spyOn<any>(fixture.componentInstance, 'setColorMap').and.callFake(() => {})
      }

      describe('> obs does not emit', () => {
        beforeEach(() => {
          setup()
        })
        it('> does not call set colormap', () => {
          expect(prvSetCMSpy).not.toHaveBeenCalled()
        } )
      })

      describe('> if obs does emit', () => {
        beforeEach(() => {
          setup()
        })
        it('> setcolormap gets called', fakeAsync(() => {
          setcolorMap$.next({
            'foo-bar': {
              1: { red: 100, green: 100, blue: 100 },
              2: { red: 200, green: 200, blue: 200 },
            },
            'hello-world': {
              1: { red: 10, green: 10, blue: 10 },
              2: { red: 20, green: 20, blue: 20 },
            }
          })
          tick(320)
          expect(prvSetCMSpy).toHaveBeenCalled()
        }))

        it('> call arg is as expected', fakeAsync(() => {
          setcolorMap$.next({
            'foo-bar': {
              1: { red: 100, green: 100, blue: 100 },
              2: { red: 200, green: 200, blue: 200 },
            },
            'hello-world': {
              1: { red: 10, green: 10, blue: 10 },
              2: { red: 20, green: 20, blue: 20 },
            }
          })
          tick(320)
          const map = new Map([
            ['foo-bar', new Map([
              ['1', { red: 100, green: 100, blue: 100 }],
              ['2', { red: 200, green: 200, blue: 200 }],
            ])],
            ['hello-world', new Map([
              ['1', { red: 10, green: 10, blue: 10 }],
              ['2', { red: 20, green: 20, blue: 20 }],
            ])]
          ])

          expect(prvSetCMSpy).toHaveBeenCalledWith(map)
        }))
      })
    })

    describe('> # setColorMap', () => {
      let nehubaViewerSpy: any
      let ngViewerStatechildrenGetSpy = jasmine.createSpy('get')
      let layersMngerToJsonSpy = jasmine.createSpy('layersMngerToJsonSpy')
      let posToJsonSpy = jasmine.createSpy('posToJsonSpy')
      let layerMgerRestoreStateSpy = jasmine.createSpy('layerMgerRestoreStateSpy')
      let posRestoreStateSpy = jasmine.createSpy("posRestoreStateSpy")

      const ngId1 = 'foo-bar'
      const ngId2 = 'hello-world'
      beforeEach(() => {
        nehubaViewerSpy = {
          dispose(){

          },
          ngviewer: {
            state: {
              children: {
                get: ngViewerStatechildrenGetSpy
              }
            }
          }
        }

        ngViewerStatechildrenGetSpy.and.callFake(prop => {
          if (prop === "position") {
            return {
              toJSON: posToJsonSpy,
              restoreState: posRestoreStateSpy
            }
          }
          if (prop === "layers") {
            return {
              toJSON: layersMngerToJsonSpy,
              restoreState: layerMgerRestoreStateSpy,
            }
          }
          throw new Error(`prop ${prop} is not anticipated`)
        })
        posToJsonSpy.and.returnValue([1.1, 2.2, 3.3])
        layersMngerToJsonSpy.and.returnValue([{
          name: ngId1
        }, {
          name: ngId2
        }])
      })
      afterEach(() => {
        ngViewerStatechildrenGetSpy.calls.reset()
        layersMngerToJsonSpy.calls.reset()
        layerMgerRestoreStateSpy.calls.reset()
      })
      it('> calls nehubaViewer.restoreState', () => {
        const fixture = TestBed.createComponent(NehubaViewerUnit)
        fixture.componentInstance.nehubaViewer = nehubaViewerSpy
        fixture.detectChanges()

        const mainMap = new Map<string, Map<number, { red: number, green: number, blue: number }>>()
        const fooBarMap = new Map()
        fooBarMap.set(1, {red: 100, green: 100, blue: 100})
        fooBarMap.set(2, {red: 200, green: 200, blue: 200})
        mainMap.set(ngId1, fooBarMap)

        const helloWorldMap = new Map()
        helloWorldMap.set(1, {red: 10, green: 10, blue: 10})
        helloWorldMap.set(2, {red: 20, green: 20, blue: 20})
        mainMap.set(ngId2, helloWorldMap)

        fixture.componentInstance['setColorMap'](mainMap)

        expect(layerMgerRestoreStateSpy).toHaveBeenCalledOnceWith([{
          name: ngId1,
          segmentColors: {
            1: rgbToHex([100, 100, 100]),
            2: rgbToHex([200, 200, 200]),
          }
        }, {
          name: ngId2,
          segmentColors: {
            1: rgbToHex([10, 10, 10]),
            2: rgbToHex([20, 20, 20]),
          }
        }])

        expect(posRestoreStateSpy).toHaveBeenCalledOnceWith(
          [ 1.1, 2.2, 3.3 ]
        )
      })
    })

  })
})