CEC-2977 Filter portal access based on auth provider (#231)

* fix/fleet-vehicles-search

* fix/fleet-name-update

* Update hasRole logic, create RoleWrap component

* Add MAGNA and MAGNAGROUP env vars

* Add Permissions

Co-authored-by: jwu-fisker <jwu@fiskerinc.com>
This commit is contained in:
arpanetus
2022-11-09 06:46:33 +06:00
committed by GitHub
parent 94950d583e
commit f2f046968e
76 changed files with 1321 additions and 917 deletions

View File

@@ -6,14 +6,14 @@ import { render, waitFor } from "@testing-library/react";
import { CarUpdatesProvider } from "../../Contexts/CarUpdatesContext";
import CarUpdateStatusTable from "../CarUpdateStatusTable";
import { StatusProvider } from "../../Contexts/StatusContext";
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
import addSnapshotSerializer from "../../../utils/snapshot";
const renderCarUpdateStatusTable = async () => {
const { container } = render(
<StatusProvider>
<CarUpdatesProvider>
<CarUpdateStatusTable carupdateid={283} token={TEST_AUTH_OBJECT} />
<CarUpdateStatusTable carupdateid={283} token={TEST_AUTH_OBJECT_FISKER} />
</CarUpdatesProvider>
</StatusProvider>
);

View File

@@ -1,4 +1,3 @@
import React, { useEffect, useState } from "react";
import {
LinearProgress,
Table,
@@ -9,19 +8,22 @@ import {
TableRow,
Tooltip,
} from "@material-ui/core";
import { Link } from "react-router-dom";
import CancelIcon from "@material-ui/icons/Cancel";
import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { logger } from "../../../services/monitoring";
import { LocalDateTimeString } from "../../../utils/dates";
import TableHeaderSortable from "../../Table/HeaderSortable";
import {
CarUpdatesProvider,
useCarUpdatesContext,
} from "../../Contexts/CarUpdatesContext";
import { useStatusContext } from "../../Contexts/StatusContext";
import useStyles from "../../useStyles";
import { logger } from "../../../services/monitoring";
import { useUserContext } from "../../Contexts/UserContext";
import TableHeaderSortable from "../../Table/HeaderSortable";
import { useLocalStorage } from "../../useLocalStorage";
import useStyles from "../../useStyles";
import { RoleWrap } from "../RoleWrap";
const tableColumns = [
{
@@ -68,6 +70,8 @@ const MainForm = ({ vin, token }) => {
} = useCarUpdatesContext();
const { setMessage } = useStatusContext();
const { groups, providers } = useUserContext();
useEffect(() => {
(async () => {
try {
@@ -176,11 +180,17 @@ const MainForm = ({ vin, token }) => {
{LocalDateTimeString(row.updated)}
</TableCell>
<TableCell>
<Tooltip key={row.vin} title={`Send cancel for ${row.vin}`}>
<Link to="#" onClick={() => sendCancel(row)}>
<CancelIcon />
</Link>
</Tooltip>
<RoleWrap
groups={groups}
providers={providers}
rolesPerProvider={Permissions.FiskerCreate}
>
<Tooltip key={row.vin} title={`Send cancel for ${row.vin}`}>
<Link to="#" onClick={() => sendCancel(row)}>
<CancelIcon />
</Link>
</Tooltip>
</RoleWrap>
</TableCell>
</TableRow>
))}

View File

@@ -0,0 +1,23 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`RoleWrap RoleWrap with access, child renders 1`] = `
<div>
<div
data-testid="test-role-wrap-child"
>
Test
</div>
</div>
`;
exports[`RoleWrap RoleWrap without access, child does not render 1`] = `<div />`;
exports[`RoleWrap RoleWrap without access, eitherComponent renders 1`] = `
<div>
<div
data-testid="test-role-wrap-child"
>
Either
</div>
</div>
`;

View File

@@ -0,0 +1,19 @@
import {hasRole} from "../../../utils/roles";
import React from "react";
export const RoleWrap = (props) => {
const {groups, rolesPerProvider, providers} = props;
const eitherComponent = props["eitherComponent"] || null;
if (!hasRole(groups, rolesPerProvider, providers)) {
return eitherComponent != null ? eitherComponent : <></>;
}
return (
<React.Fragment>
{props.children}
</React.Fragment>
)
}

View File

@@ -0,0 +1,70 @@
import { render, screen } from "@testing-library/react";
import { Permissions, Providers, Roles } from "../../../utils/roles";
import addSnapshotSerializer from "../../../utils/snapshot";
import { RoleWrap } from "./index";
const selector = "test-role-wrap-child";
const renderRoleWrap = async (
groups,
providers,
rolesPerProvider,
eitherComponent
) => {
const { container } = render(
<RoleWrap
groups={groups}
providers={providers}
rolesPerProvider={rolesPerProvider}
eitherComponent={eitherComponent}
>
<div data-testid={selector}>Test</div>
</RoleWrap>
);
return container;
};
describe("RoleWrap", () => {
beforeAll(() => {
addSnapshotSerializer(expect);
});
it("RoleWrap with access, child renders", async () => {
const view = await renderRoleWrap(
[Roles.READ],
[Providers.FISKER],
Permissions.FiskerRead,
null
);
const childComponent = screen.getByTestId(selector);
expect(childComponent).toHaveTextContent("Test");
expect(view).toMatchSnapshot();
});
it("RoleWrap without access, child does not render", async () => {
const view = await renderRoleWrap(
[Roles.READ],
[Providers.FISKER],
Permissions.FiskerCreate,
null
);
const childComponent = screen.queryByTestId(selector);
expect(childComponent).toBeNull();
expect(view).toMatchSnapshot();
});
it("RoleWrap without access, eitherComponent renders", async () => {
const view = await renderRoleWrap(
[Roles.READ],
[Providers.FISKER],
Permissions.FiskerCreate,
<div data-testid={selector}>Either</div>
);
const childComponent = screen.getByTestId(selector);
expect(childComponent).toHaveTextContent("Either");
expect(view).toMatchSnapshot();
});
});