Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
feat: #204 Adding action, reducers, and selectors required for reports
  • Loading branch information
Juan Gabriel Guzman committed May 29, 2020
commit 5747dc3217170e2d9088ebaef7ddb7b4ff12f5ed
15 changes: 15 additions & 0 deletions src/app/modules/time-clock/store/entry.actions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,19 @@ describe('Actions for Entries', () => {
const updateActiveEntryFail = new actions.UpdateActiveEntryFail('error');
expect(updateActiveEntryFail.type).toEqual(actions.EntryActionTypes.UPDATE_ACTIVE_ENTRY_FAIL);
});

it('LoadEntriesByTimeRange type is EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE', () => {
const action = new actions.LoadEntriesByTimeRange(null);
expect(action.type).toEqual(actions.EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE);
});

it('LoadEntriesByTimeRangeSuccess type is EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE_SUCCESS', () => {
const action = new actions.LoadEntriesByTimeRangeSuccess(null);
expect(action.type).toEqual(actions.EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE_SUCCESS);
});

it('LoadEntriesByTimeRangeFail type is EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE_FAIL', () => {
const action = new actions.LoadEntriesByTimeRangeFail();
expect(action.type).toEqual(actions.EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE_FAIL);
});
});
24 changes: 23 additions & 1 deletion src/app/modules/time-clock/store/entry.actions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { TimeEntriesSummary } from '../models/time.entry.summary';
import { Action } from '@ngrx/store';
import { NewEntry, Entry } from '../../shared/models';
import {TimeEntriesTimeRange} from '../models/time-entries-time-range';

