Commit 07b6587b authored by Enrique Alcántara's avatar Enrique Alcántara

Merge branch '217759_add_audit_event_store' into 'master'

Add audit events store for event filtering

See merge request gitlab-org/gitlab!34060
parents 7f57e2e3 c481410a
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