diff --git a/package.json b/package.json
index 7e64861e44..c6c150e97f 100644
--- a/package.json
+++ b/package.json
@@ -71,10 +71,10 @@
"re-reselect": "5.1.0",
"react": "18.3.1",
"react-dom": "18.3.1",
- "react-dropzone": "14.2.3",
+ "react-dropzone": "14.3.8",
"react-ga4": "2.1.0",
"react-redux": "8.1.3",
- "react-router-dom": "6.24.0",
+ "react-router-dom": "6.29.0",
"react-storage-hooks": "4.0.1",
"react-useportal": "1.0.19",
"reconnecting-websocket": "4.4.0",
@@ -118,9 +118,9 @@
"@types/node": "20.12.12",
"@types/path-parse": "1.0.22",
"@types/pluralize": "0.0.33",
- "@types/react": "18.3.3",
- "@types/react-dom": "18.3.0",
- "@types/react-redux": "7.1.33",
+ "@types/react": "18.3.18",
+ "@types/react-dom": "18.3.5",
+ "@types/react-redux": "7.1.34",
"@types/react-router": "5.1.20",
"@types/react-router-dom": "5.3.3",
"@types/redux-mock-store": "1.0.6",
diff --git a/src/app/settings/views/Scripts/ScriptsUpload/ScriptsUpload.test.tsx b/src/app/settings/views/Scripts/ScriptsUpload/ScriptsUpload.test.tsx
index 6a61dff1a0..dd727b90e6 100644
--- a/src/app/settings/views/Scripts/ScriptsUpload/ScriptsUpload.test.tsx
+++ b/src/app/settings/views/Scripts/ScriptsUpload/ScriptsUpload.test.tsx
@@ -3,7 +3,6 @@ import type { FileWithPath } from "react-dropzone";
import { Provider } from "react-redux";
import { MemoryRouter } from "react-router-dom";
import type { Dispatch } from "redux";
-import { HistoryRouter as Router } from "redux-first-history/rr6";
import configureStore from "redux-mock-store";
import ScriptsUpload, { Labels as ScriptsUploadLabels } from "./ScriptsUpload";
@@ -19,7 +18,7 @@ import {
render,
waitFor,
fireEvent,
- renderWithMockStore,
+ renderWithProviders,
} from "@/testing/utils";
const mockStore = configureStore();
@@ -61,19 +60,16 @@ describe("ScriptsUpload", () => {
it("accepts files of any mimetype", async () => {
const files = [createFile("foo.sh", 2000, "")];
- renderWithMockStore(
-
-
- ,
- { state }
- );
+ renderWithProviders(, {
+ state,
+ });
const upload = screen.getByLabelText(ScriptsUploadLabels.FileUploadArea);
await userEvent.upload(upload, files);
await waitFor(() =>
expect(
- screen.getByText("foo.sh (2000 bytes) ready for upload.")
+ screen.getByText("./foo.sh (2000 bytes) ready for upload.")
).toBeInTheDocument()
);
});
@@ -212,12 +208,10 @@ describe("ScriptsUpload", () => {
const history = createMemoryHistory({
initialEntries: ["/"],
});
- renderWithMockStore(
-
-
- ,
- { state }
- );
+ renderWithProviders(, {
+ state,
+ history,
+ });
await userEvent.click(screen.getByRole("button", { name: "Cancel" }));
expect(history.location.pathname).toBe("/settings/scripts/commissioning"); // linting errors occur if you use settingsUrls.scripts
});
@@ -226,12 +220,7 @@ describe("ScriptsUpload", () => {
const history = createMemoryHistory({
initialEntries: ["/"],
});
- renderWithMockStore(
-
-
- ,
- { state }
- );
+ renderWithProviders(, { state, history });
await userEvent.click(screen.getByRole("button", { name: "Cancel" }));
expect(history.location.pathname).toBe("/settings/scripts/testing"); // linting errors occur if you use settingsUrls.scripts
});
diff --git a/src/testing/utils.tsx b/src/testing/utils.tsx
index da688dcf70..b428ee8d77 100644
--- a/src/testing/utils.tsx
+++ b/src/testing/utils.tsx
@@ -1,4 +1,4 @@
-import { type ReactNode } from "react";
+import { type ReactNode, useEffect } from "react";
import type { ValueOf } from "@canonical/react-components";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
@@ -544,6 +544,7 @@ type TestProviderProps = {
queryData?: { queryKey: any; data: Partial> | undefined }[];
store?: MockStoreEnhanced;
route?: string;
+ history?: MemoryHistory;
};
/**
@@ -553,6 +554,7 @@ type TestProviderProps = {
* @param state The app state used for testing
* @param store The mock store
* @param route The route for the test
+ * @param history The history object for navigation
* @constructor
*/
export const TestProvider = ({
@@ -560,20 +562,27 @@ export const TestProvider = ({
state = factory.rootState(),
store,
route = "/",
+ history = createMemoryHistory({ initialEntries: [route] }),
}: TestProviderProps) => {
- window.history.pushState({}, "Test page", route);
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false, staleTime: Infinity } },
});
const mockStore = store ?? configureStore()(state);
+ useEffect(() => {
+ const stopListening = history.listen(({ location }) => {
+ window.history.pushState({}, "", location.pathname + location.search);
+ });
+ return () => stopListening();
+ }, [history]);
+
return (
- {children}
+ {children}
@@ -589,20 +598,27 @@ export const TestProvider = ({
*/
export const renderWithProviders = (
ui: ReactNode,
- options?: Omit & Partial
+ options?: Omit &
+ Partial & { history?: MemoryHistory }
) => {
- const { state, queryData, store, ...renderOptions } = options ?? {};
- return render(ui, {
- wrapper: (props) => (
-
- ),
- ...renderOptions,
- });
+ const { state, queryData, store, history, ...renderOptions } = options ?? {};
+ const testHistory = history ?? createMemoryHistory();
+
+ return {
+ ...render(ui, {
+ wrapper: (props) => (
+
+ ),
+ ...renderOptions,
+ }),
+ history: testHistory,
+ };
};
/**
diff --git a/yarn.lock b/yarn.lock
index 2115aab767..fe97b9f45b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3530,10 +3530,10 @@
redux-thunk "^2.4.2"
reselect "^4.1.8"
-"@remix-run/router@1.17.0":
- version "1.17.0"
- resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.17.0.tgz#fbb0add487478ef42247d5942e7a5d8a2e20095f"
- integrity sha512-2D6XaHEVvkCn682XBnipbJjgZUU7xjLtA4dGJRBVUKpEaDYOZMENZoZjAOSb7qirxt5RupjzZxz4fK2FO+EFPw==
+"@remix-run/router@1.22.0":
+ version "1.22.0"
+ resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.22.0.tgz#dd8096cb055c475a4de6b35322b8d3b118c17b43"
+ integrity sha512-MBOl8MeOzpK0HQQQshKB7pABXbmyHizdTpqnrIseTbsv0nAepwC2ENZa1aaBExNQcpLoXmWthhak8SABLzvGPw==
"@rollup/pluginutils@^4.2.1":
version "4.2.1"
@@ -5106,10 +5106,15 @@
dependencies:
"@types/react" "*"
-"@types/react-redux@7.1.33":
- version "7.1.33"
- resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.33.tgz#53c5564f03f1ded90904e3c90f77e4bd4dc20b15"
- integrity sha512-NF8m5AjWCkert+fosDsN3hAlHzpjSiXlVy9EgQEmLoBhaNXbmyeGs/aj5dQzKuF+/q+S7JQagorGDW8pJ28Hmg==
+"@types/react-dom@18.3.5":
+ version "18.3.5"
+ resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.5.tgz#45f9f87398c5dcea085b715c58ddcf1faf65f716"
+ integrity sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==
+
+"@types/react-redux@7.1.34":
+ version "7.1.34"
+ resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.34.tgz#83613e1957c481521e6776beeac4fd506d11bd0e"
+ integrity sha512-GdFaVjEbYv4Fthm2ZLvj1VSCedV7TqE5y1kNwnjSdBOTXuRSgowux6J8TAct15T3CKBr63UMk+2CO7ilRhyrAQ==
dependencies:
"@types/hoist-non-react-statics" "^3.3.0"
"@types/react" "*"
@@ -5148,6 +5153,14 @@
"@types/prop-types" "*"
csstype "^3.0.2"
+"@types/react@18.3.18":
+ version "18.3.18"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.18.tgz#9b382c4cd32e13e463f97df07c2ee3bbcd26904b"
+ integrity sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==
+ dependencies:
+ "@types/prop-types" "*"
+ csstype "^3.0.2"
+
"@types/redux-mock-store@1.0.6":
version "1.0.6"
resolved "https://registry.yarnpkg.com/@types/redux-mock-store/-/redux-mock-store-1.0.6.tgz#0a03b2655028b7cf62670d41ac1de5ca1b1f5958"
@@ -6027,10 +6040,10 @@ at-least-node@^1.0.0:
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
-attr-accept@^2.2.2:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.2.tgz#646613809660110749e92f2c10833b70968d929b"
- integrity sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==
+attr-accept@^2.2.4:
+ version "2.2.5"
+ resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.5.tgz#d7061d958e6d4f97bf8665c68b75851a0713ab5e"
+ integrity sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==
available-typed-arrays@^1.0.5:
version "1.0.5"
@@ -8441,12 +8454,12 @@ file-entry-cache@^6.0.1:
dependencies:
flat-cache "^3.0.4"
-file-selector@^0.6.0:
- version "0.6.0"
- resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-0.6.0.tgz#fa0a8d9007b829504db4d07dd4de0310b65287dc"
- integrity sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==
+file-selector@^2.1.0:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-2.1.2.tgz#fe7c7ee9e550952dfbc863d73b14dc740d7de8b4"
+ integrity sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==
dependencies:
- tslib "^2.4.0"
+ tslib "^2.7.0"
file-system-cache@2.3.0:
version "2.3.0"
@@ -12046,13 +12059,13 @@ react-dom@18.3.1:
loose-envify "^1.1.0"
scheduler "^0.23.2"
-react-dropzone@14.2.3:
- version "14.2.3"
- resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-14.2.3.tgz#0acab68308fda2d54d1273a1e626264e13d4e84b"
- integrity sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==
+react-dropzone@14.3.8:
+ version "14.3.8"
+ resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-14.3.8.tgz#a7eab118f8a452fe3f8b162d64454e81ba830582"
+ integrity sha512-sBgODnq+lcA4P296DY4wacOZz3JFpD99fp+hb//iBO2HHnyeZU3FwWyXJ6salNpqQdsZrgMrotuko/BdJMV8Ug==
dependencies:
- attr-accept "^2.2.2"
- file-selector "^0.6.0"
+ attr-accept "^2.2.4"
+ file-selector "^2.1.0"
prop-types "^15.8.1"
react-element-to-jsx-string@^15.0.0:
@@ -12130,20 +12143,20 @@ react-remove-scroll@2.5.5:
use-callback-ref "^1.3.0"
use-sidecar "^1.1.2"
-react-router-dom@6.24.0:
- version "6.24.0"
- resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.24.0.tgz#ec49dc38c49bb9bd25b310a8ae849268d3085e1d"
- integrity sha512-960sKuau6/yEwS8e+NVEidYQb1hNjAYM327gjEyXlc6r3Skf2vtwuJ2l7lssdegD2YjoKG5l8MsVyeTDlVeY8g==
+react-router-dom@6.29.0:
+ version "6.29.0"
+ resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.29.0.tgz#2ffb56b03ef3d6d6daafcfad9f3922132d2ced94"
+ integrity sha512-pkEbJPATRJ2iotK+wUwHfy0xs2T59YPEN8BQxVCPeBZvK7kfPESRc/nyxzdcxR17hXgUPYx2whMwl+eo9cUdnQ==
dependencies:
- "@remix-run/router" "1.17.0"
- react-router "6.24.0"
+ "@remix-run/router" "1.22.0"
+ react-router "6.29.0"
-react-router@6.24.0:
- version "6.24.0"
- resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.24.0.tgz#aa46648f26b6525e07f908ad3e1ad2e68d131155"
- integrity sha512-sQrgJ5bXk7vbcC4BxQxeNa5UmboFm35we1AFK0VvQaz9g0LzxEIuLOhHIoZ8rnu9BO21ishGeL9no1WB76W/eg==
+react-router@6.29.0:
+ version "6.29.0"
+ resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.29.0.tgz#14a329ca838b4de048fc5cca82874b727ee546b7"
+ integrity sha512-DXZJoE0q+KyeVw75Ck6GkPxFak63C4fGqZGNijnWgzB/HzSP1ZfTlBj5COaGWwhrMQ/R8bXiq5Ooy4KG+ReyjQ==
dependencies:
- "@remix-run/router" "1.17.0"
+ "@remix-run/router" "1.22.0"
react-storage-hooks@4.0.1:
version "4.0.1"
@@ -13096,7 +13109,7 @@ string-natural-compare@^3.0.1:
resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4"
integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==
-"string-width-cjs@npm:string-width@^4.2.0":
+"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -13114,15 +13127,6 @@ string-width@^4.1.0, string-width@^4.2.0:
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.0"
-string-width@^4.2.3:
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
- integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
- dependencies:
- emoji-regex "^8.0.0"
- is-fullwidth-code-point "^3.0.0"
- strip-ansi "^6.0.1"
-
string-width@^5.0.1, string-width@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
@@ -13188,7 +13192,7 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -13202,13 +13206,6 @@ strip-ansi@^6.0.0:
dependencies:
ansi-regex "^5.0.0"
-strip-ansi@^6.0.1:
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
- integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
- dependencies:
- ansi-regex "^5.0.1"
-
strip-ansi@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2"
@@ -13655,6 +13652,11 @@ tslib@^2.4.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
+tslib@^2.7.0:
+ version "2.8.1"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
+ integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
+
tsutils@^3.21.0:
version "3.21.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
@@ -14400,7 +14402,7 @@ wordwrap@^1.0.0:
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -14418,15 +14420,6 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"
-wrap-ansi@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
- integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
- dependencies:
- ansi-styles "^4.0.0"
- string-width "^4.1.0"
- strip-ansi "^6.0.0"
-
wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"