Commit 986133cd authored by Kushal Pandya's avatar Kushal Pandya

Roadmap App Store

parent 0a221897
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
export default class RoadmapStore {
constructor(groupId, timeframe) {
this.state = {};
this.state.epics = [];
this.state.currentGroupId = groupId;
this.state.timeframe = timeframe;
this.firstTimeframeItem = this.state.timeframe[0];
this.lastTimeframeItem = this.state.timeframe[this.state.timeframe.length - 1];
}
setEpics(epics) {
this.state.epics = epics.map(
epic => RoadmapStore.formatEpicDetails(epic, this.firstTimeframeItem, this.lastTimeframeItem),
);
}
getEpics() {
return this.state.epics;
}
getCurrentGroupId() {
return this.state.currentGroupId;
}
getTimeframe() {
return this.state.timeframe;
}
/**
* This method constructs Epic object and assigns proxy dates
* in case start or end dates are unavailable.
*
* @param {Object} rawEpic
* @param {Date} firstTimeframeItem
* @param {Date} lastTimeframeItem
*/
static formatEpicDetails(rawEpic, firstTimeframeItem, lastTimeframeItem) {
const epicItem = convertObjectPropsToCamelCase(rawEpic);
if (rawEpic.start_date) {
// If startDate is present
const startDate = new Date(rawEpic.start_date);
if (startDate <= firstTimeframeItem) {
// If startDate is less than first timeframe item
// startDate is out of range;
epicItem.startDateOutOfRange = true;
// store original start date in different object
epicItem.originalStartDate = startDate;
// Use startDate object to set a proxy date so
// that timeline bar can render it.
epicItem.startDate = new Date(firstTimeframeItem.getTime());
} else {
// startDate is within timeframe range
epicItem.startDate = startDate;
}
} else {
// Start date is not available
epicItem.startDateUndefined = true;
// Set proxy date so that timeline bar can render it.
epicItem.startDate = new Date(firstTimeframeItem.getTime());
}
// Same as above but for endDate
// This entire chunk can be moved into generic method
// but we're keeping it here for the sake of simplicity.
if (rawEpic.end_date) {
const endDate = new Date(rawEpic.end_date);
if (endDate >= lastTimeframeItem) {
epicItem.endDateOutOfRange = true;
epicItem.originalEndDate = endDate;
epicItem.endDate = new Date(lastTimeframeItem.getTime());
} else {
epicItem.endDate = endDate;
}
} else {
epicItem.endDateUndefined = true;
epicItem.endDate = new Date(lastTimeframeItem.getTime());
}
return epicItem;
}
}
import RoadmapStore from 'ee/roadmap/store/roadmap_store';
import { mockGroupId, mockTimeframe, rawEpics } from '../mock_data';
describe('RoadmapStore', () => {
let store;
beforeEach(() => {
store = new RoadmapStore(mockGroupId, mockTimeframe);
});
describe('constructor', () => {
it('initializes default state', () => {
expect(store.state).toBeDefined();
expect(Array.isArray(store.state.epics)).toBe(true);
expect(store.state.currentGroupId).toBe(mockGroupId);
expect(store.state.timeframe).toBe(mockTimeframe);
expect(store.firstTimeframeItem).toBe(store.state.timeframe[0]);
expect(store.lastTimeframeItem).toBe(store.state.timeframe[store.state.timeframe.length - 1]);
});
});
describe('setEpics', () => {
it('sets Epics list to state', () => {
store.setEpics(rawEpics);
expect(store.getEpics().length).toBe(rawEpics.length);
});
});
describe('getCurrentGroupId', () => {
it('gets currentGroupId from store state', () => {
expect(store.getCurrentGroupId()).toBe(mockGroupId);
});
});
describe('getTimeframe', () => {
it('gets timeframe from store state', () => {
expect(store.getTimeframe()).toBe(mockTimeframe);
});
});
describe('formatEpicDetails', () => {
const rawEpic = rawEpics[0];
it('returns formatted Epic object from raw Epic object', () => {
const epic = RoadmapStore.formatEpicDetails(rawEpic);
expect(epic.id).toBe(rawEpic.id);
expect(epic.name).toBe(rawEpic.name);
expect(epic.groupId).toBe(rawEpic.group_id);
expect(epic.groupName).toBe(rawEpic.group_name);
});
it('returns formatted Epic object with startDateUndefined and proxy date set when start date is not available', () => {
const rawEpicWithoutSD = Object.assign({}, rawEpic, {
start_date: null,
});
const epic = RoadmapStore.formatEpicDetails(
rawEpicWithoutSD,
store.firstTimeframeItem,
store.lastTimeframeItem,
);
expect(epic.id).toBe(rawEpic.id);
expect(epic.startDateUndefined).toBe(true);
expect(epic.startDate.getTime()).toBe(store.firstTimeframeItem.getTime());
});
it('returns formatted Epic object with endDateUndefined and proxy date set when end date is not available', () => {
const rawEpicWithoutED = Object.assign({}, rawEpic, {
end_date: null,
});
const epic = RoadmapStore.formatEpicDetails(
rawEpicWithoutED,
store.firstTimeframeItem,
store.lastTimeframeItem,
);
expect(epic.id).toBe(rawEpic.id);
expect(epic.endDateUndefined).toBe(true);
expect(epic.endDate.getTime()).toBe(store.lastTimeframeItem.getTime());
});
it('returns formatted Epic object with startDateOutOfRange, proxy date and cached original start date set when start date is out of timeframe range', () => {
const rawStartDate = '2017-1-1';
const rawEpicSDOut = Object.assign({}, rawEpic, {
start_date: rawStartDate,
});
const epic = RoadmapStore.formatEpicDetails(
rawEpicSDOut,
store.firstTimeframeItem,
store.lastTimeframeItem,
);
expect(epic.id).toBe(rawEpic.id);
expect(epic.startDateOutOfRange).toBe(true);
expect(epic.startDate.getTime()).toBe(store.firstTimeframeItem.getTime());
expect(epic.originalStartDate.getTime()).toBe(new Date(rawStartDate).getTime());
});
it('returns formatted Epic object with endDateOutOfRange, proxy date and cached original end date set when end date is out of timeframe range', () => {
const rawEndDate = '2019-1-1';
const rawEpicEDOut = Object.assign({}, rawEpic, {
end_date: rawEndDate,
});
const epic = RoadmapStore.formatEpicDetails(
rawEpicEDOut,
store.firstTimeframeItem,
store.lastTimeframeItem,
);
expect(epic.id).toBe(rawEpic.id);
expect(epic.endDateOutOfRange).toBe(true);
expect(epic.endDate.getTime()).toBe(store.lastTimeframeItem.getTime());
expect(epic.originalEndDate.getTime()).toBe(new Date(rawEndDate).getTime());
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment