chronograf/ui/test/data_explorer/reducers/queryConfig.test.js

487 lines
13 KiB
JavaScript
Raw Normal View History

2017-03-30 22:29:43 +00:00
import reducer from 'src/data_explorer/reducers/queryConfigs'
2017-11-03 21:08:48 +00:00
2018-02-27 15:09:07 +00:00
import defaultQueryConfig from 'utils/defaultQueryConfig'
import {
2017-10-12 17:48:36 +00:00
fill,
2017-11-03 21:08:48 +00:00
timeShift,
chooseTag,
groupByTag,
groupByTime,
2017-10-12 17:48:36 +00:00
toggleField,
removeFuncs,
updateRawQuery,
2017-04-07 19:51:18 +00:00
editQueryStatus,
2017-10-12 17:48:36 +00:00
chooseNamespace,
chooseMeasurement,
applyFuncsToField,
addInitialField,
2017-10-12 17:48:36 +00:00
updateQueryConfig,
toggleTagAcceptance,
2017-04-04 21:46:55 +00:00
} from 'src/data_explorer/actions/view'
import {LINEAR, NULL_STRING} from 'shared/constants/queryFillOptions'
2017-02-06 19:41:42 +00:00
const fakeAddQueryAction = (panelID, queryID) => {
return {
type: 'DE_ADD_QUERY',
2017-02-06 19:41:42 +00:00
payload: {panelID, queryID},
2017-03-30 22:29:43 +00:00
}
}
2017-11-03 20:56:01 +00:00
function buildInitialState(queryID, params) {
return Object.assign({}, defaultQueryConfig({id: queryID}), params)
}
describe('Chronograf.Reducers.DataExplorer.queryConfigs', () => {
2017-11-03 20:56:01 +00:00
const queryID = 123
it('can add a query', () => {
2017-11-03 20:56:01 +00:00
const state = reducer({}, fakeAddQueryAction('blah', queryID))
2017-11-03 20:56:01 +00:00
const actual = state[queryID]
const expected = defaultQueryConfig({id: queryID})
2018-02-27 06:08:13 +00:00
expect(actual).toEqual(expected)
2017-03-30 22:29:43 +00:00
})
describe('choosing db, rp, and measurement', () => {
2017-03-30 22:29:43 +00:00
let state
beforeEach(() => {
2017-11-03 20:56:01 +00:00
state = reducer({}, fakeAddQueryAction('any', queryID))
2017-03-30 22:29:43 +00:00
})
it('sets the db and rp', () => {
2017-05-30 20:38:50 +00:00
const newState = reducer(
state,
2017-11-03 20:56:01 +00:00
chooseNamespace(queryID, {
2017-05-30 20:38:50 +00:00
database: 'telegraf',
retentionPolicy: 'monitor',
})
)
2018-02-27 06:08:13 +00:00
expect(newState[queryID].database).toBe('telegraf')
expect(newState[queryID].retentionPolicy).toBe('monitor')
2017-03-30 22:29:43 +00:00
})
it('sets the measurement', () => {
2017-11-03 20:56:01 +00:00
const newState = reducer(state, chooseMeasurement(queryID, 'mem'))
2018-02-27 06:08:13 +00:00
expect(newState[queryID].measurement).toBe('mem')
2017-03-30 22:29:43 +00:00
})
})
2017-10-11 19:13:25 +00:00
describe('a query has measurements and fields', () => {
2017-03-30 22:29:43 +00:00
let state
beforeEach(() => {
2017-11-03 20:56:01 +00:00
const one = reducer({}, fakeAddQueryAction('any', queryID))
2017-05-30 20:38:50 +00:00
const two = reducer(
one,
2017-11-03 20:56:01 +00:00
chooseNamespace(queryID, {
2017-05-30 20:38:50 +00:00
database: '_internal',
retentionPolicy: 'daily',
})
)
2017-11-03 20:56:01 +00:00
const three = reducer(two, chooseMeasurement(queryID, 'disk'))
2017-05-30 20:38:50 +00:00
state = reducer(
three,
2017-11-03 20:56:01 +00:00
addInitialField(queryID, {
2017-10-17 19:44:16 +00:00
value: 'a great field',
2017-10-10 21:09:06 +00:00
type: 'field',
})
2017-05-30 20:38:50 +00:00
)
2017-03-30 22:29:43 +00:00
})
2017-10-12 17:48:36 +00:00
describe('choosing a new namespace', () => {
2017-05-30 20:38:50 +00:00
it('clears out the old measurement and fields', () => {
// what about tags?
2018-02-27 06:08:13 +00:00
expect(state[queryID].measurement).toBe('disk')
expect(state[queryID].fields.length).toBe(1)
2017-05-30 20:38:50 +00:00
const newState = reducer(
state,
2017-11-03 20:56:01 +00:00
chooseNamespace(queryID, {
2017-05-30 20:38:50 +00:00
database: 'newdb',
retentionPolicy: 'newrp',
})
)
2018-02-27 15:09:07 +00:00
expect(newState[queryID].measurement).toBe(null)
2018-02-27 06:08:13 +00:00
expect(newState[queryID].fields.length).toBe(0)
2017-03-30 22:29:43 +00:00
})
})
describe('choosing a new measurement', () => {
2017-05-30 20:38:50 +00:00
it('leaves the namespace and clears out the old fields', () => {
// what about tags?
2018-02-27 06:08:13 +00:00
expect(state[queryID].fields.length).toBe(1)
2017-05-30 20:38:50 +00:00
const newState = reducer(
state,
2017-11-03 20:56:01 +00:00
chooseMeasurement(queryID, 'newmeasurement')
2017-05-30 20:38:50 +00:00
)
2018-02-27 06:08:13 +00:00
expect(state[queryID].database).toBe(newState[queryID].database)
expect(state[queryID].retentionPolicy).toBe(
2017-11-03 20:56:01 +00:00
newState[queryID].retentionPolicy
2017-05-30 20:38:50 +00:00
)
2018-02-27 06:08:13 +00:00
expect(newState[queryID].fields.length).toBe(0)
2017-03-30 22:29:43 +00:00
})
})
describe('DE_TOGGLE_FIELD', () => {
it('can toggle multiple fields', () => {
2018-02-27 06:08:13 +00:00
expect(state[queryID].fields.length).toBe(1)
const newState = reducer(
state,
2017-11-03 20:56:01 +00:00
toggleField(queryID, {
2017-10-17 19:44:16 +00:00
value: 'f2',
type: 'field',
})
)
2018-02-27 06:08:13 +00:00
expect(newState[queryID].fields.length).toBe(2)
expect(newState[queryID].fields[1].alias).toEqual('mean_f2')
expect(newState[queryID].fields[1].args).toEqual([
2017-10-17 19:44:16 +00:00
{value: 'f2', type: 'field'},
])
2018-02-27 06:08:13 +00:00
expect(newState[queryID].fields[1].value).toEqual('mean')
})
it('applies a func to newly selected fields', () => {
2018-02-27 06:08:13 +00:00
expect(state[queryID].fields.length).toBe(1)
expect(state[queryID].fields[0].type).toBe('func')
expect(state[queryID].fields[0].value).toBe('mean')
const newState = reducer(
state,
2017-11-03 20:56:01 +00:00
toggleField(queryID, {
2017-10-17 19:44:16 +00:00
value: 'f2',
2017-10-10 21:09:06 +00:00
type: 'field',
})
)
2018-02-27 06:08:13 +00:00
expect(newState[queryID].fields[1].value).toBe('mean')
expect(newState[queryID].fields[1].alias).toBe('mean_f2')
expect(newState[queryID].fields[1].args).toEqual([
2017-10-17 19:44:16 +00:00
{value: 'f2', type: 'field'},
])
2018-02-27 06:08:13 +00:00
expect(newState[queryID].fields[1].type).toBe('func')
})
2017-08-30 21:09:24 +00:00
it('adds the field property to query config if not found', () => {
2017-11-03 20:56:01 +00:00
delete state[queryID].fields
2018-02-27 06:08:13 +00:00
expect(state[queryID].fields).toBe(undefined)
2017-08-30 21:09:24 +00:00
const newState = reducer(
state,
2017-11-03 20:56:01 +00:00
toggleField(queryID, {value: 'fk1', type: 'field'})
2017-08-30 21:09:24 +00:00
)
2018-02-27 06:08:13 +00:00
expect(newState[queryID].fields.length).toBe(1)
2017-08-30 21:09:24 +00:00
})
})
2017-03-30 22:29:43 +00:00
})
2017-10-11 19:13:25 +00:00
describe('DE_APPLY_FUNCS_TO_FIELD', () => {
it('applies new functions to a field', () => {
2017-10-17 19:44:16 +00:00
const f1 = {value: 'f1', type: 'field'}
const f2 = {value: 'f2', type: 'field'}
const initialState = {
2017-11-03 20:56:01 +00:00
[queryID]: {
id: 123,
database: 'db1',
measurement: 'm1',
fields: [
2017-10-17 19:44:16 +00:00
{value: 'fn1', type: 'func', args: [f1], alias: `fn1_${f1.value}`},
{value: 'fn1', type: 'func', args: [f2], alias: `fn1_${f2.value}`},
{value: 'fn2', type: 'func', args: [f1], alias: `fn2_${f1.value}`},
],
2017-03-30 22:29:43 +00:00
},
}
2017-11-03 20:56:01 +00:00
const action = applyFuncsToField(queryID, {
2017-10-17 19:44:16 +00:00
field: {value: 'f1', type: 'field'},
funcs: [
2017-10-17 19:44:16 +00:00
{value: 'fn3', type: 'func', args: []},
{value: 'fn4', type: 'func', args: []},
],
2017-03-30 22:29:43 +00:00
})
2017-03-30 22:29:43 +00:00
const nextState = reducer(initialState, action)
2018-02-27 06:08:13 +00:00
expect(nextState[queryID].fields).toEqual([
2017-10-17 19:44:16 +00:00
{value: 'fn3', type: 'func', args: [f1], alias: `fn3_${f1.value}`},
{value: 'fn4', type: 'func', args: [f1], alias: `fn4_${f1.value}`},
{value: 'fn1', type: 'func', args: [f2], alias: `fn1_${f2.value}`},
2017-03-30 22:29:43 +00:00
])
})
2017-10-12 17:48:36 +00:00
})
2017-10-12 17:48:36 +00:00
describe('DE_REMOVE_FUNCS', () => {
it('removes all functions and group by time when one field has no funcs applied', () => {
2017-10-17 19:44:16 +00:00
const f1 = {value: 'f1', type: 'field'}
const f2 = {value: 'f2', type: 'field'}
2017-10-12 17:48:36 +00:00
const fields = [
2017-10-17 19:44:16 +00:00
{value: 'fn1', type: 'func', args: [f1], alias: `fn1_${f1.value}`},
{value: 'fn1', type: 'func', args: [f2], alias: `fn1_${f2.value}`},
2017-10-12 17:48:36 +00:00
]
const groupBy = {time: '1m', tags: []}
const initialState = {
2017-11-03 20:56:01 +00:00
[queryID]: {
id: 123,
database: 'db1',
measurement: 'm1',
2017-10-12 17:48:36 +00:00
fields,
groupBy,
2017-03-30 22:29:43 +00:00
},
}
2017-11-03 20:56:01 +00:00
const action = removeFuncs(queryID, fields, groupBy)
2017-03-30 22:29:43 +00:00
const nextState = reducer(initialState, action)
2017-11-03 20:56:01 +00:00
const actual = nextState[queryID].fields
2017-10-11 19:13:25 +00:00
const expected = [f1, f2]
2018-02-27 06:08:13 +00:00
expect(actual).toEqual(expected)
expect(nextState[queryID].groupBy.time).toBe(null)
2017-03-30 22:29:43 +00:00
})
})
describe('DE_CHOOSE_TAG', () => {
it('adds a tag key/value to the query', () => {
const initialState = {
2017-11-03 20:56:01 +00:00
[queryID]: buildInitialState(queryID, {
tags: {
k1: ['v0'],
k2: ['foo'],
},
}),
2017-03-30 22:29:43 +00:00
}
2017-11-03 20:56:01 +00:00
const action = chooseTag(queryID, {
key: 'k1',
value: 'v1',
2017-03-30 22:29:43 +00:00
})
2017-03-30 22:29:43 +00:00
const nextState = reducer(initialState, action)
2018-02-27 06:08:13 +00:00
expect(nextState[queryID].tags).toEqual({
k1: ['v0', 'v1'],
k2: ['foo'],
2017-03-30 22:29:43 +00:00
})
})
2017-05-30 20:38:50 +00:00
it("creates a new entry if it's the first key", () => {
const initialState = {
2017-11-03 20:56:01 +00:00
[queryID]: buildInitialState(queryID, {
tags: {},
}),
2017-03-30 22:29:43 +00:00
}
2017-11-03 20:56:01 +00:00
const action = chooseTag(queryID, {
key: 'k1',
value: 'v1',
2017-03-30 22:29:43 +00:00
})
2017-03-30 22:29:43 +00:00
const nextState = reducer(initialState, action)
2018-02-27 06:08:13 +00:00
expect(nextState[queryID].tags).toEqual({
k1: ['v1'],
2017-03-30 22:29:43 +00:00
})
})
it('removes a value that is already in the list', () => {
const initialState = {
2017-11-03 20:56:01 +00:00
[queryID]: buildInitialState(queryID, {
tags: {
k1: ['v1'],
},
}),
2017-03-30 22:29:43 +00:00
}
2017-11-03 20:56:01 +00:00
const action = chooseTag(queryID, {
key: 'k1',
value: 'v1',
2017-03-30 22:29:43 +00:00
})
2017-03-30 22:29:43 +00:00
const nextState = reducer(initialState, action)
// TODO: this should probably remove the `k1` property entirely from the tags object
2018-02-27 06:08:13 +00:00
expect(nextState[queryID].tags).toEqual({})
2017-03-30 22:29:43 +00:00
})
})
describe('DE_GROUP_BY_TAG', () => {
it('adds a tag key/value to the query', () => {
const initialState = {
2017-11-03 20:56:01 +00:00
[queryID]: {
id: 123,
database: 'db1',
measurement: 'm1',
fields: [],
tags: {},
groupBy: {tags: [], time: null},
2017-03-30 22:29:43 +00:00
},
}
2017-11-03 20:56:01 +00:00
const action = groupByTag(queryID, 'k1')
2017-03-30 22:29:43 +00:00
const nextState = reducer(initialState, action)
2018-02-27 06:08:13 +00:00
expect(nextState[queryID].groupBy).toEqual({
time: null,
tags: ['k1'],
2017-03-30 22:29:43 +00:00
})
})
it('removes a tag if the given tag key is already in the GROUP BY list', () => {
const initialState = {
2017-11-03 20:56:01 +00:00
[queryID]: {
id: 123,
database: 'db1',
measurement: 'm1',
fields: [],
tags: {},
groupBy: {tags: ['k1'], time: null},
2017-03-30 22:29:43 +00:00
},
}
2017-11-03 20:56:01 +00:00
const action = groupByTag(queryID, 'k1')
2017-03-30 22:29:43 +00:00
const nextState = reducer(initialState, action)
2018-02-27 06:08:13 +00:00
expect(nextState[queryID].groupBy).toEqual({
time: null,
tags: [],
2017-03-30 22:29:43 +00:00
})
})
})
describe('DE_TOGGLE_TAG_ACCEPTANCE', () => {
it('it toggles areTagsAccepted', () => {
const initialState = {
2017-11-03 20:56:01 +00:00
[queryID]: buildInitialState(queryID),
2017-03-30 22:29:43 +00:00
}
2017-11-03 20:56:01 +00:00
const action = toggleTagAcceptance(queryID)
2017-03-30 22:29:43 +00:00
const nextState = reducer(initialState, action)
2018-02-27 06:08:13 +00:00
expect(nextState[queryID].areTagsAccepted).toBe(
2017-11-03 20:56:01 +00:00
!initialState[queryID].areTagsAccepted
2017-05-30 20:38:50 +00:00
)
2017-03-30 22:29:43 +00:00
})
})
describe('DE_GROUP_BY_TIME', () => {
it('applys the appropriate group by time', () => {
2017-03-30 22:29:43 +00:00
const time = '100y'
const initialState = {
2017-11-03 20:56:01 +00:00
[queryID]: buildInitialState(queryID),
2017-03-30 22:29:43 +00:00
}
2017-11-03 20:56:01 +00:00
const action = groupByTime(queryID, time)
2017-03-30 22:29:43 +00:00
const nextState = reducer(initialState, action)
2018-02-27 06:08:13 +00:00
expect(nextState[queryID].groupBy.time).toBe(time)
2017-03-30 22:29:43 +00:00
})
})
it('updates entire config', () => {
const initialState = {
2017-11-03 20:56:01 +00:00
[queryID]: buildInitialState(queryID),
}
2017-11-03 20:56:01 +00:00
const expected = defaultQueryConfig({id: queryID}, {rawText: 'hello'})
const action = updateQueryConfig(expected)
const nextState = reducer(initialState, action)
2018-02-27 06:08:13 +00:00
expect(nextState[queryID]).toEqual(expected)
})
2017-05-30 20:38:50 +00:00
it("updates a query's raw text", () => {
const initialState = {
2017-11-03 20:56:01 +00:00
[queryID]: buildInitialState(queryID),
2017-03-30 22:29:43 +00:00
}
const text = 'foo'
2017-11-03 20:56:01 +00:00
const action = updateRawQuery(queryID, text)
2017-03-30 22:29:43 +00:00
const nextState = reducer(initialState, action)
2018-02-27 06:08:13 +00:00
expect(nextState[queryID].rawText).toBe('foo')
2017-03-30 22:29:43 +00:00
})
2017-03-29 21:36:06 +00:00
2017-05-30 20:38:50 +00:00
it("updates a query's raw status", () => {
2017-03-29 21:36:06 +00:00
const initialState = {
2017-11-03 20:56:01 +00:00
[queryID]: buildInitialState(queryID),
2017-03-29 21:36:06 +00:00
}
const status = 'your query was sweet'
2017-11-03 20:56:01 +00:00
const action = editQueryStatus(queryID, status)
2017-03-29 21:36:06 +00:00
const nextState = reducer(initialState, action)
2018-02-27 06:08:13 +00:00
expect(nextState[queryID].status).toBe(status)
2017-03-29 21:36:06 +00:00
})
describe('DE_FILL', () => {
it('applies an explicit fill when group by time is used', () => {
const initialState = {
2017-11-03 20:56:01 +00:00
[queryID]: buildInitialState(queryID),
}
const time = '10s'
2017-11-03 20:56:01 +00:00
const action = groupByTime(queryID, time)
const nextState = reducer(initialState, action)
2018-02-27 06:08:13 +00:00
expect(nextState[queryID].fill).toBe(NULL_STRING)
})
it('updates fill to non-null-string non-number string value', () => {
const initialState = {
2017-11-03 20:56:01 +00:00
[queryID]: buildInitialState(queryID),
}
2017-11-03 20:56:01 +00:00
const action = fill(queryID, LINEAR)
const nextState = reducer(initialState, action)
2018-02-27 06:08:13 +00:00
expect(nextState[queryID].fill).toBe(LINEAR)
})
it('updates fill to string integer value', () => {
const initialState = {
2017-11-03 20:56:01 +00:00
[queryID]: buildInitialState(queryID),
}
const INT_STRING = '1337'
2017-11-03 20:56:01 +00:00
const action = fill(queryID, INT_STRING)
const nextState = reducer(initialState, action)
2018-02-27 06:08:13 +00:00
expect(nextState[queryID].fill).toBe(INT_STRING)
})
it('updates fill to string float value', () => {
const initialState = {
2017-11-03 20:56:01 +00:00
[queryID]: buildInitialState(queryID),
}
const FLOAT_STRING = '1.337'
2017-11-03 20:56:01 +00:00
const action = fill(queryID, FLOAT_STRING)
const nextState = reducer(initialState, action)
2018-02-27 06:08:13 +00:00
expect(nextState[queryID].fill).toBe(FLOAT_STRING)
})
})
2017-11-03 21:08:48 +00:00
describe('DE_TIME_SHIFT', () => {
it('can shift the time', () => {
const initialState = {
[queryID]: buildInitialState(queryID),
}
const shift = {quantity: 1, unit: 'd', duration: '1d'}
2017-11-03 21:08:48 +00:00
const action = timeShift(queryID, shift)
const nextState = reducer(initialState, action)
2018-02-27 06:08:13 +00:00
expect(nextState[queryID].shifts).toEqual([shift])
2017-11-03 21:08:48 +00:00
})
})
2017-03-30 22:29:43 +00:00
})