Allow slashes in persistence keys (#1961)

* Allow slashes in persistence keys

* Add unit tests
This commit is contained in:
Laurent Nguyen 2024-09-09 19:12:55 +02:00 committed by GitHub
parent 2c2f0c8d7b
commit 50c47a82d6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 34 additions and 10 deletions

View File

@ -1,4 +1,11 @@
import { createKeyFromPath, deleteState, loadState, MAX_ENTRY_NB, saveState } from "Shared/AppStatePersistenceUtility"; import {
createKeyFromPath,
deleteState,
loadState,
MAX_ENTRY_NB,
PATH_SEPARATOR,
saveState,
} from "Shared/AppStatePersistenceUtility";
import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility"; import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility";
jest.mock("Shared/StorageUtility", () => ({ jest.mock("Shared/StorageUtility", () => ({
@ -166,5 +173,28 @@ describe("AppStatePersistenceUtility", () => {
expect(key).toContain(storePath.databaseName); expect(key).toContain(storePath.databaseName);
expect(key).toContain(storePath.containerName); expect(key).toContain(storePath.containerName);
}); });
it("should handle components that include special characters", () => {
const storePath = {
componentName: "a/b/c",
subComponentName: 'd"e"f',
globalAccountName: "g:h",
databaseName: "i{j",
containerName: "https://blahblah.document.azure.com:443/",
};
const key = createKeyFromPath(storePath);
const segments = key.split(PATH_SEPARATOR);
expect(segments.length).toEqual(6); // There should be 5 segments
expect(segments[0]).toBe("");
const expectSubstringsInValue = (value: string, subStrings: string[]): boolean =>
subStrings.every((subString) => value.includes(subString));
expect(expectSubstringsInValue(segments[1], ["a", "b", "c"])).toBe(true);
expect(expectSubstringsInValue(segments[2], ["d", "e", "f"])).toBe(true);
expect(expectSubstringsInValue(segments[3], ["g", "h"])).toBe(true);
expect(expectSubstringsInValue(segments[4], ["i", "j"])).toBe(true);
expect(expectSubstringsInValue(segments[5], ["https", "blahblah", "document", "com", "443"])).toBe(true);
});
}); });
}); });

View File

@ -2,7 +2,7 @@ import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility";
// The component name whose state is being saved. Component name must not include special characters. // The component name whose state is being saved. Component name must not include special characters.
export type ComponentName = "DocumentsTab"; export type ComponentName = "DocumentsTab";
export const PATH_SEPARATOR = "/"; // export for testing purposes
const SCHEMA_VERSION = 1; const SCHEMA_VERSION = 1;
// Export for testing purposes // Export for testing purposes
@ -87,16 +87,10 @@ const orderedPathSegments: (keyof StorePath)[] = [
* @param path * @param path
*/ */
export const createKeyFromPath = (path: StorePath): string => { export const createKeyFromPath = (path: StorePath): string => {
if (path.componentName.includes("/")) { let key = `${PATH_SEPARATOR}${encodeURIComponent(path.componentName)}`; // ComponentName is always there
throw new Error(`Invalid component name: ${path.componentName}`);
}
let key = `/${path.componentName}`; // ComponentName is always there
orderedPathSegments.forEach((segment) => { orderedPathSegments.forEach((segment) => {
const segmentValue = path[segment as keyof StorePath]; const segmentValue = path[segment as keyof StorePath];
if (segmentValue.includes("/")) { key += `${PATH_SEPARATOR}${segmentValue !== undefined ? encodeURIComponent(segmentValue) : ""}`;
throw new Error(`Invalid setting path segment: ${segment}`);
}
key += `/${segmentValue !== undefined ? segmentValue : ""}`;
}); });
return key; return key;
}; };