From 13de42e14bfaea865b724fbadb3467e16987e5ca Mon Sep 17 00:00:00 2001 From: PaulRC-ioet Date: Mon, 23 Nov 2020 11:37:03 -0500 Subject: [PATCH] test: #576 add test to effects files and selectors --- .../store/activity-management.effects.spec.ts | 125 +++++++++++++++ .../activity-management.selectors.spec.ts | 15 ++ .../store/project-type.effects.spec.ts | 124 +++++++++++++++ .../store/project-type.selectors.spec.ts | 28 ++++ .../components/store/project.effects.spec.ts | 149 ++++++++++++++++++ .../store/project.selectors.spec.ts | 39 +++++ .../store/customer-management.effects.spec.ts | 124 +++++++++++++++ .../customer-management.selectors.spec.ts | 15 ++ .../shared/store/technology.effects.spec.ts | 52 ++++++ .../time-clock/store/entry.effects.spec.ts | 77 ++++++++- .../time-clock/store/entry.selectors.spec.ts | 32 +++- 11 files changed, 778 insertions(+), 2 deletions(-) create mode 100644 src/app/modules/activities-management/store/activity-management.effects.spec.ts create mode 100644 src/app/modules/customer-management/components/projects-type/store/project-type.effects.spec.ts create mode 100644 src/app/modules/customer-management/components/projects-type/store/project-type.selectors.spec.ts create mode 100644 src/app/modules/customer-management/components/projects/components/store/project.effects.spec.ts create mode 100644 src/app/modules/customer-management/components/projects/components/store/project.selectors.spec.ts create mode 100644 src/app/modules/customer-management/store/customer-management.effects.spec.ts create mode 100644 src/app/modules/shared/store/technology.effects.spec.ts diff --git a/src/app/modules/activities-management/store/activity-management.effects.spec.ts b/src/app/modules/activities-management/store/activity-management.effects.spec.ts new file mode 100644 index 000000000..8caa787ad --- /dev/null +++ b/src/app/modules/activities-management/store/activity-management.effects.spec.ts @@ -0,0 +1,125 @@ +import { Activity } from '../../shared/models/activity.model'; +import { TestBed } from '@angular/core/testing'; +import { provideMockActions } from '@ngrx/effects/testing'; +import { Action } from '@ngrx/store'; +import { Observable, of, throwError } from 'rxjs'; +import { ActivityService } from '../services/activity.service'; +import { ActivityManagementActionTypes } from './activity-management.actions'; +import { ActivityEffects } from './activity-management.effects'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { ToastrModule, ToastrService } from 'ngx-toastr'; +import { INFO_SAVED_SUCCESSFULLY, INFO_DELETE_SUCCESSFULLY } from '../../shared/messages'; + +describe('ActivityEffects', () => { + let actions$: Observable; + let effects: ActivityEffects; + let service: ActivityService; + let toastrService; + const activity: Activity = { id: 'id', name: 'name', description: 'description', tenant_id: 'tenantId' }; + const activityList: Activity[] = []; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ActivityEffects, provideMockActions(() => actions$)], + imports: [HttpClientTestingModule, ToastrModule.forRoot()], + declarations: [], + }); + effects = TestBed.inject(ActivityEffects); + service = TestBed.inject(ActivityService); + toastrService = TestBed.inject(ToastrService); + }); + + it('should be created', async () => { + expect(effects).toBeTruthy(); + }); + + it('action type is LOAD_ACTIVITIES_SUCCESS when service is executed sucessfully', async () => { + actions$ = of({ type: ActivityManagementActionTypes.LOAD_ACTIVITIES }); + const serviceSpy = spyOn(service, 'getActivities'); + serviceSpy.and.returnValue(of(activityList)); + + effects.getActivities$.subscribe((action) => { + expect(action.type).toEqual(ActivityManagementActionTypes.LOAD_ACTIVITIES_SUCCESS); + }); + }); + + it('action type is LOAD_ACTIVITIES_FAIL when service fail in execution', async () => { + actions$ = of({ type: ActivityManagementActionTypes.LOAD_ACTIVITIES }); + const serviceSpy = spyOn(service, 'getActivities'); + serviceSpy.and.returnValue(throwError({ error: { message: 'fail!' } })); + spyOn(toastrService, 'error'); + + effects.getActivities$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(ActivityManagementActionTypes.LOAD_ACTIVITIES_FAIL); + }); + }); + + it('action type is UPDATE_ACTIVITIES_SUCCESS when service is executed sucessfully', async () => { + actions$ = of({ type: ActivityManagementActionTypes.UPDATE_ACTIVITY, activity }); + spyOn(service, 'updateActivity').and.returnValue(of(activity)); + spyOn(toastrService, 'success'); + + effects.updateActivity$.subscribe((action) => { + expect(toastrService.success).toHaveBeenCalledWith(INFO_SAVED_SUCCESSFULLY); + expect(action.type).toEqual(ActivityManagementActionTypes.UPDATE_ACTIVITY_SUCCESS); + }); + }); + + it('action type is UPDATE_ACTIVITIES_FAIL when service fail in execution', async () => { + actions$ = of({ type: ActivityManagementActionTypes.UPDATE_ACTIVITY, activity }); + spyOn(service, 'updateActivity').and.returnValue(throwError({ error: { message: 'fail!' } })); + spyOn(toastrService, 'error'); + + effects.updateActivity$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(ActivityManagementActionTypes.UPDATE_ACTIVITY_FAIL); + }); + }); + + it('action type is CREATE_ACTIVITY_SUCCESS when service is executed sucessfully', async () => { + actions$ = of({ type: ActivityManagementActionTypes.CREATE_ACTIVITY, activity }); + spyOn(service, 'createActivity').and.returnValue(of(activity)); + spyOn(toastrService, 'success'); + + effects.createActivity$.subscribe((action) => { + expect(toastrService.success).toHaveBeenCalledWith(INFO_SAVED_SUCCESSFULLY); + expect(action.type).toEqual(ActivityManagementActionTypes.CREATE_ACTIVITY_SUCCESS); + }); + }); + + it('action type is CREATE_ACTIVITY_FAIL when service fail in execution', async () => { + actions$ = of({ type: ActivityManagementActionTypes.CREATE_ACTIVITY, activity }); + spyOn(service, 'createActivity').and.returnValue(throwError({ error: { message: 'fail!' } })); + spyOn(toastrService, 'error'); + + effects.createActivity$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(ActivityManagementActionTypes.CREATE_ACTIVITY_FAIL); + }); + }); + + it('action type is DELETE_ACTIVITY_SUCCESS when service is executed sucessfully', async () => { + const activityId = 'activityId'; + actions$ = of({ type: ActivityManagementActionTypes.DELETE_ACTIVITY, activityId }); + spyOn(service, 'deleteActivity').and.returnValue(of({})); + spyOn(toastrService, 'success'); + + effects.deleteActivity$.subscribe((action) => { + expect(toastrService.success).toHaveBeenCalledWith(INFO_DELETE_SUCCESSFULLY); + expect(action.type).toEqual(ActivityManagementActionTypes.DELETE_ACTIVITY_SUCCESS); + }); + }); + + it('action type is DELETE_ACTIVITY_FAIL when service fail in execution', async () => { + const activityId = 'activityId'; + actions$ = of({ type: ActivityManagementActionTypes.DELETE_ACTIVITY, activityId }); + spyOn(service, 'deleteActivity').and.returnValue(throwError({ error: { message: 'fail!' } })); + spyOn(toastrService, 'error'); + + effects.deleteActivity$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(ActivityManagementActionTypes.DELETE_ACTIVITY_FAIL); + }); + }); +}); diff --git a/src/app/modules/activities-management/store/activity-management.selectors.spec.ts b/src/app/modules/activities-management/store/activity-management.selectors.spec.ts index c2e43bf3c..79ee34b3e 100644 --- a/src/app/modules/activities-management/store/activity-management.selectors.spec.ts +++ b/src/app/modules/activities-management/store/activity-management.selectors.spec.ts @@ -16,4 +16,19 @@ describe('ActivityManagement Selectors', () => { expect(activityFound).toEqual(activities[0]); }); + it('should return all the data in the state when the selector allActivities is called', () => { + const activities = [{id: 'id', name: 'abc', description: 'xxx'}, + {id: '2', name: 'xyz', description: 'yyy'}]; + const activityState = {data: activities}; + + expect(selectors.allActivities.projector(activityState)).toBe(activities); + }); + + it('should select isLoading when the selector getIsLoading is called', () => { + const isLoadingValue = true; + const activityState = { isLoading: isLoadingValue }; + + expect(selectors.getIsLoading.projector(activityState)).toBe(isLoadingValue); + }); + }); diff --git a/src/app/modules/customer-management/components/projects-type/store/project-type.effects.spec.ts b/src/app/modules/customer-management/components/projects-type/store/project-type.effects.spec.ts new file mode 100644 index 000000000..4f14ccdc2 --- /dev/null +++ b/src/app/modules/customer-management/components/projects-type/store/project-type.effects.spec.ts @@ -0,0 +1,124 @@ +import { ProjectType } from '../../../../shared/models/project-type.model'; +import { TestBed } from '@angular/core/testing'; +import { provideMockActions } from '@ngrx/effects/testing'; +import { Action } from '@ngrx/store'; +import { Observable, of, throwError } from 'rxjs'; +import { ProjectTypeService } from '../services/project-type.service'; +import { ProjectTypeActionTypes } from './project-type.actions'; +import { ProjectTypeEffects } from './project-type.effects'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { ToastrModule, ToastrService } from 'ngx-toastr'; +import { INFO_DELETE_SUCCESSFULLY, INFO_SAVED_SUCCESSFULLY } from '../../../../shared/messages'; + +describe('ProjectTypeEffects', () => { + let actions$: Observable; + let effects: ProjectTypeEffects; + let service: ProjectTypeService; + let toastrService; + const projectType: ProjectType = { id: 'id', name: 'name', description: 'description' }; + const projectTypes: ProjectType[] = []; + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ProjectTypeEffects, provideMockActions(() => actions$)], + imports: [HttpClientTestingModule, ToastrModule.forRoot()], + declarations: [], + }); + effects = TestBed.inject(ProjectTypeEffects); + service = TestBed.inject(ProjectTypeService); + toastrService = TestBed.inject(ToastrService); + }); + + it('SHOULD be created', async () => { + expect(effects).toBeTruthy(); + }); + + it('action type is LOAD_PROJECT_TYPES_SUCCESS when service is executed sucessfully', async () => { + actions$ = of({ type: ProjectTypeActionTypes.LOAD_PROJECT_TYPES }); + const serviceSpy = spyOn(service, 'getProjectTypes'); + serviceSpy.and.returnValue(of(projectTypes)); + + effects.getProjectTypes$.subscribe((action) => { + expect(action.type).toEqual(ProjectTypeActionTypes.LOAD_PROJECT_TYPES_SUCCESS); + }); + }); + + it('action type is LOAD_PROJECT_TYPES_FAIL when service fail in execution', async () => { + actions$ = of({ type: ProjectTypeActionTypes.LOAD_PROJECT_TYPES }); + const serviceSpy = spyOn(service, 'getProjectTypes'); + serviceSpy.and.returnValue(throwError({ error: { message: 'fail!' } })); + spyOn(toastrService, 'error'); + + effects.getProjectTypes$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(ProjectTypeActionTypes.LOAD_PROJECT_TYPES_FAIL); + }); + }); + + it('action type is UPDATE_PROJECT_TYPE_SUCCESS when service is executed sucessfully', async () => { + actions$ = of({ type: ProjectTypeActionTypes.UPDATE_PROJECT_TYPE, projectType }); + spyOn(toastrService, 'success'); + spyOn(service, 'updateProjectType').and.returnValue(of(projectType)); + + effects.updateProjectType$.subscribe((action) => { + expect(toastrService.success).toHaveBeenCalledWith(INFO_SAVED_SUCCESSFULLY); + expect(action.type).toEqual(ProjectTypeActionTypes.UPDATE_PROJECT_TYPE_SUCCESS); + }); + }); + + it('action type is UPDATE_PROJECT_TYPE_FAIL when service fail in execution', async () => { + actions$ = of({ type: ProjectTypeActionTypes.UPDATE_PROJECT_TYPE, projectType }); + spyOn(toastrService, 'error'); + spyOn(service, 'updateProjectType').and.returnValue(throwError({ error: { message: 'fail!' } })); + + effects.updateProjectType$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(ProjectTypeActionTypes.UPDATE_PROJECT_TYPE_FAIL); + }); + }); + + it('action type is CREATE_PROJECT_TYPE_SUCCESS when service is executed sucessfully', async () => { + actions$ = of({ type: ProjectTypeActionTypes.CREATE_PROJECT_TYPE, payload: projectType }); + spyOn(toastrService, 'success'); + spyOn(service, 'createProjectType').and.returnValue(of(projectType)); + + effects.createProjectType$.subscribe((action) => { + expect(toastrService.success).toHaveBeenCalledWith(INFO_SAVED_SUCCESSFULLY); + expect(action.type).toEqual(ProjectTypeActionTypes.CREATE_PROJECT_TYPE_SUCCESS); + }); + }); + + it('action type is CREATE_PROJECT_TYPE_FAIL when service fail in execution', async () => { + actions$ = of({ type: ProjectTypeActionTypes.CREATE_PROJECT_TYPE, payload: projectType }); + spyOn(toastrService, 'error'); + spyOn(service, 'createProjectType').and.returnValue(throwError({ error: { message: 'fail!' } })); + + effects.createProjectType$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(ProjectTypeActionTypes.CREATE_PROJECT_TYPE_FAIL); + }); + }); + + it('action type is DELETE_PROJECT_TYPE_SUCCESS when service is executed sucessfully', async () => { + const projectTypeId = 'projectTypeId'; + actions$ = of({ type: ProjectTypeActionTypes.DELETE_PROJECT_TYPE, projectTypeId }); + spyOn(toastrService, 'success'); + spyOn(service, 'deleteProjectType').and.returnValue(of({})); + + effects.deleteProjectType$.subscribe((action) => { + expect(toastrService.success).toHaveBeenCalledWith(INFO_DELETE_SUCCESSFULLY); + expect(action.type).toEqual(ProjectTypeActionTypes.DELETE_PROJECT_TYPE_SUCCESS); + }); + }); + + it('action type is DELETE_PROJECT_TYPE_FAIL when service fail in execution', async () => { + const projectTypeId = 'projectTypeId'; + actions$ = of({ type: ProjectTypeActionTypes.DELETE_PROJECT_TYPE, projectTypeId }); + spyOn(toastrService, 'error'); + spyOn(service, 'deleteProjectType').and.returnValue(throwError({ error: { message: 'fail!' } })); + + effects.deleteProjectType$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(ProjectTypeActionTypes.DELETE_PROJECT_TYPE_FAIL); + }); + }); +}); diff --git a/src/app/modules/customer-management/components/projects-type/store/project-type.selectors.spec.ts b/src/app/modules/customer-management/components/projects-type/store/project-type.selectors.spec.ts new file mode 100644 index 000000000..04e7633e4 --- /dev/null +++ b/src/app/modules/customer-management/components/projects-type/store/project-type.selectors.spec.ts @@ -0,0 +1,28 @@ +import * as selectors from './project-type.selectors'; +import { ProjectType } from '../../../../shared/models/project-type.model'; +describe('ProjectTypeSelectors', () => { + it('should select allProjectTypes', () => { + const projectType = [{ id: 'id', name: 'abc', description: 'xxx' }]; + const projectTypeState = { data: projectType }; + + expect(selectors.allProjectTypes.projector(projectTypeState)).toBe(projectType); + }); + + it('should select projectTypeIdToEdit', () => { + const projectType = 'projectTypeId'; + const projectTypeState = { projectTypeIdToEdit: projectType }; + + expect(selectors.projectTypeIdToEdit.projector(projectTypeState)).toBe(projectType); + }); + + it('should select getProjectTypeById', () => { + const projectTypes = [ + { id: 'id', name: 'abc', description: 'xxx' }, + { id: 'id2', name: 'abc2', description: 'xxx' }, + ]; + const projectTypeId = 'id'; + const projectTypeExpect = { id: 'id', name: 'abc', description: 'xxx' }; + + expect(selectors.getProjectTypeById.projector(projectTypes, projectTypeId)).toEqual(projectTypeExpect); + }); +}); diff --git a/src/app/modules/customer-management/components/projects/components/store/project.effects.spec.ts b/src/app/modules/customer-management/components/projects/components/store/project.effects.spec.ts new file mode 100644 index 000000000..1b689ff14 --- /dev/null +++ b/src/app/modules/customer-management/components/projects/components/store/project.effects.spec.ts @@ -0,0 +1,149 @@ +import { Project } from '../../../../../shared/models/project.model'; +import { TestBed } from '@angular/core/testing'; +import { provideMockActions } from '@ngrx/effects/testing'; +import { Action } from '@ngrx/store'; +import { Observable, of, throwError } from 'rxjs'; +import { ProjectService } from '../services/project.service'; +import { ProjectActionTypes } from './project.actions'; +import { ProjectEffects } from './project.effects'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { ToastrModule, ToastrService } from 'ngx-toastr'; +import { INFO_SAVED_SUCCESSFULLY, INFO_DELETE_SUCCESSFULLY } from '../../../../../shared/messages'; + +describe('ProjectEffects', () => { + let actions$: Observable; + let effects: ProjectEffects; + let service: ProjectService; + let toastrService; + const project: Project = { id: 'id', name: 'name', description: 'descrition' }; + const projects: Project[] = []; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ProjectEffects, provideMockActions(() => actions$)], + imports: [HttpClientTestingModule, ToastrModule.forRoot()], + declarations: [], + }); + effects = TestBed.inject(ProjectEffects); + service = TestBed.inject(ProjectService); + toastrService = TestBed.inject(ToastrService); + }); + + it('SHOULD be created', async () => { + expect(effects).toBeTruthy(); + }); + + it('action type is LOAD_PROJECTS_SUCCESS when service is executed sucessfully', async () => { + actions$ = of({ type: ProjectActionTypes.LOAD_PROJECTS }); + const serviceSpy = spyOn(service, 'getAllProjects'); + serviceSpy.and.returnValue(of(projects)); + + effects.loadProjects$.subscribe((action) => { + expect(action.type).toEqual(ProjectActionTypes.LOAD_PROJECTS_SUCCESS); + }); + }); + + it('action type is LOAD_PROJECTS_FAIL when service fail in execution', async () => { + actions$ = of({ type: ProjectActionTypes.LOAD_PROJECTS }); + const serviceSpy = spyOn(service, 'getAllProjects'); + serviceSpy.and.returnValue(throwError({ error: { message: 'fail!' } })); + spyOn(toastrService, 'error'); + + effects.loadProjects$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(ProjectActionTypes.LOAD_PROJECTS_FAIL); + }); + }); + + it('action type is UPDATE_PROJECT_SUCCESS when service is executed sucessfully', async () => { + actions$ = of({ type: ProjectActionTypes.UPDATE_PROJECT, project }); + spyOn(toastrService, 'success'); + spyOn(service, 'updateProject').and.returnValue(of(project)); + + effects.updateProject$.subscribe((action) => { + expect(toastrService.success).toHaveBeenCalledWith(INFO_SAVED_SUCCESSFULLY); + expect(action.type).toEqual(ProjectActionTypes.UPDATE_PROJECT_SUCCESS); + }); + }); + + it('action type is UPDATE_PROJECT_FAIL when service fail in execution', async () => { + actions$ = of({ type: ProjectActionTypes.UPDATE_PROJECT, project }); + spyOn(toastrService, 'error'); + spyOn(service, 'updateProject').and.returnValue(throwError({ error: { message: 'fail!' } })); + + effects.updateProject$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(ProjectActionTypes.UPDATE_PROJECT_FAIL); + }); + }); + + it('action type is CREATE_PROJECT_SUCCESS when service is executed sucessfully', async () => { + actions$ = of({ type: ProjectActionTypes.CREATE_PROJECT, payload: project }); + spyOn(toastrService, 'success'); + spyOn(service, 'createProject').and.returnValue(of(project)); + + effects.createProject$.subscribe((action) => { + expect(toastrService.success).toHaveBeenCalledWith(INFO_SAVED_SUCCESSFULLY); + expect(action.type).toEqual(ProjectActionTypes.CREATE_PROJECT_SUCCESS); + }); + }); + + it('action type is CREATE_PROJECT_FAIL when service fail in execution', async () => { + actions$ = of({ type: ProjectActionTypes.CREATE_PROJECT, payload: project }); + spyOn(toastrService, 'error'); + spyOn(service, 'createProject').and.returnValue(throwError({ error: { message: 'fail!' } })); + + effects.createProject$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(ProjectActionTypes.CREATE_PROJECT_FAIL); + }); + }); + + it('action type is DELETE_PROJECT_SUCCESS when service is executed sucessfully', async () => { + const projectId = 'projectId'; + actions$ = of({ type: ProjectActionTypes.DELETE_PROJECT, projectId }); + spyOn(toastrService, 'success'); + spyOn(service, 'deleteProject').and.returnValue(of({})); + + effects.deleteProject$.subscribe((action) => { + expect(toastrService.success).toHaveBeenCalledWith(INFO_DELETE_SUCCESSFULLY); + expect(action.type).toEqual(ProjectActionTypes.DELETE_PROJECT_SUCCESS); + }); + }); + + it('action type is DELETE_PROJECT_FAIL when service fail in execution', async () => { + const projectId = 'projectId'; + actions$ = of({ type: ProjectActionTypes.DELETE_PROJECT, projectId }); + spyOn(toastrService, 'error'); + spyOn(service, 'deleteProject').and.returnValue(throwError({ error: { message: 'fail!' } })); + + effects.deleteProject$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(ProjectActionTypes.DELETE_PROJECT_FAIL); + }); + }); + + it('action type is LOAD_CUSTOMER_PROJECTS_SUCCESS when service is executed sucessfully', async () => { + const customerId = 'customerId'; + actions$ = of({ type: ProjectActionTypes.LOAD_CUSTOMER_PROJECTS, payload: customerId}); + const serviceSpy = spyOn(service, 'getProjects'); + serviceSpy.and.returnValue(of(projects)); + + effects.loadCustomerProjects$.subscribe((action) => { + expect(action.type).toEqual(ProjectActionTypes.LOAD_CUSTOMER_PROJECTS_SUCCESS); + }); + }); + + it('action type is LOAD_CUSTOMER_PROJECTS_FAIL when service fail in execution', async () => { + const customerId = 'customerId'; + actions$ = of({ type: ProjectActionTypes.LOAD_CUSTOMER_PROJECTS, payload: customerId }); + const serviceSpy = spyOn(service, 'getProjects'); + serviceSpy.and.returnValue(throwError({ error: { message: 'fail!' } })); + spyOn(toastrService, 'error'); + + effects.loadCustomerProjects$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(ProjectActionTypes.LOAD_CUSTOMER_PROJECTS_FAIL); + }); + }); +}); diff --git a/src/app/modules/customer-management/components/projects/components/store/project.selectors.spec.ts b/src/app/modules/customer-management/components/projects/components/store/project.selectors.spec.ts new file mode 100644 index 000000000..6104c9e3d --- /dev/null +++ b/src/app/modules/customer-management/components/projects/components/store/project.selectors.spec.ts @@ -0,0 +1,39 @@ +import * as selectors from './project.selectors'; + +describe('ProjectSelectors', () => { + it('should select getCustomerProjects', () => { + const projectState = { + projects: [], + customerProjects: [], + isLoading: true, + message: '', + projectToEdit: { id: 'id', name: 'abc', description: 'xxx' }, + }; + + expect(selectors.getCustomerProjects.projector(projectState)).toBe(projectState); + }); + + it('should select getProjects', () => { + const project = [ + { id: 'id', name: 'abc', description: 'xxx' }, + { id: 'id', name: 'abc', description: 'xxx' }, + ]; + const projectState = { projects: project }; + + expect(selectors.getProjects.projector(projectState)).toBe(project); + }); + + it('should select getProjectsToEdit', () => { + const project = { id: 'id', name: 'abc', description: 'xxx' }; + const projectState = { projectToEdit: project }; + + expect(selectors.getProjectToEdit.projector(projectState)).toBe(project); + }); + + it('should select getIsLoading', () => { + const isLoadingValue = true; + const projectState = { isLoading: isLoadingValue }; + + expect(selectors.getIsLoading.projector(projectState)).toBe(isLoadingValue); + }); +}); diff --git a/src/app/modules/customer-management/store/customer-management.effects.spec.ts b/src/app/modules/customer-management/store/customer-management.effects.spec.ts new file mode 100644 index 000000000..bd1167996 --- /dev/null +++ b/src/app/modules/customer-management/store/customer-management.effects.spec.ts @@ -0,0 +1,124 @@ +import { Customer } from '../../shared/models/customer.model'; +import { TestBed } from '@angular/core/testing'; +import { provideMockActions } from '@ngrx/effects/testing'; +import { Action } from '@ngrx/store'; +import { Observable, of, throwError } from 'rxjs'; +import { CustomerService } from '../services/customer.service'; +import { CustomerManagementActionTypes } from './customer-management.actions'; +import { CustomerEffects } from './customer-management.effects'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { ToastrModule, ToastrService } from 'ngx-toastr'; +import { INFO_SAVED_SUCCESSFULLY, INFO_DELETE_SUCCESSFULLY } from '../../shared/messages'; + +describe('CustomerEffects', () => { + let actions$: Observable; + let effects: CustomerEffects; + let service: CustomerService; + let toastrService; + const customer: Customer = { id: 'id', name: 'name', description: 'description' }; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [CustomerEffects, provideMockActions(() => actions$)], + imports: [HttpClientTestingModule, ToastrModule.forRoot()], + declarations: [], + }); + effects = TestBed.inject(CustomerEffects); + service = TestBed.inject(CustomerService); + toastrService = TestBed.inject(ToastrService); + }); + + it('SHOULD be created', async () => { + expect(effects).toBeTruthy(); + }); + + it('action type is LOAD_CUSTOMERS_SUCCESS when service is executed sucessfully', async () => { + actions$ = of({ type: CustomerManagementActionTypes.LOAD_CUSTOMERS }); + const serviceSpy = spyOn(service, 'getCustomers'); + serviceSpy.and.returnValue(of(customer)); + + effects.loadCustomers$.subscribe((action) => { + expect(action.type).toEqual(CustomerManagementActionTypes.LOAD_CUSTOMERS_SUCCESS); + }); + }); + + it('action type is LOAD_CUSTOMERS_FAIL when service fail in execution', async () => { + actions$ = of({ type: CustomerManagementActionTypes.LOAD_CUSTOMERS }); + const serviceSpy = spyOn(service, 'getCustomers'); + serviceSpy.and.returnValue(throwError({ error: { message: 'fail!' } })); + spyOn(toastrService, 'error'); + + effects.loadCustomers$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(CustomerManagementActionTypes.LOAD_CUSTOMERS_FAIL); + }); + }); + + it('action type is UPDATE_CUSTOMERS_SUCCESS when service is executed sucessfully', async () => { + actions$ = of({ type: CustomerManagementActionTypes.UPDATE_CUSTOMER, customer }); + spyOn(toastrService, 'success'); + spyOn(service, 'updateCustomer').and.returnValue(of(customer)); + + effects.updateCustomer$.subscribe((action) => { + expect(toastrService.success).toHaveBeenCalledWith(INFO_SAVED_SUCCESSFULLY); + expect(action.type).toEqual(CustomerManagementActionTypes.UPDATE_CUSTOMER_SUCCESS); + }); + }); + + it('action type is UPDATE_CUSTOMERS_FAIL when service fail in execution', async () => { + actions$ = of({ type: CustomerManagementActionTypes.UPDATE_CUSTOMER, customer }); + spyOn(toastrService, 'error'); + spyOn(service, 'updateCustomer').and.returnValue(throwError({ error: { message: 'fail!' } })); + + effects.updateCustomer$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(CustomerManagementActionTypes.UPDATE_CUSTOMER_FAIL); + }); + }); + + it('action type is CREATE_CUSTOMER_SUCCESS when service is executed sucessfully', async () => { + actions$ = of({ type: CustomerManagementActionTypes.CREATE_CUSTOMER, payload: customer }); + spyOn(toastrService, 'success'); + spyOn(service, 'createCustomer').and.returnValue(of(customer)); + + effects.createCustomer$.subscribe((action) => { + expect(toastrService.success).toHaveBeenCalledWith(INFO_SAVED_SUCCESSFULLY); + expect(action.type).toEqual(CustomerManagementActionTypes.CREATE_CUSTOMER_SUCCESS); + }); + }); + + it('action type is CREATE_CUSTOMER_FAIL when service fail in execution', async () => { + actions$ = of({ type: CustomerManagementActionTypes.CREATE_CUSTOMER, payload: customer }); + spyOn(toastrService, 'error'); + spyOn(service, 'createCustomer').and.returnValue(throwError({ error: { message: 'fail!' } })); + + effects.createCustomer$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(CustomerManagementActionTypes.CREATE_CUSTOMER_FAIL); + }); + }); + + it('action type is DELETE_CUSTOMER_SUCCESS when service is executed sucessfully', async () => { + const customerId = 'customerId'; + actions$ = of({ type: CustomerManagementActionTypes.DELETE_CUSTOMER, customerId }); + spyOn(toastrService, 'success'); + spyOn(service, 'deleteCustomer').and.returnValue(of({})); + + effects.deleteCustomer$.subscribe((action) => { + expect(toastrService.success).toHaveBeenCalledWith(INFO_DELETE_SUCCESSFULLY); + expect(action.type).toEqual(CustomerManagementActionTypes.DELETE_CUSTOMER_SUCCESS); + }); + }); + + it('action type is DELETE_CUSTOMER_FAIL when service fail in execution', async () => { + const customerId = 'customerId'; + actions$ = of({ type: CustomerManagementActionTypes.DELETE_CUSTOMER, customerId }); + spyOn(toastrService, 'error'); + spyOn(service, 'deleteCustomer').and.returnValue(throwError({ error: { message: 'fail!' } })); + + effects.deleteCustomer$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(CustomerManagementActionTypes.DELETE_CUSTOMER_FAIL); + }); + }); +}); diff --git a/src/app/modules/customer-management/store/customer-management.selectors.spec.ts b/src/app/modules/customer-management/store/customer-management.selectors.spec.ts index b0cbd7c6c..7b0f8326c 100644 --- a/src/app/modules/customer-management/store/customer-management.selectors.spec.ts +++ b/src/app/modules/customer-management/store/customer-management.selectors.spec.ts @@ -25,4 +25,19 @@ describe('Customer selectors', () => { const customerState = { customerId }; expect(selectors.getCustomerId.projector(customerState)).toBe(customerId); }); + + it('should select customerUnderEdition', () => { + const customerId = 'id'; + const customers = [{id: 'id', name: 'abc', description: 'xxx'}, + {id: '2', name: 'xyz', description: 'yyy'}]; + const customerFound = selectors.getCustomerUnderEdition.projector(customers, customerId); + expect(customerFound).toEqual(customers[0]); + }); + + it('should select getIsLoading', () => { + const isLoadingValue = true; + const customerManagementState = { isLoading: isLoadingValue }; + + expect(selectors.getIsLoading.projector(customerManagementState)).toBe(isLoadingValue); + }); }); diff --git a/src/app/modules/shared/store/technology.effects.spec.ts b/src/app/modules/shared/store/technology.effects.spec.ts new file mode 100644 index 000000000..18f239d32 --- /dev/null +++ b/src/app/modules/shared/store/technology.effects.spec.ts @@ -0,0 +1,52 @@ +import { Technology } from '../models/technology.model'; +import { TestBed } from '@angular/core/testing'; +import { provideMockActions } from '@ngrx/effects/testing'; +import { Action } from '@ngrx/store'; +import { Observable, of, throwError } from 'rxjs'; +import { TechnologyService } from '../services/technology.service'; +import { TechnologyActionTypes, FindTechnology } from './technology.actions'; +import { TechnologyEffects } from './technology.effects'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; + +describe('TechnologyEffects', () => { + let actions$: Observable; + let effects: TechnologyEffects; + let service: TechnologyService; + const technology: Technology = { items: ['angular', 'angularjs'] }; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [TechnologyEffects, provideMockActions(() => actions$)], + imports: [HttpClientTestingModule], + declarations: [], + }); + effects = TestBed.inject(TechnologyEffects); + service = TestBed.inject(TechnologyService); + }); + + it('should be created', async () => { + expect(effects).toBeTruthy(); + }); + + it('action type is LOAD_TECHNOLOGIES_SUCCESS when service is executed sucessfully', async () => { + const findTechnology = 'angular'; + actions$ = of(new FindTechnology(findTechnology)); + const serviceSpy = spyOn(service, 'getTechnologies'); + serviceSpy.and.returnValue(of(technology)); + + effects.findTechnology$.subscribe((action) => { + expect(action.type).toEqual(TechnologyActionTypes.FIND_TECHNOLOGIES_SUCESS); + }); + }); + + it('action type is LOAD_TECHNOLOGIES_FAIL when service fail in execution', async () => { + const findTechnology = 'angular'; + actions$ = of(new FindTechnology(findTechnology)); + const serviceSpy = spyOn(service, 'getTechnologies'); + serviceSpy.and.returnValue(throwError({ error: { message: 'fail!' } })); + + effects.findTechnology$.subscribe((action) => { + expect(action.type).toEqual(TechnologyActionTypes.FIND_TECHNOLOGIES_FAIL); + }); + }); +}); diff --git a/src/app/modules/time-clock/store/entry.effects.spec.ts b/src/app/modules/time-clock/store/entry.effects.spec.ts index e1607196c..7b189aa22 100644 --- a/src/app/modules/time-clock/store/entry.effects.spec.ts +++ b/src/app/modules/time-clock/store/entry.effects.spec.ts @@ -261,7 +261,82 @@ describe('TimeEntryActionEffects', () => { }); }); + it('action type is LOAD_ENTRIES_SUCCESS when service is executed sucessfully', async () => { + actions$ = of({ type: EntryActionTypes.LOAD_ENTRIES }); + const serviceSpy = spyOn(service, 'loadEntries'); + serviceSpy.and.returnValue(of(entry)); + + effects.loadEntries$.subscribe((action) => { + expect(action.type).toEqual(EntryActionTypes.LOAD_ENTRIES_SUCCESS); + }); + }); + + it('action type is LOAD_ENTRIES_FAIL when service fail in execution', async () => { + actions$ = of({ type: EntryActionTypes.LOAD_ENTRIES }); + const serviceSpy = spyOn(service, 'loadEntries'); + serviceSpy.and.returnValue(throwError({ error: { message: 'fail!' } })); + spyOn(toastrService, 'warning'); + + effects.loadEntries$.subscribe((action) => { + expect(toastrService.warning).toHaveBeenCalled(); + expect(action.type).toEqual(EntryActionTypes.LOAD_ENTRIES_FAIL); + }); + }); + + it('type is CREATE_ENTRY_SUCCESS when service is executed sucessfully and display a INFO_SAVE_SUCCESS', async () => { + const entryTest: Entry = { project_id: 'p-id', start_date: new Date(), id: 'id', end_date: new Date() }; + actions$ = of({ type: EntryActionTypes.CREATE_ENTRY, payload: entryTest }); + spyOn(toastrService, 'success'); + spyOn(service, 'createEntry').and.returnValue(of(entryTest)); + + effects.createEntry$.subscribe((action) => { + expect(toastrService.success).toHaveBeenCalledWith(INFO_SAVED_SUCCESSFULLY); + expect(action.type).toEqual(EntryActionTypes.CREATE_ENTRY_SUCCESS); + }); + }); + + it('type is CREATE_ENTRY_SUCCESS when service is executed sucessfully and display a clocked In message', async () => { + const entryTest: Entry = { project_id: 'p-id', start_date: new Date(), id: 'id', end_date: null }; + actions$ = of({ type: EntryActionTypes.CREATE_ENTRY, payload: entryTest }); + spyOn(toastrService, 'success'); + spyOn(service, 'createEntry').and.returnValue(of(entryTest)); + + effects.createEntry$.subscribe((action) => { + expect(toastrService.success).toHaveBeenCalledWith('You clocked-in successfully'); + expect(action.type).toEqual(EntryActionTypes.CREATE_ENTRY_SUCCESS); + }); + }); - // TODO Implement the remaining unit tests for the other effects. + it('action type is CREATE_ENTRY_FAIL when service fail in execution', async () => { + actions$ = of({ type: EntryActionTypes.CREATE_ENTRY, payload: entry }); + spyOn(toastrService, 'error'); + spyOn(service, 'createEntry').and.returnValue(throwError({ error: { message: 'fail!' } })); + + effects.createEntry$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(EntryActionTypes.CREATE_ENTRY_FAIL); + }); + }); + + it('action type is STOP_TIME_ENTRY_RUNNING_SUCCESS when service is executed sucessfully and display a clocked Out message', async () => { + actions$ = of({ type: EntryActionTypes.STOP_TIME_ENTRY_RUNNING, payload: entry }); + spyOn(toastrService, 'success'); + spyOn(service, 'stopEntryRunning').and.returnValue(of(entry)); + effects.stopTimeEntryRunning$.subscribe((action) => { + expect(toastrService.success).toHaveBeenCalledWith('You clocked-out successfully'); + expect(action.type).toEqual(EntryActionTypes.STOP_TIME_ENTRY_RUNNING_SUCCESS); + }); + }); + + it('action type is STOP_TIME_ENTRY_RUNNING_FAILED when service fail in execution', async () => { + actions$ = of({ type: EntryActionTypes.STOP_TIME_ENTRY_RUNNING, payload: entry }); + spyOn(toastrService, 'error'); + spyOn(service, 'stopEntryRunning').and.returnValue(throwError({ error: { message: 'fail!' } })); + + effects.stopTimeEntryRunning$.subscribe((action) => { + expect(toastrService.error).toHaveBeenCalled(); + expect(action.type).toEqual(EntryActionTypes.STOP_TIME_ENTRY_RUNNING_FAILED); + }); + }); }); diff --git a/src/app/modules/time-clock/store/entry.selectors.spec.ts b/src/app/modules/time-clock/store/entry.selectors.spec.ts index ab8b4c8c0..d3fa7c708 100644 --- a/src/app/modules/time-clock/store/entry.selectors.spec.ts +++ b/src/app/modules/time-clock/store/entry.selectors.spec.ts @@ -1,3 +1,5 @@ +import { Entry } from '../../shared/models'; +import { TimeDetails, TimeEntriesSummary } from '../models/time.entry.summary'; import * as selectors from './entry.selectors'; describe('Entry selectors', () => { @@ -16,10 +18,38 @@ describe('Entry selectors', () => { }); it('should select the report data source', () => { - const reportDataSource = { isLoading: false, data: []}; + const reportDataSource = { isLoading: false, data: [] }; const entryState = { reportDataSource }; expect(selectors.getReportDataSource.projector(entryState)).toEqual(reportDataSource); }); + it('should select getEntrySummary', () => { + const timeDetails: TimeDetails = { hours: '45', minutes: '45', seconds: '1' }; + const timeEntriesSummaryTest: TimeEntriesSummary = { day: timeDetails, month: timeDetails, week: timeDetails }; + const entryState = { timeEntriesSummary: timeEntriesSummaryTest }; + + expect(selectors.getEntriesSummary.projector(entryState)).toEqual(timeEntriesSummaryTest); + }); + + it('should select getActiveTimeEntry', () => { + const activeEntry: Entry = { start_date: new Date() }; + const entryState = { active: activeEntry }; + + expect(selectors.getActiveTimeEntry.projector(entryState)).toEqual(activeEntry); + }); + + it('should select getCreateError', () => { + const error = true; + const entryState = { createError: error }; + + expect(selectors.getCreateError.projector(entryState)).toEqual(error); + }); + + it('should select getUpdateError', () => { + const error = true; + const entryState = { updateError: error }; + + expect(selectors.getUpdateError.projector(entryState)).toEqual(error); + }); });