@@ -19,10 +19,14 @@ import {
1919 NgbModalRef ,
2020} from '@ng-bootstrap/ng-bootstrap' ;
2121import { TranslateModule } from '@ngx-translate/core' ;
22- import { of as observableOf } from 'rxjs' ;
22+ import {
23+ BehaviorSubject ,
24+ of as observableOf ,
25+ } from 'rxjs' ;
2326
2427import { AuthService } from '../../core/auth/auth.service' ;
2528import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service' ;
29+ import { FeatureID } from '../../core/data/feature-authorization/feature-id' ;
2630import { ScriptDataService } from '../../core/data/processes/script-data.service' ;
2731import { Item } from '../../core/shared/item.model' ;
2832import { MenuService } from '../../shared/menu/menu.service' ;
@@ -105,6 +109,70 @@ describe('AdminSidebarComponent', () => {
105109 fixture . detectChanges ( ) ;
106110 } ) ;
107111
112+ describe ( 'authorization' , ( ) => {
113+ /**
114+ * Re-create the component so that its single ngOnInit runs under the stubs/spies configured by the
115+ * test, instead of the default detectChanges() from the outer beforeEach (which runs before them).
116+ */
117+ const initFreshComponent = ( ) => {
118+ fixture = TestBed . createComponent ( AdminSidebarComponent ) ;
119+ comp = fixture . componentInstance ;
120+ comp . sections = observableOf ( [ ] ) ;
121+ fixture . detectChanges ( ) ;
122+ } ;
123+
124+ beforeEach ( ( ) => {
125+ spyOn ( menuService , 'showMenu' ) ;
126+ spyOn ( menuService , 'hideMenu' ) ;
127+ } ) ;
128+
129+ it ( 'should show the admin menu for a user with an administrative role' , ( ) => {
130+ authorizationService . isAuthorized = jasmine . createSpy ( 'isAuthorized' ) . and . callFake ( ( featureID : FeatureID ) => {
131+ return observableOf ( featureID === FeatureID . AdministratorOf ) ;
132+ } ) ;
133+
134+ initFreshComponent ( ) ;
135+
136+ expect ( menuService . showMenu ) . toHaveBeenCalledWith ( comp . menuID ) ;
137+ expect ( menuService . hideMenu ) . not . toHaveBeenCalled ( ) ;
138+ } ) ;
139+
140+ it ( 'should hide the admin menu for an authenticated non-admin user' , ( ) => {
141+ authorizationService . isAuthorized = jasmine . createSpy ( 'isAuthorized' ) . and . returnValue ( observableOf ( false ) ) ;
142+
143+ initFreshComponent ( ) ;
144+
145+ expect ( menuService . showMenu ) . not . toHaveBeenCalled ( ) ;
146+ expect ( menuService . hideMenu ) . toHaveBeenCalledWith ( comp . menuID ) ;
147+ } ) ;
148+
149+ it ( 'should hide the admin menu without requesting authorizations for an anonymous user' , ( ) => {
150+ spyOn ( TestBed . inject ( AuthService ) , 'isAuthenticated' ) . and . returnValue ( observableOf ( false ) ) ;
151+ authorizationService . isAuthorized = jasmine . createSpy ( 'isAuthorized' ) . and . returnValue ( observableOf ( false ) ) ;
152+
153+ initFreshComponent ( ) ;
154+
155+ expect ( menuService . showMenu ) . not . toHaveBeenCalled ( ) ;
156+ expect ( menuService . hideMenu ) . toHaveBeenCalledWith ( comp . menuID ) ;
157+ expect ( authorizationService . isAuthorized ) . not . toHaveBeenCalled ( ) ;
158+ } ) ;
159+
160+ it ( 'should reveal the admin menu once authentication resolves (guards against a one-shot take(1) regression)' , ( ) => {
161+ const authenticated$ = new BehaviorSubject < boolean > ( false ) ;
162+ spyOn ( TestBed . inject ( AuthService ) , 'isAuthenticated' ) . and . returnValue ( authenticated$ ) ;
163+ authorizationService . isAuthorized = jasmine . createSpy ( 'isAuthorized' ) . and . callFake ( ( featureID : FeatureID ) => {
164+ return observableOf ( featureID === FeatureID . AdministratorOf ) ;
165+ } ) ;
166+
167+ initFreshComponent ( ) ;
168+ expect ( menuService . hideMenu ) . toHaveBeenCalledWith ( comp . menuID ) ;
169+
170+ authenticated$ . next ( true ) ;
171+
172+ expect ( menuService . showMenu ) . toHaveBeenCalledWith ( comp . menuID ) ;
173+ } ) ;
174+ } ) ;
175+
108176 describe ( 'startSlide' , ( ) => {
109177 describe ( 'when expanding' , ( ) => {
110178 beforeEach ( ( ) => {
0 commit comments