exports[`addCustomEvent should correctly add a custom event 1`] = `
Object {
- "date": "2016-10-27T12:21:15+0200",
+ "date": 2016-10-27T10:21:15.000Z,
"events": Array [
Object {
"category": "Custom",
exports[`changeEvent should correctly update an event 1`] = `
Object {
- "date": "2016-10-27T16:33:50+0200",
+ "date": 2016-10-27T14:33:50.000Z,
"events": Array [
Object {
"category": "VERSION",
exports[`deleteAnalysis should correctly delete an analyses 1`] = `
Array [
Object {
- "date": "2016-10-27T12:21:15+0200",
+ "date": 2016-10-27T10:21:15.000Z,
"events": Array [],
"key": "A2",
},
Object {
- "date": "2016-10-26T12:17:29+0200",
+ "date": 2016-10-26T10:17:29.000Z,
"events": Array [
Object {
"category": "OTHER",
exports[`deleteEvent should correctly remove an event 1`] = `
Object {
- "date": "2016-10-27T16:33:50+0200",
+ "date": 2016-10-27T14:33:50.000Z,
"events": Array [],
"key": "A1",
}
exports[`deleteEvent should correctly remove an event 2`] = `
Object {
- "date": "2016-10-27T12:21:15+0200",
+ "date": 2016-10-27T10:21:15.000Z,
"events": Array [],
"key": "A2",
}
exports[`deleteEvent should correctly remove an event 3`] = `
Object {
- "date": "2016-10-26T12:17:29+0200",
+ "date": 2016-10-26T10:17:29.000Z,
"events": Array [
Object {
"category": "OTHER",
const ANALYSES = [
{
key: 'A1',
- date: '2016-10-27T16:33:50+0200',
+ date: new Date('2016-10-27T16:33:50+0200'),
events: [
{
key: 'E1',
},
{
key: 'A2',
- date: '2016-10-27T12:21:15+0200',
+ date: new Date('2016-10-27T12:21:15+0200'),
events: []
},
{
key: 'A3',
- date: '2016-10-26T12:17:29+0200',
+ date: new Date('2016-10-26T12:17:29+0200'),
events: [
{
key: 'E2',
}
filterAnalyses = (analyses: Array<Analysis>, query: Query): Array<Analysis> => {
- if (!query.category) {
+ if (!query.category && !query.from && !query.to) {
return analyses;
}
- return analyses.filter(
- analysis => analysis.events.find(event => event.category === query.category) != null
- );
+ return analyses.filter(analysis => {
+ const isAfterFrom = !query.from || analysis.date >= query.from;
+ const isBeforeTo = !query.to || analysis.date <= query.to;
+ const hasSelectedCategoryEvents =
+ !query.category || analysis.events.find(event => event.category === query.category) != null;
+ return isAfterFrom && isBeforeTo && hasSelectedCategoryEvents;
+ });
};
getMetricType = () => {
}
): Promise<{ analyses: Array<Analysis>, paging: Paging }> => {
const parameters = { project, p, ps };
- return api.getProjectActivity({ ...parameters, ...additional }).catch(throwGlobalError);
+ return api.getProjectActivity({ ...parameters, ...additional }).then(
+ ({ analyses, paging }) => ({
+ analyses: analyses.map(analysis => ({ ...analysis, date: moment(analysis.date).toDate() })),
+ paging
+ }),
+ throwGlobalError
+ );
};
fetchMeasuresHistory = (metrics: Array<string>): Promise<Array<MeasureHistory>> =>
const ANALYSES = [
{
key: 'A1',
- date: '2016-10-27T16:33:50+0200',
+ date: new Date('2016-10-27T16:33:50+0200'),
events: [
{
key: 'E1',
},
{
key: 'A2',
- date: '2016-10-27T12:21:15+0200',
+ date: new Date('2016-10-27T12:21:15+0200'),
events: []
},
{
key: 'A3',
- date: '2016-10-26T12:17:29+0200',
+ date: new Date('2016-10-26T12:17:29+0200'),
events: [
{
key: 'E2',
expect(shallow(<ProjectActivityApp {...DEFAULT_PROPS} />)).toMatchSnapshot();
});
-it('should correctly filter analyses', () => {
+it('should correctly filter analyses by category', () => {
const wrapper = mount(<ProjectActivityApp {...DEFAULT_PROPS} />);
wrapper.setProps({ query: { ...DEFAULT_PROPS.query, category: 'VERSION' } });
expect(wrapper.state()).toMatchSnapshot();
});
+
+it('should correctly filter analyses by date range', () => {
+ const wrapper = mount(<ProjectActivityApp {...DEFAULT_PROPS} />);
+ wrapper.setProps({
+ query: {
+ ...DEFAULT_PROPS.query,
+ from: new Date('2016-10-27T12:21:15+0200'),
+ to: new Date('2016-10-27T12:21:15+0200')
+ }
+ });
+ expect(wrapper.state()).toMatchSnapshot();
+});
const ANALYSES = [
{
key: 'A1',
- date: '2016-10-27T16:33:50+0200',
+ date: new Date('2016-10-27T16:33:50+0200'),
events: [
{
key: 'E1',
},
{
key: 'A2',
- date: '2016-10-27T12:21:15+0200',
+ date: new Date('2016-10-27T12:21:15+0200'),
events: []
},
{
key: 'A3',
- date: '2016-10-26T12:17:29+0200',
+ date: new Date('2016-10-26T12:17:29+0200'),
events: [
{
key: 'E2',
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`should correctly filter analyses 1`] = `
+exports[`should correctly filter analyses by category 1`] = `
Object {
"filteredAnalyses": Array [
Object {
- "date": "2016-10-27T16:33:50+0200",
+ "date": 2016-10-27T14:33:50.000Z,
"events": Array [
Object {
"category": "VERSION",
"key": "A1",
},
Object {
- "date": "2016-10-26T12:17:29+0200",
+ "date": 2016-10-26T10:17:29.000Z,
"events": Array [
Object {
"category": "VERSION",
}
`;
+exports[`should correctly filter analyses by date range 1`] = `
+Object {
+ "filteredAnalyses": Array [
+ Object {
+ "date": 2016-10-27T10:21:15.000Z,
+ "events": Array [],
+ "key": "A2",
+ },
+ ],
+}
+`;
+
exports[`should render correctly 1`] = `
<div
className="page page-limited"
analyses={
Array [
Object {
- "date": "2016-10-27T16:33:50+0200",
+ "date": 2016-10-27T14:33:50.000Z,
"events": Array [
Object {
"category": "VERSION",
"key": "A1",
},
Object {
- "date": "2016-10-27T12:21:15+0200",
+ "date": 2016-10-27T10:21:15.000Z,
"events": Array [],
"key": "A2",
},
Object {
- "date": "2016-10-26T12:17:29+0200",
+ "date": 2016-10-26T10:17:29.000Z,
"events": Array [
Object {
"category": "VERSION",
analyses={
Array [
Object {
- "date": "2016-10-27T16:33:50+0200",
+ "date": 2016-10-27T14:33:50.000Z,
"events": Array [
Object {
"category": "VERSION",
"key": "A1",
},
Object {
- "date": "2016-10-27T12:21:15+0200",
+ "date": 2016-10-27T10:21:15.000Z,
"events": Array [],
"key": "A2",
},
Object {
- "date": "2016-10-26T12:17:29+0200",
+ "date": 2016-10-26T10:17:29.000Z,
"events": Array [
Object {
"category": "VERSION",
export type Analysis = {
key: string,
- date: string,
+ date: Date,
events: Array<Event>
};
export type Query = {
category: string,
+ from?: Date,
graph: string,
- project: string
+ project: string,
+ to?: Date
};
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
// @flow
-import { cleanQuery, parseAsString, serializeString } from '../../helpers/query';
+import {
+ cleanQuery,
+ parseAsDate,
+ parseAsString,
+ serializeDate,
+ serializeString
+} from '../../helpers/query';
import { translate } from '../../helpers/l10n';
import type { MeasureHistory, Query } from './types';
import type { RawQuery } from '../../helpers/query';
export const parseQuery = (urlQuery: RawQuery): Query => ({
category: parseAsString(urlQuery['category']),
+ from: parseAsDate(urlQuery['from']),
graph: parseGraph(urlQuery['graph']),
- project: parseAsString(urlQuery['id'])
+ project: parseAsString(urlQuery['id']),
+ to: parseAsDate(urlQuery['to'])
});
export const serializeQuery = (query: Query): RawQuery =>
export const serializeUrlQuery = (query: Query): RawQuery => {
return cleanQuery({
category: serializeString(query.category),
+ from: serializeDate(query.from),
graph: serializeGraph(query.graph),
- id: serializeString(query.project)
+ id: serializeString(query.project),
+ to: serializeDate(query.to)
});
};
export const activityQueryChanged = (prevQuery: Query, nextQuery: Query): boolean =>
- prevQuery.category !== nextQuery.category;
+ prevQuery.category !== nextQuery.category ||
+ prevQuery.from !== nextQuery.from ||
+ prevQuery.to !== nextQuery.to;
export const historyQueryChanged = (prevQuery: Query, nextQuery: Query): boolean =>
prevQuery.graph !== nextQuery.graph;
"e": 0,
}
`;
+
+exports[`parseAsDate should parse string date correctly 1`] = `2016-06-20T13:09:48.256Z`;
});
});
+describe('parseAsDate', () => {
+ it('should parse string date correctly', () => {
+ expect(query.parseAsDate('2016-06-20T13:09:48.256Z')).toMatchSnapshot();
+ expect(query.parseAsDate('')).toBeFalsy();
+ expect(query.parseAsDate()).toBeFalsy();
+ });
+});
+
+describe('serializeDate', () => {
+ it('should serialize string correctly', () => {
+ expect(query.serializeDate(new Date('2016-06-20T13:09:48.256Z'))).toBe(
+ '2016-06-20T13:09:48.256Z'
+ );
+ expect(query.serializeDate('')).toBeUndefined();
+ expect(query.serializeDate()).toBeUndefined();
+ });
+});
+
describe('serializeString', () => {
it('should serialize string correctly', () => {
expect(query.serializeString('foo')).toBe('foo');
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { isNil, omitBy } from 'lodash';
+import moment from 'moment';
export type RawQuery = { [string]: string };
export const parseAsBoolean = (value: ?string, defaultValue: boolean = true): boolean =>
(value === 'false' ? false : value === 'true' ? true : defaultValue);
+export const parseAsDate = (value: ?string): ?Date => {
+ const date = moment(value);
+ if (value && date) {
+ return date.toDate();
+ }
+};
+
export const parseAsFacetMode = (facetMode: string) =>
(facetMode === 'debt' || facetMode === 'effort' ? 'effort' : 'count');
export const parseAsArray = <T>(value: ?string, itemParser: string => T): Array<T> =>
(value ? value.split(',').map(itemParser) : []);
+export const serializeDate = (value: ?Date): ?string => {
+ if (value != null && value.toISOString) {
+ return value.toISOString();
+ }
+};
+
export const serializeString = (value: string): ?string => value || undefined;
export const serializeStringArray = (value: ?Array<string>): ?string =>