Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {FormControl, FormGroup} from '@angular/forms';
import * as entryActions from '../../../time-clock/store/entry.actions';
import {Store} from '@ngrx/store';
import {EntryState} from '../../../time-clock/store/entry.reducer';
import * as moment from 'moment';

@Component({
selector: 'app-time-range-form',
Expand All @@ -22,9 +23,8 @@ export class TimeRangeFormComponent {

onSubmit() {
this.store.dispatch(new entryActions.LoadEntriesByTimeRange({
start_date: this.startDate.value,
end_date: this.endDate.value,
user_id: '*',
start_date: moment(this.startDate.value).startOf('day'),
end_date: moment(this.endDate.value).endOf('day'),
}));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {EntryState} from '../../../time-clock/store/entry.reducer';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {InputDateComponent} from '../../../shared/components/input-date/input-date.component';
import * as entryActions from '../../../time-clock/store/entry.actions';
import * as moment from 'moment';

describe('Reports Page', () => {
describe('TimeRangeFormComponent', () => {
Expand Down Expand Up @@ -54,20 +55,17 @@ describe('Reports Page', () => {
});

it('when submitting form a new LoadEntriesByTimeRange action is triggered', () => {

const startDateValue = new Date();
const endDateValue = new Date();
endDateValue.setMonth(1);
const yesterday = moment(new Date()).subtract(1, 'days');
const today = moment(new Date());
spyOn(store, 'dispatch');
component.reportForm.controls.startDate.setValue(startDateValue);
component.reportForm.controls.endDate.setValue(endDateValue);
component.reportForm.controls.startDate.setValue(yesterday);
component.reportForm.controls.endDate.setValue(today);

component.onSubmit();

expect(store.dispatch).toHaveBeenCalledWith(new entryActions.LoadEntriesByTimeRange({
start_date: startDateValue,
end_date: endDateValue,
user_id: '*',
start_date: yesterday.startOf('day'),
end_date: today.endOf('day')
}));
});

Expand Down
7 changes: 4 additions & 3 deletions src/app/modules/time-clock/models/time-entries-time-range.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Moment} from 'moment';

export interface TimeEntriesTimeRange {
start_date: Date;
end_date: Date;
user_id: string;
start_date: Moment;
end_date: Moment;
}
28 changes: 15 additions & 13 deletions src/app/modules/time-clock/services/entry.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';
import {inject, TestBed} from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { inject, TestBed } from '@angular/core/testing';

import {EntryService} from './entry.service';
import {NewEntry} from '../../shared/models';
import {DatePipe} from '@angular/common';
import {TimeEntriesTimeRange} from '../models/time-entries-time-range';
import { EntryService } from './entry.service';
import { NewEntry } from '../../shared/models';
import { DatePipe } from '@angular/common';
import { TimeEntriesTimeRange } from '../models/time-entries-time-range';
import * as moment from 'moment';

describe('EntryService', () => {
let service: EntryService;
Expand Down Expand Up @@ -89,17 +90,18 @@ describe('EntryService', () => {
});

it('when getting time entries for report, time range should be sent', () => {
const startDateValue = new Date();
const endDateValue = new Date();
const yesterday = moment(new Date()).subtract(1, 'day');
const today = moment(new Date());
const pipe: DatePipe = new DatePipe('en');
const timeRange: TimeEntriesTimeRange = {start_date: startDateValue, end_date: endDateValue, user_id: '*'};
const timeRange: TimeEntriesTimeRange = {start_date: yesterday, end_date: today};
const userId = '123';

service.loadEntriesByTimeRange(timeRange).subscribe();
service.loadEntriesByTimeRange(timeRange, userId).subscribe();

const loadEntryRequest = httpMock.expectOne(req => req.method === 'GET' && req.url === service.baseUrl);

expect(loadEntryRequest.request.params.get('start_date')).toBe(pipe.transform(startDateValue,
expect(loadEntryRequest.request.params.get('start_date')).toBe(pipe.transform(yesterday,
EntryService.TIME_ENTRIES_DATE_TIME_FORMAT));
expect(loadEntryRequest.request.params.get('end_date')).toBe(pipe.transform(endDateValue, EntryService.TIME_ENTRIES_DATE_TIME_FORMAT));
expect(loadEntryRequest.request.params.get('end_date')).toBe(pipe.transform(today, EntryService.TIME_ENTRIES_DATE_TIME_FORMAT));
expect(loadEntryRequest.request.params.get('user_id')).toEqual('123');
});
});
20 changes: 10 additions & 10 deletions src/app/modules/time-clock/services/entry.service.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {TimeEntriesSummary} from '../models/time.entry.summary';
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import { TimeEntriesSummary } from '../models/time.entry.summary';
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import {Observable} from 'rxjs';
import {environment} from './../../../../environments/environment';
import {TimeEntriesTimeRange} from '../models/time-entries-time-range';
import {DatePipe} from '@angular/common';
import { Observable } from 'rxjs';
import { environment } from './../../../../environments/environment';
import { TimeEntriesTimeRange } from '../models/time-entries-time-range';
import { DatePipe } from '@angular/common';

@Injectable({
providedIn: 'root',
Expand All @@ -15,7 +15,7 @@ export class EntryService {
constructor(private http: HttpClient, private datePipe: DatePipe) {
}

static TIME_ENTRIES_DATE_TIME_FORMAT = 'yyyy-MM-ddThh:mm:ssZZZZZ';
static TIME_ENTRIES_DATE_TIME_FORMAT = 'yyyy-MM-ddTHH:mm:ssZZZZZ';
baseUrl = `${environment.timeTrackerApiUrl}/time-entries`;

loadActiveEntry(): Observable<any> {
Expand Down Expand Up @@ -50,13 +50,13 @@ export class EntryService {
return this.http.get<TimeEntriesSummary>(summaryUrl);
}

loadEntriesByTimeRange(range: TimeEntriesTimeRange): Observable<any> {
loadEntriesByTimeRange(range: TimeEntriesTimeRange, userId: string): Observable<any> {
return this.http.get(this.baseUrl,
{
params: {
start_date: this.datePipe.transform(range.start_date, EntryService.TIME_ENTRIES_DATE_TIME_FORMAT),
end_date: this.datePipe.transform(range.end_date, EntryService.TIME_ENTRIES_DATE_TIME_FORMAT),
user_id: range.user_id
user_id: userId
}
}
);
Expand Down
11 changes: 10 additions & 1 deletion src/app/modules/time-clock/store/entry.actions.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import * as actions from './entry.actions';
import * as moment from 'moment';
import { DatePipe } from '@angular/common';
import { TimeEntriesTimeRange } from '../models/time-entries-time-range';

describe('Actions for Entries', () => {

Expand Down Expand Up @@ -83,8 +86,14 @@ describe('Actions for Entries', () => {
});

it('LoadEntriesByTimeRange type is EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE', () => {
const action = new actions.LoadEntriesByTimeRange(null);
const yesterday = moment(new Date()).subtract(1, 'day');
const today = moment(new Date());
const pipe: DatePipe = new DatePipe('en');
const timeRange: TimeEntriesTimeRange = {start_date: yesterday, end_date: today};
const action = new actions.LoadEntriesByTimeRange(timeRange);
expect(action.type).toEqual(actions.EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE);
expect(action.timeRange).toEqual(timeRange);
expect(action.userId).toEqual('*');
});

it('LoadEntriesByTimeRangeSuccess type is EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE_SUCCESS', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/app/modules/time-clock/store/entry.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ export class DefaultEntry implements Action {

export class LoadEntriesByTimeRange implements Action {
public readonly type = EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE;
constructor(readonly timeRange: TimeEntriesTimeRange) {
constructor(readonly timeRange: TimeEntriesTimeRange, readonly userId: string= '*') {
}
}

Expand Down
47 changes: 25 additions & 22 deletions src/app/modules/time-clock/store/entry.effects.spec.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { INFO_SAVED_SUCCESSFULLY } from './../../shared/messages';
import {TestBed} from '@angular/core/testing';
import {provideMockActions} from '@ngrx/effects/testing';
import {EntryEffects} from './entry.effects';
import {Observable, of, throwError} from 'rxjs';
import {HttpClientTestingModule} from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import { provideMockActions } from '@ngrx/effects/testing';
import { EntryEffects } from './entry.effects';
import { Observable, of, throwError } from 'rxjs';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { ToastrModule, ToastrService } from 'ngx-toastr';
import {Action} from '@ngrx/store';
import {DatePipe} from '@angular/common';
import {EntryActionTypes} from './entry.actions';
import {EntryService} from '../services/entry.service';
import {TimeEntriesTimeRange} from '../models/time-entries-time-range';
import { Action } from '@ngrx/store';
import { DatePipe } from '@angular/common';
import { EntryActionTypes } from './entry.actions';
import { EntryService } from '../services/entry.service';
import { TimeEntriesTimeRange } from '../models/time-entries-time-range';
import * as moment from 'moment';

describe('TimeEntryActionEffects', () => {

Expand Down Expand Up @@ -37,7 +38,7 @@ describe('TimeEntryActionEffects', () => {
expect(effects).toBeTruthy();
});

it('returns an action with type LOAD_ENTRIES_SUMMARY_SUCCESS when the service returns a value', () => {
it('returns an action with type LOAD_ENTRIES_SUMMARY_SUCCESS when the service returns a value', () => {
actions$ = of({type: EntryActionTypes.LOAD_ENTRIES_SUMMARY});
const serviceSpy = spyOn(service, 'summary');
serviceSpy.and.returnValue(of({}));
Expand All @@ -47,7 +48,7 @@ describe('TimeEntryActionEffects', () => {
});
});

it('returns an action with type LOAD_ENTRIES_SUMMARY_FAIL when the service fails', () => {
it('returns an action with type LOAD_ENTRIES_SUMMARY_FAIL when the service fails', () => {
actions$ = of({type: EntryActionTypes.LOAD_ENTRIES_SUMMARY});
spyOn(service, 'summary').and.returnValue(throwError('any error'));

Expand All @@ -56,9 +57,10 @@ describe('TimeEntryActionEffects', () => {
});
});

it('When the service returns a value, then LOAD_ENTRIES_BY_TIME_RANGE_SUCCESS should be triggered', () => {
const timeRange: TimeEntriesTimeRange = {start_date: new Date(), end_date: new Date(), user_id: '*' };
actions$ = of({type: EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE, timeRange});
it('When the service returns a value, then LOAD_ENTRIES_BY_TIME_RANGE_SUCCESS should be triggered', () => {
const timeRange: TimeEntriesTimeRange = {start_date: moment(new Date()), end_date: moment(new Date())};
const userId = '*';
actions$ = of({type: EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE, timeRange, userId});
const serviceSpy = spyOn(service, 'loadEntriesByTimeRange');
serviceSpy.and.returnValue(of([]));

Expand All @@ -69,13 +71,14 @@ describe('TimeEntryActionEffects', () => {
});

it('When the service fails, then LOAD_ENTRIES_BY_TIME_RANGE_FAIL should be triggered', async () => {
const timeRange: TimeEntriesTimeRange = {start_date: new Date(), end_date: new Date(), user_id: '*'};
actions$ = of({type: EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE, timeRange});
spyOn(service, 'loadEntriesByTimeRange').and.returnValue(throwError('any error'));
const timeRange: TimeEntriesTimeRange = {start_date: moment(new Date()), end_date: moment(new Date())};
const userId = '*';
actions$ = of({type: EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE, timeRange, userId});
spyOn(service, 'loadEntriesByTimeRange').and.returnValue(throwError('any error'));

effects.loadEntriesByTimeRange$.subscribe(action => {
expect(action.type).toEqual(EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE_FAIL);
});
effects.loadEntriesByTimeRange$.subscribe(action => {
expect(action.type).toEqual(EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE_FAIL);
});
});

it('returns a LOAD_ACTIVE_ENTRY_SUCCESS when the entry that is running it is in the same day', async () => {
Expand All @@ -91,7 +94,7 @@ describe('TimeEntryActionEffects', () => {

it('returns a LOAD_ACTIVE_ENTRY_SUCCESS when the entry that is running it is in the same day', async () => {
const startDateInPast = new Date();
startDateInPast.setDate( startDateInPast.getDate() - 5);
startDateInPast.setDate(startDateInPast.getDate() - 5);
const activeEntry = {start_date: startDateInPast};
actions$ = of({type: EntryActionTypes.LOAD_ACTIVE_ENTRY, activeEntry});
const serviceSpy = spyOn(service, 'loadActiveEntry');
Expand Down
6 changes: 3 additions & 3 deletions src/app/modules/time-clock/store/entry.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,9 @@ export class EntryEffects {
@Effect()
loadEntriesByTimeRange$: Observable<Action> = this.actions$.pipe(
ofType(actions.EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE),
map((action: actions.LoadEntriesByTimeRange) => action.timeRange),
mergeMap((timeRange) =>
this.entryService.loadEntriesByTimeRange(timeRange).pipe(
map((action: actions.LoadEntriesByTimeRange) => action),
mergeMap((action) =>
this.entryService.loadEntriesByTimeRange(action.timeRange, action.userId).pipe(
map((response) => {
return new actions.LoadEntriesByTimeRangeSuccess(response);
}),
Expand Down
6 changes: 3 additions & 3 deletions src/app/modules/time-clock/store/entry.reducer.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {TimeDetails, TimeEntriesSummary} from '../models/time.entry.summary';
import {Entry, NewEntry} from './../../shared/models';
import { TimeDetails, TimeEntriesSummary } from '../models/time.entry.summary';
import { Entry, NewEntry } from './../../shared/models';
import * as actions from './entry.actions';
import {entryReducer, EntryState} from './entry.reducer';
import { entryReducer, EntryState } from './entry.reducer';

describe('entryReducer', () => {

Expand Down