Skip to content

Commit 4c2c5f9

Browse files
test: TTL-910 update tests
1 parent 3d36d14 commit 4c2c5f9

File tree

2 files changed

+119
-58
lines changed

2 files changed

+119
-58
lines changed

src/app/modules/reports/components/time-entries-table/time-entries-table.component.spec.ts

Lines changed: 91 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
22
import { MockStore, provideMockStore } from '@ngrx/store/testing';
33
import { DataTablesModule } from 'angular-datatables';
44
import { NgxPaginationModule } from 'ngx-pagination';
5-
import { Entry } from 'src/app/modules/shared/models';
5+
import { Activity, Entry } from 'src/app/modules/shared/models';
66
import { SubstractDatePipe } from 'src/app/modules/shared/pipes/substract-date/substract-date.pipe';
77
import { SubstractDatePipeDisplayAsFloat } from 'src/app/modules/shared/pipes/substract-date-return-float/substract-date-return-float.pipe';
88
import { getReportDataSource, getResultSumEntriesSelected } from 'src/app/modules/time-clock/store/entry.selectors';
@@ -11,6 +11,16 @@ import { TimeEntriesTableComponent } from './time-entries-table.component';
1111
import { TotalHours } from '../../models/total-hours-report';
1212
import { ActionsSubject } from '@ngrx/store';
1313
import { UserActionTypes } from 'src/app/modules/users/store';
14+
import { ProjectActionTypes } from 'src/app/modules/customer-management/components/projects/components/store/project.actions';
15+
import { Project } from 'src/app/modules/shared/models';
16+
import { Customer } from 'src/app/modules/shared/models';
17+
import { SearchUserComponent } from 'src/app/modules/shared/components/search-user/search-user.component';
18+
import { SearchProjectComponent } from 'src/app/modules/shared/components/search-project/search-project.component';
19+
import { SearchActivityComponent } from 'src/app/modules/shared/components/search-activity/search-activity.component';
20+
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
21+
import { MatCheckboxModule } from '@angular/material/checkbox';
22+
import { NgSelectModule } from '@ng-select/ng-select';
23+
import { ActivityManagementActionTypes } from 'src/app/modules/activities-management/store';
1424

