Skip to content

Commit

Permalink
feat: prevent creating slices and custom types with reserved name (#1507
Browse files Browse the repository at this point in the history
)
  • Loading branch information
BohdanOne authored Dec 17, 2024
1 parent c41b16e commit 5d6f55c
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,18 @@ export const CreateCustomTypeModal: React.FC<CreateCustomTypeModalProps> = ({
})} name is already taken.`;
}

if (["update", "insert"].includes(label.toLowerCase())) {
errors.label = `Name "${label}" is reserved for Slice Machine use.`;
}

if (!id || !id.length) {
errors.id = "ID cannot be empty.";
}

if (["update", "insert"].includes(id.toLowerCase())) {
errors.id = `Id "${id}" is reserved for Slice Machine use.`;
}

// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
if (!errors.id && id && !API_ID_REGEX.exec(id)) {
errors.id = "Invalid id: No special characters allowed.";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ export const RenameCustomTypeModal: React.FC<RenameCustomTypeModalProps> = ({
})} name is already taken.`;
}

if (["update", "insert"].includes(newName.toLowerCase())) {
errors.customTypeName = `Name "${newName}" is reserved for Slice Machine use.`;
}

return Object.keys(errors).length > 0 ? errors : undefined;
}}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,21 @@ export function validateSliceModalValues(
if (!sliceName) {
return { sliceName: "Cannot be empty" };
}
if (RESERVED_SLICE_NAME.includes(sliceName.toLowerCase())) {
return {
sliceName: `Name "${sliceName}" is reserved for Slice Machine use.`,
};
}
if (!API_ID_REGEX.exec(sliceName)) {
return { sliceName: "No special characters allowed" };
return { sliceName: "No special characters allowed." };
}
const cased = startCase(camelCase(sliceName)).replace(/\s/gm, "");
if (cased !== sliceName.trim()) {
return { sliceName: "Value has to be PascalCased" };
return { sliceName: "Value has to be PascalCased." };
}
// See: #599
if (sliceName.match(/^\d/)) {
return { sliceName: "Value cannot start with a number" };
}
if (RESERVED_SLICE_NAME.includes(sliceName)) {
return {
sliceName: `${sliceName} is reserved for Slice Machine use`,
};
return { sliceName: "Value cannot start with a number." };
}

const localNames = localLibs.flatMap((lib) =>
Expand Down
2 changes: 1 addition & 1 deletion packages/slice-machine/src/legacy/lib/consts.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// A list of slice names that are reserved for internal uses.
export const RESERVED_SLICE_NAME = ["components"];
export const RESERVED_SLICE_NAME = ["components", "update", "insert"];

export const acceptedImagesTypes = ["png", "jpg", "jpeg"];

Expand Down
17 changes: 17 additions & 0 deletions playwright/tests/customTypes/customTypesTable.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,23 @@ test("I cannot create a custom type with a name or id already used", async ({
).toBeDisabled();
});

test("I cannot create a custom type with a name update or insert", async ({
customTypesTablePage,
}) => {
await customTypesTablePage.goto();
await customTypesTablePage.openCreateDialog();

await expect(customTypesTablePage.createTypeDialog.title).toBeVisible();
await customTypesTablePage.createTypeDialog.nameInput.fill("update");
await expect(
customTypesTablePage.createTypeDialog.submitButton,
).toBeDisabled();
await customTypesTablePage.createTypeDialog.nameInput.fill("insert");
await expect(
customTypesTablePage.createTypeDialog.submitButton,
).toBeDisabled();
});

test("I can rename a custom type", async ({
reusableCustomType,
customTypesTablePage,
Expand Down
13 changes: 13 additions & 0 deletions playwright/tests/pageTypes/pageTypesTable.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,19 @@ test("I cannot create a page type with a name or id already used", async ({
await expect(pageTypesTablePage.createTypeDialog.submitButton).toBeDisabled();
});

test("I cannot create a page type with a name update or insert", async ({
pageTypesTablePage,
}) => {
await pageTypesTablePage.goto();
await pageTypesTablePage.openCreateDialog();

await expect(pageTypesTablePage.createTypeDialog.title).toBeVisible();
await pageTypesTablePage.createTypeDialog.nameInput.fill("update");
await expect(pageTypesTablePage.createTypeDialog.submitButton).toBeDisabled();
await pageTypesTablePage.createTypeDialog.nameInput.fill("insert");
await expect(pageTypesTablePage.createTypeDialog.submitButton).toBeDisabled();
});

test("I can rename a page type", async ({
pageTypesTablePage,
reusablePageType,
Expand Down
16 changes: 16 additions & 0 deletions playwright/tests/slices/slicesList.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,22 @@ test("I cannot rename a slice with a name starting with a number", async ({
await expect(slicesListPage.renameSliceDialog.submitButton).toBeDisabled();
});

test("I cannot create a slice with a restricted name ", async ({
slicesListPage,
}) => {
await slicesListPage.goto();
await slicesListPage.openCreateDialog();

const { nameInput, submitButton } = slicesListPage.createSliceDialog;

await nameInput.fill("components");
await expect(submitButton).toBeDisabled();
await nameInput.fill("update");
await expect(submitButton).toBeDisabled();
await nameInput.fill("insert");
await expect(submitButton).toBeDisabled();
});

test("I cannot create two slices with the same name", async ({
sliceBuilderPage,
slicesListPage,
Expand Down

0 comments on commit 5d6f55c

Please sign in to comment.