fixed some cypress tests and fixed issue where an invalid date caused the page to constantly reload w/ burnettk

This commit is contained in:
jasquat 2022-12-28 12:27:37 -05:00
parent 9c52ff6f43
commit c68b85a9c2
8 changed files with 52 additions and 32 deletions

View File

@ -176,7 +176,8 @@ def handle_exception(exception: Exception) -> flask.wrappers.Response:
id = capture_exception(exception) id = capture_exception(exception)
if isinstance(exception, ApiError): if isinstance(exception, ApiError):
current_app.logger.info(f"Sending ApiError exception to sentry: {exception} with error code {exception.error_code}") current_app.logger.info(
f"Sending ApiError exception to sentry: {exception} with error code {exception.error_code}")
organization_slug = current_app.config.get("SENTRY_ORGANIZATION_SLUG") organization_slug = current_app.config.get("SENTRY_ORGANIZATION_SLUG")
project_slug = current_app.config.get("SENTRY_PROJECT_SLUG") project_slug = current_app.config.get("SENTRY_PROJECT_SLUG")

View File

@ -135,7 +135,6 @@ def permissions_check(body: Dict[str, Dict[str, list[str]]]) -> flask.wrappers.R
status_code=400, status_code=400,
) )
) )
response_dict: dict[str, dict[str, bool]] = {} response_dict: dict[str, dict[str, bool]] = {}
requests_to_check = body["requests_to_check"] requests_to_check = body["requests_to_check"]

View File

