chronograf/ui/spec/data_explorer/reducers/queryConfigSpec.js

423 lines
11 KiB
JavaScript
Raw Normal View History

2017-03-30 22:29:43 +00:00
import reducer from 'src/data_explorer/reducers/queryConfigs'
import defaultQueryConfig from 'src/utils/defaultQueryConfig'
import {
chooseNamespace,
chooseMeasurement,
toggleField,
applyFuncsToField,
chooseTag,
groupByTag,
groupByTime,
toggleTagAcceptance,
fill,
updateQueryConfig,
updateRawQuery,
2017-04-07 19:51:18 +00:00
editQueryStatus,
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
}
}
function buildInitialState(queryId, params) {
return Object.assign({}, defaultQueryConfig({id: queryId}), params)
}
describe('Chronograf.Reducers.DataExplorer.queryConfigs', () => {
2017-03-30 22:29:43 +00:00
const queryId = 123
it('can add a query', () => {
2017-03-30 22:29:43 +00:00
const state = reducer({}, fakeAddQueryAction('blah', queryId))
2017-03-30 22:29:43 +00:00
const actual = state[queryId]
const expected = defaultQueryConfig({id: queryId})
2017-03-30 22:29:43 +00:00
expect(actual).to.deep.equal(expected)
})
describe('choosing db, rp, and measurement', () => {
2017-03-30 22:29:43 +00:00
let state
beforeEach(() => {
2017-03-30 22:29:43 +00:00
state = reducer({}, fakeAddQueryAction('any', queryId))
})
it('sets the db and rp', () => {
2017-05-30 20:38:50 +00:00
const newState = reducer(
state,
chooseNamespace(queryId, {
database: 'telegraf',
retentionPolicy: 'monitor',
})
)
2017-03-30 22:29:43 +00:00
expect(newState[queryId].database).to.equal('telegraf')
expect(newState[queryId].retentionPolicy).to.equal('monitor')
})
it('sets the measurement', () => {
2017-03-30 22:29:43 +00:00
const newState = reducer(state, chooseMeasurement(queryId, 'mem'))
2017-03-30 22:29:43 +00:00
expect(newState[queryId].measurement).to.equal('mem')
})
})
describe('a query has measurements and fields', () => {
2017-03-30 22:29:43 +00:00
let state
beforeEach(() => {
2017-03-30 22:29:43 +00:00
const one = reducer({}, fakeAddQueryAction('any', queryId))
2017-05-30 20:38:50 +00:00
const two = reducer(
one,
chooseNamespace(queryId, {
database: '_internal',
retentionPolicy: 'daily',
})
)
2017-03-30 22:29:43 +00:00
const three = reducer(two, chooseMeasurement(queryId, 'disk'))
2017-05-30 20:38:50 +00:00
state = reducer(
three,
toggleField(queryId, {field: 'a great field', funcs: []})
)
2017-03-30 22:29:43 +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?
2017-03-30 22:29:43 +00:00
expect(state[queryId].measurement).to.exist
expect(state[queryId].fields.length).to.equal(1)
2017-05-30 20:38:50 +00:00
const newState = reducer(
state,
chooseNamespace(queryId, {
database: 'newdb',
retentionPolicy: 'newrp',
})
)
2017-03-30 22:29:43 +00:00
expect(newState[queryId].measurement).not.to.exist
expect(newState[queryId].fields.length).to.equal(0)
})
})
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?
2017-03-30 22:29:43 +00:00
expect(state[queryId].fields.length).to.equal(1)
2017-05-30 20:38:50 +00:00
const newState = reducer(
state,
chooseMeasurement(queryId, 'newmeasurement')
)
2017-03-30 22:29:43 +00:00
expect(state[queryId].database).to.equal(newState[queryId].database)
2017-05-30 20:38:50 +00:00
expect(state[queryId].retentionPolicy).to.equal(
newState[queryId].retentionPolicy
)
2017-03-30 22:29:43 +00:00
expect(newState[queryId].fields.length).to.equal(0)
})
})
describe('DE_TOGGLE_FIELD', () => {
it('can toggle multiple fields', () => {
expect(state[queryId].fields.length).to.equal(1)
const newState = reducer(
state,
toggleField(queryId, {field: 'a different field', funcs: []})
)
expect(newState[queryId].fields.length).to.equal(2)
expect(newState[queryId].fields[1].field).to.equal('a different field')
})
it('applies a funcs to newly selected fields', () => {
expect(state[queryId].fields.length).to.equal(1)
const oneFieldOneFunc = reducer(
state,
applyFuncsToField(queryId, {field: 'a great field', funcs: ['func1']})
)
const newState = reducer(
oneFieldOneFunc,
toggleField(queryId, {field: 'a different field', funcs: []})
)
expect(newState[queryId].fields[1].funcs.length).to.equal(1)
expect(newState[queryId].fields[1].funcs[0]).to.equal('func1')
})
2017-08-30 21:09:24 +00:00
it('adds the field property to query config if not found', () => {
delete state[queryId].fields
expect(state[queryId].fields).to.equal(undefined)
const field = 'fk1'
const newState = reducer(
state,
toggleField(queryId, {field: 'fk1', funcs: []})
)
expect(newState[queryId].fields.length).to.equal(1)
expect(newState[queryId].fields[0].field).to.equal(field)
})
})
2017-03-30 22:29:43 +00:00
})
describe('DE_APPLY_FUNCS_TO_FIELD', () => {
it('applies functions to a field without any existing functions', () => {
const initialState = {
[queryId]: {
id: 123,
database: 'db1',
measurement: 'm1',
fields: [
{field: 'f1', funcs: ['fn1', 'fn2']},
{field: 'f2', funcs: ['fn1']},
],
2017-03-30 22:29:43 +00:00
},
}
const action = applyFuncsToField(queryId, {
field: 'f1',
funcs: ['fn3', 'fn4'],
2017-03-30 22:29:43 +00:00
})
2017-03-30 22:29:43 +00:00
const nextState = reducer(initialState, action)
expect(nextState[queryId].fields).to.eql([
{field: 'f1', funcs: ['fn3', 'fn4']},
{field: 'f2', funcs: ['fn1']},
2017-03-30 22:29:43 +00:00
])
})
it('removes all functions and group by time when one field has no funcs applied', () => {
const initialState = {
[queryId]: {
id: 123,
database: 'db1',
measurement: 'm1',
fields: [
{field: 'f1', funcs: ['fn1', 'fn2']},
{field: 'f2', funcs: ['fn3', 'fn4']},
],
groupBy: {
time: '1m',
tags: [],
},
2017-03-30 22:29:43 +00:00
},
}
const action = applyFuncsToField(queryId, {
field: 'f1',
funcs: [],
2017-03-30 22:29:43 +00:00
})
2017-03-30 22:29:43 +00:00
const nextState = reducer(initialState, action)
expect(nextState[queryId].fields).to.eql([
{field: 'f1', funcs: []},
{field: 'f2', funcs: []},
2017-03-30 22:29:43 +00:00
])
expect(nextState[queryId].groupBy.time).to.equal(null)
})
})
describe('DE_CHOOSE_TAG', () => {
it('adds a tag key/value to the query', () => {
const initialState = {
[queryId]: buildInitialState(queryId, {
tags: {
k1: ['v0'],
k2: ['foo'],
},
}),
2017-03-30 22:29:43 +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)
expect(nextState[queryId].tags).to.eql({
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 = {
[queryId]: buildInitialState(queryId, {
tags: {},
}),
2017-03-30 22:29:43 +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)
expect(nextState[queryId].tags).to.eql({
k1: ['v1'],
2017-03-30 22:29:43 +00:00
})
})
it('removes a value that is already in the list', () => {
const initialState = {
[queryId]: buildInitialState(queryId, {
tags: {
k1: ['v1'],
},
}),
2017-03-30 22:29:43 +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
2017-03-30 22:29:43 +00:00
expect(nextState[queryId].tags).to.eql({})
})
})
describe('DE_GROUP_BY_TAG', () => {
it('adds a tag key/value to the query', () => {
const initialState = {
[queryId]: {
id: 123,
database: 'db1',
measurement: 'm1',
fields: [],
tags: {},
groupBy: {tags: [], time: null},
2017-03-30 22:29:43 +00:00
},
}
const action = groupByTag(queryId, 'k1')
2017-03-30 22:29:43 +00:00
const nextState = reducer(initialState, action)
expect(nextState[queryId].groupBy).to.eql({
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 = {
[queryId]: {
id: 123,
database: 'db1',
measurement: 'm1',
fields: [],
tags: {},
groupBy: {tags: ['k1'], time: null},
2017-03-30 22:29:43 +00:00
},
}
const action = groupByTag(queryId, 'k1')
2017-03-30 22:29:43 +00:00
const nextState = reducer(initialState, action)
expect(nextState[queryId].groupBy).to.eql({
time: null,
tags: [],
2017-03-30 22:29:43 +00:00
})
})
})
describe('DE_TOGGLE_TAG_ACCEPTANCE', () => {
it('it toggles areTagsAccepted', () => {
const initialState = {
[queryId]: buildInitialState(queryId),
2017-03-30 22:29:43 +00:00
}
const action = toggleTagAcceptance(queryId)
2017-03-30 22:29:43 +00:00
const nextState = reducer(initialState, action)
2017-05-30 20:38:50 +00:00
expect(nextState[queryId].areTagsAccepted).to.equal(
!initialState[queryId].areTagsAccepted
)
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 = {
[queryId]: buildInitialState(queryId),
2017-03-30 22:29:43 +00:00
}
2017-03-30 22:29:43 +00:00
const action = groupByTime(queryId, time)
2017-03-30 22:29:43 +00:00
const nextState = reducer(initialState, action)
2017-03-30 22:29:43 +00:00
expect(nextState[queryId].groupBy.time).to.equal(time)
})
})
it('updates entire config', () => {
const initialState = {
[queryId]: buildInitialState(queryId),
}
const expected = defaultQueryConfig({id: queryId}, {rawText: 'hello'})
const action = updateQueryConfig(expected)
const nextState = reducer(initialState, action)
expect(nextState[queryId]).to.deep.equal(expected)
})
2017-05-30 20:38:50 +00:00
it("updates a query's raw text", () => {
const initialState = {
[queryId]: buildInitialState(queryId),
2017-03-30 22:29:43 +00:00
}
const text = 'foo'
const action = updateRawQuery(queryId, text)
2017-03-30 22:29:43 +00:00
const nextState = reducer(initialState, action)
2017-03-30 22:29:43 +00:00
expect(nextState[queryId].rawText).to.equal('foo')
})
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 = {
[queryId]: buildInitialState(queryId),
}
const status = 'your query was sweet'
2017-04-07 19:51:18 +00:00
const action = editQueryStatus(queryId, status)
2017-03-29 21:36:06 +00:00
const nextState = reducer(initialState, action)
2017-04-07 19:51:18 +00:00
expect(nextState[queryId].status).to.equal(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 = {
[queryId]: buildInitialState(queryId),
}
const time = '10s'
const action = groupByTime(queryId, time)
const nextState = reducer(initialState, action)
expect(nextState[queryId].fill).to.equal(NULL_STRING)
})
it('updates fill to non-null-string non-number string value', () => {
const initialState = {
[queryId]: buildInitialState(queryId),
}
const action = fill(queryId, LINEAR)
const nextState = reducer(initialState, action)
expect(nextState[queryId].fill).to.equal(LINEAR)
})
})
2017-03-30 22:29:43 +00:00
})