From 5f4ddc8fd7d84500457bb08b0981a84a2d1594b1 Mon Sep 17 00:00:00 2001
From: Hassan Abouelela
Date: Sat, 18 Jun 2022 23:59:14 +0400
Subject: Bump React To 18.2.0
Bump react to v18, and handle all the breaking changes. This includes
bumping a lot of other dependencies to versions which support react 18,
and handling the breaking changes for those.
Refer to the following documents for migration guides:
React: https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html
Router: https://reactrouter.com/docs/en/v6/upgrading/v5
Signed-off-by: Hassan Abouelela
---
src/App.tsx | 50 +++++++++++++++++------------------
src/components/Question.tsx | 16 ++++++++---
src/index.tsx | 15 ++++++-----
src/tests/pages/CallbackPage.test.tsx | 14 +++++-----
src/tests/pages/FormPage.test.tsx | 14 +++-------
src/tests/pages/LandingPage.test.tsx | 21 +++++++--------
6 files changed, 66 insertions(+), 64 deletions(-)
(limited to 'src')
diff --git a/src/App.tsx b/src/App.tsx
index 523e583..752a6c6 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -3,11 +3,7 @@
import React, { Suspense } from "react";
import { jsx, css, Global } from "@emotion/react";
-import {
- BrowserRouter as Router,
- Route,
- Switch
-} from "react-router-dom";
+import { BrowserRouter, Route, Routes } from "react-router-dom";
import { PropagateLoader } from "react-spinners";
@@ -35,31 +31,33 @@ function PageLoading() {
;
}
+function Routing(): JSX.Element {
+ const renderedRoutes = routes.map(({path, Component}) => (
+ }>
+ }/>
+ ));
+
+ return (
+
+ {renderedRoutes}
+
+ );
+}
+
function App(): JSX.Element {
return (
-
- (
-
-
-
- {routes.map(({path, Component}) => (
-
- }>
-
-
-
- ))}
-
-
-
- )}/>
-
+
+
+
+
+ }/>
+
+
+
+
);
}
diff --git a/src/components/Question.tsx b/src/components/Question.tsx
index ebacb4a..61e66e0 100644
--- a/src/components/Question.tsx
+++ b/src/components/Question.tsx
@@ -35,14 +35,22 @@ class RenderedQuestion extends React.Component {
}
this.blurHandler = this.blurHandler.bind(this);
- this.setPublicState("valid", true);
- this.setPublicState("error", "");
+ const _state: {[key: string]: string | boolean | null} = {
+ "valid": true,
+ "error": "",
+ };
+
if (props.question.type === QuestionType.Code) {
- this.setPublicState("unittestsFailed", false);
+ _state["unittestsFailed"] = false;
}
if (!skip_normal_state.includes(props.question.type)) {
- this.setPublicState("value", "");
+ _state["value"] = "";
+ }
+
+ this.state = _state;
+ for (const [key, value] of Object.entries(_state)) {
+ this.props.public_state.set(key, value);
}
}
diff --git a/src/index.tsx b/src/index.tsx
index 4bce5a4..2565964 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,5 +1,7 @@
+/** @jsx jsx */
+import { jsx } from "@emotion/react";
import React from "react";
-import ReactDOM from "react-dom";
+import { createRoot } from "react-dom/client";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
@@ -33,8 +35,10 @@ console.log(` SHA: %c ${process.env.COMMIT_REF} `, `padding: 2px; border-radiu
console.log("%cCome join us on Discord! https://discord.gg/python", `font-size: 1.5em; font-family: "Hind", "Arial"; color: ${colors.blurple}`);
-/* eslint-disable react/react-in-jsx-scope */
-ReactDOM.render(
+const rootDocument = document.getElementById("root");
+// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+const root = createRoot(rootDocument!);
+root.render(
An error has occurred with Python Discord Forms. Please let us know in the Discord server at discord.gg/python
}
@@ -47,10 +51,9 @@ ReactDOM.render(
console.log(err);
}}
>
-
+
- ,
- document.getElementById("root")
+
);
/* eslint-enable react/react-in-jsx-scope */
diff --git a/src/tests/pages/CallbackPage.test.tsx b/src/tests/pages/CallbackPage.test.tsx
index 70f2fed..37fb932 100644
--- a/src/tests/pages/CallbackPage.test.tsx
+++ b/src/tests/pages/CallbackPage.test.tsx
@@ -1,9 +1,9 @@
import React from "react";
-import { render } from "@testing-library/react";
+import { render, waitFor } from "@testing-library/react";
import CallbackPage from "../../pages/CallbackPage";
-test("callback page sends provided code", () => {
+test("callback page sends provided code", async () => {
global.opener = {
postMessage: jest.fn()
};
@@ -14,9 +14,11 @@ test("callback page sends provided code", () => {
render();
- expect(global.opener.postMessage).toBeCalledTimes(1);
- expect(global.opener.postMessage).toBeCalledWith({
- code: "abcde_code",
- state: "abcde_state"
+ await waitFor(() => {
+ expect(global.opener.postMessage).toBeCalledTimes(1);
+ expect(global.opener.postMessage).toBeCalledWith({
+ code: "abcde_code",
+ state: "abcde_state"
+ });
});
});
diff --git a/src/tests/pages/FormPage.test.tsx b/src/tests/pages/FormPage.test.tsx
index 947c075..3a906f3 100644
--- a/src/tests/pages/FormPage.test.tsx
+++ b/src/tests/pages/FormPage.test.tsx
@@ -1,18 +1,13 @@
import React from "react";
import { render } from "@testing-library/react";
-import { createMemoryHistory } from "history";
-
-import { Route, BrowserRouter as Router } from "react-router-dom";
+import { MemoryRouter } from "react-router-dom";
import FormPage from "../../pages/FormPage";
import * as forms from "../../api/forms";
test("renders specific form page with loading bar", () => {
- const history = createMemoryHistory();
- history.push("/form/route");
-
- const { getByText } = render();
+ const { getByText } = render(, {wrapper: MemoryRouter});
// If we rendered the headerbar we rendered the forms page.
const headerBar = getByText(/Loading.../);
expect(headerBar).toBeInTheDocument();
@@ -20,14 +15,11 @@ test("renders specific form page with loading bar", () => {
/* TODO: Find why this test spits out promise errors that fail CI */
test.skip("calls api method to load form", () => {
- const history = createMemoryHistory();
- history.push("/form/ban-appeals");
-
const oldImpl = forms.getForm;
Object.defineProperty(forms, "getForm", {value: jest.fn(oldImpl)});
- render();
+ render(, {wrapper: MemoryRouter});
expect(forms.getForm).toBeCalled();
});
diff --git a/src/tests/pages/LandingPage.test.tsx b/src/tests/pages/LandingPage.test.tsx
index 6f8a530..727b922 100644
--- a/src/tests/pages/LandingPage.test.tsx
+++ b/src/tests/pages/LandingPage.test.tsx
@@ -1,10 +1,10 @@
import React from "react";
-import { render } from "@testing-library/react";
+import { render, waitFor } from "@testing-library/react";
import LandingPage from "../../pages/LandingPage";
import * as forms from "../../api/forms";
-import { BrowserRouter as Router } from "react-router-dom";
+import { MemoryRouter } from "react-router-dom";
import { QuestionType } from "../../api/question";
const testingForm: forms.Form = {
@@ -25,13 +25,12 @@ const testingForm: forms.Form = {
submitted_text: null
};
-test("renders landing page", () => {
- const setForms = jest.fn(() => [testingForm]);
- Object.defineProperty(forms, "getForms", setForms);
- const handleForms = jest.spyOn(React, "useState");
- handleForms.mockImplementation(() => [[testingForm], setForms]);
- const { getByText } = render();
- // If we rendered the headerbar we rendered the landing page.
- const headerBar = getByText(/Python Discord Forms/);
- expect(headerBar).toBeInTheDocument();
+test("renders landing page", async () => {
+ jest.spyOn(forms, "getForms").mockImplementation(() => Promise.resolve([testingForm]));
+
+ const { getByText } = render(, {wrapper: MemoryRouter});
+ await waitFor(() => {
+ const headerBar = getByText(/Python Discord Forms/);
+ expect(headerBar).toBeInTheDocument();
+ });
});
--
cgit v1.2.3