Commit c481410a authored by Jiaan Louw's avatar Jiaan Louw Committed by Enrique Alcántara

Add audit events store

This is the first iteration of the
audit events store, which manages
the state of the filter bar.
parent 465d678f
import { setUrlParams, queryToObject, visitUrl } from '~/lib/utils/url_utility';
import { parseAuditEventSearchQuery, createAuditEventSearchQuery } from '../utils';
import * as types from './mutation_types';
export const initializeAuditEvents = ({ commit }) => {
commit(
types.INITIALIZE_AUDIT_EVENTS,
parseAuditEventSearchQuery(queryToObject(window.location.search)),
);
};
export const searchForAuditEvents = ({ state }) => {
visitUrl(setUrlParams(createAuditEventSearchQuery(state)));
};
export const setDateRange = ({ commit, dispatch }, { startDate, endDate }) => {
commit(types.SET_DATE_RANGE, { startDate, endDate });
dispatch('searchForAuditEvents');
};
export const setFilterValue = ({ commit, dispatch }, { id, type }) => {
commit(types.SET_FILTER_VALUE, { id, type });
dispatch('searchForAuditEvents');
};
export const setSortBy = ({ commit, dispatch }, sortBy) => {
commit(types.SET_SORT_BY, sortBy);
dispatch('searchForAuditEvents');
};
import Vue from 'vue';
import Vuex from 'vuex';
import * as actions from './actions';
import mutations from './mutations';
import state from './state';
Vue.use(Vuex);
export default () =>
new Vuex.Store({
namespaced: true,
actions,
mutations,
state,
});
export const SET_FILTER_VALUE = 'SET_FILTER_VALUE';
export const SET_DATE_RANGE = 'SET_DATE_RANGE';
export const SET_SORT_BY = 'SET_SORT_BY';
export const INITIALIZE_AUDIT_EVENTS = 'INITIALIZE_AUDIT_EVENTS';
import * as types from './mutation_types';
export default {
[types.INITIALIZE_AUDIT_EVENTS](
state,
{
entity_id: id = null,
entity_type: type = null,
created_after: startDate = null,
created_before: endDate = null,
sort: sortBy = null,
} = {},
) {
state.filterValue = { id, type };
state.startDate = startDate;
state.endDate = endDate;
state.sortBy = sortBy;
},
[types.SET_FILTER_VALUE](state, { id, type }) {
state.filterValue = { id, type };
},
[types.SET_DATE_RANGE](state, { startDate, endDate }) {
state.startDate = startDate;
state.endDate = endDate;
},
[types.SET_SORT_BY](state, sortBy) {
state.sortBy = sortBy;
},
};
export default () => ({
filterValue: {
id: null,
type: null,
},
startDate: null,
endDate: null,
sortBy: null,
});
import { parsePikadayDate, pikadayToString } from '~/lib/utils/datetime_utility';
export const isNumeric = str => { export const isNumeric = str => {
return !Number.isNaN(parseInt(str, 10), 10); return !Number.isNaN(parseInt(str, 10), 10);
}; };
export default {}; export const parseAuditEventSearchQuery = ({
created_after: createdAfter,
created_before: createdBefore,
...restOfParams
}) => ({
...restOfParams,
created_after: createdAfter ? parsePikadayDate(createdAfter) : null,
created_before: createdBefore ? parsePikadayDate(createdBefore) : null,
});
export const createAuditEventSearchQuery = ({ filterValue, startDate, endDate, sortBy }) => ({
entity_id: filterValue.id,
entity_type: filterValue.type,
created_after: startDate ? pikadayToString(startDate) : null,
created_before: endDate ? pikadayToString(endDate) : null,
sort: sortBy,
});
import testAction from 'helpers/vuex_action_helper';
import createState from 'ee/audit_events/store/state';
import * as actions from 'ee/audit_events/store/actions';
import * as types from 'ee/audit_events/store/mutation_types';
import * as urlUtility from '~/lib/utils/url_utility';
describe('Audit Event actions', () => {
let state;
const startDate = new Date('March 13, 2020 12:00:00');
const endDate = new Date('April 13, 2020 12:00:00');
beforeEach(() => {
state = createState();
});
afterEach(() => {
state = null;
});
it.each`
action | type | payload
${'setDateRange'} | ${types.SET_DATE_RANGE} | ${{ startDate, endDate }}
${'setFilterValue'} | ${types.SET_FILTER_VALUE} | ${{ id: '1', type: 'user' }}
${'setSortBy'} | ${types.SET_SORT_BY} | ${'created_asc'}
`(
'$action should commit $type with $payload and dispatches "searchForAuditEvents"',
({ action, type, payload }) => {
testAction(
actions[action],
payload,
state,
[
{
type,
payload,
},
],
[{ type: 'searchForAuditEvents' }],
);
},
);
describe('searchForAuditEvents', () => {
let spy;
beforeEach(() => {
delete window.location;
window.location = new URL('https://test/');
spy = jest.spyOn(urlUtility, 'visitUrl').mockReturnValue({});
});
afterEach(() => {
spy.mockRestore();
});
describe('with a default state', () => {
it('should call visitUrl without a search query', () => {
return testAction(actions.searchForAuditEvents, null, state, []).then(() => {
expect(spy).toHaveBeenCalledWith('https://test/');
});
});
});
describe('with a state that has a search query', () => {
beforeEach(() => {
state.sortBy = 'created_asc';
});
it('should call visitUrl with a search query', () => {
return testAction(actions.searchForAuditEvents, null, state, []).then(() => {
expect(spy).toHaveBeenCalledWith('https://test/?sort=created_asc');
});
});
});
});
describe('initializeAuditEvents', () => {
describe('with an empty search query', () => {
beforeEach(() => {
delete window.location;
window.location = { search: '' };
});
it(`commits "${types.INITIALIZE_AUDIT_EVENTS}" with empty dates`, () => {
testAction(actions.initializeAuditEvents, null, state, [
{
type: types.INITIALIZE_AUDIT_EVENTS,
payload: {
created_after: null,
created_before: null,
},
},
]);
});
});
describe('with a full search query', () => {
beforeEach(() => {
delete window.location;
window.location = {
search:
'sort=created_desc&entity_type=User&entity_id=44&created_after=2020-06-05&created_before=2020-06-25',
};
});
it(`commits "${types.INITIALIZE_AUDIT_EVENTS}" with the query data`, () => {
testAction(actions.initializeAuditEvents, null, state, [
{
type: types.INITIALIZE_AUDIT_EVENTS,
payload: {
created_after: new Date('2020-06-05T00:00:00.000Z'),
created_before: new Date('2020-06-25T00:00:00.000Z'),
entity_id: '44',
entity_type: 'User',
sort: 'created_desc',
},
},
]);
});
});
});
});
import mutations from 'ee/audit_events/store/mutations';
import * as types from 'ee/audit_events/store/mutation_types';
describe('Audit Event mutations', () => {
let state = null;
const startDate = new Date('March 13, 2020 12:00:00');
const endDate = new Date('April 13, 2020 12:00:00');
beforeEach(() => {
state = {};
});
afterEach(() => {
state = null;
});
it.each`
mutation | payload | expectedState
${types.SET_FILTER_VALUE} | ${{ id: '1', type: 'user' }} | ${{ filterValue: { id: '1', type: 'user' } }}
${types.SET_DATE_RANGE} | ${{ startDate, endDate }} | ${{ startDate, endDate }}
${types.SET_SORT_BY} | ${'created_asc'} | ${{ sortBy: 'created_asc' }}
`(
'$mutation with payload $payload will update state with $expectedState',
({ mutation, payload, expectedState }) => {
state = {};
mutations[mutation](state, payload);
expect(state).toMatchObject(expectedState);
},
);
describe(`${types.INITIALIZE_AUDIT_EVENTS}`, () => {
const payload = {
entity_id: '1',
entity_type: 'user',
created_after: startDate,
created_before: endDate,
sort: 'created_asc',
};
it.each`
stateKey | expectedState
${'filterValue'} | ${{ id: payload.entity_id, type: payload.entity_type }}
${'startDate'} | ${payload.created_after}
${'endDate'} | ${payload.created_before}
${'sortBy'} | ${payload.sort}
`('state.$stateKey should be set to $expectedState', ({ stateKey, expectedState }) => {
state = {};
mutations[types.INITIALIZE_AUDIT_EVENTS](state, payload);
expect(state[stateKey]).toEqual(expectedState);
});
});
});
import { parseAuditEventSearchQuery, createAuditEventSearchQuery } from 'ee/audit_events/utils';
describe('Audit Event Utils', () => {
describe('parseAuditEventSearchQuery', () => {
it('returns a query object with parsed date values', () => {
const input = {
created_after: '2020-03-13',
created_before: '2020-04-13',
sortBy: 'created_asc',
};
expect(parseAuditEventSearchQuery(input)).toEqual({
created_after: new Date('2020-03-13'),
created_before: new Date('2020-04-13'),
sortBy: 'created_asc',
});
});
});
describe('createAuditEventSearchQuery', () => {
it('returns a query object with remapped keys and stringified dates', () => {
const input = {
filterValue: {
id: '1',
type: 'user',
},
startDate: new Date('2020-03-13'),
endDate: new Date('2020-04-13'),
sortBy: 'bar',
};
expect(createAuditEventSearchQuery(input)).toEqual({
entity_id: '1',
entity_type: 'user',
created_after: '2020-03-13',
created_before: '2020-04-13',
sort: 'bar',
});
});
});
});
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