1525
describe('Reports Page', () => {
1626
describe('TimeEntriesTableComponent', () => {
@@ -55,13 +65,13 @@ describe('Reports Page', () => {
5565
uri: 'custom uri',
5666
project_id: '123',
5767
project_name: 'Time-Tracker',
58-
}
68+
},
5969
];
6070

6171
const state: EntryState = {
6272
active: timeEntry,
6373
isLoading: false,
64-
resultSumEntriesSelected: new TotalHours(),
74+
resultSumEntriesSelected: new TotalHours(),
6575
message: '',
6676
createError: false,
6777
updateError: false,
@@ -81,25 +91,37 @@ describe('Reports Page', () => {
8191
beforeEach(
8292
waitForAsync(() => {
8393
TestBed.configureTestingModule({
84-
imports: [NgxPaginationModule, DataTablesModule],
85-
declarations: [TimeEntriesTableComponent, SubstractDatePipe, SubstractDatePipeDisplayAsFloat],
94+
imports: [
95+
NgxPaginationModule,
96+
DataTablesModule,
97+
MatCheckboxModule,
98+
NgSelectModule,
99+
FormsModule,
100+
ReactiveFormsModule,
101+
],
102+
declarations: [
103+
TimeEntriesTableComponent,
104+
SubstractDatePipe,
105+
SubstractDatePipeDisplayAsFloat,
106+
SearchUserComponent,
107+
SearchProjectComponent,
108+
SearchActivityComponent,
109+
],
86110
providers: [provideMockStore({ initialState: state }), { provide: ActionsSubject, useValue: actionSub }],
87111
}).compileComponents();
88-
89112
})
90113
);
91114

92-
beforeEach(
93-
() => {
94-
fixture = TestBed.createComponent(TimeEntriesTableComponent);
95-
component = fixture.componentInstance;
96-
store = TestBed.inject(MockStore);
97-
store.setState(state);
98-
getReportDataSourceSelectorMock = (store.overrideSelector(getReportDataSource, state.reportDataSource),
115+
beforeEach(() => {
116+
fixture = TestBed.createComponent(TimeEntriesTableComponent);
117+
component = fixture.componentInstance;
118+
store = TestBed.inject(MockStore);
119+
store.setState(state);
120+
getReportDataSourceSelectorMock =
121+
(store.overrideSelector(getReportDataSource, state.reportDataSource),
99122
store.overrideSelector(getResultSumEntriesSelected, state.resultSumEntriesSelected));
100-
fixture.detectChanges();
101-
}
102-
);
123+
fixture.detectChanges();
124+
});
103125

104126
beforeEach(() => {
105127
row = 0;
@@ -144,11 +166,10 @@ describe('Reports Page', () => {
144166
const params = [
145167
{ url: 'http://example.com', expected_value: true },
146168
{ url: 'https://example.com', expected_value: true },
147-
{ url: 'no-url-example', expected_value: false }
169+
{ url: 'no-url-example', expected_value: false },
148170
];
149171
params.map((param) => {
150172
it(`Given the url ${param.url}, the method isURL should return ${param.expected_value}`, () => {
151-
152173
expect(component.isURL(param.url)).toEqual(param.expected_value);
153174
});
154175
});
@@ -160,50 +181,47 @@ describe('Reports Page', () => {
160181
});
161182

162183
it('when the rerenderDataTable method is called and dtElement and dtInstance are defined, the destroy and next methods are called ',
163-
() => {
164-
spyOn(component.dtTrigger, 'next');
184+
() => {
185+
spyOn(component.dtTrigger, 'next');
165186

166-
component.ngAfterViewInit();
187+
component.ngAfterViewInit();
167188

168-
component.dtElement.dtInstance.then((dtInstance) => {
169-
expect(component.dtTrigger.next).toHaveBeenCalled();
170-
});
189+
component.dtElement.dtInstance.then((dtInstance) => {
190+
expect(component.dtTrigger.next).toHaveBeenCalled();
171191
});
192+
});
172193

173194
it(`When the user method is called, the emit method is called`, () => {
174195
const userId = 'abc123';
175196
spyOn(component.selectedUserId, 'emit');
176197
component.user(userId);
177198
expect(component.selectedUserId.emit).toHaveBeenCalled();
178-
179199
});
180200

181201
it('Should populate the users with the payload from the action executed', () => {
182202
const actionSubject = TestBed.inject(ActionsSubject) as ActionsSubject;
183203
const usersArray = [];
184204
const action = {
185205
type: UserActionTypes.LOAD_USERS_SUCCESS,
186-
payload: usersArray
206+
payload: usersArray,
187207
};
188208

189209
actionSubject.next(action);
190210

191-
192211
expect(component.users).toEqual(usersArray);
193212
});
194213

195214
it('The sum of the data dates is equal to {"hours": 3, "minutes":20,"seconds":0}', () => {
196215
const { hours, minutes, seconds }: TotalHours = component.sumDates(timeEntryList);
197216
expect({ hours, minutes, seconds }).toEqual({ hours: 3, minutes: 20, seconds: 0 });
198-
199217
});
200218

201219
it('the sume of hours of entries selected is equal to {hours:0, minutes:0, seconds:0}', () => {
202220
let checked = true;
203-
let {hours, minutes, seconds}: TotalHours = component.sumHoursEntriesSelected(timeEntryList[0], checked);
221+
let { hours, minutes, seconds }: TotalHours = component.sumHoursEntriesSelected(timeEntryList[0], checked);
204222
checked = false;
205-
({hours, minutes, seconds} = component.sumHoursEntriesSelected(timeEntryList[0], checked));
206-
expect({hours, minutes, seconds}).toEqual({hours: 0, minutes: 0, seconds: 0});
223+
({ hours, minutes, seconds } = component.sumHoursEntriesSelected(timeEntryList[0], checked));
224+
expect({ hours, minutes, seconds }).toEqual({ hours: 0, minutes: 0, seconds: 0 });
207225
});
208226

209227
it('should export data with the correct format', () => {
@@ -228,7 +246,7 @@ describe('Reports Page', () => {
228246
"ng-reflect-ng-for-of": "git"
229247
}--><!--ng-container--><!--bindings={
230248
"ng-reflect-ng-if": "true"
231-
}-->`
249+
}-->`,
232250
];
233251
const dataFormat = [
234252
'<span matripple="" class="mat-ripple mat-checkbox-ripple mat-focus-indicator" ng-reflect-trigger="[object HTMLLabelElement]" ng-reflect-disabled="false" ng-reflect-radius="20" ng-reflect-centered="true" ng-reflect-animation="[object Object]">&nbsp;',
@@ -245,7 +263,7 @@ describe('Reports Page', () => {
245263
'Activity_Name',
246264
' https://ioetec.atlassian.net/browse/CB-115 ',
247265
'',
248-
' git '
266+
' git ',
249267
];
250268

251269
data.forEach((value: any, index) => {
@@ -257,7 +275,7 @@ describe('Reports Page', () => {
257275
it('Should render column header called Time Zone', () => {
258276
const table = document.querySelector('table#time-entries-table');
259277
const tableHeaderElements = Array.from(table.getElementsByTagName('th'));
260-
const tableHeaderTitles = tableHeaderElements.map(element => (element.textContent));
278+
const tableHeaderTitles = tableHeaderElements.map((element) => element.textContent);
261279
expect(tableHeaderTitles).toContain('Time zone');
262280
});
263281

@@ -272,6 +290,45 @@ describe('Reports Page', () => {
272290
expect(cell).toContain('UTC-5');
273291
});
274292

293+
it('Should populate the projects with the payload from the action executed', () => {
294+
const actionSubject = TestBed.inject(ActionsSubject) as ActionsSubject;
295+
const customerObj: Customer = { name: 'name' };
296+
const projectsArray: Project[] = [
297+
{
298+
id: 'test_id',
299+
customer_id: 'customer_id',
300+
customer: customerObj,
301+
name: 'name',
302+
description: 'description',
303+
project_type_id: 'project_type_id',
304+
status: 'active',
305+
},
306+
];
307+
const action = {
308+
type: ProjectActionTypes.LOAD_PROJECTS_SUCCESS,
309+
payload: projectsArray,
310+
};
311+
actionSubject.next(action);
312+
expect(component.projects).toEqual(projectsArray);
313+
});
314+
315+
it('Should populate the activities with the payload from the action executed', () => {
316+
const actionSubject = TestBed.inject(ActionsSubject) as ActionsSubject;
317+
const activitiesArray: Activity[] = [
318+
{
319+
id: 'test_id',
320+
name: 'name',
321+
description: 'description',
322+
status: 'string'
323+
},
324+
];
325+
const action = {
326+
type: ActivityManagementActionTypes.LOAD_ACTIVITIES_SUCCESS,
327+
payload: activitiesArray,
328+
};
329+
actionSubject.next(action);
330+
expect(component.activities).toEqual(activitiesArray);
331+
});
275332

276333
afterEach(() => {
277334
fixture.destroy();

src/app/modules/reports/components/time-range-custom/time-range-custom.component.ts

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
import { formatDate } from '@angular/common';
2-
import {
3-
ChangeDetectionStrategy,
4-
Component,
5-
Input,
6-
OnChanges,
7-
OnInit,
8-
SimpleChanges,
9-
} from '@angular/core';
10-
import {FormGroup, FormControl} from '@angular/forms';
2+
import { ChangeDetectionStrategy, Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
3+
import { FormGroup, FormControl } from '@angular/forms';
114
import { Store } from '@ngrx/store';
125
import * as moment from 'moment';
136
import { ToastrService } from 'ngx-toastr';
@@ -16,7 +9,6 @@ import { DATE_FORMAT } from 'src/environments/environment';
169
import * as entryActions from '../../../time-clock/store/entry.actions';
1710
import { TimeRangeHeaderComponent } from './time-range-header/time-range-header.component';
1811

19-
2012
@Component({
2113
selector: 'app-time-range-custom',
2214
templateUrl: './time-range-custom.component.html',
@@ -33,29 +25,34 @@ export class TimeRangeCustomComponent implements OnInit, OnChanges {
3325
end: new FormControl(null),
3426
});
3527

36-
constructor(private store: Store<EntryState>, private toastrService: ToastrService) {
37-
}
28+
constructor(private store: Store<EntryState>, private toastrService: ToastrService) {}
3829

3930
ngOnInit(): void {
4031
this.setInitialDataOnScreen();
4132
}
4233

43-
ngOnChanges(changes: SimpleChanges){
44-
if (!changes.userId.firstChange){
45-
this.onSubmit();
34+
ngOnChanges(changes: SimpleChanges) {
35+
if (changes.userId) {
36+
if (!changes.userId.firstChange) {
37+
this.onSubmit();
38+
}
4639
}
47-
if (!changes.projectId.firstChange){
48-
this.onSubmit();
40+
if (changes.projectId) {
41+
if (!changes.projectId.firstChange) {
42+
this.onSubmit();
43+
}
4944
}
50-
if (!changes.activityId.firstChange){
51-
this.onSubmit();
45+
if (changes.activityId) {
46+
if (!changes.activityId.firstChange) {
47+
this.onSubmit();
48+
}
5249
}
5350
}
5451

5552
setInitialDataOnScreen() {
5653
this.range.setValue({
5754
start: formatDate(moment().startOf('isoWeek').format('l'), DATE_FORMAT, 'en'),
58-
end: formatDate(moment().format('l'), DATE_FORMAT, 'en')
55+
end: formatDate(moment().format('l'), DATE_FORMAT, 'en'),
5956
});
6057
localStorage.setItem('rangeDatePicker', 'custom');
6158
this.onSubmit();
@@ -67,10 +64,17 @@ export class TimeRangeCustomComponent implements OnInit, OnChanges {
6764
if (endDate.isBefore(startDate)) {
6865
this.toastrService.error('The end date should be after the start date');
6966
} else {
70-
this.store.dispatch(new entryActions.LoadEntriesByTimeRange({
71-
start_date: moment(this.range.getRawValue().start).startOf('day'),
72-
end_date: moment(this.range.getRawValue().end).endOf('day'),
73-
}, this.userId, this.projectId, this.activityId));
67+
this.store.dispatch(
68+
new entryActions.LoadEntriesByTimeRange(
69+
{
70+
start_date: moment(this.range.getRawValue().start).startOf('day'),
71+
end_date: moment(this.range.getRawValue().end).endOf('day'),
72+
},
73+
this.userId,
74+
this.projectId,
75+
this.activityId
76+
)
77+
);
7478
}
7579
}
7680

0 commit comments

Comments
 (0)