Skip to content

Commit

Permalink
front: add validation when importing trains from json file
Browse files Browse the repository at this point in the history
Signed-off-by: Clara Ni <[email protected]>
  • Loading branch information
clarani committed Jan 2, 2025
1 parent 64fade6 commit 3f4ed07
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -327,30 +327,30 @@ const ImportTrainScheduleConfig = ({
return;
}

const fileHasBeenParsed = processJsonFile(
fileContent,
file.type,
setTrainsJsonData,
dispatch,
t
);

// the file has been processed, return
if (fileHasBeenParsed) {
return;
}

// try to parse the file as an XML file
try {
processJsonFile(fileContent, setTrainsJsonData, dispatch, t);
await processXmlFile(fileContent, parseRailML, updateTrainSchedules);
} catch {
// if file was json, display error message immidiately and return
if (file.type === 'application/json') {
dispatch(
setFailure({
name: t('errorMessages.error'),
message: t('errorMessages.errorInvalidFile'),
})
);
return;
}

try {
await processXmlFile(fileContent, parseRailML, updateTrainSchedules);
} catch {
dispatch(
setFailure({
name: t('errorMessages.error'),
message: t('errorMessages.errorUnsupportedFileType'),
})
);
}
// the file is not supported or is an invalid XML file
dispatch(
setFailure({
name: t('errorMessages.error'),
message: t('errorMessages.errorInvalidFile'),
})
);
}
};
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,83 @@ export const handleFileReadingError = (error: Error) => {
console.error('File reading error:', error);
};

const TRAIN_SCHEDULE_COMPULSORY_KEYS: (keyof TrainScheduleBase)[] = [
'constraint_distribution',
'path',
'rolling_stock_name',
'start_time',
'train_name',
];

const validateTrainSchedules = (
importedTrainSchedules: Partial<TrainScheduleBase>[]
): TrainScheduleBase[] => {
const isInvalidTrainSchedules = importedTrainSchedules.some((trainSchedule) => {
if (
TRAIN_SCHEDULE_COMPULSORY_KEYS.some((key) => !(key in trainSchedule)) ||
!Array.isArray(trainSchedule.path)
) {
return true;
}
const hasInvalidSteps = trainSchedule.path.some((step) => !('id' in step));
return hasInvalidSteps;
});

if (isInvalidTrainSchedules) {
throw new Error('Invalid train schedules: some compulsory keys are missing');
}
return importedTrainSchedules as TrainScheduleBase[];
};

export const processJsonFile = (
fileContent: string,
fileExtension: string,
setTrainsJsonData: (data: TrainScheduleBase[]) => void,
dispatch: Dispatch,
t: TFunction
) => {
const importedTrainSchedules: TrainScheduleBase[] = JSON.parse(fileContent);
if (importedTrainSchedules && importedTrainSchedules.length > 0) {
setTrainsJsonData(importedTrainSchedules);
} else {
const isJsonFile = fileExtension === 'application/json';

// try to parse the file content
let rawContent;
try {
rawContent = JSON.parse(fileContent);
} catch {
if (isJsonFile) {
dispatch(
setFailure({
name: t('errorMessages.error'),
message: t('errorMessages.errorInvalidFile'),
})
);
}
return isJsonFile;
}

// validate the trainSchedules
try {
const importedTrainSchedules = validateTrainSchedules(rawContent);
if (importedTrainSchedules.length > 0) {
setTrainsJsonData(importedTrainSchedules);
} else {
dispatch(
setFailure({
name: t('errorMessages.error'),
message: t('errorMessages.errorEmptyFile'),
})
);
}
} catch {
dispatch(
setFailure({
name: t('errorMessages.error'),
message: t('errorMessages.errorEmptyFile'),
message: t('errorMessages.errorInvalidFile'),
})
);
}

// file has been parsed successfully
return true;
};

export const processXmlFile = async (
Expand Down

0 comments on commit 3f4ed07

Please sign in to comment.