[Discover] Show error and fix app state when updating data view ID in the URL to an invalid ID (#141540)

* [Discover] Fix issue where updating the data view ID in the URL to an invalid ID does not trigger an error, and sets the app state to an invalid state

* [Discover] Clean up work for invalid data view ID

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Davis McPhee 2022-09-26 13:52:23 -03:00 committed by GitHub
parent e35a7310e5
commit 74bf60f14a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 5 deletions

View file

@ -16,7 +16,7 @@ import { useUrlTracking } from './use_url_tracking';
import { getState } from '../services/discover_state';
import { getStateDefaults } from '../utils/get_state_defaults';
import { DiscoverServices } from '../../../build_services';
import { loadDataView } from '../utils/resolve_data_view';
import { loadDataView, resolveDataView } from '../utils/resolve_data_view';
import { useSavedSearch as useSavedSearchData } from './use_saved_search';
import {
MODIFY_COLUMNS_ON_SWITCH,
@ -67,7 +67,7 @@ export function useDiscoverState({
[history, savedSearch, services]
);
const { appStateContainer } = stateContainer;
const { appStateContainer, replaceUrlAppState } = stateContainer;
const [state, setState] = useState(appStateContainer.getState());
@ -190,13 +190,25 @@ export function useDiscoverState({
* That's because appState is updated before savedSearchData$
* The following line of code catches this, but should be improved
*/
const nextDataView = await loadDataView(
const nextDataViewData = await loadDataView(
services.dataViews,
services.uiSettings,
nextState.index
);
savedSearch.searchSource.setField('index', nextDataView.loaded);
const nextDataView = resolveDataView(
nextDataViewData,
savedSearch.searchSource,
services.toastNotifications
);
// If the requested data view is not found, don't try to load it,
// and instead reset the app state to the fallback data view
if (!nextDataViewData.stateValFound) {
replaceUrlAppState({ index: nextDataView.id });
return;
}
savedSearch.searchSource.setField('index', nextDataView);
reset();
}
@ -206,7 +218,16 @@ export function useDiscoverState({
setState(nextState);
});
return () => unsubscribe();
}, [services, appStateContainer, state, refetch$, data$, reset, savedSearch.searchSource]);
}, [
services,
appStateContainer,
state,
refetch$,
data$,
reset,
savedSearch.searchSource,
replaceUrlAppState,
]);
/**
* function to revert any changes to a given saved search

View file

@ -166,6 +166,7 @@ export function resolveDataView(
ownDataViewId: ownDataView.id,
},
}),
'data-test-subj': 'dscDataViewNotFoundShowSavedWarning',
});
return ownDataView;
}
@ -180,6 +181,7 @@ export function resolveDataView(
loadedDataViewId: loadedDataView.id,
},
}),
'data-test-subj': 'dscDataViewNotFoundShowDefaultWarning',
});
}

View file

@ -362,5 +362,39 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
expect(newMainPanelSize).to.be(mainPanelSize - resizeDistance);
});
});
describe('URL state', () => {
const getCurrentDataViewId = (currentUrl: string) => {
const [indexSubstring] = currentUrl.match(/index:[^,]*/)!;
const dataViewId = indexSubstring.replace('index:', '');
return dataViewId;
};
it('should show a warning and fall back to the default data view when navigating to a URL with an invalid data view ID', async () => {
await PageObjects.common.navigateToApp('discover');
await PageObjects.timePicker.setDefaultAbsoluteRange();
await PageObjects.header.waitUntilLoadingHasFinished();
const originalUrl = await browser.getCurrentUrl();
const dataViewId = getCurrentDataViewId(originalUrl);
const newUrl = originalUrl.replace(dataViewId, 'invalid-data-view-id');
await browser.get(newUrl);
await PageObjects.header.waitUntilLoadingHasFinished();
expect(await browser.getCurrentUrl()).to.be(originalUrl);
expect(await testSubjects.exists('dscDataViewNotFoundShowDefaultWarning')).to.be(true);
});
it('should show a warning and fall back to the current data view if the URL is updated to an invalid data view ID', async () => {
await PageObjects.common.navigateToApp('discover');
await PageObjects.timePicker.setDefaultAbsoluteRange();
const originalHash = await browser.execute<[], string>('return window.location.hash');
const dataViewId = getCurrentDataViewId(originalHash);
const newHash = originalHash.replace(dataViewId, 'invalid-data-view-id');
await browser.execute(`window.location.hash = "${newHash}"`);
await PageObjects.header.waitUntilLoadingHasFinished();
const currentHash = await browser.execute<[], string>('return window.location.hash');
expect(currentHash).to.be(originalHash);
expect(await testSubjects.exists('dscDataViewNotFoundShowSavedWarning')).to.be(true);
});
});
});
}