Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/app/modules/user/store/user.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class UserEffects {
loadUserInfo$: Observable<Action> = this.actions$.pipe(
ofType(actions.UserActionTypes.LOAD_USER),
map((action: actions.LoadUser) => action.userId),
mergeMap((userId) =>
mergeMap((userId: string) =>
this.userService.loadUser(userId).pipe(
map((response) => new actions.LoadUserSuccess(response)),
catchError((error) => of(new actions.LoadUserFail(error)))
Expand Down
1 change: 1 addition & 0 deletions src/app/modules/users/models/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export interface User {
name: string;
email: string;
roles?: string[];
groups?: string[];
id: string;
tenant_id?: string;
deleted?: string;
Expand Down
20 changes: 20 additions & 0 deletions src/app/modules/users/services/users.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,24 @@ describe('UsersService', () => {
const grantRoleRequest = httpMock.expectOne(`${service.baseUrl}/${userId}/roles/${roleId}/revoke`);
expect(grantRoleRequest.request.method).toBe('POST');
});

it('add group to a User', () => {
const userId = 'userId';
const group = 'admin';
const addGroupURL = `${service.baseUrl}/${userId}/groups/add`;

service.addGroupToUser(userId, group).subscribe();

expect(httpMock.expectOne(addGroupURL).request.method).toBe('POST');
});

it('remove group to a User', () => {
const userId = 'userId';
const group = 'admin';
const removeGroupURL = `${service.baseUrl}/${userId}/groups/remove`;

service.removeGroupToUser(userId, group).subscribe();

expect(httpMock.expectOne(removeGroupURL).request.method).toBe('POST');
});
});
13 changes: 13 additions & 0 deletions src/app/modules/users/services/users.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { User } from '../models/users';
import { environment } from './../../../../environments/environment';
@Injectable({
providedIn: 'root',
Expand All @@ -23,4 +24,16 @@ export class UsersService {
const url = `${this.baseUrl}/${userId}/roles/${roleId}/revoke`;
return this.http.post(url, null);
}

addGroupToUser(userId: string, group: string): Observable<User> {
return this.http.post<User>(`${this.baseUrl}/${userId}/groups/add`, {
group_name: group,
});
}

removeGroupToUser(userId: string, group: string): Observable<User> {
return this.http.post<User>(`${this.baseUrl}/${userId}/groups/remove`, {
group_name: group,
});
}
}
42 changes: 42 additions & 0 deletions src/app/modules/users/store/user.actions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,46 @@ describe('UserActions', () => {
const action = new actions.RevokeRoleUserFail('error');
expect(action.type).toEqual(actions.UserActionTypes.REVOKE_USER_ROLE_FAIL);
});

it('AddGroupToUser type is UserActionTypes.ADD_GROUP_TO_USER', () => {
const userId = 'userId';
const groupName = 'groupName';
const action = new actions.AddGroupToUser(userId, groupName);

expect(action.type).toEqual(actions.UserActionTypes.ADD_GROUP_TO_USER);
});

it('AddGroupToUserSuccess type is UserActionTypes.ADD_GROUP_TO_USER_SUCCESS', () => {
const payload: User = { id: 'id', email: 'email', name: 'name' };
const action = new actions.AddGroupToUserSuccess(payload);

expect(action.type).toEqual(actions.UserActionTypes.ADD_GROUP_TO_USER_SUCCESS);
});

it('AddGroupToUserFail type is UserActionTypes.ADD_GROUP_TO_USER_FAIL', () => {
const action = new actions.AddGroupToUserFail('error');

expect(action.type).toEqual(actions.UserActionTypes.ADD_GROUP_TO_USER_FAIL);
});

it('RemoveGroupToUser type is UserActionTypes.REMOVE_GROUP_TO_USER', () => {
const userId = 'userId';
const groupName = 'groupName';
const action = new actions.RemoveGroupToUser(userId, groupName);

expect(action.type).toEqual(actions.UserActionTypes.REMOVE_GROUP_TO_USER);
});

it('RemoveGroupToUserSuccess type is UserActionTypes.REMOVE_GROUP_TO_USER_SUCCESS', () => {
const payload: User = { id: 'id', email: 'email', name: 'name' };
const action = new actions.RemoveGroupToUserSuccess(payload);

expect(action.type).toEqual(actions.UserActionTypes.REMOVE_GROUP_TO_USER_SUCCESS);
});

it('RemoveGroupToUserFail type is UserActionTypes.REMOVE_GROUP_TO_USER_FAIL', () => {
const action = new actions.RemoveGroupToUserFail('error');

expect(action.type).toEqual(actions.UserActionTypes.REMOVE_GROUP_TO_USER_FAIL);
});
});
45 changes: 44 additions & 1 deletion src/app/modules/users/store/user.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ export enum UserActionTypes {
REVOKE_USER_ROLE = '[User] REVOKE_USER_ROLE',
REVOKE_USER_ROLE_SUCCESS = '[User] REVOKE_USER_ROLE_SUCCESS',
REVOKE_USER_ROLE_FAIL = '[User] REVOKE_USER_ROLE_FAIL',
ADD_GROUP_TO_USER = '[User] ADD_GROUP_TO_USER',
ADD_GROUP_TO_USER_SUCCESS = '[User] ADD_GROUP_TO_USER_SUCCESS',
ADD_GROUP_TO_USER_FAIL = '[User] ADD_GROUP_TO_USER_FAIL',
REMOVE_GROUP_TO_USER = '[User] REMOVE_GROUP_TO_USER',
REMOVE_GROUP_TO_USER_SUCCESS = '[User] REMOVE_GROUP_TO_USER_SUCCESS',
REMOVE_GROUP_TO_USER_FAIL = '[User] REMOVE_GROUP_TO_USER_FAIL',
DEFAULT_USER = '[USER] DEFAULT_USER',
}

Expand Down Expand Up @@ -57,6 +63,37 @@ export class RevokeRoleUserFail implements Action {
public readonly type = UserActionTypes.REVOKE_USER_ROLE_FAIL;
constructor(public error: string) {}
}

export class AddGroupToUser implements Action {
public readonly type = UserActionTypes.ADD_GROUP_TO_USER;
constructor(public userId: string, public groupName: string) {}
}

export class AddGroupToUserSuccess implements Action {
public readonly type = UserActionTypes.ADD_GROUP_TO_USER_SUCCESS;
constructor(readonly payload: User) {}
}

export class AddGroupToUserFail implements Action {
public readonly type = UserActionTypes.ADD_GROUP_TO_USER_FAIL;
constructor(public error: string) {}
}

export class RemoveGroupToUser implements Action {
public readonly type = UserActionTypes.REMOVE_GROUP_TO_USER;
constructor(public userId: string, public groupName: string) {}
}

export class RemoveGroupToUserSuccess implements Action {
public readonly type = UserActionTypes.REMOVE_GROUP_TO_USER_SUCCESS;
constructor(readonly payload: User) {}
}

export class RemoveGroupToUserFail implements Action {
public readonly type = UserActionTypes.REMOVE_GROUP_TO_USER_FAIL;
constructor(public error: string) {}
}

export class DefaultUser implements Action {
public readonly type = UserActionTypes.DEFAULT_USER;
}
Expand All @@ -71,4 +108,10 @@ export type UserActions =
| GrantRoleUserFail
| RevokeRoleUser
| RevokeRoleUserSuccess
| RevokeRoleUserFail;
| RevokeRoleUserFail
| AddGroupToUser
| AddGroupToUserSuccess
| AddGroupToUserFail
| RemoveGroupToUser
| RemoveGroupToUserSuccess
| RemoveGroupToUserFail;
72 changes: 72 additions & 0 deletions src/app/modules/users/store/user.effects.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,76 @@ describe('UserEffects', () => {
expect(action.type).toEqual(UserActionTypes.REVOKE_USER_ROLE_FAIL);
});
});

it('action type is ADD_GROUP_TO_USER_SUCCESS when service is executed sucessfully', async () => {
const userId = 'userId';
const groupName = 'groupName';
actions$ = of({
type: UserActionTypes.ADD_GROUP_TO_USER,
userId,
groupName,
});

spyOn(toastrService, 'success');
spyOn(service, 'addGroupToUser').and.returnValue(of(user));

effects.addGroupToUser$.subscribe((action) => {
expect(toastrService.success).toHaveBeenCalledWith('Add group to a user success');
expect(action.type).toEqual(UserActionTypes.ADD_GROUP_TO_USER_SUCCESS);
});
});

it('action type is ADD_GROUP_TO_USER_FAIL when service is executed and fail', async () => {
const userId = 'userId';
const groupName = 'groupName';
actions$ = of({
type: UserActionTypes.ADD_GROUP_TO_USER,
userId,
groupName,
});

spyOn(toastrService, 'error');
spyOn(service, 'addGroupToUser').and.returnValue(throwError({ error: { message: 'error' } }));

effects.addGroupToUser$.subscribe((action) => {
expect(toastrService.error).toHaveBeenCalled();
expect(action.type).toEqual(UserActionTypes.ADD_GROUP_TO_USER_FAIL);
});
});

it('action type is REMOVE_GROUP_TO_USER_SUCCESS when service is executed succesfully', async () => {
const userId = 'userId';
const groupName = 'groupName';
actions$ = of({
type: UserActionTypes.REMOVE_GROUP_TO_USER,
userId,
groupName,
});

spyOn(toastrService, 'success');
spyOn(service, 'removeGroupToUser').and.returnValue(of(user));

effects.removeGroupToUser$.subscribe((action) => {
expect(toastrService.success).toHaveBeenCalledWith('Remove group to a user success');
expect(action.type).toEqual(UserActionTypes.REMOVE_GROUP_TO_USER_SUCCESS);
});
});

it('action type is REMOVE_GROUP_TO_USER_FAIL when service is executed succesfully', async () => {
const userId = 'userId';
const groupName = 'groupName';
actions$ = of({
type: UserActionTypes.REMOVE_GROUP_TO_USER,
userId,
groupName,
});

spyOn(toastrService, 'error');
spyOn(service, 'removeGroupToUser').and.returnValue(throwError({ error: { message: 'error' } }));

effects.removeGroupToUser$.subscribe((action) => {
expect(toastrService.error).toHaveBeenCalled();
expect(action.type).toEqual(UserActionTypes.REMOVE_GROUP_TO_USER_FAIL);
});
});
});
36 changes: 36 additions & 0 deletions src/app/modules/users/store/user.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,40 @@ export class UserEffects {
)
)
);

