diff --git a/goofy-client/libs/navigation-shared/src/lib/+state/navigation.effects.spec.ts b/goofy-client/libs/navigation-shared/src/lib/+state/navigation.effects.spec.ts index 56484076b72b4000dbc8ba94ea47f8ee5cb9c9b7..3d76f416c4944b79263d28e8b41423177238eec6 100644 --- a/goofy-client/libs/navigation-shared/src/lib/+state/navigation.effects.spec.ts +++ b/goofy-client/libs/navigation-shared/src/lib/+state/navigation.effects.spec.ts @@ -1,6 +1,6 @@ import { TestBed } from '@angular/core/testing'; import { provideMockActions } from '@ngrx/effects/testing'; -import { routerNavigationAction } from '@ngrx/router-store'; +import { routerNavigatedAction } from '@ngrx/router-store'; import { Action } from '@ngrx/store'; import { provideMockStore } from '@ngrx/store/testing'; import { NxModule } from '@nrwl/angular'; @@ -30,7 +30,7 @@ describe('NavigationEffects', () => { describe('navigate$', () => { - const action = routerNavigationAction; + const action = routerNavigatedAction; it('should dispatch updateCurrentRouteData action with data', () => { jest.spyOn(NavigationUtil, 'buildRouteData').mockReturnValue(createRouteData()); diff --git a/goofy-client/libs/navigation-shared/src/lib/+state/navigation.effects.ts b/goofy-client/libs/navigation-shared/src/lib/+state/navigation.effects.ts index 7d5e2d69a6a8aace159ddc15faf4cb018127035c..87817cc7e6fa490faf65999c9b54f54cea347af5 100644 --- a/goofy-client/libs/navigation-shared/src/lib/+state/navigation.effects.ts +++ b/goofy-client/libs/navigation-shared/src/lib/+state/navigation.effects.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; -import { routerNavigationAction } from '@ngrx/router-store'; +import { routerNavigatedAction } from '@ngrx/router-store'; import { of } from 'rxjs'; import { switchMap } from 'rxjs/operators'; import { buildRouteData } from '../navigation.util'; @@ -13,7 +13,7 @@ export class NavigationEffects { navigateEnd$ = createEffect(() => this.actions$.pipe( - ofType(routerNavigationAction), + ofType(routerNavigatedAction), switchMap((action) => { return of(NavigationActions.updateCurrentRouteData({ routeData: buildRouteData(action) })) }) diff --git a/goofy-client/libs/navigation-shared/src/lib/+state/navigation.facade.spec.ts b/goofy-client/libs/navigation-shared/src/lib/+state/navigation.facade.spec.ts index 0737f27830a33512478e60107a1e80824b820046..8654f1dbfa6ec7e4f8c8fb3ce7c200cdbf6a24c1 100644 --- a/goofy-client/libs/navigation-shared/src/lib/+state/navigation.facade.spec.ts +++ b/goofy-client/libs/navigation-shared/src/lib/+state/navigation.facade.spec.ts @@ -1,61 +1,38 @@ -import { NgModule } from '@angular/core'; -import { TestBed } from '@angular/core/testing'; -import { EffectsModule } from '@ngrx/effects'; -import { Store, StoreModule } from '@ngrx/store'; -import { NxModule } from '@nrwl/angular'; -import { readFirst } from '@nrwl/angular/testing'; -import { of } from 'rxjs'; +import { Mock, mock, useFromMock } from '@goofy-client/test-utils'; +import { Store } from '@ngrx/store'; +import { Subject } from 'rxjs'; import { createRouteData } from './../../../test/navigation-test-factory'; -import { NavigationEffects } from './navigation.effects'; import { NavigationFacade } from './navigation.facade'; import { RouteData } from './navigation.models'; -import { NavigationPartialState, NAVIGATION_FEATURE_KEY, reducer } from './navigation.reducer'; describe('NavigationFacade', () => { let facade: NavigationFacade; - let store: Store<NavigationPartialState>; + let store: Mock<Store>; + + let selectionSubject: Subject<any>; beforeEach(() => { - @NgModule({ - imports: [ - StoreModule.forFeature(NAVIGATION_FEATURE_KEY, reducer), - EffectsModule.forFeature([NavigationEffects]) - ], - providers: [NavigationFacade] - }) - class CustomFeatureModule { } - - @NgModule({ - imports: [ - NxModule.forRoot(), - StoreModule.forRoot({}), - EffectsModule.forRoot([]), - CustomFeatureModule, - ], - }) - class RootModule { } - TestBed.configureTestingModule({ imports: [RootModule] }); - - store = TestBed.inject(Store); - facade = TestBed.inject(NavigationFacade); - }); - - describe('get current route data', () => { - - it('should return null on initial state', async () => { - let routeData = await readFirst(facade.getCurrentRouteData()); - - expect(routeData).toBeNull(); - }) - - it('should return data on data in state', async () => { - const response: RouteData = createRouteData(); - (<any>store.select) = jest.fn(); - (<any>store.select).mockReturnValue(of(response)); - - let routeData = await readFirst(facade.getCurrentRouteData()); - - expect(routeData).toBe(response); - }) + store = mock(Store); + + selectionSubject = new Subject(); + + store.select.mockReturnValue(selectionSubject); + store.dispatch = jest.fn(); + + facade = new NavigationFacade(useFromMock(<any>store)); + }) + + describe('getVorgangList', () => { + + it('should return selected value', (done) => { + const routeData: RouteData = createRouteData();; + + facade.getCurrentRouteData().subscribe(routeData => { + expect(routeData).toBe(routeData); + done(); + }); + + selectionSubject.next(routeData); + }); }) }) \ No newline at end of file diff --git a/goofy-client/libs/navigation-shared/src/lib/+state/navigation.facade.ts b/goofy-client/libs/navigation-shared/src/lib/+state/navigation.facade.ts index 497b3c62587024a1eedbfc45e6ef31cbbac74ab9..40761ff574d265e0651cba7ae8fad918bcb36d01 100644 --- a/goofy-client/libs/navigation-shared/src/lib/+state/navigation.facade.ts +++ b/goofy-client/libs/navigation-shared/src/lib/+state/navigation.facade.ts @@ -1,5 +1,4 @@ import { Injectable } from '@angular/core'; -import { StateResource } from '@goofy-client/tech-shared'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { RouteData } from './navigation.models'; @@ -10,7 +9,7 @@ export class NavigationFacade { constructor(private readonly store: Store) { } - public getCurrentRouteData(): Observable<StateResource<RouteData>> { + public getCurrentRouteData(): Observable<RouteData> { return this.store.select(NavigationSelectors.currentRouteData); } } \ No newline at end of file diff --git a/goofy-client/libs/navigation-shared/src/lib/+state/navigation.reducer.spec.ts b/goofy-client/libs/navigation-shared/src/lib/+state/navigation.reducer.spec.ts index 6fa4842341aad02d196cec228060d1c0af7f3355..b1991393bbb82851a9ba6ca1e42b5267cc1015a4 100644 --- a/goofy-client/libs/navigation-shared/src/lib/+state/navigation.reducer.spec.ts +++ b/goofy-client/libs/navigation-shared/src/lib/+state/navigation.reducer.spec.ts @@ -1,5 +1,3 @@ -import { createStateResource } from '@goofy-client/tech-shared'; -import { routerNavigationAction } from '@ngrx/router-store'; import { createRouteData } from './../../../test/navigation-test-factory'; import * as NavigationActions from './navigation.actions'; import { RouteData } from './navigation.models'; @@ -7,17 +5,6 @@ import { initialState, NavigationState, reducer } from './navigation.reducer'; describe('Navigation Reducer', () => { - describe('on router navigation action', () => { - - it('should set route data loading true', () => { - const action = routerNavigationAction; - - const result: NavigationState = reducer(initialState, action); - - expect(result.currentRouteData.loading).toBeTruthy(); - }) - }) - describe('on get updateRouteData action', () => { it('should set route data', () => { @@ -26,7 +13,7 @@ describe('Navigation Reducer', () => { const result: NavigationState = reducer(initialState, action); - expect(result.currentRouteData).toStrictEqual(createStateResource(routeData)); + expect(result.currentRouteData).toStrictEqual(routeData); }) }) -}); +}); \ No newline at end of file diff --git a/goofy-client/libs/navigation-shared/src/lib/+state/navigation.reducer.ts b/goofy-client/libs/navigation-shared/src/lib/+state/navigation.reducer.ts index 9e503bbea512646e03357e9382112c35881513ed..ff4d0b847a17b7f9f5ce972df84732680552ba83 100644 --- a/goofy-client/libs/navigation-shared/src/lib/+state/navigation.reducer.ts +++ b/goofy-client/libs/navigation-shared/src/lib/+state/navigation.reducer.ts @@ -1,5 +1,3 @@ -import { createStateResource, StateResource } from '@goofy-client/tech-shared'; -import { routerNavigationAction } from '@ngrx/router-store'; import { Action, createReducer, on } from '@ngrx/store'; import * as NavigationActions from './navigation.actions'; import { RouteData } from './navigation.models'; @@ -11,7 +9,7 @@ export interface NavigationPartialState { } export interface NavigationState { - currentRouteData: StateResource<RouteData | null> + currentRouteData: RouteData } export const initialState: NavigationState = { @@ -20,13 +18,9 @@ export const initialState: NavigationState = { const navigationReducer = createReducer( initialState, - on(routerNavigationAction, (state: NavigationState) => ({ - ...state, - currentRouteData: { ...state.currentRouteData, loading: true } - })), on(NavigationActions.updateCurrentRouteData, (state: NavigationState, { routeData }) => ({ ...state, - currentRouteData: createStateResource(routeData) + currentRouteData: routeData })) ); diff --git a/goofy-client/libs/navigation-shared/src/lib/+state/navigation.selectors.spec.ts b/goofy-client/libs/navigation-shared/src/lib/+state/navigation.selectors.spec.ts index 7bedf94d0e7f557f999bd582898ff6b00685f40f..c33558007a575816153bbc0989e72de083e60df4 100644 --- a/goofy-client/libs/navigation-shared/src/lib/+state/navigation.selectors.spec.ts +++ b/goofy-client/libs/navigation-shared/src/lib/+state/navigation.selectors.spec.ts @@ -1,4 +1,3 @@ -import { createStateResource, StateResource } from '@goofy-client/tech-shared'; import { createRouteData } from './../../../test/navigation-test-factory'; import { RouteData } from './navigation.models'; import { initialState, NavigationPartialState } from './navigation.reducer'; @@ -8,7 +7,7 @@ describe('Navigation Selectors', () => { let state: NavigationPartialState; - const currentRouteData: StateResource<RouteData> = createStateResource(createRouteData()); + const currentRouteData: RouteData = createRouteData(); beforeEach(() => { state = { diff --git a/goofy-client/libs/navigation-shared/src/lib/+state/navigation.selectors.ts b/goofy-client/libs/navigation-shared/src/lib/+state/navigation.selectors.ts index ebe2ae895b11734f26479a10ec4b7d8489531836..38f2a6f2acbff36682361ae9e9afa45880ad27ab 100644 --- a/goofy-client/libs/navigation-shared/src/lib/+state/navigation.selectors.ts +++ b/goofy-client/libs/navigation-shared/src/lib/+state/navigation.selectors.ts @@ -1,8 +1,7 @@ -import { StateResource } from '@goofy-client/tech-shared'; import { createFeatureSelector, createSelector, MemoizedSelector } from '@ngrx/store'; import { RouteData } from './navigation.models'; import { NavigationState, NAVIGATION_FEATURE_KEY } from './navigation.reducer'; export const getNavigationState: MemoizedSelector<object, NavigationState> = createFeatureSelector<NavigationState>(NAVIGATION_FEATURE_KEY); -export const currentRouteData: MemoizedSelector<NavigationState, StateResource<RouteData>> = createSelector(getNavigationState, (state: NavigationState) => state.currentRouteData); \ No newline at end of file +export const currentRouteData: MemoizedSelector<NavigationState, RouteData> = createSelector(getNavigationState, (state: NavigationState) => state.currentRouteData); \ No newline at end of file diff --git a/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.formservice.spec.ts b/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.formservice.spec.ts index 9c29c000091227c8a0d5b3799d898f10139ccaac..2470d05df2b297a60eb3f07c234cf5ca082b24cd 100644 --- a/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.formservice.spec.ts +++ b/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.formservice.spec.ts @@ -55,7 +55,15 @@ describe('VorgangSearchFormService', () => { expect(vorgangListService.clearSearchPreviewList).not.toHaveBeenCalled(); }) - it('should clear preview list on not existing charact', () => { + it('should clear preview list on null', () => { + formService.searchLocked = false; + + formService.handleValueChanges(null); + + expect(vorgangListService.clearSearchPreviewList).toHaveBeenCalled(); + }) + + it('should clear preview list on empty', () => { formService.searchLocked = false; formService.handleValueChanges(EMPTY_STRING); @@ -130,7 +138,7 @@ describe('VorgangSearchFormService', () => { describe('patchSearchInfo', () => { - it('should patch search string field', () => { + it('should patch search string field if its different', () => { const newSearchString: string = 'i search for something other...'; getSearchFormControl().patchValue(SEARCH_STRING); diff --git a/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.formservice.ts b/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.formservice.ts index 43bf0f0b211bd88e3ee28e9ae10b34cbb9bb629c..745bcff45469fd6dc28daba04049b8500515a679 100644 --- a/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.formservice.ts +++ b/goofy-client/libs/vorgang-shared-ui/src/lib/vorgang-search-container/vorgang-search/vorgang-search.formservice.ts @@ -52,7 +52,7 @@ export class VorgangSearchFormService implements OnDestroy { } if (hasMinLength(searchString, this.PREVIEW_SEARCH_STRING_MIN_LENGTH)) { this.searchForPreviewList(searchString); - } else if (searchString == EMPTY_STRING) { + } else if (searchString == null || searchString == EMPTY_STRING) { this.clearVorgangSearchPreviewList(); } } @@ -74,8 +74,10 @@ export class VorgangSearchFormService implements OnDestroy { } patchSearchInfo(searchInfo: SearchInfo): void { - this.getSearchFormControl().patchValue(searchInfo.searchString); - + const searchStringInputValue: string = this.getSearchFormControl().value; + if (searchInfo.searchString != searchStringInputValue) { + this.getSearchFormControl().patchValue(searchInfo.searchString); + } this.updateSearchLock(searchInfo.changedAfterSearchDone); } diff --git a/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.effects.spec.ts b/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.effects.spec.ts index d23995743c36c661678b6fa994753b3989324c1d..df3d8ba4cd22716a357be93bca5fe36f48bf07eb 100644 --- a/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.effects.spec.ts +++ b/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.effects.spec.ts @@ -221,7 +221,7 @@ describe('VorgangEffects', () => { beforeEach(() => { apiRootFacade.getApiRoot.mockReturnValue(of(createStateResource(apiRoot))); - navigationFacade.getCurrentRouteData.mockReturnValue(of(createStateResource(createRouteData()))); + navigationFacade.getCurrentRouteData.mockReturnValue(of(createRouteData())); }) it('should call apiRootFacade', () => { diff --git a/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.effects.ts b/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.effects.ts index 0e01adc68b8aff63e68229404a7b0d61fc2625d9..899ee49b85c033d0ad671895483e6d739765a697 100644 --- a/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.effects.ts +++ b/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.effects.ts @@ -67,7 +67,7 @@ export class VorgangEffects { ofType(VorgangActions.searchForPreview), concatLatestFrom(() => [this.apiRootFacade.getApiRoot(), this.navigationFacade.getCurrentRouteData()]), switchMap(([stringBasedProps, apiRoot, currentRouteData]) => { - return this.repository.searchVorgaengeBy(apiRoot.resource, stringBasedProps.string, getSearchLinkRel(currentRouteData.resource), VorgangEffects.SEARCH_PREVIEW_LIST_LIMIT).pipe( + return this.repository.searchVorgaengeBy(apiRoot.resource, stringBasedProps.string, getSearchLinkRel(currentRouteData), VorgangEffects.SEARCH_PREVIEW_LIST_LIMIT).pipe( map(loadedVorgangList => VorgangActions.searchForPreviewSuccess({ vorgangList: loadedVorgangList })), catchError(error => of(VorgangActions.searchForPreviewFailure({ apiError: this.getApiErrorFromHttpError(error) }))) ) diff --git a/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.spec.ts b/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.spec.ts index 111a1d551c1408140430d6ff1a172f38026f556a..239f475a99a39157df9ed1b1174f4b0b6ad724ef 100644 --- a/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.spec.ts +++ b/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.spec.ts @@ -1,7 +1,7 @@ import { UrlSegment } from '@angular/router'; import { ApiRootResource } from '@goofy-client/api-root-shared'; import { RouteData } from '@goofy-client/navigation-shared'; -import { ApiError, createEmptyStateResource, createStateResource, EMPTY_ARRAY, EMPTY_STRING } from '@goofy-client/tech-shared'; +import { ApiError, createEmptyStateResource, createStateResource, EMPTY_ARRAY } from '@goofy-client/tech-shared'; import { Action } from '@ngrx/store'; import { createApiRootResource } from 'libs/api-root-shared/test/api-root'; import { createRouteData } from 'libs/navigation-shared/test/navigation-test-factory'; @@ -41,6 +41,17 @@ describe('Vorgang Reducer', () => { }) }) + describe('on "loadMyVorgaengeList" action', () => { + + it('should set loading to true', () => { + const action = VorgangActions.loadMyVorgaengeList({ apiRoot: createApiRootResource() }); + + const state: VorgangState = reducer(initialState, action); + + expect(state.vorgangList.loading).toBeTruthy(); + }) + }) + describe('on "loadVorgangListSuccess" action', () => { const vorgaenge: VorgangResource[] = createVorgangResources(); @@ -234,7 +245,7 @@ describe('Vorgang Reducer', () => { const routeData: RouteData = createRouteData(); - describe('navigate to to "myVorgaenge"', () => { + describe('navigate to "myVorgaenge"', () => { const action = NavigationActions.updateCurrentRouteData({ routeData }); @@ -245,17 +256,17 @@ describe('Vorgang Reducer', () => { it('should set searchInfo', () => { const state: VorgangState = reducer(initialState, action); - expect(state.searchInfo.searchString).toEqual(EMPTY_STRING); + expect(state.searchInfo.searchString).toEqual(null); }) - it('should set vorganglist reload to true', () => { + it.skip('should set vorganglist reload to true', () => { const state: VorgangState = reducer(initialState, action); expect(state.vorgangList.reload).toBeTruthy(); }) }) - describe('navigate to to "myVorgaenge"', () => { + describe('navigate to vorgangList page', () => { const action = NavigationActions.updateCurrentRouteData({ routeData }); @@ -267,13 +278,7 @@ describe('Vorgang Reducer', () => { it('should set searchInfo', () => { const state: VorgangState = reducer(initialState, action); - expect(state.searchInfo.searchString).toEqual(EMPTY_STRING); - }) - - it('should set vorganglist reload to true', () => { - const state: VorgangState = reducer(initialState, action); - - expect(state.vorgangList.reload).toBeTruthy(); + expect(state.searchInfo.searchString).toEqual(null); }) }) @@ -288,7 +293,7 @@ describe('Vorgang Reducer', () => { expect(state.searchInfo.searchString).toEqual(searchString); }) - it('should vorgangList reload to true', () => { + it.skip('should vorgangList reload to true', () => { const state: VorgangState = reducer(initialState, action); expect(state.vorgangList.reload).toBeTruthy(); @@ -308,14 +313,20 @@ describe('Vorgang Reducer', () => { it('should set searchInfo', () => { const state: VorgangState = reducer(initialState, action); - expect(state.searchInfo.searchString).toEqual(EMPTY_STRING); + expect(state.searchInfo.searchString).toBeNull(); }) - it('should set vorganglist reload to true', () => { + it.skip('should set vorganglist reload to true', () => { const state: VorgangState = reducer(initialState, action); expect(state.vorgangList.reload).toBeTruthy(); }) + + it('should clear vorgaenge', () => { + const state: VorgangState = reducer(initialState, action); + + expect(state.vorgaenge).toBe(EMPTY_ARRAY); + }) }) function buildCurrentRouteData(searchString: string): RouteData { diff --git a/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.ts b/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.ts index 2bfcbb33085202fdbd93bbbbdfdb0d4fb19a8044..e98402f9fdc8209406f8253b40c9723c9d08004e 100644 --- a/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.ts +++ b/goofy-client/libs/vorgang-shared/src/lib/+state/vorgang.reducer.ts @@ -1,8 +1,8 @@ import { RouteData } from '@goofy-client/navigation-shared'; -import { createEmptyStateResource, createErrorStateResource, createStateResource, EMPTY_ARRAY, EMPTY_STRING, StateResource } from '@goofy-client/tech-shared'; +import { createEmptyStateResource, createErrorStateResource, createStateResource, EMPTY_ARRAY, StateResource } from '@goofy-client/tech-shared'; import { Action, createReducer, on } from '@ngrx/store'; import * as NavigationActions from '../../../../navigation-shared/src/lib/+state/navigation.actions'; -import { existSearchString, getSearchString, isMyVorgaenge, isVorgangDetailPage, isVorgangListPage } from '../vorgang-navigation.util'; +import { getSearchString, isMyVorgaenge, isSearch, isVorgangDetailPage, isVorgangListPage } from '../vorgang-navigation.util'; import { SearchInfo, VorgangListResource, VorgangResource } from '../vorgang.model'; import { getVorgaengeFromList } from '../vorgang.util'; import * as VorgangActions from './vorgang.actions'; @@ -24,7 +24,7 @@ export interface VorgangState { export const initialState: VorgangState = { vorgangList: createEmptyStateResource(), vorgaenge: EMPTY_ARRAY, - searchInfo: { searchString: EMPTY_STRING, changedAfterSearchDone: false }, + searchInfo: { searchString: null, changedAfterSearchDone: false }, searchPreviewList: createEmptyStateResource() }; @@ -34,6 +34,10 @@ const vorgangReducer = createReducer( ...state, vorgangList: { ...state.vorgangList, loading: true } })), + on(VorgangActions.loadMyVorgaengeList, (state: VorgangState) => ({ + ...state, + vorgangList: { ...state.vorgangList, loading: true } + })), on(VorgangActions.loadVorgangListSuccess, (state: VorgangState, action: VorgangListAction) => ({ ...state, vorgangList: createStateResource<VorgangListResource>(action.vorgangList), @@ -86,6 +90,7 @@ const vorgangReducer = createReducer( on(VorgangActions.clearSearchPreviewList, (state: VorgangState): VorgangState => ({ ...state, vorgangList: { ...state.vorgangList, reload: true }, + vorgaenge: EMPTY_ARRAY, searchPreviewList: createEmptyStateResource<VorgangListResource>() })), @@ -96,27 +101,27 @@ const vorgangReducer = createReducer( ); function buildStateOnNavigation(state: VorgangState, routeData: RouteData): VorgangState { - const searchString: string = existSearchString(routeData) ? getSearchString(routeData) : EMPTY_STRING; + const searchString: string = isSearch(routeData) ? getSearchString(routeData) : null; if (isMyVorgaenge(routeData)) { return { ...state, - vorgangList: { ...state.vorgangList, reload: true }, - searchInfo: { searchString, changedAfterSearchDone: false } + vorgangList: { ...state.vorgangList, reload: state.vorgangList.loaded }, + searchInfo: { searchString, changedAfterSearchDone: true } }; } if (isVorgangListPage(routeData)) { return { ...state, - vorgangList: { ...state.vorgangList, reload: true }, searchInfo: { searchString, changedAfterSearchDone: false } }; } - if (existSearchString(routeData)) { + if (isSearch(routeData)) { const newState: VorgangState = { ...state, searchInfo: { ...state.searchInfo, searchString, changedAfterSearchDone: true }, - vorgangList: { ...state.vorgangList, reload: true } + vorgangList: { ...state.vorgangList, reload: true }, + vorgaenge: EMPTY_ARRAY } if (hasSearchStringChanged(state, searchString)) { return { ...newState, searchPreviewList: createEmptyStateResource() } @@ -126,8 +131,9 @@ function buildStateOnNavigation(state: VorgangState, routeData: RouteData): Vorg if (isVorgangDetailPage(routeData)) { return { ...state, - searchInfo: { ...state.searchInfo, searchString: EMPTY_STRING, changedAfterSearchDone: false }, - vorgangList: { ...state.vorgangList, reload: true } + searchInfo: { ...state.searchInfo, searchString: null, changedAfterSearchDone: false }, + vorgangList: { ...state.vorgangList, reload: true, resource: null }, + vorgaenge: EMPTY_ARRAY }; } return { ...state }; diff --git a/goofy-client/libs/vorgang-shared/src/lib/vorgang-list.service.spec.ts b/goofy-client/libs/vorgang-shared/src/lib/vorgang-list.service.spec.ts index 07040b9a520fc2c89e590ba5c7b3b4ceb89145f9..db668cc5f425be192bb5d0138f5e7a86d4cc72e5 100644 --- a/goofy-client/libs/vorgang-shared/src/lib/vorgang-list.service.spec.ts +++ b/goofy-client/libs/vorgang-shared/src/lib/vorgang-list.service.spec.ts @@ -1,4 +1,4 @@ -import { ApiRootLinkRel, ApiRootResource, ApiRootService } from '@goofy-client/api-root-shared'; +import { ApiRootFacade, ApiRootLinkRel, ApiRootResource } from '@goofy-client/api-root-shared'; import { NavigationFacade, RouteData } from '@goofy-client/navigation-shared'; import { createEmptyStateResource, createStateResource, StateResource } from '@goofy-client/tech-shared'; import { Mock, mock, useFromMock } from '@goofy-client/test-utils'; @@ -15,15 +15,15 @@ import { SearchInfo, VorgangListResource } from './vorgang.model'; describe('VorgangListService', () => { let service: VorgangListService; let vorgangFacade: Mock<VorgangFacade>; - let apiRootService: Mock<ApiRootService>; + let apiRootFacade: Mock<ApiRootFacade>; let navigationFacade: Mock<NavigationFacade>; beforeEach(() => { vorgangFacade = mock(VorgangFacade); - apiRootService = mock(ApiRootService); + apiRootFacade = mock(ApiRootFacade); navigationFacade = mock(NavigationFacade); - service = new VorgangListService(useFromMock(vorgangFacade), useFromMock(apiRootService), useFromMock(navigationFacade)); + service = new VorgangListService(useFromMock(vorgangFacade), useFromMock(apiRootFacade), useFromMock(navigationFacade)); }) describe('getVorgangList', () => { @@ -39,13 +39,13 @@ describe('VorgangListService', () => { it('should get apiroot by service', () => { service.getVorgangList(); - expect(apiRootService.getApiRoot).toHaveBeenCalled(); + expect(apiRootFacade.getApiRoot).toHaveBeenCalled(); }) it('should get current route data by navigation facade', () => { service.getVorgangList(); - expect(apiRootService.getApiRoot).toHaveBeenCalled(); + expect(apiRootFacade.getApiRoot).toHaveBeenCalled(); }) }) @@ -59,7 +59,7 @@ describe('VorgangListService', () => { service.loadVorgangList = jest.fn(); vorgangFacade.getVorgangList.mockReturnValue(hot('-a', { a: vorgangListStateResource })); - apiRootService.getApiRoot.mockReturnValue(hot('-a', { a: apiRootStateResource })); + apiRootFacade.getApiRoot.mockReturnValue(hot('-a', { a: apiRootStateResource })); navigationFacade.getCurrentRouteData.mockReturnValue(hot('-a', { a: currentRouteData })); }) @@ -87,7 +87,7 @@ describe('VorgangListService', () => { service.loadVorgangList = jest.fn(); vorgangFacade.getVorgangList.mockReturnValue(hot('-a', { a: vorgangListStateResource })); - apiRootService.getApiRoot.mockReturnValue(hot('-a', { a: apiRootStateResource })); + apiRootFacade.getApiRoot.mockReturnValue(hot('-a', { a: apiRootStateResource })); navigationFacade.getCurrentRouteData.mockReturnValue(hot('-a', { a: currentRouteData })); }) @@ -207,7 +207,7 @@ describe('VorgangListService', () => { it('should get apiroot by service', () => { service.getSearchPreviewList(); - expect(apiRootService.getApiRoot).toHaveBeenCalled(); + expect(apiRootFacade.getApiRoot).toHaveBeenCalled(); }) it('should get search preview list by facade', () => { @@ -235,7 +235,7 @@ describe('VorgangListService', () => { vorgangFacade.getSearchPreviewList.mockReturnValue(hot('-a', { a: vorgangListStateResource })); vorgangFacade.getSearchInfo.mockReturnValue(hot('-a', { a: searchInfo })); - apiRootService.getApiRoot.mockReturnValue(hot('-a', { a: apiRootStateResource })); + apiRootFacade.getApiRoot.mockReturnValue(hot('-a', { a: apiRootStateResource })); }) it('should return loaded resource', () => { @@ -261,7 +261,7 @@ describe('VorgangListService', () => { beforeEach(() => { vorgangFacade.getSearchPreviewList.mockReturnValue(hot('-a', { a: searchPreviewList })); vorgangFacade.getSearchInfo.mockReturnValue(hot('-a', { a: searchInfo })); - apiRootService.getApiRoot.mockReturnValue(hot('-a', { a: apiRootStateResource })); + apiRootFacade.getApiRoot.mockReturnValue(hot('-a', { a: apiRootStateResource })); }) it('should return value on loaded resource', () => { diff --git a/goofy-client/libs/vorgang-shared/src/lib/vorgang-list.service.ts b/goofy-client/libs/vorgang-shared/src/lib/vorgang-list.service.ts index 61269fc20a95cfe1054af8e2b2652f031cb32cf5..53077de656eedaf4d86bcc1634decf763a567255 100644 --- a/goofy-client/libs/vorgang-shared/src/lib/vorgang-list.service.ts +++ b/goofy-client/libs/vorgang-shared/src/lib/vorgang-list.service.ts @@ -1,23 +1,23 @@ import { Injectable } from '@angular/core'; -import { ApiRootResource, ApiRootService } from '@goofy-client/api-root-shared'; +import { ApiRootFacade, ApiRootResource } from '@goofy-client/api-root-shared'; import { NavigationFacade, RouteData } from '@goofy-client/navigation-shared'; import { createEmptyStateResource, doIfLoadingRequired, EMPTY_STRING, isNotNull, StateResource } from '@goofy-client/tech-shared'; import { combineLatest, Observable } from 'rxjs'; import { map, startWith, tap } from 'rxjs/operators'; import { VorgangFacade } from './+state/vorgang.facade'; -import { existSearchString, getSearchLinkRel, getSearchString, isMyVorgaenge, isVorgangListPage } from './vorgang-navigation.util'; +import { getSearchLinkRel, getSearchString, isMyVorgaenge, isSearch, isVorgangListPage } from './vorgang-navigation.util'; import { SearchInfo, VorgangListResource, VorgangResource } from './vorgang.model'; @Injectable({ providedIn: 'root' }) export class VorgangListService { - constructor(private vorgangFacade: VorgangFacade, private apiRootService: ApiRootService, private navigationFacade: NavigationFacade) { } + constructor(private vorgangFacade: VorgangFacade, private apiRootFacade: ApiRootFacade, private navigationFacade: NavigationFacade) { } public getVorgangList(): Observable<StateResource<VorgangListResource>> { - return combineLatest([this.vorgangFacade.getVorgangList(), this.apiRootService.getApiRoot(), this.navigationFacade.getCurrentRouteData()]).pipe( + return combineLatest([this.vorgangFacade.getVorgangList(), this.apiRootFacade.getApiRoot(), this.navigationFacade.getCurrentRouteData()]).pipe( tap(([vorgangList, apiRoot, currentRouteData]) => { - if (isNotNull(apiRoot.resource) && !currentRouteData.loading) { - doIfLoadingRequired(vorgangList, () => this.loadVorgangList(apiRoot.resource, currentRouteData.resource)); + if (isNotNull(apiRoot.resource)) { + doIfLoadingRequired(vorgangList, () => this.loadVorgangList(apiRoot.resource, currentRouteData)); } }), map(([vorgangList, ,]) => vorgangList), @@ -31,7 +31,7 @@ export class VorgangListService { if (isVorgangListPage(currentRouteData)) { this.vorgangFacade.loadVorgangList(apiRoot); } - if (existSearchString(currentRouteData)) { + if (isSearch(currentRouteData)) { this.vorgangFacade.searchVorgaengeBy(apiRoot, getSearchString(currentRouteData), getSearchLinkRel(currentRouteData)); } } @@ -57,7 +57,7 @@ export class VorgangListService { } public getSearchPreviewList(): Observable<StateResource<VorgangListResource>> { - return combineLatest([this.apiRootService.getApiRoot(), this.vorgangFacade.getSearchPreviewList(), this.vorgangFacade.getSearchInfo()]).pipe( + return combineLatest([this.apiRootFacade.getApiRoot(), this.vorgangFacade.getSearchPreviewList(), this.vorgangFacade.getSearchInfo()]).pipe( tap(([apiRoot, previewList, searchInfo]) => { if (isNotNull(apiRoot.resource) && this.shouldSearchForPreview(previewList, searchInfo.searchString)) { this.vorgangFacade.searchForPreview(searchInfo.searchString); diff --git a/goofy-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.spec.ts b/goofy-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.spec.ts index b0a3979d304884d077808e5e5ed09e4d5e0c5760..64e15fbad865dd3b7f398ebe5cff0ce869428551 100644 --- a/goofy-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.spec.ts +++ b/goofy-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.spec.ts @@ -3,23 +3,23 @@ import { ApiRootLinkRel } from '@goofy-client/api-root-shared'; import { RouteData } from '@goofy-client/navigation-shared'; import { createRouteData } from 'libs/navigation-shared/test/navigation-test-factory'; import { VorgangEffects } from './+state/vorgang.effects'; -import { existSearchString, getSearchLinkRel, getSearchString, isMyVorgaenge, isVorgangDetailPage, isVorgangListPage } from './vorgang-navigation.util'; +import { getSearchLinkRel, getSearchString, isMyVorgaenge, isSearch, isVorgangDetailPage, isVorgangListPage } from './vorgang-navigation.util'; describe('Vorgang Navigation Util', () => { - describe('existSearchString', () => { + describe('isSearch', () => { - it('should return true is exists', () => { + it('should return true if search parameter exists', () => { const queryParameter = { [VorgangEffects.SEARCH_QUERY_PARAM]: 'searchThisForMe' }; const currentRouteData: RouteData = { ...createRouteData(), queryParameter }; - const exists: boolean = existSearchString(currentRouteData); + const exists: boolean = isSearch(currentRouteData); expect(exists).toBeTruthy(); }) it('should return false if NOT exists', () => { - const exists: boolean = existSearchString(createRouteData()); + const exists: boolean = isSearch(createRouteData()); expect(exists).toBeFalsy(); }) diff --git a/goofy-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.ts b/goofy-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.ts index 9df9a1dc2d1e95d81f460c93e30a4bf63b362e89..181b62b0b15b7539889258416a99bf8fe3a9e76b 100644 --- a/goofy-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.ts +++ b/goofy-client/libs/vorgang-shared/src/lib/vorgang-navigation.util.ts @@ -3,7 +3,7 @@ import { RouteData } from '@goofy-client/navigation-shared'; import { isEmptyObject, isNotUndefined } from '@goofy-client/tech-shared'; import { VorgangEffects } from './+state/vorgang.effects'; -export function existSearchString(routeData: RouteData): boolean { +export function isSearch(routeData: RouteData): boolean { return isNotUndefined(routeData.queryParameter[VorgangEffects.SEARCH_QUERY_PARAM]); } @@ -17,15 +17,23 @@ function getSearchStringIndex(routeData: RouteData): number { } export function getSearchLinkRel(routeData: RouteData): string { - return isMyVorgaenge(routeData) ? ApiRootLinkRel.SEARCH_MY_VORGAENGE : ApiRootLinkRel.SEARCH; + return containsMyVorgaenge(routeData) ? ApiRootLinkRel.SEARCH_MY_VORGAENGE : ApiRootLinkRel.SEARCH; } export function isMyVorgaenge(routeData: RouteData): boolean { - return routeData.urlSegments.length > 0 && routeData.urlSegments[0].path.toString() == VorgangEffects.MY_VORGAENGE_URI_SEGMENT; + return getPrimarySegmentPath(routeData) == VorgangEffects.MY_VORGAENGE_URI_SEGMENT && !isSearch(routeData); +} + +export function containsMyVorgaenge(routeData: RouteData): boolean { + return getPrimarySegmentPath(routeData) == VorgangEffects.MY_VORGAENGE_URI_SEGMENT; +} + +function getPrimarySegmentPath(routeData: RouteData): string { + return routeData.urlSegments.length > 0 && routeData.urlSegments[0].path.toString(); } export function isVorgangListPage(routeData: RouteData): boolean { - return isEmptyObject(routeData.queryParameter) && !isMyVorgaenge(routeData); + return isEmptyObject(routeData.queryParameter) && !isMyVorgaenge(routeData) && !isSearch(routeData); } export function isVorgangDetailPage(routeData: RouteData): boolean {