Fleet UI: Catch unlikely key edge case, test, refactor (#20015)

This commit is contained in:
RachelElysia 2024-06-26 12:24:11 -04:00 committed by GitHub
parent dc0d215880
commit 8baf57e12a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 27 additions and 36 deletions

View file

@ -11,6 +11,7 @@ const objArray = [
},
];
// tests json known value edge case and hypothetical key edge case
const objArray2 = [
{
host_display_name: "Rachel@Fleet",
@ -22,6 +23,7 @@ const objArray2 = [
hibernatefile: "/var/vm/sleepimage",
},
},
'edge","case': "true",
},
];
@ -30,6 +32,7 @@ const tableHeaders = [
{ id: "last_fetched", sortType: "caseInsensitive" },
{ id: "uid", sortType: "alphanumeric" },
{ id: "json_result", sortType: "caseInsensitive" },
{ id: 'edge","case', sortType: "caseInsensitve" },
];
describe("convertToCSV - utility", () => {
@ -38,9 +41,9 @@ describe("convertToCSV - utility", () => {
'"first_name","last_name"\n"Mike","Stone"\n"Paul","Simon"'
);
});
it("correctly creates table headers and fields with quotes and commas to CSV format", () => {
it("correctly creates table headers and fields including quotes and commas to CSV format", () => {
expect(convertToCSV({ objArray: objArray2, tableHeaders })).toEqual(
'"host_display_name","last_fetched","uid","json_result"\n"Rachel@Fleet","2024-06-25T13:11:18Z","145","{""AC Power:"":{""acwake"":""0"",""hibernatefile"":""/var/vm/sleepimage""}}"'
'"host_display_name","last_fetched","uid","json_result","edge"",""case"\n"Rachel@Fleet","2024-06-25T13:11:18Z","145","{""AC Power:"":{""acwake"":""0"",""hibernatefile"":""/var/vm/sleepimage""}}","true"'
);
});
});

View file

@ -6,6 +6,21 @@ interface ConvertToCSV {
tableHeaders?: any[]; // TODO: typing
}
const formatFieldForCSV = (value: any): string => {
// If the value is an object, stringify it first
if (typeof value === "object") {
value = JSON.stringify(value);
}
// Escape double quotes in the value by doubling them
if (typeof value === "string") {
value = value.replace(/"/g, '""');
}
// Wrap the value in double quotes to enclose any value that may
// have a, or a " in it to distinguish them from a comma separated delimiter
return `"${value}"`;
};
const convertToCSV = ({
objArray,
fieldSortFunc = defaultFieldSortFunc,
@ -15,45 +30,18 @@ const convertToCSV = ({
? tableHeaders.map((header: { id: string }) => header.id)
: Object.keys(objArray[0]);
const fields = fieldSortFunc(tableHeadersStrings);
let fields = fieldSortFunc(tableHeadersStrings);
// TODO: Revisit after v5 if column names are modified/removed from API response.
const hostNameIndex = fields.indexOf("Host");
if (hostNameIndex >= 0) {
fields.splice(hostNameIndex, 1);
}
fields = fields.filter((field) => field !== "Host");
// Revisit end
const jsonFields = fields.map((field) => JSON.stringify(field));
const rows = objArray.map((row: any) => {
// TODO: typing
return fields
.map((field) => {
// Check if the value of the field is a string and needs to be quoted
let value = row[field];
const headerRow = fields.map((field) => formatFieldForCSV(field)).join(",");
const dataRows = objArray.map((row) =>
fields.map((field) => formatFieldForCSV(row[field])).join(",")
);
// If the value is an object, stringify it first
if (typeof value === "object") {
value = JSON.stringify(value);
}
// Escape double quotes in the value by doubling them
if (typeof value === "string") {
value = value.replace(/"/g, '""');
}
// Wrap the value in double quotes to enclose any value tha
// might have a, or a " in it to distinguish them from a comma separated delimiter
value = `"${value}"`;
return value;
})
.join(",");
});
rows.unshift(jsonFields.join(","));
return rows.join("\n");
return [headerRow, ...dataRows].join("\n");
};
export default convertToCSV;