@ -168,6 +168,8 @@ describe('process-instances', () => {
it('can filter', () => { it('can filter', () => {
cy.getBySel('process-instance-list-link').click(); cy.getBySel('process-instance-list-link').click();
cy.getBySel('process-instance-list-all').click();
cy.contains('All Process Instances');
cy.assertAtLeastOneItemInPaginatedResults(); cy.assertAtLeastOneItemInPaginatedResults();
const statusSelect = '#process-instance-status-select'; const statusSelect = '#process-instance-status-select';
@ -175,6 +177,7 @@ describe('process-instances', () => {
if (!['all', 'waiting'].includes(processStatus)) { if (!['all', 'waiting'].includes(processStatus)) {
cy.get(statusSelect).click(); cy.get(statusSelect).click();
cy.get(statusSelect).contains(processStatus).click(); cy.get(statusSelect).contains(processStatus).click();
cy.get(statusSelect).click();
cy.getBySel('filter-button').click(); cy.getBySel('filter-button').click();
// FIXME: wait a little bit for the useEffects to be able to fully set processInstanceFilters // FIXME: wait a little bit for the useEffects to be able to fully set processInstanceFilters
cy.wait(1000); cy.wait(1000);

View File

@ -92,7 +92,7 @@ describe('tasks', () => {
cy.contains('Tasks').should('exist'); cy.contains('Tasks').should('exist');
// FIXME: this will probably need a better way to link to the proper form that we want // FIXME: this will probably need a better way to link to the proper form that we want
cy.contains('Complete Task').click(); cy.contains('Go').click();
submitInputIntoFormField( submitInputIntoFormField(
'get_user_generated_number_four', 'get_user_generated_number_four',

View File

@ -40,6 +40,7 @@ import {
getProcessModelFullIdentifierFromSearchParams, getProcessModelFullIdentifierFromSearchParams,
modifyProcessIdentifierForPathParam, modifyProcessIdentifierForPathParam,
refreshAtInterval, refreshAtInterval,
setErrorMessageSafely,
} from '../helpers'; } from '../helpers';
import PaginationForTable from './PaginationForTable'; import PaginationForTable from './PaginationForTable';
@ -130,11 +131,11 @@ export default function ProcessInstanceListTable({
const [endFromTimeInvalid, setEndFromTimeInvalid] = useState<boolean>(false); const [endFromTimeInvalid, setEndFromTimeInvalid] = useState<boolean>(false);
const [endToTimeInvalid, setEndToTimeInvalid] = useState<boolean>(false); const [endToTimeInvalid, setEndToTimeInvalid] = useState<boolean>(false);
const setErrorMessage = (useContext as any)(ErrorContext)[1]; const [errorMessage, setErrorMessage] = (useContext as any)(ErrorContext);
const processInstancePathPrefix = const processInstancePathPrefix =
variant === 'all' variant === 'all'
? '/admin/process-instances' ? '/admin/process-instances/all'
: '/admin/process-instances/for-me'; : '/admin/process-instances/for-me';
const [processStatusAllOptions, setProcessStatusAllOptions] = useState<any[]>( const [processStatusAllOptions, setProcessStatusAllOptions] = useState<any[]>(
@ -428,8 +429,11 @@ export default function ProcessInstanceListTable({
} }
}; };
// TODO: after factoring this out page hangs when invalid date ranges and applying the filter // jasquat/burnettk - 2022-12-28 do not check the validity of the dates when rendering components to avoid the page being
const calculateStartAndEndSeconds = () => { // re-rendered while the user is still typing. NOTE that we also prevented rerendering
// with the use of the setErrorMessageSafely function. we are not sure why the context not
// changing still causes things to rerender when we call its setter without our extra check.
const calculateStartAndEndSeconds = (validate: boolean = true) => {
const startFromSeconds = convertDateAndTimeStringsToSeconds( const startFromSeconds = convertDateAndTimeStringsToSeconds(
startFromDate, startFromDate,
startFromTime || '00:00:00' startFromTime || '00:00:00'
@ -447,29 +451,25 @@ export default function ProcessInstanceListTable({
endToTime || '00:00:00' endToTime || '00:00:00'
); );
let valid = true; let valid = true;
if (validate) {
let message = '';
if (isTrueComparison(startFromSeconds, '>', startToSeconds)) { if (isTrueComparison(startFromSeconds, '>', startToSeconds)) {
setErrorMessage({ message = '"Start date from" cannot be after "start date to"';
message: '"Start date from" cannot be after "start date to"',
});
valid = false;
} }
if (isTrueComparison(endFromSeconds, '>', endToSeconds)) { if (isTrueComparison(endFromSeconds, '>', endToSeconds)) {
setErrorMessage({ message = '"End date from" cannot be after "end date to"';
message: '"End date from" cannot be after "end date to"',
});
valid = false;
} }
if (isTrueComparison(startFromSeconds, '>', endFromSeconds)) { if (isTrueComparison(startFromSeconds, '>', endFromSeconds)) {
setErrorMessage({ message = '"Start date from" cannot be after "end date from"';
message: '"Start date from" cannot be after "end date from"',
});
valid = false;
} }
if (isTrueComparison(startToSeconds, '>', endToSeconds)) { if (isTrueComparison(startToSeconds, '>', endToSeconds)) {
setErrorMessage({ message = '"Start date to" cannot be after "end date to"';
message: '"Start date to" cannot be after "end date to"', }
}); if (message !== '') {
valid = false; valid = false;
setErrorMessageSafely(message, errorMessage, setErrorMessage);
}
} }
return { return {
@ -657,7 +657,7 @@ export default function ProcessInstanceListTable({
startToSeconds, startToSeconds,
endFromSeconds, endFromSeconds,
endToSeconds, endToSeconds,
} = calculateStartAndEndSeconds(); } = calculateStartAndEndSeconds(false);
if (!valid || !reportMetadata) { if (!valid || !reportMetadata) {
return null; return null;

View File

@ -8,6 +8,7 @@ import {
DEFAULT_PER_PAGE, DEFAULT_PER_PAGE,
DEFAULT_PAGE, DEFAULT_PAGE,
} from './components/PaginationForTable'; } from './components/PaginationForTable';
import { ErrorForDisplay } from './interfaces';
// https://www.30secondsofcode.org/js/s/slugify // https://www.30secondsofcode.org/js/s/slugify
export const slugifyString = (str: any) => { export const slugifyString = (str: any) => {
@ -238,3 +239,17 @@ export const getBpmnProcessIdentifiers = (rootBpmnElement: any) => {
childProcesses.push(rootBpmnElement.businessObject.id); childProcesses.push(rootBpmnElement.businessObject.id);
return childProcesses; return childProcesses;
}; };
// Setting the error message state to the same string is still considered a change
// and re-renders the page so check the message first to avoid that.
export const setErrorMessageSafely = (
newErrorMessageString: string,
oldErrorMessage: ErrorForDisplay,
errorMessageSetter: any
) => {
if (oldErrorMessage && oldErrorMessage.message === newErrorMessageString) {
return null;
}
errorMessageSetter({ message: newErrorMessageString });
return null;
};

View File

@ -67,6 +67,7 @@ export default function ProcessInstanceList({ variant }: OwnProps) {
<TabList aria-label="List of tabs"> <TabList aria-label="List of tabs">
<Tab <Tab
title="Only show process instances for the current user." title="Only show process instances for the current user."
data-qa="process-instance-list-for-me"
onClick={() => { onClick={() => {
navigate('/admin/process-instances/for-me'); navigate('/admin/process-instances/for-me');
}} }}
@ -76,6 +77,7 @@ export default function ProcessInstanceList({ variant }: OwnProps) {
<Can I="GET" a={targetUris.processInstanceListPath} ability={ability}> <Can I="GET" a={targetUris.processInstanceListPath} ability={ability}>
<Tab <Tab
title="Show all process instances for all users." title="Show all process instances for all users."
data-qa="process-instance-list-all"
onClick={() => { onClick={() => {
navigate('/admin/process-instances/all'); navigate('/admin/process-instances/all');
}} }}