Skip to content
Merged
Next Next commit
fix: TT-106 Syntax correction in the ProjectListHover, EntryFields, T…
…imeClock components and test files
  • Loading branch information
VanessaIniguezG authored and scastillo-jp committed Feb 17, 2021
commit b11035362aefd6d13ea81ae13ae821759135bb5f
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Observable, of } from 'rxjs';
import { LoadActiveEntry, EntryActionTypes, UpdateEntry } from './../../store/entry.actions';
import { ActivityManagementActionTypes } from './../../../activities-management/store/activity-management.actions';
import {waitForAsync, ComponentFixture, TestBed} from '@angular/core/testing';
Expand All @@ -15,6 +16,7 @@ import { formatDate } from '@angular/common';
import { NgxMaterialTimepickerModule } from 'ngx-material-timepicker';
import * as moment from 'moment';
import { DATE_FORMAT_YEAR } from 'src/environments/environment';
import { FeatureManagerService } from 'src/app/modules/shared/feature-toggles/feature-toggle-manager.service';

describe('EntryFieldsComponent', () => {
type Merged = TechnologyState & ProjectState;
Expand All @@ -24,6 +26,7 @@ describe('EntryFieldsComponent', () => {
let mockTechnologySelector;
let mockProjectsSelector;
let entryForm;
let featureManagerService: FeatureManagerService;
const actionSub: ActionsSubject = new ActionsSubject();
const toastrServiceStub = {
error: (message?: string, title?: string, override?: Partial<IndividualConfig>) => { },
Expand Down Expand Up @@ -114,6 +117,7 @@ describe('EntryFieldsComponent', () => {
entryForm = TestBed.inject(FormBuilder);
mockTechnologySelector = store.overrideSelector(allTechnologies, state.technologies);
mockProjectsSelector = store.overrideSelector(getCustomerProjects, state.projects);
featureManagerService = TestBed.inject(FeatureManagerService);
}));

beforeEach(() => {
Expand All @@ -136,8 +140,6 @@ describe('EntryFieldsComponent', () => {

spyOn(component.entryForm, 'patchValue');

component.setDataToUpdate(entry);

expect(component.entryForm.patchValue).toHaveBeenCalledTimes(1);
expect(component.entryForm.patchValue).toHaveBeenCalledWith(
{
Expand All @@ -151,11 +153,22 @@ describe('EntryFieldsComponent', () => {
expect(component.selectedTechnologies).toEqual([]);
});

const exponentialGrowth = [true, false];
exponentialGrowth.map((toggleValue) => {
it(`when FeatureToggle is ${toggleValue} should return true`, () => {
spyOn(featureManagerService, 'isToggleEnabled').and.returnValue(of(toggleValue));
const isFeatureToggleActivated: Promise<boolean> = component.isFeatureToggleActivated();
expect(featureManagerService.isToggleEnabled).toHaveBeenCalled();
isFeatureToggleActivated.then((value) => expect(value).toEqual(toggleValue));
});
});

it('displays error message when the date selected is in the future', () => {
const mockEntry = { ...entry,
start_date : moment().format(DATE_FORMAT_YEAR),
start_hour : moment().format('HH:mm')
};

component.newData = mockEntry;
component.activeEntry = mockEntry ;
component.setDataToUpdate(mockEntry);
Expand Down Expand Up @@ -411,5 +424,4 @@ describe('EntryFieldsComponent', () => {

expect(component.selectedTechnologies).toBe(initialTechnologies);
});

});
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { ActivityManagementActionTypes } from './../../../activities-management/store/activity-management.actions';
import { EntryActionTypes, LoadActiveEntry } from './../../store/entry.actions';
import { filter } from 'rxjs/operators';
import { Component, OnInit } from '@angular/core';
import { filter, map } from 'rxjs/operators';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { Store, ActionsSubject, select } from '@ngrx/store';
import { Activity, NewEntry } from '../../../shared/models';
import { ProjectState } from '../../../customer-management/components/projects/components/store/project.reducer';
import { TechnologyState } from '../../../shared/store/technology.reducers';
import { ActivityState, LoadActivities } from '../../../activities-management/store';
import { FeatureManagerService } from 'src/app/modules/shared/feature-toggles/feature-toggle-manager.service';

import * as entryActions from '../../store/entry.actions';
import { get } from 'lodash';
Expand All @@ -16,6 +17,7 @@ import { ToastrService } from 'ngx-toastr';
import { formatDate } from '@angular/common';
import { getTimeEntriesDataSource } from '../../store/entry.selectors';
import { DATE_FORMAT } from 'src/environments/environment';
import { Subscription } from 'rxjs';

type Merged = TechnologyState & ProjectState & ActivityState;

Expand All @@ -24,16 +26,25 @@ type Merged = TechnologyState & ProjectState & ActivityState;
templateUrl: './entry-fields.component.html',
styleUrls: ['./entry-fields.component.scss'],
})
export class EntryFieldsComponent implements OnInit {
export class EntryFieldsComponent implements OnInit, OnDestroy {
entryForm: FormGroup;
selectedTechnologies: string[] = [];
activities: Activity[] = [];
activeEntry;
newData;
lastEntry;
showTimeInbuttons = false;
loadActivitiesSubscribe: Subscription;
loadActiveEntrySubscribe: Subscription;
actionSetDateSubscribe: Subscription;
loadActivitiesSubject;
loadActiveEntrySubject;
actionSetDateSubject;

exponentialGrowth;

constructor(
private featureManagerService: FeatureManagerService,
private formBuilder: FormBuilder,
private store: Store<Merged>,
private actionsSubject$: ActionsSubject,
Expand All @@ -48,17 +59,20 @@ export class EntryFieldsComponent implements OnInit {
});
}

ngOnInit(): void {

async ngOnInit(): Promise<void> {
this.exponentialGrowth = await this.isFeatureToggleActivated();
this.store.dispatch(new LoadActivities());
this.store.dispatch(new entryActions.LoadEntries(new Date().getMonth() + 1, new Date().getFullYear()));
this.actionsSubject$
this.loadActivitiesSubject = this.actionsSubject$
.pipe(filter((action: any) => action.type === ActivityManagementActionTypes.LOAD_ACTIVITIES_SUCCESS))
.subscribe((action) => {
this.activities = action.payload;
this.store.dispatch(new LoadActiveEntry());
});

this.actionsSubject$
// tslint:disable-next-line
this.exponentialGrowth ? this.loadActivitiesSubscribe = this.loadActivitiesSubject : this.loadActivitiesSubject;
this.loadActiveEntrySubject = this.actionsSubject$
.pipe(
filter(
(action: any) =>
Expand All @@ -76,8 +90,9 @@ export class EntryFieldsComponent implements OnInit {
this.store.dispatch(new entryActions.LoadEntriesSummary());
}
});

this.actionsSubject$
// tslint:disable-next-line
this.exponentialGrowth ? this.loadActiveEntrySubscribe = this.loadActiveEntrySubject : this.loadActiveEntrySubject;
this.actionSetDateSubject = this.actionsSubject$
.pipe(filter((action: any) => action.type === EntryActionTypes.LOAD_ACTIVE_ENTRY_SUCCESS))
.subscribe((action) => {
this.activeEntry = action.payload;
Expand All @@ -90,17 +105,16 @@ export class EntryFieldsComponent implements OnInit {
start_date: this.activeEntry.start_date,
start_hour: formatDate(this.activeEntry.start_date, 'HH:mm', 'en'),
};
});
});
// tslint:disable-next-line
this.exponentialGrowth ? this.actionSetDateSubscribe = this.actionSetDateSubject : this.actionSetDateSubject;
}

get activity_id() {
return this.entryForm.get('activity_id');
}

get start_hour() {
return this.entryForm.get('start_hour');
}

setDataToUpdate(entryData: NewEntry) {
if (entryData) {
this.entryForm.patchValue({
Expand Down Expand Up @@ -174,4 +188,22 @@ export class EntryFieldsComponent implements OnInit {
onTechnologyRemoved($event: string[]) {
this.store.dispatch(new entryActions.UpdateEntryRunning({ ...this.newData, technologies: $event }));
}


ngOnDestroy(): void {

if (this.exponentialGrowth) {
this.loadActivitiesSubscribe.unsubscribe();
this.loadActiveEntrySubscribe.unsubscribe();
this.actionSetDateSubscribe.unsubscribe();
}
}

isFeatureToggleActivated() {
return this.featureManagerService.isToggleEnabledForUser('exponential-growth').pipe(
map((enabled) => {
return enabled === true ? true : false;
})
).toPromise();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { provideMockStore, MockStore } from '@ngrx/store/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { AutocompleteLibModule } from 'angular-ng-autocomplete';
import { Subscription } from 'rxjs';
import { Subscription, of } from 'rxjs';
import { ProjectState } from '../../../customer-management/components/projects/components/store/project.reducer';
import { getCustomerProjects } from '../../../customer-management/components/projects/components/store/project.selectors';
import { FilterProjectPipe } from '../../../shared/pipes';
import { UpdateEntryRunning } from '../../store/entry.actions';
import { ProjectListHoverComponent } from './project-list-hover.component';
import { FeatureManagerService } from 'src/app/modules/shared/feature-toggles/feature-toggle-manager.service';

describe('ProjectListHoverComponent', () => {
let component: ProjectListHoverComponent;
let fixture: ComponentFixture<ProjectListHoverComponent>;
let store: MockStore<ProjectState>;
let mockProjectsSelector;
let featureManagerService: FeatureManagerService;
const toastrServiceStub = {
error: (message?: string, title?: string, override?: Partial<IndividualConfig>) => { }
};
Expand Down Expand Up @@ -56,6 +58,7 @@ describe('ProjectListHoverComponent', () => {
fixture = TestBed.createComponent(ProjectListHoverComponent);
component = fixture.componentInstance;
fixture.detectChanges();
featureManagerService = TestBed.inject(FeatureManagerService);
});

it('should create', () => {
Expand Down Expand Up @@ -118,7 +121,15 @@ describe('ProjectListHoverComponent', () => {
.toHaveBeenCalledWith({ project_id: 'customer - xyz'});
});


const exponentialGrowth = [true, false];
exponentialGrowth.map((toggleValue) => {
it(`when FeatureToggle is ${toggleValue} should return true`, () => {
spyOn(featureManagerService, 'isToggleEnabled').and.returnValue(of(toggleValue));
const isFeatureToggleActivated: Promise<boolean> = component.isFeatureToggleActivated();
expect(featureManagerService.isToggleEnabled).toHaveBeenCalled();
isFeatureToggleActivated.then((value) => expect(value).toEqual(toggleValue));
});
});
// TODO Fix this test since it is throwing this error
// Expected spy dispatch to have been called with:
// [CreateEntry({ payload: Object({ project_id: '1', start_date: '2020-07-27T22:30:26.743Z', timezone_offset: 300 }),
Expand All @@ -140,5 +151,4 @@ describe('ProjectListHoverComponent', () => {
// })
// );
// });

});
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,48 @@ import { FormBuilder, FormGroup } from '@angular/forms';
import { ActionsSubject, select, Store } from '@ngrx/store';
import { ToastrService } from 'ngx-toastr';
import { Observable, Subscription } from 'rxjs';
import { delay, filter } from 'rxjs/operators';
import { delay, filter, map } from 'rxjs/operators';
import { Project } from 'src/app/modules/shared/models';
import * as actions from '../../../customer-management/components/projects/components/store/project.actions';
import { ProjectState } from '../../../customer-management/components/projects/components/store/project.reducer';
import * as entryActions from '../../store/entry.actions';
import { getIsLoading, getProjects } from './../../../customer-management/components/projects/components/store/project.selectors';
import { EntryActionTypes } from './../../store/entry.actions';
import { getActiveTimeEntry } from './../../store/entry.selectors';
import { FeatureManagerService } from 'src/app/modules/shared/feature-toggles/feature-toggle-manager.service';
@Component({
selector: 'app-project-list-hover',
templateUrl: './project-list-hover.component.html',
styleUrls: ['./project-list-hover.component.scss'],
})
export class ProjectListHoverComponent implements OnInit, OnDestroy {

keyword = 'search_field';
listProjects: Project[] = [];
activeEntry;
projectsForm: FormGroup;
showClockIn: boolean;
updateEntrySubscription: Subscription;
isLoading$: Observable<boolean>;
projectsSubscribe: Subscription;
activeEntrySubscribe: Subscription;
projectsSubject;
activeEntrySubject;
exponentialGrowth;

constructor(private formBuilder: FormBuilder, private store: Store<ProjectState>,
constructor(private featureManagerService: FeatureManagerService,
private formBuilder: FormBuilder, private store: Store<ProjectState>,
private actionsSubject$: ActionsSubject, private toastrService: ToastrService) {
this.projectsForm = this.formBuilder.group({ project_id: null, });
this.isLoading$ = this.store.pipe(delay(0), select(getIsLoading));
}

ngOnInit(): void {
async ngOnInit(): Promise<void> {

this.exponentialGrowth = await this.isFeatureToggleActivated();

this.store.dispatch(new actions.LoadProjects());
const projects$ = this.store.pipe(select(getProjects));
projects$.subscribe((projects) => {
this.projectsSubject = projects$.subscribe((projects) => {
this.listProjects = [];
projects.forEach((project) => {
const projectWithSearchField = {...project};
Expand All @@ -45,7 +54,8 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy {
);
this.loadActiveTimeEntry();
});

// tslint:disable-next-line
this.exponentialGrowth ? this.projectsSubscribe = this.projectsSubject : this.projectsSubject;
this.updateEntrySubscription = this.actionsSubject$.pipe(
filter((action: any) => (
action.type === EntryActionTypes.UPDATE_ENTRY_SUCCESS
Expand All @@ -61,7 +71,7 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy {
loadActiveTimeEntry() {
this.store.dispatch(new entryActions.LoadActiveEntry());
const activeEntry$ = this.store.pipe(select(getActiveTimeEntry));
activeEntry$.subscribe((activeEntry) => {
this.activeEntrySubject = activeEntry$.subscribe((activeEntry) => {
this.activeEntry = activeEntry;
if (activeEntry) {
this.showClockIn = false;
Expand All @@ -71,8 +81,9 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy {
this.projectsForm.setValue({ project_id: null });
}
});
// tslint:disable-next-line
this.exponentialGrowth ? this.activeEntrySubscribe = this.activeEntrySubject : this.activeEntrySubject;
}

setSelectedProject() {
this.listProjects.forEach( (project) => {
if (project.id === this.activeEntry.project_id) {
Expand Down Expand Up @@ -110,6 +121,18 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy {
}

ngOnDestroy(): void {
if (this.exponentialGrowth) {
this.projectsSubscribe.unsubscribe();
this.activeEntrySubscribe.unsubscribe();
}
this.updateEntrySubscription.unsubscribe();
}

isFeatureToggleActivated() {
return this.featureManagerService.isToggleEnabledForUser('exponential-growth').pipe(
map((enabled) => {
return enabled === true ? true : false;
})
).toPromise();
}
}
14 changes: 14 additions & 0 deletions src/app/modules/time-clock/pages/time-clock.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { of } from 'rxjs';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check if is using of?

import { FormBuilder } from '@angular/forms';
import { StopTimeEntryRunning, EntryActionTypes, LoadEntriesSummary } from './../store/entry.actions';
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
Expand All @@ -11,12 +12,14 @@ import { AzureAdB2CService } from '../../login/services/azure.ad.b2c.service';
import { ActionsSubject } from '@ngrx/store';
import { EntryFieldsComponent } from '../components/entry-fields/entry-fields.component';
import { ToastrService } from 'ngx-toastr';
import { FeatureManagerService } from 'src/app/modules/shared/feature-toggles/feature-toggle-manager.service';

describe('TimeClockComponent', () => {
let component: TimeClockComponent;
let fixture: ComponentFixture<TimeClockComponent>;
let store: MockStore<ProjectState>;
let azureAdB2CService: AzureAdB2CService;
let featureManagerService: FeatureManagerService;
const actionSub: ActionsSubject = new ActionsSubject();

let injectedToastrService;
Expand Down Expand Up @@ -69,6 +72,7 @@ describe('TimeClockComponent', () => {
fixture.detectChanges();
azureAdB2CService = TestBed.inject(AzureAdB2CService);
injectedToastrService = TestBed.inject(ToastrService);
featureManagerService = TestBed.inject(FeatureManagerService);
});

it('should be created', () => {
Expand Down Expand Up @@ -142,4 +146,14 @@ describe('TimeClockComponent', () => {

expect(injectedToastrService.error).toHaveBeenCalled();
});

const exponentialGrowth = [true, false];
exponentialGrowth.map((toggleValue) => {
it(`when FeatureToggle is ${toggleValue} should return true`, () => {
spyOn(featureManagerService, 'isToggleEnabled').and.returnValue(of(toggleValue));
const isFeatureToggleActivated: Promise<boolean> = component.isFeatureToggleActivated();
expect(featureManagerService.isToggleEnabled).toHaveBeenCalled();
isFeatureToggleActivated.then((value) => expect(value).toEqual(toggleValue));
});
});
});
Loading