@Effect()
addGroupToUser$: Observable<Action> = this.actions$.pipe(
ofType(actions.UserActionTypes.ADD_GROUP_TO_USER),
map((action: actions.AddGroupToUser) => action),
mergeMap((action) =>
this.userService.addGroupToUser(action.userId, action.groupName).pipe(
map((response) => {
this.toastrService.success('Add group to a user success');
return new actions.AddGroupToUserSuccess(response);
}),
catchError((error) => {
this.toastrService.error(error.error.message);
return of(new actions.AddGroupToUserFail(error));
})
)
)
);

@Effect()
removeGroupToUser$: Observable<Action> = this.actions$.pipe(
ofType(actions.UserActionTypes.REMOVE_GROUP_TO_USER),
map((action: actions.RemoveGroupToUser) => action),
mergeMap((action) =>
this.userService.removeGroupToUser(action.userId, action.groupName).pipe(
map((response) => {
this.toastrService.success('Remove group to a user success');
return new actions.RemoveGroupToUserSuccess(response);
}),
catchError((error) => {
this.toastrService.error(error.error.message);
return of(new actions.RemoveGroupToUserFail(error));
})
)
)
);
}
64 changes: 64 additions & 0 deletions src/app/modules/users/store/user.reducer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,70 @@ describe('userReducer', () => {
expect(state.isLoading).toEqual(false);
});