export enum EntryActionTypes {
LOAD_ENTRIES_SUMMARY = '[Entry] LOAD_ENTRIES_SUMMARY',
Expand All @@ -27,6 +28,9 @@ export enum EntryActionTypes {
DEFAULT_ENTRY = '[Entry] DEFAULT_ENTRY',
CLEAN_ENTRY_CREATE_ERROR = '[Entry] CLEAN_ENTRY_CREATE_ERROR',
CLEAN_ENTRY_UPDATE_ERROR = '[Entry] CLEAN_ENTRY_UPDATE_ERROR',
LOAD_ENTRIES_BY_TIME_RANGE = '[Entry] LOAD_ENTRIES_BY_TIME_RANGE',
LOAD_ENTRIES_BY_TIME_RANGE_SUCCESS = '[Entry] LOAD_ENTRIES_BY_TIME_RANGE_SUCCESS',
LOAD_ENTRIES_BY_TIME_RANGE_FAIL = '[Entry] LOAD_ENTRIES_BY_TIME_RANGE_FAIL',
}

export class LoadEntriesSummary implements Action {
Expand Down Expand Up @@ -154,6 +158,21 @@ export class DefaultEntry implements Action {
public readonly type = EntryActionTypes.DEFAULT_ENTRY;
}

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

export class LoadEntriesByTimeRangeSuccess implements Action {
readonly type = EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE_SUCCESS;
constructor(readonly payload: Entry[]) {}
}

export class LoadEntriesByTimeRangeFail implements Action {
readonly type = EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE_FAIL;
}

export type EntryActions =
| LoadEntriesSummary
| LoadEntriesSummarySuccess
Expand All @@ -178,4 +197,7 @@ export type EntryActions =
| StopTimeEntryRunningFail
| CleanEntryCreateError
| CleanEntryUpdateError
| DefaultEntry;
| DefaultEntry
| LoadEntriesByTimeRange
| LoadEntriesByTimeRangeSuccess
| LoadEntriesByTimeRangeFail
77 changes: 67 additions & 10 deletions src/app/modules/time-clock/store/entry.reducer.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { TimeEntriesSummary, TimeDetails } from '../models/time.entry.summary';
import { NewEntry, Entry } from './../../shared/models';
import {TimeEntriesSummary, TimeDetails} from '../models/time.entry.summary';
import {NewEntry, Entry} from './../../shared/models';
import * as actions from './entry.actions';
import { entryReducer, EntryState } from './entry.reducer';
import {entryReducer, EntryState} from './entry.reducer';

describe('entryReducer', () => {

const emptyTimeDetails: TimeDetails = { hours: '--:--', minutes: '--:--', seconds: '--:--' };
const emptyTimeEntriesSummary: TimeEntriesSummary = { day: emptyTimeDetails, week: emptyTimeDetails, month: emptyTimeDetails };
const emptyTimeDetails: TimeDetails = {hours: '--:--', minutes: '--:--', seconds: '--:--'};
const emptyTimeEntriesSummary: TimeEntriesSummary = {day: emptyTimeDetails, week: emptyTimeDetails, month: emptyTimeDetails};


const initialState: EntryState = {
active: null,
Expand All @@ -15,7 +16,8 @@ describe('entryReducer', () => {
message: '',
createError: null,
updateError: null,
timeEntriesSummary: emptyTimeEntriesSummary
timeEntriesSummary: emptyTimeEntriesSummary,
entriesForReport: []
};

const entry: NewEntry = {
Expand All @@ -25,6 +27,19 @@ describe('entryReducer', () => {
technologies: ['angular', 'typescript'],
};

const entryList: Entry[] = [
{
project_id: '123',
comments: 'description',
technologies: ['angular', 'javascript'],
uri: 'uri',
id: 'id',
start_date: new Date(),
end_date: new Date(),
activity_id: 'activity',
}
];

it('sets timeEntriesSummary from action on LOAD_ENTRIES_SUMMARY_SUCCESS', () => {
const payload = null;
const action = new actions.LoadEntriesSummarySuccess(payload);
Expand Down Expand Up @@ -64,7 +79,7 @@ describe('entryReducer', () => {

it('on LoadActiveEntrySuccess, activeEntryFound are saved in the store', () => {
const activeEntryFound: NewEntry[] = [
{ project_id: '123', description: 'description', technologies: ['angular', 'javascript'] , activity_id: 'xyz'},
{project_id: '123', description: 'description', technologies: ['angular', 'javascript'], activity_id: 'xyz'},
];
const action = new actions.LoadActiveEntrySuccess(activeEntryFound);
const state = entryReducer(initialState, action);
Expand Down Expand Up @@ -109,15 +124,15 @@ describe('entryReducer', () => {
});

it('on CreateEntry, isLoading is true', () => {
const entryToCreate: NewEntry = { project_id: '1', start_date: '2020-04-21T19:51:36.559000+00:00' };
const entryToCreate: NewEntry = {project_id: '1', start_date: '2020-04-21T19:51:36.559000+00:00'};
const action = new actions.CreateEntry(entryToCreate);
const state = entryReducer(initialState, action);

expect(state.isLoading).toEqual(true);
});

it('on CreateEntrySuccess, message is updated', () => {
const entryToCreate: NewEntry = { project_id: '1', start_date: '2020-04-21T19:51:36.559000+00:00' };
const entryToCreate: NewEntry = {project_id: '1', start_date: '2020-04-21T19:51:36.559000+00:00'};
const action = new actions.CreateEntrySuccess(entryToCreate);
const state = entryReducer(initialState, action);

Expand Down Expand Up @@ -158,6 +173,8 @@ describe('entryReducer', () => {
message: '',
createError: null,
updateError: null,
entriesForReport: []

};
const action = new actions.DeleteEntrySuccess('id');
const state = entryReducer(currentState, action);
Expand Down Expand Up @@ -196,7 +213,8 @@ describe('entryReducer', () => {
message: '',
createError: null,
updateError: null,
timeEntriesSummary: emptyTimeEntriesSummary
timeEntriesSummary: emptyTimeEntriesSummary,
entriesForReport: []
};
const entryUpdated: Entry = {
id: 'id',
Expand Down Expand Up @@ -257,4 +275,43 @@ describe('entryReducer', () => {

expect(state.isLoading).toBeFalsy();
});

it('sets timeEntriesSummary from action on LOAD_ENTRIES_SUMMARY_SUCCESS', () => {
const payload = null;
const action = new actions.LoadEntriesSummarySuccess(payload);
const state = entryReducer(initialState, action);
expect(state.timeEntriesSummary).toBe(payload);
});

it('sets message on LOAD_ACTIVE_ENTRY_FAIL', () => {
const action = new actions.LoadActiveEntryFail('');
const state = entryReducer(initialState, action);
expect(state.message).toBe('Something went wrong fetching active entry!');
});

it('on LoadEntriesByTimeRange, the state has isLoading is true', () => {
const action = new actions.LoadEntriesByTimeRange(null);

const state = entryReducer(initialState, action);

expect(state.isLoading).toBeTrue();
});

it('on LoadEntriesByTimeRangeSuccess, the entriesForReport is populated with the payload info from the action', () => {
const payload = entryList;
const action = new actions.LoadEntriesByTimeRangeSuccess(payload);

const state = entryReducer(initialState, action);

expect(state.entriesForReport).toEqual(payload);
});

it('on LoadEntriesByTimeRangeFail, the state has isLoading is false and the entriesForReport is an empty array ', () => {
const action = new actions.LoadEntriesByTimeRangeFail();

const state = entryReducer(initialState, action);

expect(state.isLoading).toBeFalse();
expect(state.entriesForReport).toEqual([]);
});
});
23 changes: 23 additions & 0 deletions src/app/modules/time-clock/store/entry.reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface EntryState {
createError: boolean;
updateError: boolean;
timeEntriesSummary: TimeEntriesSummary;
entriesForReport: Entry[];
}

const emptyTimeDetails: TimeDetails = { hours: '--:--', minutes: '--:--', seconds: '--:--' };
Expand All @@ -23,6 +24,7 @@ export const initialState = {
createError: null,
updateError: null,
timeEntriesSummary: emptyTimeEntriesSummary,
entriesForReport: []
};

export const entryReducer = (state: EntryState = initialState, action: EntryActions) => {
Expand Down Expand Up @@ -204,6 +206,27 @@ export const entryReducer = (state: EntryState = initialState, action: EntryActi
};
}

case EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE: {
return {
...state,
isLoading: true,
};
}
case EntryActionTypes.LOAD_ENTRIES_BY_TIME_RANGE_SUCCESS:
return {
...state,
entriesForReport: action.payload,
isLoading: false,
};

case EntryActionTypes.LOAD_ACTIVE_ENTRY_FAIL: {
return {
...state,
entriesForReport: [],
isLoading: false,
};
}

default: {
return state;
}
Expand Down
7 changes: 7 additions & 0 deletions src/app/modules/time-clock/store/entry.selectors.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,11 @@ describe('Entry selectors', () => {
expect(selectors.allEntries.projector(entryState)).toBe(entryList);
});

it('should select the entries for report', () => {
const entryList = [];
const entryState = { entriesForReport: entryList };

expect(selectors.entriesForReport.projector(entryState)).toBe(entryList);
});

});
2 changes: 2 additions & 0 deletions src/app/modules/time-clock/store/entry.selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ export const getUpdateError = createSelector(getEntryState, (state: EntryState)
export const getStatusMessage = createSelector(getEntryState, (state: EntryState) => state.message);

export const allEntries = createSelector(getEntryState, (state: EntryState) => state.entryList);

export const entriesForReport = createSelector(getEntryState, (state: EntryState) => state.entriesForReport);