diff --git a/package.json b/package.json index 1b3d6c8b92..43a3791a2a 100644 --- a/package.json +++ b/package.json @@ -39,8 +39,7 @@ "react-hotkeys-hook": "^4.6.1", "react-i18next": "^15.2.0", "react-redux": "^9.1.2", - "react-router": "^6.22.0", - "react-router-dom": "^6.28.0", + "react-router": "^7.0.2", "react-snowfall": "^2.2.0", "react-to-print": "^2.15.1", "react-toastify": "^10.0.6", diff --git a/src/components/BoardHeader/HeaderMenu/BoardOptions/BoardOptionLink.tsx b/src/components/BoardHeader/HeaderMenu/BoardOptions/BoardOptionLink.tsx index b32fc9b666..85f98b9ace 100644 --- a/src/components/BoardHeader/HeaderMenu/BoardOptions/BoardOptionLink.tsx +++ b/src/components/BoardHeader/HeaderMenu/BoardOptions/BoardOptionLink.tsx @@ -1,5 +1,5 @@ import {MouseEventHandler, VFC} from "react"; -import {Link} from "react-router-dom"; +import {Link} from "react-router"; import classNames from "classnames"; import "./BoardOptionLink.scss"; diff --git a/src/components/BoardHeader/HeaderMenu/__tests__/__snapshots__/HeaderMenu.test.tsx.snap b/src/components/BoardHeader/HeaderMenu/__tests__/__snapshots__/HeaderMenu.test.tsx.snap index 402541dd19..7824ea8cbc 100644 --- a/src/components/BoardHeader/HeaderMenu/__tests__/__snapshots__/HeaderMenu.test.tsx.snap +++ b/src/components/BoardHeader/HeaderMenu/__tests__/__snapshots__/HeaderMenu.test.tsx.snap @@ -135,6 +135,7 @@ exports[` should render correctly for moderator 1`] = ` >

should render correctly for participants 1`] = ` >

({ ...jest.requireActual("utils/export"), diff --git a/src/components/SettingsDialog/SettingsDialog.tsx b/src/components/SettingsDialog/SettingsDialog.tsx index 4432a68625..892c8b5008 100644 --- a/src/components/SettingsDialog/SettingsDialog.tsx +++ b/src/components/SettingsDialog/SettingsDialog.tsx @@ -1,7 +1,6 @@ import {useEffect, useState} from "react"; import {animated, Transition} from "@react-spring/web"; -import {Outlet, useLocation, useNavigate} from "react-router"; -import {Link} from "react-router-dom"; +import {Outlet, useLocation, useNavigate, Link} from "react-router"; import classNames from "classnames"; import {useTranslation} from "react-i18next"; import {Avatar} from "components/Avatar"; diff --git a/src/components/SettingsDialog/__tests__/__snapshots__/SettingsDialog.test.tsx.snap b/src/components/SettingsDialog/__tests__/__snapshots__/SettingsDialog.test.tsx.snap index 466d29d3d9..856eb501b0 100644 --- a/src/components/SettingsDialog/__tests__/__snapshots__/SettingsDialog.test.tsx.snap +++ b/src/components/SettingsDialog/__tests__/__snapshots__/SettingsDialog.test.tsx.snap @@ -96,6 +96,7 @@ exports[`SettingsDialog should render correctly 1`] = ` > @@ -663,6 +671,7 @@ exports[`SettingsDialog should render correctly 1`] = ` ({ - ...jest.requireActual("react-router-dom"), +jest.mock("react-router", () => ({ + ...jest.requireActual("react-router"), useNavigate: () => mockedUsedNavigate, })); diff --git a/src/components/VotingDialog/VotingDialog.tsx b/src/components/VotingDialog/VotingDialog.tsx index 37a245b627..06982f444e 100644 --- a/src/components/VotingDialog/VotingDialog.tsx +++ b/src/components/VotingDialog/VotingDialog.tsx @@ -1,7 +1,7 @@ import {useState} from "react"; import {useTranslation} from "react-i18next"; import {Dialog} from "components/Dialog"; -import {useNavigate} from "react-router-dom"; +import {useNavigate} from "react-router"; import {useAppDispatch, useAppSelector} from "store"; import {Toggle} from "components/Toggle"; import {getNumberFromStorage, saveToStorage, getFromStorage} from "utils/storage"; diff --git a/src/components/VotingDialog/__tests__/VotingDialog.test.tsx b/src/components/VotingDialog/__tests__/VotingDialog.test.tsx index 6456548041..e98a60764f 100644 --- a/src/components/VotingDialog/__tests__/VotingDialog.test.tsx +++ b/src/components/VotingDialog/__tests__/VotingDialog.test.tsx @@ -9,8 +9,8 @@ import i18nTest from "i18nTest"; const mockedUsedNavigate = jest.fn(); -jest.mock("react-router-dom", () => ({ - ...jest.requireActual("react-router-dom"), +jest.mock("react-router", () => ({ + ...jest.requireActual("react-router"), useNavigate: () => mockedUsedNavigate, })); diff --git a/src/routes/Board/Board.tsx b/src/routes/Board/Board.tsx index 92379a5af5..b5f0d83eb0 100644 --- a/src/routes/Board/Board.tsx +++ b/src/routes/Board/Board.tsx @@ -7,7 +7,7 @@ import {useAppDispatch, useAppSelector} from "store"; import {useEffect} from "react"; import {toast} from "react-toastify"; import _ from "underscore"; -import {Outlet} from "react-router-dom"; +import {Outlet} from "react-router"; import {leaveBoard} from "store/features"; import {SnowfallWrapper} from "components/SnowfallWrapper/SnowfallWrapper"; diff --git a/src/routes/Homepage/Homepage.tsx b/src/routes/Homepage/Homepage.tsx index a766c16688..3d216f1127 100644 --- a/src/routes/Homepage/Homepage.tsx +++ b/src/routes/Homepage/Homepage.tsx @@ -4,7 +4,7 @@ import {Trans, useTranslation, withTranslation} from "react-i18next"; import {ReactComponent as German} from "assets/flags/DE.svg"; import {ReactComponent as English} from "assets/flags/US.svg"; import {ArrowRight, Logout} from "components/Icon"; -import {Link, useHref} from "react-router-dom"; +import {Link, useHref} from "react-router"; import {AppInfo} from "components/AppInfo"; import {HeroIllustration} from "components/HeroIllustration"; import {Button} from "components/Button"; diff --git a/src/routes/LoginBoard/LoginBoard.tsx b/src/routes/LoginBoard/LoginBoard.tsx index dea9b996d2..235b84e229 100644 --- a/src/routes/LoginBoard/LoginBoard.tsx +++ b/src/routes/LoginBoard/LoginBoard.tsx @@ -1,11 +1,10 @@ -import {Link} from "react-router-dom"; import {getRandomName} from "utils/random"; import {Auth} from "utils/auth"; import {Toast} from "utils/Toast"; import {useState} from "react"; import {LoginProviders} from "components/LoginProviders"; import {Trans, useTranslation} from "react-i18next"; -import {useLocation} from "react-router"; +import {Link, useLocation} from "react-router"; import {HeroIllustration} from "components/HeroIllustration"; import {ScrumlrLogo} from "components/ScrumlrLogo"; import {Refresh} from "components/Icon"; diff --git a/src/routes/RequireAuthentication.tsx b/src/routes/RequireAuthentication.tsx index ba031a4ebf..21cfe17ec5 100644 --- a/src/routes/RequireAuthentication.tsx +++ b/src/routes/RequireAuthentication.tsx @@ -1,5 +1,4 @@ -import {Navigate} from "react-router-dom"; -import {useLocation} from "react-router"; +import {useLocation, Navigate} from "react-router"; import {FC, PropsWithChildren} from "react"; import {useTranslation} from "react-i18next"; import {useAppSelector} from "store"; diff --git a/src/routes/Router.tsx b/src/routes/Router.tsx index 07cc8197ec..2b2bf2b7b1 100644 --- a/src/routes/Router.tsx +++ b/src/routes/Router.tsx @@ -1,10 +1,9 @@ -import {BrowserRouter, Routes} from "react-router-dom"; +import {BrowserRouter, Route, Routes} from "react-router"; import {LoginBoard} from "routes/LoginBoard"; import {NewBoard} from "routes/NewBoard"; import {BoardGuard} from "routes/Board"; import {NotFound} from "routes/NotFound"; import {RequireAuthentication} from "routes/RequireAuthentication"; -import {Route} from "react-router"; import {SettingsDialog} from "components/SettingsDialog"; import {ExportBoard} from "components/SettingsDialog/ExportBoard"; import {ShareSession} from "components/SettingsDialog/ShareSession"; diff --git a/src/routes/StackView/__tests__/StackView.test.tsx b/src/routes/StackView/__tests__/StackView.test.tsx index c4ae1c8771..7aad0be63e 100644 --- a/src/routes/StackView/__tests__/StackView.test.tsx +++ b/src/routes/StackView/__tests__/StackView.test.tsx @@ -14,6 +14,12 @@ jest.mock("utils/hooks/useImageChecker.ts", () => ({ useImageChecker: () => false, })); +jest.mock("react-router", () => ({ + ...jest.requireActual("react-router"), + useParams: jest.fn(), + useNavigate: jest.fn(), +})); + const BOARD_ID = "test-board-id"; const NOTE_ID = "test-notes-id-1"; @@ -54,12 +60,13 @@ describe("StackView", () => { describe("side effects", () => { it("should navigate to board route on close", () => { - const navigateSpy = jest.fn(); - jest.spyOn(reactRouter, "useNavigate").mockImplementationOnce(() => navigateSpy); + const mockedUsedNavigate = jest.fn(); + jest.spyOn(reactRouter, "useNavigate").mockImplementationOnce(() => mockedUsedNavigate); + const {container} = render(createStackView(), {container: global.document.querySelector("#portal")!}); expect(container.querySelector(".stack-view__portal")).not.toBeNull(); fireEvent.click(container.querySelector(".stack-view__portal")!); - expect(navigateSpy).toHaveBeenCalledWith(`/board/${BOARD_ID}`); + expect(mockedUsedNavigate).toHaveBeenCalledWith(`/board/${BOARD_ID}`); }); }); }); diff --git a/src/routes/__tests__/RequireAuthentication.test.tsx b/src/routes/__tests__/RequireAuthentication.test.tsx index 6287aba88e..c46f73d05a 100644 --- a/src/routes/__tests__/RequireAuthentication.test.tsx +++ b/src/routes/__tests__/RequireAuthentication.test.tsx @@ -6,8 +6,8 @@ import {ApplicationState} from "store"; import {Provider} from "react-redux"; import getTestStore from "utils/test/getTestStore"; -jest.mock("react-router-dom", () => ({ - ...jest.requireActual("react-router-dom"), +jest.mock("react-router", () => ({ + ...jest.requireActual("react-router"), Navigate: () =>

Error
, })); diff --git a/src/setupTests.ts b/src/setupTests.ts index 8b6ff02257..12c895eff4 100644 --- a/src/setupTests.ts +++ b/src/setupTests.ts @@ -4,8 +4,13 @@ // learn more: https://github.com/testing-library/jest-dom import "@testing-library/jest-dom"; +import {TextEncoder} from "util"; + global.ResizeObserver = require("resize-observer-polyfill"); +// global.TextDecoder = require('util').TextDecoder; +global.TextEncoder = TextEncoder; + // jest can't handle match media, and the official workaround doesn't work (lol): // https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom // the package to mock it correctly almost works, but not quite: diff --git a/yarn.lock b/yarn.lock index 3fd9504402..73f0e2f90b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2015,11 +2015,6 @@ redux-thunk "^3.1.0" reselect "^5.1.0" -"@remix-run/router@1.21.0": - version "1.21.0" - resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.21.0.tgz#c65ae4262bdcfe415dbd4f64ec87676e4a56e2b5" - integrity sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA== - "@rollup/plugin-babel@^5.2.0": version "5.3.1" resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283" @@ -2328,6 +2323,11 @@ dependencies: "@types/node" "*" +"@types/cookie@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.6.0.tgz#eac397f28bf1d6ae0ae081363eca2f425bedf0d5" + integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA== + "@types/eslint@^7.29.0 || ^8.4.1": version "8.44.2" resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.2.tgz#0d21c505f98a89b8dd4d37fa162b09da6089199a" @@ -4124,6 +4124,11 @@ cookie@0.6.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== +cookie@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-1.0.2.tgz#27360701532116bd3f1f9416929d176afe1e4610" + integrity sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA== + core-js-compat@^3.31.0: version "3.32.1" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.32.1.tgz#55f9a7d297c0761a8eb1d31b593e0f5b6ffae964" @@ -9763,20 +9768,15 @@ react-refresh@^0.11.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046" integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== -react-router-dom@^6.28.0: - version "6.28.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.28.0.tgz#f73ebb3490e59ac9f299377062ad1d10a9f579e6" - integrity sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg== - dependencies: - "@remix-run/router" "1.21.0" - react-router "6.28.0" - -react-router@6.28.0, react-router@^6.22.0: - version "6.28.0" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.28.0.tgz#29247c86d7ba901d7e5a13aa79a96723c3e59d0d" - integrity sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg== +react-router@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-7.0.2.tgz#2820e107cb8cec8acc5db15a17470c056ea86022" + integrity sha512-m5AcPfTRUcjwmhBzOJGEl6Y7+Crqyju0+TgTQxoS4SO+BkWbhOrcfZNq6wSWdl2BBbJbsAoBUb8ZacOFT+/JlA== dependencies: - "@remix-run/router" "1.21.0" + "@types/cookie" "^0.6.0" + cookie "^1.0.1" + set-cookie-parser "^2.6.0" + turbo-stream "2.4.0" react-scripts@^5.0.1: version "5.0.1" @@ -10460,6 +10460,11 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== +set-cookie-parser@^2.6.0: + version "2.7.1" + resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz#3016f150072202dfbe90fadee053573cc89d2943" + integrity sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ== + set-function-length@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.1.tgz#47cc5945f2c771e2cf261c6737cf9684a2a5e425" @@ -11431,6 +11436,11 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" +turbo-stream@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/turbo-stream/-/turbo-stream-2.4.0.tgz#1e4fca6725e90fa14ac4adb782f2d3759a5695f0" + integrity sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g== + tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"