grafana/public/app/features/variables/editor/reducer.test.ts
Josh Hunt 1c6eca09bb
Variables: Explicitly type variable editor extended state (#44749)
* Narrow Variable editor state using selector functions

 - Explicitly type "extended" editor state in editor/reducter.ts using a union
 - Create selectors to narrow the types, using unique properties from each extended state to discriminate the union
 - Update DataSourceVariableEditor to use new style of redux connector
 - Update variable editor components to use new selectors

* fix tests

* Make adhoc variable infoText optional, because it is!

* Add AdHocVariableEditor tests

* DataSourceVariableEditor tests

* comment

* reset

* Wrote tests for selectors \(that actually caught a bug, whodathunkit)

* fix stray types and lint issues

* Rename selector functions
2022-02-08 09:31:42 +11:00

212 lines
7.4 KiB
TypeScript

import { reducerTester } from '../../../../test/core/redux/reducerTester';
import {
addVariableEditorError,
changeVariableEditorExtended,
changeVariableNameFailed,
changeVariableNameSucceeded,
cleanEditorState,
clearIdInEditor,
initialVariableEditorState,
removeVariableEditorError,
setIdInEditor,
variableEditorMounted,
variableEditorReducer,
VariableEditorState,
variableEditorUnMounted,
} from './reducer';
import { toVariablePayload } from '../state/types';
describe('variableEditorReducer', () => {
describe('when setIdInEditor is dispatched', () => {
it('then state should be correct', () => {
const payload = { id: '0' };
reducerTester<VariableEditorState>()
.givenReducer(variableEditorReducer, { ...initialVariableEditorState })
.whenActionIsDispatched(setIdInEditor(payload))
.thenStateShouldEqual({
...initialVariableEditorState,
id: '0',
});
});
});
describe('when clearIdInEditor is dispatched', () => {
it('then state should be correct', () => {
reducerTester<VariableEditorState>()
.givenReducer(variableEditorReducer, { ...initialVariableEditorState, id: '0' })
.whenActionIsDispatched(clearIdInEditor())
.thenStateShouldEqual({
...initialVariableEditorState,
});
});
});
describe('when variableEditorMounted is dispatched', () => {
it('then state should be correct', () => {
const payload = { name: 'A name' };
reducerTester<VariableEditorState>()
.givenReducer(variableEditorReducer, { ...initialVariableEditorState })
.whenActionIsDispatched(variableEditorMounted(payload))
.thenStateShouldEqual({
...initialVariableEditorState,
name: 'A name',
});
});
});
describe('when variableEditorUnMounted is dispatched', () => {
it('then state should be correct', () => {
const initialState = {
...initialVariableEditorState,
id: '0',
name: 'A name',
isValid: false,
errors: { update: 'Something wrong' },
extended: null,
};
const payload = toVariablePayload({ id: '0', type: 'textbox' });
reducerTester<VariableEditorState>()
.givenReducer(variableEditorReducer, initialState)
.whenActionIsDispatched(variableEditorUnMounted(payload))
.thenStateShouldEqual({ ...initialVariableEditorState });
});
});
describe('when changeVariableNameSucceeded is dispatched there are other errors', () => {
it('then state should be correct', () => {
const initialState = {
...initialVariableEditorState,
name: 'A duplicate name',
isValid: false,
errors: { name: 'Duplicate', update: 'Update failed' },
};
const payload = toVariablePayload({ id: '0', type: 'textbox' }, { newName: 'New Name' });
reducerTester<VariableEditorState>()
.givenReducer(variableEditorReducer, initialState)
.whenActionIsDispatched(changeVariableNameSucceeded(payload))
.thenStateShouldEqual({
...initialState,
isValid: false,
errors: { update: 'Update failed' },
name: 'New Name',
});
});
});
describe('when changeVariableNameSucceeded is dispatched there are no other errors', () => {
it('then state should be correct', () => {
const initialState = {
...initialVariableEditorState,
name: 'A duplicate name',
isValid: false,
errors: { name: 'Duplicate' },
};
const payload = toVariablePayload({ id: '0', type: 'textbox' }, { newName: 'New Name' });
reducerTester<VariableEditorState>()
.givenReducer(variableEditorReducer, initialState)
.whenActionIsDispatched(changeVariableNameSucceeded(payload))
.thenStateShouldEqual({
...initialState,
isValid: true,
errors: {},
name: 'New Name',
});
});
});
describe('when changeVariableNameFailed is dispatched', () => {
it('then state should be correct', () => {
const payload = { newName: 'Duplicate name', errorText: 'Name is an duplicate' };
reducerTester<VariableEditorState>()
.givenReducer(variableEditorReducer, { ...initialVariableEditorState })
.whenActionIsDispatched(changeVariableNameFailed(payload))
.thenStateShouldEqual({
...initialVariableEditorState,
isValid: false,
errors: { name: 'Name is an duplicate' },
name: 'Duplicate name',
});
});
});
describe('when addVariableEditorError is dispatched', () => {
it('then state should be correct', () => {
const payload = { errorProp: 'someProp', errorText: 'someProp failed' };
reducerTester<VariableEditorState>()
.givenReducer(variableEditorReducer, { ...initialVariableEditorState })
.whenActionIsDispatched(addVariableEditorError(payload))
.thenStateShouldEqual({
...initialVariableEditorState,
isValid: false,
errors: { someProp: 'someProp failed' },
});
});
});
describe('when removeVariableEditorError is dispatched and there are other errors', () => {
it('then state should be correct', () => {
const payload = { errorProp: 'someProp' };
reducerTester<VariableEditorState>()
.givenReducer(variableEditorReducer, {
...initialVariableEditorState,
errors: { update: 'Update failed', someProp: 'someProp failed' },
isValid: false,
})
.whenActionIsDispatched(removeVariableEditorError(payload))
.thenStateShouldEqual({
...initialVariableEditorState,
isValid: false,
errors: { update: 'Update failed' },
});
});
});
describe('when removeVariableEditorError is dispatched and there are no other errors', () => {
it('then state should be correct', () => {
const payload = { errorProp: 'someProp' };
reducerTester<VariableEditorState>()
.givenReducer(variableEditorReducer, {
...initialVariableEditorState,
errors: { someProp: 'someProp failed' },
isValid: false,
})
.whenActionIsDispatched(removeVariableEditorError(payload))
.thenStateShouldEqual({
...initialVariableEditorState,
isValid: true,
errors: {},
});
});
});
describe('when changeVariableEditorExtended is dispatched', () => {
it('then state should be correct', () => {
const payload = { propName: 'someProp', propValue: [{}] };
reducerTester<VariableEditorState>()
.givenReducer(variableEditorReducer, { ...initialVariableEditorState })
.whenActionIsDispatched(changeVariableEditorExtended(payload))
.thenStateShouldEqual({
...initialVariableEditorState,
extended: {
// @ts-ignore - temp ignoring this, we'll fix it soon
someProp: [{}],
},
});
});
});
describe('when cleanEditorState is dispatched', () => {
it('then state should be correct', () => {
reducerTester<VariableEditorState>()
.givenReducer(variableEditorReducer, {
...initialVariableEditorState,
isValid: false,
errors: { name: 'Name is an duplicate' },
name: 'Duplicate name',
})
.whenActionIsDispatched(cleanEditorState())
.thenStateShouldEqual({ ...initialVariableEditorState });
});
});
});