Commit 6b4d1dce by Lukas Siatka Committed by GitHub

Explore: updates key and refId reassignment on query row operations in Explore reducer (#25249)

* Chore: adds query keys and refId reassignment on query row removal

* Chore: updates explore reducer tests to cover query row adding, removal, refId and key reassignment

* Chore: changes refId value in explore reducer from undefined to string to avoid introducing new strict null errors

* Chore: fixes a small nitpick with array spread in Explore reducer

* Chore: removes unnecessary dispatches in query row tests in Explore reducer test
parent e65dbcfe
...@@ -31,10 +31,14 @@ import { ...@@ -31,10 +31,14 @@ import {
toggleGraphAction, toggleGraphAction,
toggleTableAction, toggleTableAction,
updateDatasourceInstanceAction, updateDatasourceInstanceAction,
addQueryRowAction,
removeQueryRowAction,
} from './actionTypes'; } from './actionTypes';
import { serializeStateToUrlParam } from 'app/core/utils/explore'; import { serializeStateToUrlParam } from 'app/core/utils/explore';
import { updateLocation } from '../../../core/actions'; import { updateLocation } from '../../../core/actions';
const QUERY_KEY_REGEX = /Q-([0-9]+)-([0-9.]+)-([0-9]+)/;
describe('Explore item reducer', () => { describe('Explore item reducer', () => {
describe('scanning', () => { describe('scanning', () => {
it('should start scanning', () => { it('should start scanning', () => {
...@@ -231,6 +235,75 @@ describe('Explore item reducer', () => { ...@@ -231,6 +235,75 @@ describe('Explore item reducer', () => {
}); });
}); });
}); });
describe('query rows', () => {
it('adds a new query row', () => {
reducerTester<ExploreItemState>()
.givenReducer(itemReducer, ({
queries: [],
} as unknown) as ExploreItemState)
.whenActionIsDispatched(
addQueryRowAction({
exploreId: ExploreId.left,
query: { refId: 'A', key: 'mockKey' },
index: 0,
})
)
.thenStateShouldEqual(({
queries: [{ refId: 'A', key: 'mockKey' }],
queryKeys: ['mockKey-0'],
} as unknown) as ExploreItemState);
});
it('removes a query row', () => {
reducerTester<ExploreItemState>()
.givenReducer(itemReducer, ({
queries: [
{ refId: 'A', key: 'mockKey' },
{ refId: 'B', key: 'mockKey' },
],
queryKeys: ['mockKey-0', 'mockKey-1'],
} as unknown) as ExploreItemState)
.whenActionIsDispatched(
removeQueryRowAction({
exploreId: ExploreId.left,
index: 0,
})
)
.thenStatePredicateShouldEqual((resultingState: ExploreItemState) => {
expect(resultingState.queries.length).toBe(1);
expect(resultingState.queries[0].refId).toBe('A');
expect(resultingState.queries[0].key).toMatch(QUERY_KEY_REGEX);
expect(resultingState.queryKeys[0]).toMatch(QUERY_KEY_REGEX);
return true;
});
});
it('reassigns query refId after removing a query to keep queries in order', () => {
reducerTester<ExploreItemState>()
.givenReducer(itemReducer, ({
queries: [{ refId: 'A' }, { refId: 'B' }, { refId: 'C' }],
queryKeys: ['undefined-0', 'undefined-1', 'undefined-2'],
} as unknown) as ExploreItemState)
.whenActionIsDispatched(
removeQueryRowAction({
exploreId: ExploreId.left,
index: 0,
})
)
.thenStatePredicateShouldEqual((resultingState: ExploreItemState) => {
expect(resultingState.queries.length).toBe(2);
const queriesRefIds = resultingState.queries.map(query => query.refId);
const queriesKeys = resultingState.queries.map(query => query.key);
expect(queriesRefIds).toEqual(['A', 'B']);
queriesKeys.forEach(queryKey => {
expect(queryKey).toMatch(QUERY_KEY_REGEX);
});
resultingState.queryKeys.forEach(queryKey => {
expect(queryKey).toMatch(QUERY_KEY_REGEX);
});
return true;
});
});
});
}); });
export const setup = (urlStateOverrides?: any) => { export const setup = (urlStateOverrides?: any) => {
......
...@@ -367,15 +367,24 @@ export const itemReducer = (state: ExploreItemState = makeExploreItemState(), ac ...@@ -367,15 +367,24 @@ export const itemReducer = (state: ExploreItemState = makeExploreItemState(), ac
} }
if (removeQueryRowAction.match(action)) { if (removeQueryRowAction.match(action)) {
const { queries, queryKeys } = state; const { queries } = state;
const { index } = action.payload; const { index } = action.payload;
if (queries.length <= 1) { if (queries.length <= 1) {
return state; return state;
} }
const nextQueries = [...queries.slice(0, index), ...queries.slice(index + 1)]; // removes a query under a given index and reassigns query keys and refIds to keep everything in order
const nextQueryKeys = [...queryKeys.slice(0, index), ...queryKeys.slice(index + 1)]; const queriesAfterRemoval: DataQuery[] = [...queries.slice(0, index), ...queries.slice(index + 1)].map(query => {
return { ...query, refId: '' };
});
const nextQueries: DataQuery[] = [];
queriesAfterRemoval.forEach((query, i) => {
nextQueries.push(generateNewKeyAndAddRefIdIfMissing(query, nextQueries, i));
});
const nextQueryKeys: string[] = nextQueries.map(query => query.key);
return { return {
...state, ...state,
......
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