Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes user permissions updates #4985

Merged
merged 15 commits into from
Nov 21, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ export const getCreateMutationFromFormDataOnly = (

return {
...acc,
[name]: Array.isArray(fieldValue) ? fieldValue : { value: fieldValue },
[name]: Array.isArray(fieldValue)
? // Uses array of ids for relationships
fieldValue.map((value) => ({ id: value.id }))
: { value: fieldValue },
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ export default function ModalDeleteObject({ label, rowToDelete, open, close, onD
const date = useAtomValue(datetimeAtom);
const { objectKind } = useParams();

const objectDisplay = rowToDelete?.display_label || rowToDelete?.name?.value || rowToDelete?.name;
const objectDisplay =
rowToDelete?.display_label?.value ||
rowToDelete?.display_label ||
rowToDelete?.name?.value ||
rowToDelete?.name;

const handleDeleteObject = async () => {
if (!rowToDelete?.id) {
Expand Down
7 changes: 6 additions & 1 deletion frontend/app/src/components/ui/search-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ export const SearchInput = forwardRef<HTMLInputElement, SearchInputProps>(

<Input ref={ref} {...props} className={classNames("pl-8 h-auto", className)} />

{loading && <Spinner className="absolute inset-y-0 right-0 pr-2 flex items-center" />}
{loading && (
<Spinner
className="absolute inset-y-0 right-0 pr-2 flex items-center"
data-testid="objects-search-input-loader"
/>
)}
</div>
);
}
Expand Down
12 changes: 9 additions & 3 deletions frontend/app/src/screens/role-management/account-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,15 @@ export const AccountForm = ({
},
});

toast(<Alert type={ALERT_TYPES.SUCCESS} message={"Account created"} />, {
toastId: "alert-success-account-created",
});
if (currentObject) {
toast(<Alert type={ALERT_TYPES.SUCCESS} message={"Account updated!"} />, {
toastId: "alert-success-account-updated",
});
} else {
toast(<Alert type={ALERT_TYPES.SUCCESS} message={"Account created!"} />, {
toastId: "alert-success-account-created",
});
}

if (onSuccess) await onSuccess(result?.data?.[`${OBJECT_PERMISSION_OBJECT}Create`]);
if (onUpdateComplete) await onUpdateComplete();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,15 @@ export const AccountGroupForm = ({
},
});

toast(<Alert type={ALERT_TYPES.SUCCESS} message={"Group created"} />, {
toastId: "alert-success-group-created",
});
if (currentObject) {
toast(<Alert type={ALERT_TYPES.SUCCESS} message={"Group updated!"} />, {
toastId: "alert-success-group-updated",
});
} else {
toast(<Alert type={ALERT_TYPES.SUCCESS} message={"Group created!"} />, {
toastId: "alert-success-group-created",
});
}

if (onSuccess) await onSuccess(result?.data?.[`${OBJECT_PERMISSION_OBJECT}Create`]);
if (onUpdateComplete) await onUpdateComplete();
Expand Down
12 changes: 9 additions & 3 deletions frontend/app/src/screens/role-management/account-role-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,15 @@ export const AccountRoleForm = ({
},
});

toast(<Alert type={ALERT_TYPES.SUCCESS} message={"Role created"} />, {
toastId: "alert-success-role-created",
});
if (currentObject) {
toast(<Alert type={ALERT_TYPES.SUCCESS} message={"Role updated!"} />, {
toastId: "alert-success-role-updated",
});
} else {
toast(<Alert type={ALERT_TYPES.SUCCESS} message={"Role created!"} />, {
toastId: "alert-success-role-created",
});
}

if (onSuccess) await onSuccess(result?.data?.[`${ACCOUNT_ROLE_OBJECT}Create`]);
if (onUpdateComplete) await onUpdateComplete();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,15 @@ export const GlobalPermissionForm = ({
},
});

toast(<Alert type={ALERT_TYPES.SUCCESS} message={"Object permission created"} />, {
toastId: "alert-success-object-permission-created",
});
if (currentObject) {
toast(<Alert type={ALERT_TYPES.SUCCESS} message={"Global permission updated!"} />, {
toastId: "alert-success-global-permission-updated",
});
} else {
toast(<Alert type={ALERT_TYPES.SUCCESS} message={"Global permission created!"} />, {
toastId: "alert-success-global-permission-created",
});
}

if (onSuccess) await onSuccess(result?.data?.[`${GLOBAL_PERMISSION_OBJECT}Create`]);
if (onUpdateComplete) await onUpdateComplete();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ function GlobalPermissions() {
data[GLOBAL_PERMISSION_OBJECT]?.edges.map((edge) => {
return {
values: {
id: { value: edge?.node?.id },
id: edge?.node?.id,
display_label: { value: edge?.node?.display_label },
action: { value: edge?.node?.action?.value },
decision: {
Expand All @@ -94,6 +94,7 @@ function GlobalPermissions() {
value: { edges: edge?.node?.roles?.edges },
},
identifier: { display: <BadgeCopy value={edge?.node?.identifier?.value} /> },
__typename: edge.node.__typename,
},
};
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,15 @@ export const ObjectPermissionForm = ({
},
});

toast(<Alert type={ALERT_TYPES.SUCCESS} message={"Object permission created"} />, {
toastId: "alert-success-object-permission-created",
});
if (currentObject) {
toast(<Alert type={ALERT_TYPES.SUCCESS} message={"Object permission updated!"} />, {
toastId: "alert-success-object-permission-updated",
});
} else {
toast(<Alert type={ALERT_TYPES.SUCCESS} message={"Object permission created!"} />, {
toastId: "alert-success-object-permission-created",
});
}

if (onSuccess) await onSuccess(result?.data?.[`${OBJECT_PERMISSION_OBJECT}Create`]);
if (onUpdateComplete) await onUpdateComplete();
Expand Down
103 changes: 103 additions & 0 deletions frontend/app/tests/e2e/role-management/roles-crud.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { expect, test } from "@playwright/test";
import { ACCOUNT_STATE_PATH } from "../../constants";

test.describe("Role management - Roles CRUD", () => {
test.use({ storageState: ACCOUNT_STATE_PATH.ADMIN });
test.describe.configure({ mode: "serial" });

test("should create a role ", async ({ page }) => {
await test.step("access main view", async () => {
await page.goto("/role-management/roles");
});

await test.step("create role", async () => {
await expect(page.getByText("Retrieving roles...")).not.toBeVisible();
await page.getByRole("button", { name: "Create Account role" }).click();
await page.getByLabel("Name *").click();
await page.getByLabel("Name *").fill("test role");
await page.getByLabel("Groups").click();
await page.getByTestId("side-panel-container").getByText("Infrahub Users").click();
await page.getByLabel("Groups").click();
await page.getByTestId("side-panel-container").getByLabel("Permissions").click();
await page
.getByTestId("side-panel-container")
.getByText("global:super_admin:allow_all")
.first()
.click();
await page
.getByTestId("side-panel-container")
.getByText("global:manage_repositories:")
.click();
await page.getByTestId("side-panel-container").getByLabel("Permissions").click();
await page.getByRole("button", { name: "Create" }).click();
await expect(page.getByText("Role created!")).toBeVisible();
});

await test.step("verify role creation", async () => {
await expect(page.getByRole("cell", { name: "test role" })).toBeVisible();
await expect(
page
.getByRole("cell", {
name: "global:super_admin:allow_all global:manage_repositories:allow_all",
})
.locator("div")
.first()
).toBeVisible();
});
});

test("should update a role ", async ({ page }) => {
await test.step("access main view", async () => {
await page.goto("/role-management/roles");
});

await test.step("update role", async () => {
await page
.getByRole("row", { name: "test role Infrahub Users" })
.getByTestId("actions-row-button")
.click();
await page.getByTestId("update-row-button").click();
await page.getByLabel("Name *").click();
await page.getByLabel("Name *").fill("test role 2");
await page.getByLabel("Groups").click();
await page.getByLabel("", { exact: true }).getByText("Infrahub Users").click();
await page.getByTestId("side-panel-container").getByText("Super Administrators").click();
await page.getByLabel("Groups").click();
await page.getByTestId("side-panel-container").getByLabel("Permissions").click();
await page
.getByTestId("side-panel-container")
.getByText("global:manage_schema:allow_all")
.click();
await page.getByTestId("side-panel-container").getByLabel("Permissions").click();
await page.getByRole("button", { name: "Update" }).click();
await expect(page.getByText("Role updated!")).toBeVisible();
});

await test.step("verify role update", async () => {
await expect(page.getByText("test role 2")).toBeVisible();
await expect(page.getByText("Super Administrators").nth(1)).toBeVisible();
});
});

test("should delete a role ", async ({ page }) => {
await test.step("access main view", async () => {
await page.goto("/role-management/roles");
});

await test.step("delete role", async () => {
await page
.getByRole("row", { name: "test role 2" })
.getByTestId("actions-row-button")
.click();
await page.getByTestId("delete-row-button").click();
await page.getByTestId("modal-delete-confirm").click();
await expect(page.getByText("Are you sure you want to remove")).not.toBeVisible();
await expect(page.getByText("Object test role 2 deleted")).toBeVisible();
});

await test.step("verify role delete", async () => {
await expect(page.getByTestId("objects-search-input-loader")).not.toBeVisible();
await expect(page.getByText("test role 2")).not.toBeVisible();
});
});
});
Loading