1+ // eslint-disable-next-line max-classes-per-file
12import { ComponentFixture , fakeAsync , TestBed , tick , waitForAsync } from '@angular/core/testing' ;
23import { NoopAnimationsModule } from '@angular/platform-browser/animations' ;
34import { TranslateModule } from '@ngx-translate/core' ;
4- import { ChangeDetectionStrategy , Injector , NO_ERRORS_SCHEMA } from '@angular/core' ;
5+ import { ChangeDetectionStrategy , Injector , NO_ERRORS_SCHEMA , Component } from '@angular/core' ;
56import { MenuService } from './menu.service' ;
67import { MenuComponent } from './menu.component' ;
7- import { MenuServiceStub } from '../testing/menu-service.stub' ;
8- import { of as observableOf } from 'rxjs' ;
9- import { Router , ActivatedRoute } from '@angular/router' ;
8+ import { of as observableOf , BehaviorSubject } from 'rxjs' ;
9+ import { ActivatedRoute } from '@angular/router' ;
1010import { RouterTestingModule } from '@angular/router/testing' ;
1111import { MenuSection } from './menu-section.model' ;
1212import { MenuID } from './menu-id.model' ;
@@ -15,14 +15,39 @@ import { AuthorizationDataService } from '../../core/data/feature-authorization/
1515import { createSuccessfulRemoteDataObject } from '../remote-data.utils' ;
1616import { ThemeService } from '../theme-support/theme.service' ;
1717import { getMockThemeService } from '../mocks/theme-service.mock' ;
18+ import { MenuItemType } from './menu-item-type.model' ;
19+ import { LinkMenuItemModel } from './menu-item/models/link.model' ;
20+ import { provideMockStore , MockStore } from '@ngrx/store/testing' ;
21+ import { StoreModule , Store } from '@ngrx/store' ;
22+ import { authReducer } from '../../core/auth/auth.reducer' ;
23+ import { storeModuleConfig , AppState } from '../../app.reducer' ;
24+ import { rendersSectionForMenu } from './menu-section.decorator' ;
25+
26+ const mockMenuID = 'mock-menuID' as MenuID ;
27+
28+ @Component ( {
29+ // eslint-disable-next-line @angular-eslint/component-selector
30+ selector : '' ,
31+ template : '' ,
32+ } )
33+ @rendersSectionForMenu ( mockMenuID , true )
34+ class TestExpandableMenuComponent {
35+ }
36+
37+ @Component ( {
38+ // eslint-disable-next-line @angular-eslint/component-selector
39+ selector : '' ,
40+ template : '' ,
41+ } )
42+ @rendersSectionForMenu ( mockMenuID , false )
43+ class TestMenuComponent {
44+ }
1845
1946describe ( 'MenuComponent' , ( ) => {
2047 let comp : MenuComponent ;
2148 let fixture : ComponentFixture < MenuComponent > ;
2249 let menuService : MenuService ;
23- let router : any ;
24-
25- const mockMenuID = 'mock-menuID' as MenuID ;
50+ let store : MockStore ;
2651
2752 const mockStatisticSection = { 'id' : 'statistics_site' , 'active' : true , 'visible' : true , 'index' : 2 , 'type' : 'statistics' , 'model' : { 'type' : 1 , 'text' : 'menu.section.statistics' , 'link' : 'statistics' } } ;
2853
@@ -48,21 +73,55 @@ describe('MenuComponent', () => {
4873 children : [ ]
4974 } ;
5075
76+ const initialState = {
77+ menus : {
78+ [ mockMenuID ] : {
79+ collapsed : true ,
80+ id : mockMenuID ,
81+ previewCollapsed : true ,
82+ sectionToSubsectionIndex : {
83+ section1 : [ ] ,
84+ } ,
85+ sections : {
86+ section1 : {
87+ id : 'section1' ,
88+ active : false ,
89+ visible : true ,
90+ model : {
91+ type : MenuItemType . LINK ,
92+ text : 'test' ,
93+ link : '/test' ,
94+ } as LinkMenuItemModel ,
95+ } ,
96+ } ,
97+ visible : true ,
98+ } ,
99+ } ,
100+ } ;
101+
51102 beforeEach ( waitForAsync ( ( ) => {
52103
53104 authorizationService = jasmine . createSpyObj ( 'authorizationService' , {
54105 isAuthorized : observableOf ( false )
55106 } ) ;
56107
57- TestBed . configureTestingModule ( {
58- imports : [ TranslateModule . forRoot ( ) , NoopAnimationsModule , RouterTestingModule ] ,
108+ void TestBed . configureTestingModule ( {
109+ imports : [
110+ TranslateModule . forRoot ( ) ,
111+ NoopAnimationsModule ,
112+ RouterTestingModule ,
113+ StoreModule . forRoot ( authReducer , storeModuleConfig ) ,
114+ ] ,
59115 declarations : [ MenuComponent ] ,
60116 providers : [
61117 Injector ,
62118 { provide : ThemeService , useValue : getMockThemeService ( ) } ,
63- { provide : MenuService , useClass : MenuServiceStub } ,
119+ MenuService ,
120+ provideMockStore ( { initialState } ) ,
64121 { provide : AuthorizationDataService , useValue : authorizationService } ,
65122 { provide : ActivatedRoute , useValue : routeStub } ,
123+ TestExpandableMenuComponent ,
124+ TestMenuComponent ,
66125 ] ,
67126 schemas : [ NO_ERRORS_SCHEMA ]
68127 } ) . overrideComponent ( MenuComponent , {
@@ -74,13 +133,62 @@ describe('MenuComponent', () => {
74133 fixture = TestBed . createComponent ( MenuComponent ) ;
75134 comp = fixture . componentInstance ; // SearchPageComponent test instance
76135 comp . menuID = mockMenuID ;
77- menuService = ( comp as any ) . menuService ;
78- router = TestBed . inject ( Router ) ;
136+ menuService = TestBed . inject ( MenuService ) ;
137+ store = TestBed . inject ( Store ) as MockStore < AppState > ;
79138 spyOn ( comp as any , 'getSectionDataInjector' ) . and . returnValue ( MenuSection ) ;
80- spyOn ( comp as any , 'getSectionComponent' ) . and . returnValue ( observableOf ( { } ) ) ;
81139 fixture . detectChanges ( ) ;
82140 } ) ;
83141
142+ describe ( 'ngOnInit' , ( ) => {
143+ it ( 'should trigger the section observable again when a new sub section has been added' , ( ) => {
144+ spyOn ( comp . sectionMap$ , 'next' ) . and . callThrough ( ) ;
145+ const hasSubSections = new BehaviorSubject ( false ) ;
146+ spyOn ( menuService , 'hasSubSections' ) . and . returnValue ( hasSubSections . asObservable ( ) ) ;
147+ spyOn ( store , 'dispatch' ) . and . callThrough ( ) ;
148+
149+ store . setState ( {
150+ menus : {
151+ [ mockMenuID ] : {
152+ collapsed : true ,
153+ id : mockMenuID ,
154+ previewCollapsed : true ,
155+ sectionToSubsectionIndex : {
156+ section1 : [ 'test' ] ,
157+ } ,
158+ sections : {
159+ section1 : {
160+ id : 'section1' ,
161+ active : false ,
162+ visible : true ,
163+ model : {
164+ type : MenuItemType . LINK ,
165+ text : 'test' ,
166+ link : '/test' ,
167+ } as LinkMenuItemModel ,
168+ } ,
169+ test : {
170+ id : 'test' ,
171+ parentID : 'section1' ,
172+ active : false ,
173+ visible : true ,
174+ model : {
175+ type : MenuItemType . LINK ,
176+ text : 'test' ,
177+ link : '/test' ,
178+ } as LinkMenuItemModel ,
179+ }
180+ } ,
181+ visible : true ,
182+ } ,
183+ } ,
184+ } ) ;
185+ expect ( menuService . hasSubSections ) . toHaveBeenCalled ( ) ;
186+ hasSubSections . next ( true ) ;
187+
188+ expect ( comp . sectionMap$ . next ) . toHaveBeenCalled ( ) ;
189+ } ) ;
190+ } ) ;
191+
84192 describe ( 'toggle' , ( ) => {
85193 beforeEach ( ( ) => {
86194 spyOn ( menuService , 'toggleMenu' ) ;
0 commit comments