1+ import { FeatureManagerService } from 'src/app/modules/shared/feature-toggles/feature-toggle-manager.service' ;
12import { waitForAsync , ComponentFixture , TestBed } from '@angular/core/testing' ;
23import { MockStore , provideMockStore } from '@ngrx/store/testing' ;
3-
44import { NgxPaginationModule } from 'ngx-pagination' ;
55import { UsersListComponent } from './users-list.component' ;
6- import { UserActionTypes , UserState , LoadUsers , GrantRoleUser , RevokeRoleUser } from '../../store' ;
6+ import {
7+ UserActionTypes ,
8+ UserState ,
9+ LoadUsers ,
10+ GrantRoleUser ,
11+ RevokeRoleUser ,
12+ AddUserToGroup ,
13+ RemoveUserFromGroup ,
14+ } from '../../store' ;
15+ import { User } from '../../../user/models/user' ;
716import { ActionsSubject } from '@ngrx/store' ;
817import { DataTablesModule } from 'angular-datatables' ;
18+ import { Observable , of } from 'rxjs' ;
19+ import { FeatureToggleProvider } from 'src/app/modules/shared/feature-toggles/feature-toggle-provider.service' ;
20+ import { AppConfigurationClient } from '@azure/app-configuration' ;
21+ import { FeatureFilterProvider } from '../../../shared/feature-toggles/filters/feature-filter-provider.service' ;
22+ import { AzureAdB2CService } from '../../../login/services/azure.ad.b2c.service' ;
923
1024describe ( 'UsersListComponent' , ( ) => {
1125 let component : UsersListComponent ;
1226 let fixture : ComponentFixture < UsersListComponent > ;
1327 let store : MockStore < UserState > ;
1428 const actionSub : ActionsSubject = new ActionsSubject ( ) ;
29+ const fakeAppConfigurationConnectionString = 'Endpoint=http://fake.foo;Id=fake.id;Secret=fake.secret' ;
30+ let service : FeatureManagerService ;
31+ let fakeFeatureToggleProvider ;
1532
1633 const state : UserState = {
1734 data : [
1835 {
1936 name : 'name' ,
2037 email : 'email' ,
2138 roles : [ 'admin' , 'test' ] ,
39+ groups : [ 'time-tracker-admin' , 'time-tracker-tester' ] ,
2240 id : 'id' ,
2341 tenant_id : 'tenant id' ,
2442 deleted : 'delete' ,
@@ -30,10 +48,20 @@ describe('UsersListComponent', () => {
3048
3149 beforeEach (
3250 waitForAsync ( ( ) => {
51+ fakeFeatureToggleProvider = new FeatureToggleProvider (
52+ new AppConfigurationClient ( fakeAppConfigurationConnectionString ) ,
53+ new FeatureFilterProvider ( new AzureAdB2CService ( ) )
54+ ) ;
55+ service = new FeatureManagerService ( fakeFeatureToggleProvider ) ;
56+
3357 TestBed . configureTestingModule ( {
3458 imports : [ NgxPaginationModule , DataTablesModule ] ,
3559 declarations : [ UsersListComponent ] ,
36- providers : [ provideMockStore ( { initialState : state } ) , { provide : ActionsSubject , useValue : actionSub } ] ,
60+ providers : [
61+ provideMockStore ( { initialState : state } ) ,
62+ { provide : ActionsSubject , useValue : actionSub } ,
63+ { provide : FeatureManagerService , useValue : service }
64+ ] ,
3765 } ) . compileComponents ( ) ;
3866 } )
3967 ) ;
@@ -91,6 +119,27 @@ describe('UsersListComponent', () => {
91119 } ) ;
92120 } ) ;
93121
122+ const actionGroupParams = [
123+ { actionType : UserActionTypes . ADD_USER_TO_GROUP_SUCCESS } ,
124+ { actionType : UserActionTypes . REMOVE_USER_FROM_GROUP_SUCCESS } ,
125+ ] ;
126+
127+ actionGroupParams . map ( ( param ) => {
128+ it ( `When action ${ param . actionType } is dispatched should triggered load Users action` , ( ) => {
129+ spyOn ( store , 'dispatch' ) ;
130+
131+ const actionSubject = TestBed . inject ( ActionsSubject ) as ActionsSubject ;
132+ const action = {
133+ type : param . actionType ,
134+ payload : state . data ,
135+ } ;
136+
137+ actionSubject . next ( action ) ;
138+
139+ expect ( store . dispatch ) . toHaveBeenCalledWith ( new LoadUsers ( ) ) ;
140+ } ) ;
141+ } ) ;
142+
94143 const grantRoleTypes = [
95144 { roleId : 'admin' , roleValue : 'time-tracker-admin' } ,
96145 { roleId : 'test' , roleValue : 'time-tracker-tester' } ,
@@ -111,6 +160,32 @@ describe('UsersListComponent', () => {
111160 } ) ;
112161 } ) ;
113162
163+ const AddGroupTypes = [
164+ { groupName : 'time-tracker-admin' } ,
165+ { groupName : 'time-tracker-tester' }
166+ ] ;
167+
168+ AddGroupTypes . map ( ( param ) => {
169+ it ( `When user switchGroup to ${ param . groupName } and doesn't belong to any group, should add ${ param . groupName } group to user` , ( ) => {
170+ const groupName = param . groupName ;
171+ const user = {
172+ name : 'name' ,
173+ email : 'email' ,
174+ roles : [ ] ,
175+ groups : [ ] ,
176+ id : 'id' ,
177+ tenant_id : 'tenant id' ,
178+ deleted : 'delete' ,
179+ } ;
180+
181+ spyOn ( store , 'dispatch' ) ;
182+
183+ component . switchGroup ( groupName , user ) ;
184+
185+ expect ( store . dispatch ) . toHaveBeenCalledWith ( new AddUserToGroup ( user . id , groupName ) ) ;
186+ } ) ;
187+ } ) ;
188+
114189 const revokeRoleTypes = [
115190 { roleId : 'admin' , roleValue : 'time-tracker-admin' , userRoles : [ 'time-tracker-admin' ] } ,
116191 { roleId : 'test' , roleValue : 'time-tracker-tester' , userRoles : [ 'time-tracker-tester' ] } ,
@@ -131,6 +206,33 @@ describe('UsersListComponent', () => {
131206 } ) ;
132207 } ) ;
133208
209+ const removeGroupTypes = [
210+ { groupName : 'time-tracker-admin' , userGroups : [ 'time-tracker-admin' ] } ,
211+ { groupName : 'time-tracker-tester' , userGroups : [ 'time-tracker-tester' ] } ,
212+ ] ;
213+
214+ removeGroupTypes . map ( ( param ) => {
215+ it ( `When user switchGroup to ${ param . groupName } and belongs to group, should remove ${ param . groupName } group from user` , ( ) => {
216+ const groupName = param . groupName ;
217+ const user = {
218+ name : 'name' ,
219+ email : 'email' ,
220+ roles : [ ] ,
221+ groups : param . userGroups ,
222+ id : 'id' ,
223+ tenant_id : 'tenant id' ,
224+ deleted : 'delete' ,
225+ } ;
226+
227+
228+ spyOn ( store , 'dispatch' ) ;
229+
230+ component . switchGroup ( groupName , user ) ;
231+
232+ expect ( store . dispatch ) . toHaveBeenCalledWith ( new RemoveUserFromGroup ( user . id , groupName ) ) ;
233+ } ) ;
234+ } ) ;
235+
134236 it ( 'on success load users, the data of roles should be an array' , ( ) => {
135237 const actionSubject = TestBed . inject ( ActionsSubject ) as ActionsSubject ;
136238 const action = {
@@ -145,6 +247,20 @@ describe('UsersListComponent', () => {
145247 } ) ;
146248 } ) ;
147249
250+ it ( 'on success load users, the data of groups should be an array' , ( ) => {
251+ const actionSubject = TestBed . inject ( ActionsSubject ) as ActionsSubject ;
252+ const action = {
253+ type : UserActionTypes . LOAD_USERS_SUCCESS ,
254+ payload : state . data ,
255+ } ;
256+
257+ actionSubject . next ( action ) ;
258+
259+ component . users . map ( ( user ) => {
260+ expect ( user . groups ) . toEqual ( [ 'time-tracker-admin' , 'time-tracker-tester' ] ) ;
261+ } ) ;
262+ } ) ;
263+
148264 it ( 'on success load users, the datatable should be reloaded' , async ( ) => {
149265 const actionSubject = TestBed . inject ( ActionsSubject ) ;
150266 const action = {
@@ -158,6 +274,27 @@ describe('UsersListComponent', () => {
158274 expect ( component . dtElement . dtInstance . then ) . toHaveBeenCalled ( ) ;
159275 } ) ;
160276
277+ it ( 'When Component is created, should call the feature toggle method' , ( ) => {
278+ spyOn ( component , 'isFeatureToggleActivated' ) . and . returnValue ( of ( true ) ) ;
279+
280+ component . ngOnInit ( ) ;
281+
282+ expect ( component . isFeatureToggleActivated ) . toHaveBeenCalled ( ) ;
283+ expect ( component . isUserGroupsToggleOn ) . toBe ( true ) ;
284+ } ) ;
285+
286+ const toggleValues = [ true , false ] ;
287+ toggleValues . map ( ( toggleValue ) => {
288+ it ( `when FeatureToggle is ${ toggleValue } should return ${ toggleValue } ` , ( ) => {
289+ spyOn ( service , 'isToggleEnabledForUser' ) . and . returnValue ( of ( toggleValue ) ) ;
290+
291+ const isFeatureToggleActivated : Observable < boolean > = component . isFeatureToggleActivated ( ) ;
292+
293+ expect ( service . isToggleEnabledForUser ) . toHaveBeenCalled ( ) ;
294+ isFeatureToggleActivated . subscribe ( ( value ) => expect ( value ) . toEqual ( toggleValue ) ) ;
295+ } ) ;
296+ } ) ;
297+
161298 afterEach ( ( ) => {
162299 component . dtTrigger . unsubscribe ( ) ;
163300 component . loadUsersSubscription . unsubscribe ( ) ;
0 commit comments