Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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: 2 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import { CreateProjectTypeComponent } from './modules/customer-management/compon
import { CustomerEffects } from './modules/customer-management/store/customer-management.effects';
import { EntryEffects } from './modules/time-clock/store/entry.effects';
import { InjectTokenInterceptor } from './modules/shared/interceptors/inject.token.interceptor';
import { NotificationComponent } from './modules/shared/components/notification/notification/notification.component';

@NgModule({
declarations: [
Expand Down Expand Up @@ -88,6 +89,7 @@ import { InjectTokenInterceptor } from './modules/shared/interceptors/inject.tok
ProjectTypeListComponent,
CreateProjectTypeComponent,
EntryFieldsComponent,
NotificationComponent,
],
imports: [
CommonModule,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<div class="container">
<app-notification [notificationMsg]="notificationMsg" [isError]="isError" *ngIf="showNotification"></app-notification>
<div class="row">
<div class="col">
<app-create-activity></app-create-activity>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,92 @@
import { HttpClient, HttpHandler } from '@angular/common/http';
import { async, TestBed } from '@angular/core/testing';
import { of } from 'rxjs';
import { async, TestBed, ComponentFixture } from '@angular/core/testing';
import { of, Subscription } from 'rxjs';
import { Activity } from '../../shared/models';
import { ActivityService } from './../services/activity.service';
import { ActivitiesManagementComponent } from './activities-management.component';
import { ActionsSubject } from '@ngrx/store';

describe('ActivitiesManagementComponent', () => {
let component: ActivitiesManagementComponent;
let fixture: ComponentFixture<ActivitiesManagementComponent>;
let activityService: ActivityService;
const activitiesFromApi: Activity[] = [{ id: '123', name: 'aaa', description: 'xxx' }];

beforeEach(async(() => {
const actionSub: ActionsSubject = new ActionsSubject();
TestBed.configureTestingModule({
declarations: [ActivitiesManagementComponent],
providers: [ActivityService, HttpClient, HttpHandler],
});
component = TestBed.createComponent(ActivitiesManagementComponent).componentInstance;
providers: [ActivityService, HttpClient, HttpHandler, { provide: ActionsSubject, useValue: actionSub }],
}).compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(ActivitiesManagementComponent);
component = fixture.componentInstance;
fixture.detectChanges();

activityService = TestBed.inject(ActivityService);
spyOn(activityService, 'getActivities').and.returnValue(of(activitiesFromApi));
}));
});

it('should create the component', () => {
expect(component).toBeTruthy();
});

it('should call #setDataNotification with action #ngOnInit', () => {
const actionSubject = TestBed.inject(ActionsSubject) as ActionsSubject;
spyOn(component, 'setDataNotification');
const action = {
type: '[ActivityManagement] CREATE_ACTIVITY_SUCCESS',
};
actionSubject.next(action);

component.ngOnInit();
expect(component.setDataNotification).toHaveBeenCalledWith(action.type);
});

it('should destroy the subscription', () => {
component.actionsSubscription = new Subscription();
const subscription = spyOn(component.actionsSubscription, 'unsubscribe');

component.ngOnDestroy();

expect(subscription).toHaveBeenCalledTimes(1);
});

it('#setDataNotification should show an success notification with DELETE_ACTIVITY_SUCCESS case', () => {
const actionSubject = TestBed.inject(ActionsSubject) as ActionsSubject;
const action = {
type: '[ActivityManagement] DELETE_ACTIVITY_SUCESS',
};
actionSubject.next(action);

component.setDataNotification(action.type);
expect(component.showNotification).toBeTrue();
expect(component.isError).toBeFalse();
});

it('#setDataNotification should show an error notification with CREATE_ACTIVITY_FAIL case', () => {
const actionSubject = TestBed.inject(ActionsSubject) as ActionsSubject;
const action = {
type: '[ActivityManagement] CREATE_ACTIVITY_FAIL',
};
actionSubject.next(action);

component.setDataNotification(action.type);
expect(component.showNotification).toBeTrue();
expect(component.isError).toBeTrue();
});

it('#setDataNotification should not show an error notification with incorrect action', () => {
const actionSubject = TestBed.inject(ActionsSubject) as ActionsSubject;
const action = {
type: '[ActivityManagement] TEST',
};
actionSubject.next(action);

component.setDataNotification(action.type);
expect(component.showNotification).toBeFalse();
expect(component.isError).toBeFalse();
});
});
Original file line number Diff line number Diff line change
@@ -1,12 +1,52 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
import { ActionsSubject } from '@ngrx/store';
import { Subscription } from 'rxjs';
import { ActivityManagementActionTypes } from '../store';

@Component({
selector: 'app-activities-management',
templateUrl: './activities-management.component.html',
styleUrls: ['./activities-management.component.scss'],
})
export class ActivitiesManagementComponent implements OnInit {
constructor() {}
export class ActivitiesManagementComponent implements OnInit, OnDestroy {
notificationMsg = '';
showNotification = false;
isError = false;
actionsSubscription: Subscription;

ngOnInit(): void {}
constructor(private actionsSubject$: ActionsSubject) {}

ngOnInit() {
this.actionsSubscription = this.actionsSubject$.subscribe((action) => {
this.setDataNotification(action.type);
});
}

ngOnDestroy() {
this.actionsSubscription.unsubscribe();
}

setDataNotification(action: any) {
this.showNotification = true;
switch (action) {
case ActivityManagementActionTypes.CREATE_ACTIVITY_SUCCESS: {
this.notificationMsg = 'The activity has been saved successfully.';
break;
}
case ActivityManagementActionTypes.DELETE_ACTIVITY_SUCCESS: {
this.notificationMsg = 'The activity has been removed successfully.';
break;
}
case ActivityManagementActionTypes.CREATE_ACTIVITY_FAIL || ActivityManagementActionTypes.DELETE_ACTIVITY_FAIL: {
this.notificationMsg = 'An unexpected error happened, please try again later.';
this.isError = true;
break;
}
default: {
this.showNotification = false;
break;
}
}
setTimeout(() => ((this.showNotification = false), (this.isError = false)), 3000);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div
*ngIf="notificationMsg"
[ngClass]="isError ? 'bg-primary' : 'bg-secondary'"
class="alert alert-dismissible fade fade-in show text-white"
role="alert"
>
<strong>{{ notificationMsg }}</strong>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { NotificationComponent } from './notification.component';

describe('NotificationComponent', () => {
let component: NotificationComponent;
let fixture: ComponentFixture<NotificationComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ NotificationComponent ]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(NotificationComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Component, OnInit, Input } from '@angular/core';

@Component({
selector: 'app-notification',
templateUrl: './notification.component.html',
styleUrls: ['./notification.component.scss'],
})
export class NotificationComponent implements OnInit {
@Input() notificationMsg = '';
@Input() isError: boolean;
constructor() {}

ngOnInit(): void {}
}