it('on AddGroupToUser, isLoading is true', () => {
const userId = 'userId';
const groupName = 'groupName';
const action = new actions.AddGroupToUser(userId, groupName);
const state = userReducer(initialState, action);

expect(state.isLoading).toEqual(true);
});

it('on AddGroupToUserSuccess, user groups should change', () => {
const currentState: UserState = {
data: [{ id: 'id', name: 'name', email: 'email', groups: null }],
isLoading: false,
message: '',
};
const userWithGroupAdded: User = { id: 'id', name: 'name', email: 'email', groups: ['group'] };
const action = new actions.AddGroupToUserSuccess(userWithGroupAdded);
const state = userReducer(currentState, action);

expect(state.data).toEqual([userWithGroupAdded]);
expect(state.isLoading).toEqual(false);
expect(state.message).toEqual('Add group to a user success');
});

it('on AddGroupToUserFail, should show a message with an error message', () => {
const action = new actions.AddGroupToUserFail('error');
const state = userReducer(initialState, action);

expect(state.message).toEqual('Something went wrong adding group to a user');
expect(state.isLoading).toEqual(false);
});

it('on RemoveGroupToUser, isLoading is true', () => {
const userId = 'userId';
const groupName = 'groupName';
const action = new actions.RemoveGroupToUser(userId, groupName);
const state = userReducer(initialState, action);

expect(state.isLoading).toEqual(true);
});

it('on RemoveGroupToUserSuccess, user groups should change', () => {
const currentState: UserState = {
data: [{ id: 'id', name: 'name', email: 'email', groups: ['group'] }],
isLoading: false,
message: '',
};
const userWithGroupRemoved: User = { id: 'id', name: 'name', email: 'email', groups: null };
const action = new actions.RemoveGroupToUserSuccess(userWithGroupRemoved);
const state = userReducer(currentState, action);

expect(state.data).toEqual([userWithGroupRemoved]);
expect(state.isLoading).toEqual(false);
expect(state.message).toEqual('Remove group to a user success');
});

it('on RemoveGroupToUserFail, should show a message with an error message', () => {
const action = new actions.RemoveGroupToUserFail('error');
const state = userReducer(initialState, action);

expect(state.message).toEqual('Something went wrong removing group to a user');
expect(state.isLoading).toEqual(false);
});

it('on Default, ', () => {
const action = new actions.DefaultUser();
const state = userReducer(initialState, action);
Expand Down
Loading