mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-29 00:16:39 +01:00
Merge branch 'develop' into rc
This commit is contained in:
@@ -49,6 +49,7 @@ import {
|
||||
columnMenuAtom,
|
||||
columnModalAtom,
|
||||
tableFiltersPopoverAtom,
|
||||
tableNextPageAtom,
|
||||
} from "@src/atoms/tableScope";
|
||||
import { FieldType } from "@src/constants/fields";
|
||||
import { getFieldProp } from "@src/components/fields";
|
||||
@@ -89,6 +90,8 @@ export default function ColumnMenu() {
|
||||
tableFiltersPopoverAtom,
|
||||
tableScope
|
||||
);
|
||||
const [tableNextPage] = useAtom(tableNextPageAtom, tableScope);
|
||||
|
||||
const [altPress] = useAtom(altPressAtom, globalScope);
|
||||
const { enqueueSnackbar, closeSnackbar } = useSnackbar();
|
||||
|
||||
@@ -305,7 +308,15 @@ export default function ColumnMenu() {
|
||||
: () =>
|
||||
confirm({
|
||||
title: "Evaluate all?",
|
||||
body: "All rows will be evaluated. This may take a while.",
|
||||
body: (
|
||||
<>
|
||||
All documents in {tableSettings.collection} collection will be
|
||||
evaluated.
|
||||
<br />{" "}
|
||||
{tableNextPage.available &&
|
||||
"For large collections this will take a while and might incur significant firestore costs."}
|
||||
</>
|
||||
),
|
||||
handleConfirm: handleEvaluateAll,
|
||||
}),
|
||||
},
|
||||
|
||||
@@ -20,7 +20,10 @@ export default function Markdown({
|
||||
sx={[fieldSx, { display: "block", maxHeight: 300, overflow: "auto" }]}
|
||||
data-color-mode={theme.palette.mode}
|
||||
>
|
||||
<MDEditor.Markdown source={value} />
|
||||
<MDEditor.Markdown
|
||||
source={value}
|
||||
style={{ backgroundColor: theme.palette.background.paper }}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -37,6 +40,7 @@ export default function Markdown({
|
||||
data-color-mode={theme.palette.mode}
|
||||
>
|
||||
<MDEditor
|
||||
style={{ backgroundColor: theme.palette.background.paper }}
|
||||
height={300}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import { customRender, signInAsAdmin } from "./testUtils";
|
||||
import { screen, renderHook } from "@testing-library/react";
|
||||
import { useAtom, useSetAtom } from "jotai";
|
||||
import { customRender, signIn } from "./testUtils";
|
||||
import { screen, fireEvent } from "@testing-library/react";
|
||||
|
||||
import App from "@src/App";
|
||||
import JotaiTestPage from "@src/pages/Test/JotaiTestPage";
|
||||
|
||||
import { globalScope, currentUserAtom } from "@src/atoms/globalScope";
|
||||
|
||||
test("renders without crashing", async () => {
|
||||
customRender(<JotaiTestPage />);
|
||||
expect(await screen.findByText(/Sign in with Google/i)).toBeInTheDocument();
|
||||
@@ -16,18 +13,53 @@ test("renders without crashing", async () => {
|
||||
).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test("signs in", async () => {
|
||||
const initialAtomValues = await signInAsAdmin();
|
||||
describe("sign in with roles", () => {
|
||||
test("signs in as admin", async () => {
|
||||
customRender(<App />, await signIn("admin"), true);
|
||||
expect((await screen.findAllByText(/tables/i)).length).toBeGreaterThan(0);
|
||||
|
||||
customRender(<App />, initialAtomValues, true);
|
||||
// const {
|
||||
// result: { current: currentUser },
|
||||
// } = renderHook(() => useSetAtom(currentUserAtom, globalScope));
|
||||
// expect(currentUser).toBeDefined();
|
||||
const userMenuButton = screen.getByLabelText("Open user menu");
|
||||
expect(userMenuButton).toBeInTheDocument();
|
||||
fireEvent.click(userMenuButton);
|
||||
expect(await screen.findByText(/admin@example.com/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// expect(await screen.findByText(/Loading/i)).toBeInTheDocument();
|
||||
expect((await screen.findAllByText(/tablesd/i)).length).toBeGreaterThan(0);
|
||||
test("signs in as ops", async () => {
|
||||
customRender(<App />, await signIn("ops"), true);
|
||||
expect((await screen.findAllByText(/tables/i)).length).toBeGreaterThan(0);
|
||||
|
||||
const userMenuButton = screen.getByLabelText("Open user menu");
|
||||
expect(userMenuButton).toBeInTheDocument();
|
||||
fireEvent.click(userMenuButton);
|
||||
expect(await screen.findByText(/ops@example.com/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("signs in as editor", async () => {
|
||||
customRender(<App />, await signIn("editor"), true);
|
||||
expect((await screen.findAllByText(/tables/i)).length).toBeGreaterThan(0);
|
||||
|
||||
const userMenuButton = screen.getByLabelText("Open user menu");
|
||||
expect(userMenuButton).toBeInTheDocument();
|
||||
fireEvent.click(userMenuButton);
|
||||
expect(await screen.findByText(/editor@example.com/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("signs in as viewer", async () => {
|
||||
customRender(<App />, await signIn("viewer"), true);
|
||||
expect((await screen.findAllByText(/tables/i)).length).toBeGreaterThan(0);
|
||||
|
||||
const userMenuButton = screen.getByLabelText("Open user menu");
|
||||
expect(userMenuButton).toBeInTheDocument();
|
||||
fireEvent.click(userMenuButton);
|
||||
expect(await screen.findByText(/viewer@example.com/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("signs in with no roles", async () => {
|
||||
customRender(<App />, await signIn("noRoles"), true);
|
||||
|
||||
expect(await screen.findByText(/Access denied/i)).toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByText(/Your account has no roles set/i)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
// TODO:
|
||||
// test("signs in without roles in auth")
|
||||
|
||||
@@ -3,6 +3,7 @@ import { initializeApp } from "firebase/app";
|
||||
import {
|
||||
getAuth,
|
||||
connectAuthEmulator,
|
||||
signOut,
|
||||
signInWithEmailAndPassword,
|
||||
} from "firebase/auth";
|
||||
import {
|
||||
@@ -21,6 +22,14 @@ import {
|
||||
} from "@src/sources/ProjectSourceFirebase";
|
||||
import { currentUserAtom } from "@src/atoms/globalScope";
|
||||
|
||||
/** Initialize Firebase */
|
||||
console.log("Initializing Firebase...");
|
||||
const app = initializeApp(envConfig);
|
||||
const auth = getAuth(app);
|
||||
connectAuthEmulator(auth, "http://localhost:9099", { disableWarnings: true });
|
||||
const db = initializeFirestore(app, { ignoreUndefinedProperties: true });
|
||||
connectFirestoreEmulator(db, "localhost", 9299);
|
||||
|
||||
/**
|
||||
* Render with Jotai `globalScope` providers
|
||||
* & `ProjectSourceFirebase` component
|
||||
@@ -38,25 +47,26 @@ export const customRender = (
|
||||
);
|
||||
|
||||
/**
|
||||
* Signs in with Google as an admin: admin(at)example.com
|
||||
* Signs in with email and password.
|
||||
* Returns `initialAtomValues`, which must be passed to `customRender`.
|
||||
*/
|
||||
export const signInAsAdmin = async () => {
|
||||
const app = initializeApp(envConfig);
|
||||
const auth = getAuth(app);
|
||||
connectAuthEmulator(auth, "http://localhost:9099", { disableWarnings: true });
|
||||
const db = initializeFirestore(app, { ignoreUndefinedProperties: true });
|
||||
connectFirestoreEmulator(db, "localhost", 9299);
|
||||
export const signIn = async (
|
||||
userType: "admin" | "ops" | "editor" | "viewer" | "noRoles"
|
||||
) => {
|
||||
await signOut(auth);
|
||||
|
||||
const userCredential = await signInWithEmailAndPassword(
|
||||
auth,
|
||||
"admin@example.com",
|
||||
"adminUser"
|
||||
`${userType}@example.com`,
|
||||
`${userType}User`
|
||||
);
|
||||
expect(userCredential.user.email?.toLowerCase()).toBe(
|
||||
`${userType}@example.com`.toLowerCase()
|
||||
);
|
||||
expect(userCredential.user.email).toBe("admin@example.com");
|
||||
|
||||
const tokenResult = await userCredential.user.getIdTokenResult();
|
||||
expect(tokenResult.claims.roles).toContain("ADMIN");
|
||||
if (userType === "noRoles") expect(tokenResult.claims.roles).toBeUndefined();
|
||||
else expect(tokenResult.claims.roles).toContain(userType.toUpperCase());
|
||||
|
||||
const initialAtomValues = [
|
||||
[firebaseConfigAtom, envConfig],
|
||||
@@ -69,7 +79,7 @@ export const signInAsAdmin = async () => {
|
||||
return initialAtomValues;
|
||||
};
|
||||
|
||||
// Suppress Jotai warning about setting an initial value for derived atoms
|
||||
/** Suppress Jotai warning about setting an initial value for derived atoms */
|
||||
const realConsoleWarn = console.warn.bind(console.warn);
|
||||
beforeAll(() => {
|
||||
console.warn = (msg) =>
|
||||
|
||||
Reference in New Issue
Block a user