diff --git a/src/app/modules/activities-management/store/activity-management.actions.ts b/src/app/modules/activities-management/store/activity-management.actions.ts index 95094b412..bf69a3c31 100644 --- a/src/app/modules/activities-management/store/activity-management.actions.ts +++ b/src/app/modules/activities-management/store/activity-management.actions.ts @@ -20,6 +20,7 @@ export enum ActivityManagementActionTypes { UNARCHIVE_ACTIVITY_FAIL = '[ActivityManagement] UNARCHIVE_ACTIVITY_FAIL', SET_ACTIVITY_ID_TO_EDIT = '[ActivityManagement] SET_ACTIVITY_ID_TO_EDIT', RESET_ACTIVITY_ID_TO_EDIT = '[ActivityManagement] RESET_ACTIVITY_ID_TO_EDIT', + DEFAULT_ACTIVITY = '[ActivityManagement] DEFAULT_ACTIVITY', } export class LoadActivities implements Action { @@ -118,6 +119,10 @@ export class ResetActivityToEdit implements Action { public readonly type = ActivityManagementActionTypes.RESET_ACTIVITY_ID_TO_EDIT; } +export class DefaultActivities implements Action { + public readonly type = ActivityManagementActionTypes.DEFAULT_ACTIVITY; +} + export type ActivityManagementActions = | LoadActivities | LoadActivitiesSuccess @@ -135,4 +140,5 @@ export type ActivityManagementActions = | UnarchiveActivitySuccess | UnarchiveActivityFail | SetActivityToEdit - | ResetActivityToEdit; + | ResetActivityToEdit + | DefaultActivities; diff --git a/src/app/modules/activities-management/store/activity-management.reducers.spec.ts b/src/app/modules/activities-management/store/activity-management.reducers.spec.ts index 7da4d4419..560e063a4 100644 --- a/src/app/modules/activities-management/store/activity-management.reducers.spec.ts +++ b/src/app/modules/activities-management/store/activity-management.reducers.spec.ts @@ -142,4 +142,25 @@ describe('activityManagementReducer', () => { expect(state.message).toEqual('Something went wrong unarchiving activities!'); expect(state.isLoading).toBeFalse(); }); + + it('on SetActivityidToEdit, message equal to \"Set activityIdToEdit property\"', () => { + const action = new actions.SetActivityToEdit('1'); + const state = activityManagementReducer(initialState, action); + expect(state.message).toEqual('Set activityIdToEdit property'); + expect(state.isLoading).toBeFalse(); + }); + + it('on ResetActivityIdToEdit, message equal to \"Reset activityIdToEdit property\"', () => { + const action = new actions.ResetActivityToEdit(); + const state = activityManagementReducer(initialState, action); + expect(state.message).toEqual('Reset activityIdToEdit property'); + expect(state.isLoading).toBeFalse(); + }); + + it('on DefaultAction, state equal to initial state', () => { + const action = new actions.DefaultActivities(); + const state = activityManagementReducer(initialState, action); + expect(state.data).toEqual(initialState.data); + }); + }); diff --git a/src/app/modules/customer-management/components/management-customer-projects/management-customer-projects.component.spec.ts b/src/app/modules/customer-management/components/management-customer-projects/management-customer-projects.component.spec.ts index 90618e4ee..3668b3a1d 100644 --- a/src/app/modules/customer-management/components/management-customer-projects/management-customer-projects.component.spec.ts +++ b/src/app/modules/customer-management/components/management-customer-projects/management-customer-projects.component.spec.ts @@ -3,6 +3,7 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { ManagementCustomerProjectsComponent } from './management-customer-projects.component'; import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { CustomerState } from '../../store'; +import { of } from 'rxjs'; describe('ManagmentCustomerProjectsComponent', () => { let component: ManagementCustomerProjectsComponent; @@ -38,6 +39,18 @@ describe('ManagmentCustomerProjectsComponent', () => { expect(component).toBeTruthy(); }); + it('set customerName on ngOnInit', () => { + spyOn(store, 'dispatch'); + spyOn(store, 'pipe').and.returnValue(of({ + id: 1, + name: 'project 4', + description: 'project 1 to test methos projectss', + status: 'inactive' + })); + component.ngOnInit(); + expect(component.customerName).toEqual('project 4'); + }); + it('should be enable tabs', () => { component.areTabsActive = false; component.activeTabs(true); diff --git a/src/app/modules/customer-management/components/projects-type/components/project-type-list/project-type-list.component.spec.ts b/src/app/modules/customer-management/components/projects-type/components/project-type-list/project-type-list.component.spec.ts index e6b23b93f..beaac1a18 100644 --- a/src/app/modules/customer-management/components/projects-type/components/project-type-list/project-type-list.component.spec.ts +++ b/src/app/modules/customer-management/components/projects-type/components/project-type-list/project-type-list.component.spec.ts @@ -5,6 +5,7 @@ import { NgxPaginationModule } from 'ngx-pagination'; import { DeleteProjectType, SetProjectTypeToEdit } from './../../store/project-type.actions'; import { allProjectTypes, ProjectTypeState } from '../../store'; import { ProjectTypeListComponent } from './project-type-list.component'; +import { ProjectType } from 'src/app/modules/shared/models'; describe('ProjectTypeTableListComponent', () => { let component: ProjectTypeListComponent; @@ -68,4 +69,16 @@ describe('ProjectTypeTableListComponent', () => { expect(store.dispatch).toHaveBeenCalledWith(new SetProjectTypeToEdit('id')); }); + it('open the modal with the correct parameters', () => { + const item: ProjectType = { + id: `1`, + name: `Project 1`, + description: `Description project 1` + }; + component.openModal(item); + expect(component.idToDelete).toEqual(item.id); + expect(component.message).toEqual(`Are you sure you want to delete ${item.name}?`); + expect(component.showModal).toBe(true); + }); + }); diff --git a/src/app/modules/customer-management/components/projects-type/store/project-type.reducers.spec.ts b/src/app/modules/customer-management/components/projects-type/store/project-type.reducers.spec.ts index e87804249..b46d0fe2c 100644 --- a/src/app/modules/customer-management/components/projects-type/store/project-type.reducers.spec.ts +++ b/src/app/modules/customer-management/components/projects-type/store/project-type.reducers.spec.ts @@ -6,7 +6,7 @@ describe('projectTypeReducer', () => { const initialState: ProjectTypeState = { data: [], isLoading: false, message: '', projectTypeIdToEdit: '' }; const projectType: ProjectType = { id: '1', name: 'Training', description: 'It is good for learning' }; - it('on Default, ', () => { + it('on DefaultAction, state equal to initial state', () => { const action = new actions.DefaultProjectTypes(); const state = projectTypeReducer(initialState, action); expect(state.data).toEqual(initialState.data); diff --git a/src/app/modules/customer-management/components/projects/components/services/project.service.spec.ts b/src/app/modules/customer-management/components/projects/components/services/project.service.spec.ts index 496867eef..f1fd70831 100644 --- a/src/app/modules/customer-management/components/projects/components/services/project.service.spec.ts +++ b/src/app/modules/customer-management/components/projects/components/services/project.service.spec.ts @@ -48,6 +48,16 @@ describe('ProjectService', () => { } )); + it('all projects are read using GET from url', () => { + const projectsFoundSize = projectsList.length; + service.getAllProjects().subscribe((projectsInResponse) => { + expect(projectsInResponse.length).toBe(projectsFoundSize); + }); + const getProjectsRequest = httpMock.expectOne(service.url); + expect(getProjectsRequest.request.method).toBe('GET'); + getProjectsRequest.flush(projectsList); + }); + it('projects are read using GET from url', () => { const projectsFoundSize = projectsList.length; service.url = '/projects'; diff --git a/src/app/modules/customer-management/components/projects/components/store/project.actions.ts b/src/app/modules/customer-management/components/projects/components/store/project.actions.ts index d0c26cc24..ef75d7efe 100644 --- a/src/app/modules/customer-management/components/projects/components/store/project.actions.ts +++ b/src/app/modules/customer-management/components/projects/components/store/project.actions.ts @@ -25,6 +25,7 @@ export enum ProjectActionTypes { UNARCHIVE_PROJECT = '[Projects] UNARCHIVE_PROJECT', UNARCHIVE_PROJECT_SUCCESS = '[Projects] UNARCHIVE_PROJECT_SUCCESS', UNARCHIVE_PROJECT_FAIL = '[Projects] UNARCHIVE_PROJECT_FAIL', + DEFAULT_PROJECT = '[Projects] DEFAULT_PROJECTS', } export class CleanCustomerProjects implements Action { @@ -154,6 +155,10 @@ export class UnarchiveProjectFail implements Action { constructor(public error: string) {} } +export class DefaultProjects implements Action { + public readonly type = ProjectActionTypes.DEFAULT_PROJECT; +} + export type ProjectActions = | CleanCustomerProjects | LoadProjects @@ -177,4 +182,5 @@ export type ProjectActions = | DeleteProjectFail | UnarchiveProject | UnarchiveProjectSuccess - | UnarchiveProjectFail; + | UnarchiveProjectFail + | DefaultProjects; diff --git a/src/app/modules/customer-management/components/projects/components/store/project.reducer.spec.ts b/src/app/modules/customer-management/components/projects/components/store/project.reducer.spec.ts index cf387017a..4e3cda813 100644 --- a/src/app/modules/customer-management/components/projects/components/store/project.reducer.spec.ts +++ b/src/app/modules/customer-management/components/projects/components/store/project.reducer.spec.ts @@ -22,6 +22,26 @@ describe('projectReducer', () => { }); it('on LoadProjects, isLoading is true', () => { + const action = new actions.LoadProjects(); + const state = projectReducer(initialState, action); + expect(state.isLoading).toEqual(true); + }); + + it('on LoadProjectsSucces, projectsFound are saved in the store', () => { + const projectsFound: Project[] = [project]; + const action = new actions.LoadProjectsSuccess(projectsFound); + const state = projectReducer(initialState, action); + expect(action.payload).toEqual([project]); + expect(state.isLoading).toEqual(false); + }); + + it('on LoadProjectsFail, loadProject equal []', () => { + const action = new actions.LoadProjectsFail('error'); + const state = projectReducer(initialState, action); + expect(state.isLoading).toEqual(false); + }); + + it('on LoadCustomerProjects, isLoading is true', () => { const action = new actions.LoadCustomerProjects('1'); const state = projectReducer(initialState, action); expect(state.isLoading).toEqual(true); @@ -201,4 +221,11 @@ describe('projectReducer', () => { expect(state.message).toEqual('Something went wrong unarchiving projects!'); expect(state.isLoading).toEqual(false); }); + + it('on DefaultAction, state equal to initial state', () => { + const action = new actions.DefaultProjects(); + const state = projectReducer(initialState, action); + expect(state).toEqual(initialState); + }); + }); diff --git a/src/app/modules/customer-management/store/customer-management.actions.ts b/src/app/modules/customer-management/store/customer-management.actions.ts index 2dc9ff43d..dc7a6c100 100644 --- a/src/app/modules/customer-management/store/customer-management.actions.ts +++ b/src/app/modules/customer-management/store/customer-management.actions.ts @@ -19,6 +19,7 @@ export enum CustomerManagementActionTypes { UNARCHIVE_CUSTOMER = '[CustomerManagement] UNARCHIVE_CUSTOMER', UNARCHIVE_CUSTOMER_SUCCESS = '[CustomerManagement] UNARCHIVE_CUSTOMER_SUCCESS', UNARCHIVE_CUSTOMER_FAIL = '[CustomerManagement] UNARCHIVE_CUSTOMER_FAIL', + DEFAULT_CUSTOMER = '[CustomerManagement] DEFAULT_CUSTOMER', } export class LoadCustomers implements Action { @@ -118,6 +119,10 @@ export class UnarchiveCustomerFail implements Action { constructor(public error: string) {} } +export class DefaultCustomer implements Action { + public readonly type = CustomerManagementActionTypes.DEFAULT_CUSTOMER; +} + export type CustomerManagementActions = | CreateCustomer | CreateCustomerSuccess @@ -135,4 +140,5 @@ export type CustomerManagementActions = | ResetCustomerToEdit | UnarchiveCustomer | UnarchiveCustomerSuccess - | UnarchiveCustomerFail; + | UnarchiveCustomerFail + | DefaultCustomer; diff --git a/src/app/modules/customer-management/store/customer-management.reducers.spec.ts b/src/app/modules/customer-management/store/customer-management.reducers.spec.ts index e662e6277..7dd8911ff 100644 --- a/src/app/modules/customer-management/store/customer-management.reducers.spec.ts +++ b/src/app/modules/customer-management/store/customer-management.reducers.spec.ts @@ -166,4 +166,10 @@ describe('customerManagementReducer', () => { expect(state.message).toEqual('Something went wrong unarchiving customer!'); expect(state.isLoading).toEqual(false); }); + + it('on DefaultAction, state equal to initial state', () => { + const action = new actions.DefaultCustomer(); + const state = customerManagementReducer(initialState, action); + expect(state.data).toEqual(initialState.data); + }); }); diff --git a/src/app/modules/login/services/azure.ad.b2c.service.spec.ts b/src/app/modules/login/services/azure.ad.b2c.service.spec.ts index 8020c05f9..baf6a364c 100644 --- a/src/app/modules/login/services/azure.ad.b2c.service.spec.ts +++ b/src/app/modules/login/services/azure.ad.b2c.service.spec.ts @@ -21,6 +21,7 @@ describe('AzureAdB2CService', () => { name: 'abc', idToken: { iss: ' http://hostname.com/12345/v0/', + emails: 'abcd' }, idTokenClaims: {}, sid: 'abc', @@ -179,4 +180,10 @@ describe('AzureAdB2CService', () => { expect(UserAgentApplication.prototype.getAccount).toHaveBeenCalled(); }); + + it('should get email', () => { + spyOn(UserAgentApplication.prototype, 'getAccount').and.returnValues(account); + const email = service.getUserEmail(); + expect(email).toEqual('a'); + }); }); diff --git a/src/app/modules/reports/components/time-entries-table/time-entries-table.component.spec.ts b/src/app/modules/reports/components/time-entries-table/time-entries-table.component.spec.ts index 9712a7544..4f7c460f1 100644 --- a/src/app/modules/reports/components/time-entries-table/time-entries-table.component.spec.ts +++ b/src/app/modules/reports/components/time-entries-table/time-entries-table.component.spec.ts @@ -1,5 +1,6 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { MockStore, provideMockStore } from '@ngrx/store/testing'; +import { DataTableDirective } from 'angular-datatables'; import { Entry } from 'src/app/modules/shared/models'; import { SubstractDatePipe } from 'src/app/modules/shared/pipes/substract-date/substract-date.pipe'; import { getReportDataSource } from 'src/app/modules/time-clock/store/entry.selectors'; @@ -134,6 +135,17 @@ describe('Reports Page', () => { expect(component.bodyExportOptions(entry, row, column, node)).toBe('https://TT-392-uri'); }); + it('when the rerenderDataTable method is called and dtElement and dtInstance are defined, the destroy and next methods are called ', + () => { + component.dtElement = { + dtInstance: { + then : (dtInstance: DataTables.Api) => { dtInstance.destroy(); } + } + } as unknown as DataTableDirective; + spyOn(component.dtElement.dtInstance, 'then'); + component.ngAfterViewInit(); + expect(component.dtElement.dtInstance.then).toHaveBeenCalled(); + }); afterEach(() => { fixture.destroy(); diff --git a/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts b/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts index bf029c755..4e452ede8 100644 --- a/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts +++ b/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts @@ -240,7 +240,6 @@ describe('DetailsFieldsComponent', () => { technology: '', }; component.ngOnChanges(); - expect(component.shouldRestartEntry).toBeFalse(); expect(component.entryForm.value).toEqual(formValue); component.activities$.subscribe((item) => { @@ -730,6 +729,27 @@ describe('DetailsFieldsComponent', () => { expect(numberinISOFormat).toBe(expectedISOFormatNumbers[numberIndex]); }); }); + + it('when the user selects technologies, set them in the variable selectedTechnologies', () => { + const techs = ['php', 'angular']; + component.onTechnologiesUpdated(techs); + expect(component.selectedTechnologies).toEqual(techs); + }); + + it('when the user does not select a project, display a warning message.', () => { + spyOn(toastrServiceStub, 'warning'); + component.onclickFormAction(true); + expect(toastrServiceStub.warning).toHaveBeenCalled(); + }); + + it('if entry is set to project_name search_fiend is assigned in entryForm', () => { + const listProjects: Project[] = [{ id: 'id', name: 'abc', status: 'active', search_field: 'name'}]; + component.listProjects = listProjects; + component.entryToEdit = { ...entryToEdit }; + component.ngOnChanges(); + expect(component.entryForm.value.project_name).toBe('name'); + }); + /* TODO As part of https://github.com/ioet/time-tracker-ui/issues/424 a new parameter was added to the details-field-component, and now these couple of tests are failing. A solution to this error might be generate a Test Wrapper Component. More details here: diff --git a/src/app/modules/shared/components/input-date/input-date.component.spec.ts b/src/app/modules/shared/components/input-date/input-date.component.spec.ts index bf8e50de0..f2ccb6753 100644 --- a/src/app/modules/shared/components/input-date/input-date.component.spec.ts +++ b/src/app/modules/shared/components/input-date/input-date.component.spec.ts @@ -37,6 +37,42 @@ describe('InputDateComponent', () => { expect(component.value).toEqual('2020-05-20'); })); + it('it calls the close method if opened equals true', () => { + const datepicker: any = { opened : true, open : () => ({}), close : () => ({}) }; + spyOn(datepicker, 'close'); + component.openOrCloseDatePicker(datepicker); + expect(datepicker.close).toHaveBeenCalled(); + }); + + it('it calls the open method if opened equals false', () => { + const datepicker: any = { opened : false, open : () => ({}), close : () => ({}) }; + spyOn(datepicker, 'open'); + component.openOrCloseDatePicker(datepicker); + expect(datepicker.open).toHaveBeenCalled(); + }); + + it('isDisabled should be true if parameter is true', () => { + component.setDisabledState(true); + expect(component.isDisabled).toBe(true); + }); + + it('isDisabled should be false if parameter is false', () => { + component.setDisabledState(false); + expect(component.isDisabled).toBe(false); + }); + + it(`value should be '' in writeValue function when parameter is null`, () => { + const value: any = null; + component.writeValue(value); + expect(component.value).toEqual(''); + }); + + it(`value should be '' in writeValue function when parameter is not defined`, () => { + const value: any = undefined; + component.writeValue(value); + expect(component.value).toEqual(''); + }); + const params: boolean[] = [true, false]; params.forEach(disable => { it('when the disabled attribute is provided, it should disable the input ', fakeAsync(() => { diff --git a/src/app/modules/shared/feature-toggles/feature-toggles.service.spec.ts b/src/app/modules/shared/feature-toggles/feature-toggles.service.spec.ts index 6f4bac558..e2fa4f7c2 100644 --- a/src/app/modules/shared/feature-toggles/feature-toggles.service.spec.ts +++ b/src/app/modules/shared/feature-toggles/feature-toggles.service.spec.ts @@ -11,29 +11,36 @@ describe('FeatureTogglesService', () => { conditions: null, }; - it('toggles are read using azure configuration client', async () => { - const fakeAppConfigurationConnectionString = 'Endpoint=http://fake.foo;Id=fake.id;Secret=fake.secret'; - const featureToggleKey = 'foo'; - const featureToggleLabel = 'dev'; - const fakeResponse: GetConfigurationSettingResponse = { - isReadOnly: true, - key: featureToggleKey, - _response: { - request: null, - bodyAsText: 'any-response', - headers: null, - parsedHeaders: null, - status: 200 - }, - statusCode: 200, - value: JSON.stringify(anyToggle) - }; - const fakeConfigurationClient = new AppConfigurationClient(fakeAppConfigurationConnectionString); - const fakeGetConfigurationSetting = spyOn(fakeConfigurationClient, 'getConfigurationSetting').and.callFake( - () => of(fakeResponse).toPromise()); + const featureToggleKey = 'foo'; + const featureToggleLabel = 'dev'; - const service = new FeatureTogglesService(fakeConfigurationClient); + const fakeResponse: GetConfigurationSettingResponse = { + isReadOnly: true, + key: featureToggleKey, + _response: { + request: null, + bodyAsText: 'any-response', + headers: null, + parsedHeaders: null, + status: 200 + }, + statusCode: 200, + value: JSON.stringify(anyToggle) + }; + let fakeGetConfigurationSetting; + const fakeAppConfigurationConnectionString = 'Endpoint=http://fake.foo;Id=fake.id;Secret=fake.secret'; + let fakeAppConfigurationClient: any; + let service: FeatureTogglesService; + + beforeEach(() => { + fakeAppConfigurationClient = new AppConfigurationClient(fakeAppConfigurationConnectionString); + service = new FeatureTogglesService(fakeAppConfigurationClient); + fakeGetConfigurationSetting = spyOn(fakeAppConfigurationClient, 'getConfigurationSetting').and.callFake( + () => of(fakeResponse).toPromise()); + }); + + it('toggles are read using azure configuration client', async () => { service.getToggle(featureToggleKey, featureToggleLabel).subscribe((value) => { expect(fakeGetConfigurationSetting).toHaveBeenCalledWith( { key: `.appconfig.featureflag/${featureToggleKey}`, label: featureToggleLabel } @@ -41,4 +48,5 @@ describe('FeatureTogglesService', () => { expect(value).toEqual(anyToggle); }); }); + }); diff --git a/src/app/modules/shared/store/technology.actions.ts b/src/app/modules/shared/store/technology.actions.ts index a2fb2a415..03e06cb09 100644 --- a/src/app/modules/shared/store/technology.actions.ts +++ b/src/app/modules/shared/store/technology.actions.ts @@ -5,6 +5,7 @@ export enum TechnologyActionTypes { FIND_TECHNOLOGIES = '[Technology] FIND_TECHNOLOGIES', FIND_TECHNOLOGIES_SUCESS = '[Technology] FIND_TECHNOLOGIES_SUCESS', FIND_TECHNOLOGIES_FAIL = '[Technology] FIND_TECHNOLOGIES_FAIL ', + DEFAULT_TECHNOLOGIES = '[Technology] DEFAULT_TECHNOLOGY', } export class FindTechnology implements Action { @@ -25,4 +26,8 @@ export class FindTechnologyFail implements Action { constructor(public error: string) {} } -export type TechnologyActions = FindTechnology | FindTechnologySuccess | FindTechnologyFail; +export class DefaultTechnology implements Action { + public readonly type = TechnologyActionTypes.DEFAULT_TECHNOLOGIES; +} + +export type TechnologyActions = FindTechnology | FindTechnologySuccess | FindTechnologyFail | DefaultTechnology; diff --git a/src/app/modules/shared/store/technology.reducers.spec.ts b/src/app/modules/shared/store/technology.reducers.spec.ts index ac274e163..8793c34a4 100644 --- a/src/app/modules/shared/store/technology.reducers.spec.ts +++ b/src/app/modules/shared/store/technology.reducers.spec.ts @@ -23,4 +23,11 @@ describe('technologyReducer', () => { const state = technologyReducer(initialState, action); expect(state.technologyList).toEqual([]); }); + + it('on DefaultAction, state equal to initial state', () => { + const action = new actions.DefaultTechnology(); + const state = technologyReducer(initialState, action); + expect(state).toEqual(initialState); + }); + }); diff --git a/src/app/modules/time-clock/pages/time-clock.component.spec.ts b/src/app/modules/time-clock/pages/time-clock.component.spec.ts index 2a035c6c0..d5dd535fc 100644 --- a/src/app/modules/time-clock/pages/time-clock.component.spec.ts +++ b/src/app/modules/time-clock/pages/time-clock.component.spec.ts @@ -131,6 +131,12 @@ describe('TimeClockComponent', () => { expect(azureAdB2CService.getName).toHaveBeenCalledTimes(0); }); + it('if activeTimeEntry is not defined, areFieldsVisible must be false', () => { + spyOn(store, 'pipe').and.returnValue(of(null)); + component.ngOnInit(); + expect(component.areFieldsVisible).toBe(false); + }); + it('stopEntry dispatch a StopTimeEntryRunning action', () => { spyOn(store, 'dispatch'); 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 6fd6d4f78..27ec9b2d6 100644 --- a/src/app/modules/time-clock/store/entry.effects.spec.ts +++ b/src/app/modules/time-clock/store/entry.effects.spec.ts @@ -155,6 +155,15 @@ describe('TimeEntryActionEffects', () => { }); }); + it('LoadActiveEntryFail if an entry active is not found', async () => { + actions$ = of({ type: EntryActionTypes.LOAD_ACTIVE_ENTRY }); + const serviceSpy = spyOn(service, 'loadActiveEntry'); + serviceSpy.and.returnValue(of(null)); + effects.loadActiveEntry$.subscribe(action => { + expect(action.type).toEqual(EntryActionTypes.LOAD_ACTIVE_ENTRY_FAIL); + }); + }); + it('display a success message on UPDATE_ENTRY', async () => { actions$ = of({ type: EntryActionTypes.UPDATE_ENTRY, entry }); spyOn(toastrService, 'success'); @@ -389,4 +398,5 @@ describe('TimeEntryActionEffects', () => { expect(action.type).toEqual(EntryActionTypes.UPDATE_CURRENT_OR_LAST_ENTRY_FAIL); }); }); + }); diff --git a/src/app/modules/time-clock/store/entry.reducer.spec.ts b/src/app/modules/time-clock/store/entry.reducer.spec.ts index dafce2ee7..447ca1312 100644 --- a/src/app/modules/time-clock/store/entry.reducer.spec.ts +++ b/src/app/modules/time-clock/store/entry.reducer.spec.ts @@ -72,7 +72,7 @@ describe('entryReducer', () => { expect(state.isLoading).toBe(true); }); - it('on Default, ', () => { + it('on DefaultAction, state equal to initial state', () => { const action = new actions.DefaultEntry(); const state = entryReducer(initialState, action); expect(state).toEqual(initialState); @@ -136,6 +136,30 @@ describe('entryReducer', () => { expect(state.isLoading).toEqual(true); }); + it('sort previous entries when a new one is entered', () => { + const newState: EntryState = { ...initialState, timeEntriesDataSource: { + data: [ + { + project_id: '123', + description: 'description', + technologies: ['angular', 'javascript'], + uri: 'uri', + id: 'id', + start_date: new Date(), + end_date: new Date(), + activity_id: 'activity', + project_name: 'time-tracker' + } + ], + isLoading: false, + }}; + const entryCreated: Entry = { ...entry }; + entryCreated.end_date = null; + const action = new actions.CreateEntrySuccess(entryCreated); + const state = entryReducer(newState, action); + expect(state.active).toBe(entryCreated); + }); + it('on CreateEntrySuccess, if end_date is null then it is the active entry', () => { const entryCreated: Entry = { ...entry }; entryCreated.end_date = null; @@ -188,6 +212,28 @@ describe('entryReducer', () => { expect(state.timeEntriesDataSource.data).toEqual([]); }); + it('filter reportDataSource data when one is to be deleted', () => { + const newState: EntryState = { ...initialState, reportDataSource: { + data: [ + { + project_id: '123456', + description: 'description', + technologies: ['angular', 'javascript'], + uri: 'uri', + id: 'id', + start_date: new Date(), + end_date: new Date(), + activity_id: 'activity', + project_name: 'time-tracker' + } + ], + isLoading: false, + }}; + const action = new actions.DeleteEntrySuccess('idxxx'); + const state = entryReducer(newState, action); + expect(state.reportDataSource.data.length).toEqual(1); + }); + it('on LoadEntriesFail, active tobe null', () => { const action = new actions.DeleteEntryFail('error'); const state = entryReducer(initialState, action); @@ -224,6 +270,39 @@ describe('entryReducer', () => { expect(state.isLoading).toEqual(false); }); + it('sort the list of entries when one is updated', () => { + const newState: EntryState = { ...initialState, timeEntriesDataSource: { + data: [ + { + project_id: '123', + description: 'description', + technologies: ['angular', 'javascript'], + uri: 'uri', + id: 'id', + start_date: new Date(), + end_date: new Date(), + activity_id: 'activity', + project_name: 'time-tracker' + }, + { + project_id: '123456', + description: 'description', + technologies: ['angular', 'javascript'], + uri: 'uri', + id: 'id', + start_date: new Date(), + end_date: new Date(), + activity_id: 'activity', + project_name: 'time-tracker' + } + ], + isLoading: false, + }}; + const action = new actions.UpdateEntrySuccess(entry); + const state = entryReducer(newState, action); + expect(state.isLoading).toEqual(false); + }); + it('on cleanEntryCreateError, createError to be null', () => { const action = new actions.CleanEntryCreateError(null); const state = entryReducer(initialState, action); diff --git a/src/app/modules/time-entries/pages/time-entries.component.spec.ts b/src/app/modules/time-entries/pages/time-entries.component.spec.ts index 9b263a500..7c1afcde4 100644 --- a/src/app/modules/time-entries/pages/time-entries.component.spec.ts +++ b/src/app/modules/time-entries/pages/time-entries.component.spec.ts @@ -712,4 +712,50 @@ describe('TimeEntriesComponent', () => { expect(HTMLTimeEntriesView).not.toBeNull(); }); + + it('open the modal with the correct parameters', () => { + const item: any = { + id: `1`, + activity_name: `Activity 1`, + }; + component.openModal(item); + expect(component.idToDelete).toEqual(item.id); + expect(component.message).toEqual(`Are you sure you want to delete ${item.activity_name}?`); + expect(component.showModal).toBe(true); + }); + + it('if there are no entries, the isTheEntryToEditTheLastOne function should return false', () => { + const entries: Entry[] = []; + expect(component.isTheEntryToEditTheLastOne(entries)).toBe(false); + }); + + it('should create new Entry even though the activeEntry overlaps', () => { + component.entryId = 'entry_2'; + const activeEntry = { + id: 'entry_1', + project_id: 'abc', + project_name: 'Time-tracker', + start_date: new Date('2020-02-05T15:36:15.887Z'), + end_date: new Date('2020-02-05T18:36:15.887Z'), + customer_name: 'ioet Inc.', + activity_id: 'development', + technologies: ['Angular', 'TypeScript'], + description: 'No comments', + uri: 'EY-25', + }; + const entryToSave = { + entry: { + project_id: 'project-id', + end_date: '2010-05-05T10:04', + start_date: null, + timezone_offset: 300, + }, + shouldRestartEntry: true + }; + spyOn(component, 'doSave'); + component.activeTimeEntry = activeEntry; + component.saveEntry(entryToSave); + expect(component.doSave).toHaveBeenCalledWith(entryToSave); + }); + }); diff --git a/src/app/modules/time-entries/pages/time-entries.component.ts b/src/app/modules/time-entries/pages/time-entries.component.ts index 49e2648ae..61734da27 100644 --- a/src/app/modules/time-entries/pages/time-entries.component.ts +++ b/src/app/modules/time-entries/pages/time-entries.component.ts @@ -122,7 +122,7 @@ export class TimeEntriesComponent implements OnInit, OnDestroy, AfterViewInit { return false; } } - private isTheEntryToEditTheLastOne(entries: Entry[]) { + public isTheEntryToEditTheLastOne(entries: Entry[]) { if (entries && entries.length > 0) { const lastEntry = entries[0]; return lastEntry.id === this.entryId; diff --git a/src/app/modules/user/store/user.actions.ts b/src/app/modules/user/store/user.actions.ts index b5b5a664b..1543327e7 100644 --- a/src/app/modules/user/store/user.actions.ts +++ b/src/app/modules/user/store/user.actions.ts @@ -5,6 +5,7 @@ export enum UserActionTypes { LOAD_USER = '[User] LOAD_USER', LOAD_USER_SUCCESS = '[User] LOAD_USER_SUCCESS', LOAD_USER_FAIL = '[User] LOAD_USER_FAIL', + DEFAULT_USER = '[User] DEFAULT_USER', } export class LoadUser implements Action { @@ -24,4 +25,8 @@ export class LoadUserFail implements Action { constructor(public error: string) {} } -export type UserActions = LoadUser | LoadUserSuccess | LoadUserFail; +export class DefaultUser implements Action { + public readonly type = UserActionTypes.DEFAULT_USER; +} + +export type UserActions = LoadUser | LoadUserSuccess | LoadUserFail | DefaultUser; diff --git a/src/app/modules/user/store/user.reducer.spec.ts b/src/app/modules/user/store/user.reducer.spec.ts index a73313362..9fadbf2d3 100644 --- a/src/app/modules/user/store/user.reducer.spec.ts +++ b/src/app/modules/user/store/user.reducer.spec.ts @@ -1,5 +1,5 @@ import { userReducer } from './user.reducer'; -import { LoadUser, LoadUserFail, LoadUserSuccess } from './user.actions'; +import { LoadUser, LoadUserFail, LoadUserSuccess, DefaultUser } from './user.actions'; import { User } from '../models/user'; describe('userReducer', () => { @@ -41,4 +41,11 @@ describe('userReducer', () => { expect(state).toEqual(initialState); }); + + it('on DefaultAction, state equal to initial state', () => { + const action = new DefaultUser(); + const state = userReducer(initialState, action); + expect(state).toEqual(initialState); + }); + }); diff --git a/src/app/modules/users/store/user.reducers.spec.ts b/src/app/modules/users/store/user.reducers.spec.ts index 8cc8ffac8..8096f1390 100644 --- a/src/app/modules/users/store/user.reducers.spec.ts +++ b/src/app/modules/users/store/user.reducers.spec.ts @@ -187,7 +187,7 @@ describe('userReducer', () => { expect(state.message).toBe('Something went wrong revoking access role to the user'); }); - it('on Default, ', () => { + it('on DefaultAction, state equal to initial state', () => { const action = new actions.DefaultUser(); const state = userReducer(initialState, action); expect(state).toEqual(initialState);