mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
refactor(frontend): remove store.ts file (#11119)
Co-authored-by: sp.wack <83104063+amanape@users.noreply.github.com>
This commit is contained in:
parent
b883fe37e6
commit
8a7a5cce5e
@ -61,38 +61,6 @@ vi.mock("#/hooks/use-conversation-name-context-menu", () => ({
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock("react-redux", async () => {
|
||||
const actual = await vi.importActual("react-redux");
|
||||
return {
|
||||
...actual,
|
||||
useSelector: vi.fn((selector) => {
|
||||
// Create a mock state object
|
||||
const mockState = {
|
||||
agent: {
|
||||
curAgentState: "AWAITING_USER_INPUT",
|
||||
},
|
||||
initialQuery: {
|
||||
selectedRepository: null,
|
||||
replayJson: null,
|
||||
},
|
||||
conversation: {
|
||||
messageToSend: null,
|
||||
files: [],
|
||||
images: [],
|
||||
loadingFiles: [],
|
||||
loadingImages: [],
|
||||
},
|
||||
status: {
|
||||
curStatusMessage: null,
|
||||
},
|
||||
};
|
||||
|
||||
// Execute the selector function with our mock state
|
||||
return selector(mockState);
|
||||
}),
|
||||
useDispatch: vi.fn(() => vi.fn()),
|
||||
};
|
||||
});
|
||||
|
||||
// Helper function to render with Router context
|
||||
const renderChatInterfaceWithRouter = () =>
|
||||
|
||||
@ -3,7 +3,7 @@ import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { createRoutesStub } from "react-router";
|
||||
import React from "react";
|
||||
import { renderWithQueryAndI18n } from "test-utils";
|
||||
import { renderWithProviders } from "test-utils";
|
||||
import { ConversationPanel } from "#/components/features/conversation-panel/conversation-panel";
|
||||
import ConversationService from "#/api/conversation-service/conversation-service.api";
|
||||
import { Conversation } from "#/api/open-hands.types";
|
||||
@ -17,7 +17,7 @@ describe("ConversationPanel", () => {
|
||||
},
|
||||
]);
|
||||
|
||||
const renderConversationPanel = () => renderWithQueryAndI18n(<RouterStub />);
|
||||
const renderConversationPanel = () => renderWithProviders(<RouterStub />);
|
||||
|
||||
beforeAll(() => {
|
||||
vi.mock("react-router", async (importOriginal) => ({
|
||||
@ -287,7 +287,7 @@ describe("ConversationPanel", () => {
|
||||
},
|
||||
]);
|
||||
|
||||
renderWithQueryAndI18n(<MyRouterStub />);
|
||||
renderWithProviders(<MyRouterStub />);
|
||||
|
||||
const toggleButton = screen.getByText("Toggle");
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { renderWithQueryAndI18n } from "test-utils";
|
||||
import { renderWithProviders } from "test-utils";
|
||||
import { ServerStatus } from "#/components/features/controls/server-status";
|
||||
import { ServerStatusContextMenu } from "#/components/features/controls/server-status-context-menu";
|
||||
import { ConversationStatus } from "#/types/conversation-status";
|
||||
@ -84,7 +84,7 @@ describe("ServerStatus", () => {
|
||||
mockAgentStore(AgentState.RUNNING);
|
||||
|
||||
// Test RUNNING status
|
||||
const { rerender } = renderWithQueryAndI18n(
|
||||
const { rerender } = renderWithProviders(
|
||||
<ServerStatus conversationStatus="RUNNING" />,
|
||||
);
|
||||
expect(screen.getByText("Running")).toBeInTheDocument();
|
||||
@ -108,7 +108,7 @@ describe("ServerStatus", () => {
|
||||
// Mock agent store to return RUNNING state
|
||||
mockAgentStore(AgentState.RUNNING);
|
||||
|
||||
renderWithQueryAndI18n(<ServerStatus conversationStatus="RUNNING" />);
|
||||
renderWithProviders(<ServerStatus conversationStatus="RUNNING" />);
|
||||
|
||||
const statusContainer = screen.getByText("Running").closest("div");
|
||||
expect(statusContainer).toBeInTheDocument();
|
||||
@ -128,7 +128,7 @@ describe("ServerStatus", () => {
|
||||
// Mock agent store to return STOPPED state
|
||||
mockAgentStore(AgentState.STOPPED);
|
||||
|
||||
renderWithQueryAndI18n(<ServerStatus conversationStatus="STOPPED" />);
|
||||
renderWithProviders(<ServerStatus conversationStatus="STOPPED" />);
|
||||
|
||||
const statusContainer = screen.getByText("Server Stopped").closest("div");
|
||||
expect(statusContainer).toBeInTheDocument();
|
||||
@ -148,7 +148,7 @@ describe("ServerStatus", () => {
|
||||
// Mock agent store to return RUNNING state
|
||||
mockAgentStore(AgentState.RUNNING);
|
||||
|
||||
renderWithQueryAndI18n(<ServerStatus conversationStatus="STARTING" />);
|
||||
renderWithProviders(<ServerStatus conversationStatus="STARTING" />);
|
||||
|
||||
const statusContainer = screen.getByText("Running").closest("div");
|
||||
expect(statusContainer).toBeInTheDocument();
|
||||
@ -170,7 +170,7 @@ describe("ServerStatus", () => {
|
||||
// Mock agent store to return RUNNING state
|
||||
mockAgentStore(AgentState.RUNNING);
|
||||
|
||||
renderWithQueryAndI18n(<ServerStatus conversationStatus="RUNNING" />);
|
||||
renderWithProviders(<ServerStatus conversationStatus="RUNNING" />);
|
||||
|
||||
const statusContainer = screen.getByText("Running").closest("div");
|
||||
await user.click(statusContainer!);
|
||||
@ -192,7 +192,7 @@ describe("ServerStatus", () => {
|
||||
// Mock agent store to return STOPPED state
|
||||
mockAgentStore(AgentState.STOPPED);
|
||||
|
||||
renderWithQueryAndI18n(<ServerStatus conversationStatus="STOPPED" />);
|
||||
renderWithProviders(<ServerStatus conversationStatus="STOPPED" />);
|
||||
|
||||
const statusContainer = screen.getByText("Server Stopped").closest("div");
|
||||
await user.click(statusContainer!);
|
||||
@ -212,7 +212,7 @@ describe("ServerStatus", () => {
|
||||
// Mock agent store to return RUNNING state
|
||||
mockAgentStore(AgentState.RUNNING);
|
||||
|
||||
renderWithQueryAndI18n(<ServerStatus conversationStatus="RUNNING" />);
|
||||
renderWithProviders(<ServerStatus conversationStatus="RUNNING" />);
|
||||
|
||||
const statusContainer = screen.getByText("Running").closest("div");
|
||||
await user.click(statusContainer!);
|
||||
@ -232,7 +232,7 @@ describe("ServerStatus", () => {
|
||||
// Mock agent store to return STOPPED state
|
||||
mockAgentStore(AgentState.STOPPED);
|
||||
|
||||
renderWithQueryAndI18n(<ServerStatus conversationStatus="STOPPED" />);
|
||||
renderWithProviders(<ServerStatus conversationStatus="STOPPED" />);
|
||||
|
||||
const statusContainer = screen.getByText("Server Stopped").closest("div");
|
||||
await user.click(statusContainer!);
|
||||
@ -250,7 +250,7 @@ describe("ServerStatus", () => {
|
||||
// Mock agent store to return RUNNING state
|
||||
mockAgentStore(AgentState.RUNNING);
|
||||
|
||||
renderWithQueryAndI18n(<ServerStatus conversationStatus={null} />);
|
||||
renderWithProviders(<ServerStatus conversationStatus={null} />);
|
||||
|
||||
const statusText = screen.getByText("Running");
|
||||
expect(statusText).toBeInTheDocument();
|
||||
@ -268,7 +268,7 @@ describe("ServerStatusContextMenu", () => {
|
||||
});
|
||||
|
||||
it("should render stop server button when status is RUNNING", () => {
|
||||
renderWithQueryAndI18n(
|
||||
renderWithProviders(
|
||||
<ServerStatusContextMenu
|
||||
{...defaultProps}
|
||||
conversationStatus="RUNNING"
|
||||
@ -281,7 +281,7 @@ describe("ServerStatusContextMenu", () => {
|
||||
});
|
||||
|
||||
it("should render start server button when status is STOPPED", () => {
|
||||
renderWithQueryAndI18n(
|
||||
renderWithProviders(
|
||||
<ServerStatusContextMenu
|
||||
{...defaultProps}
|
||||
conversationStatus="STOPPED"
|
||||
@ -294,7 +294,7 @@ describe("ServerStatusContextMenu", () => {
|
||||
});
|
||||
|
||||
it("should not render stop server button when onStopServer is not provided", () => {
|
||||
renderWithQueryAndI18n(
|
||||
renderWithProviders(
|
||||
<ServerStatusContextMenu
|
||||
{...defaultProps}
|
||||
conversationStatus="RUNNING"
|
||||
@ -305,7 +305,7 @@ describe("ServerStatusContextMenu", () => {
|
||||
});
|
||||
|
||||
it("should not render start server button when onStartServer is not provided", () => {
|
||||
renderWithQueryAndI18n(
|
||||
renderWithProviders(
|
||||
<ServerStatusContextMenu
|
||||
{...defaultProps}
|
||||
conversationStatus="STOPPED"
|
||||
@ -319,7 +319,7 @@ describe("ServerStatusContextMenu", () => {
|
||||
const user = userEvent.setup();
|
||||
const onStopServer = vi.fn();
|
||||
|
||||
renderWithQueryAndI18n(
|
||||
renderWithProviders(
|
||||
<ServerStatusContextMenu
|
||||
{...defaultProps}
|
||||
conversationStatus="RUNNING"
|
||||
@ -337,7 +337,7 @@ describe("ServerStatusContextMenu", () => {
|
||||
const user = userEvent.setup();
|
||||
const onStartServer = vi.fn();
|
||||
|
||||
renderWithQueryAndI18n(
|
||||
renderWithProviders(
|
||||
<ServerStatusContextMenu
|
||||
{...defaultProps}
|
||||
conversationStatus="STOPPED"
|
||||
@ -352,7 +352,7 @@ describe("ServerStatusContextMenu", () => {
|
||||
});
|
||||
|
||||
it("should render correct text content for stop server button", () => {
|
||||
renderWithQueryAndI18n(
|
||||
renderWithProviders(
|
||||
<ServerStatusContextMenu
|
||||
{...defaultProps}
|
||||
conversationStatus="RUNNING"
|
||||
@ -366,7 +366,7 @@ describe("ServerStatusContextMenu", () => {
|
||||
});
|
||||
|
||||
it("should render correct text content for start server button", () => {
|
||||
renderWithQueryAndI18n(
|
||||
renderWithProviders(
|
||||
<ServerStatusContextMenu
|
||||
{...defaultProps}
|
||||
conversationStatus="STOPPED"
|
||||
@ -382,7 +382,7 @@ describe("ServerStatusContextMenu", () => {
|
||||
it("should call onClose when context menu is closed", () => {
|
||||
const onClose = vi.fn();
|
||||
|
||||
renderWithQueryAndI18n(
|
||||
renderWithProviders(
|
||||
<ServerStatusContextMenu
|
||||
{...defaultProps}
|
||||
onClose={onClose}
|
||||
@ -397,7 +397,7 @@ describe("ServerStatusContextMenu", () => {
|
||||
});
|
||||
|
||||
it("should not render any buttons for other conversation statuses", () => {
|
||||
renderWithQueryAndI18n(
|
||||
renderWithProviders(
|
||||
<ServerStatusContextMenu
|
||||
{...defaultProps}
|
||||
conversationStatus="STARTING"
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { Provider } from "react-redux";
|
||||
import { setupStore } from "test-utils";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { HomeHeader } from "#/components/features/home/home-header/home-header";
|
||||
|
||||
@ -26,11 +24,9 @@ vi.mock("react-i18next", async () => {
|
||||
const renderHomeHeader = () => {
|
||||
return render(<HomeHeader />, {
|
||||
wrapper: ({ children }) => (
|
||||
<Provider store={setupStore()}>
|
||||
<QueryClientProvider client={new QueryClient()}>
|
||||
{children}
|
||||
</QueryClientProvider>
|
||||
</Provider>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { Provider } from "react-redux";
|
||||
import { createRoutesStub } from "react-router";
|
||||
import { setupStore } from "test-utils";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import ConversationService from "#/api/conversation-service/conversation-service.api";
|
||||
@ -43,11 +41,9 @@ const renderNewConversation = () => {
|
||||
|
||||
return render(<RouterStub />, {
|
||||
wrapper: ({ children }) => (
|
||||
<Provider store={setupStore()}>
|
||||
<QueryClientProvider client={new QueryClient()}>
|
||||
{children}
|
||||
</QueryClientProvider>
|
||||
</Provider>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
@ -2,8 +2,6 @@ import { render, screen, waitFor, within } from "@testing-library/react";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
|
||||
import { setupStore } from "test-utils";
|
||||
import { Provider } from "react-redux";
|
||||
import { createRoutesStub, Outlet } from "react-router";
|
||||
import SettingsService from "#/settings-service/settings-service.api";
|
||||
import ConversationService from "#/api/conversation-service/conversation-service.api";
|
||||
@ -42,11 +40,9 @@ const renderRepoConnector = () => {
|
||||
|
||||
return render(<RouterStub />, {
|
||||
wrapper: ({ children }) => (
|
||||
<Provider store={setupStore()}>
|
||||
<QueryClientProvider client={new QueryClient()}>
|
||||
{children}
|
||||
</QueryClientProvider>
|
||||
</Provider>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
@ -2,9 +2,7 @@ import { render, screen } from "@testing-library/react";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { Provider } from "react-redux";
|
||||
import { createRoutesStub } from "react-router";
|
||||
import { setupStore } from "test-utils";
|
||||
import ConversationService from "#/api/conversation-service/conversation-service.api";
|
||||
import UserService from "#/api/user-service/user-service.api";
|
||||
import GitService from "#/api/git-service/git-service.api";
|
||||
@ -41,11 +39,9 @@ const renderTaskCard = (task = MOCK_TASK_1) => {
|
||||
|
||||
return render(<RouterStub />, {
|
||||
wrapper: ({ children }) => (
|
||||
<Provider store={setupStore()}>
|
||||
<QueryClientProvider client={new QueryClient()}>
|
||||
{children}
|
||||
</QueryClientProvider>
|
||||
</Provider>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
import { render, screen, waitFor } from "@testing-library/react";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { Provider } from "react-redux";
|
||||
import { createRoutesStub } from "react-router";
|
||||
import { setupStore } from "test-utils";
|
||||
import { TaskSuggestions } from "#/components/features/home/tasks/task-suggestions";
|
||||
import { SuggestionsService } from "#/api/suggestions-service/suggestions-service.api";
|
||||
import { MOCK_TASKS } from "#/mocks/task-suggestions-handlers";
|
||||
@ -62,11 +60,9 @@ const renderTaskSuggestions = () => {
|
||||
|
||||
return render(<RouterStub />, {
|
||||
wrapper: ({ children }) => (
|
||||
<Provider store={setupStore()}>
|
||||
<QueryClientProvider client={new QueryClient()}>
|
||||
{children}
|
||||
</QueryClientProvider>
|
||||
</Provider>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import { renderWithQueryAndI18n } from "test-utils";
|
||||
import { renderWithProviders } from "test-utils";
|
||||
import { MicroagentsModal } from "#/components/features/conversation-panel/microagents-modal";
|
||||
import ConversationService from "#/api/conversation-service/conversation-service.api";
|
||||
import { AgentState } from "#/types/agent-state";
|
||||
@ -64,7 +64,7 @@ describe("MicroagentsModal - Refresh Button", () => {
|
||||
|
||||
describe("Refresh Button Rendering", () => {
|
||||
it("should render the refresh button with correct text and test ID", async () => {
|
||||
renderWithQueryAndI18n(<MicroagentsModal {...defaultProps} />);
|
||||
renderWithProviders(<MicroagentsModal {...defaultProps} />);
|
||||
|
||||
// Wait for the component to load and render the refresh button
|
||||
const refreshButton = await screen.findByTestId("refresh-microagents");
|
||||
@ -77,7 +77,7 @@ describe("MicroagentsModal - Refresh Button", () => {
|
||||
it("should call refetch when refresh button is clicked", async () => {
|
||||
const user = userEvent.setup();
|
||||
|
||||
renderWithQueryAndI18n(<MicroagentsModal {...defaultProps} />);
|
||||
renderWithProviders(<MicroagentsModal {...defaultProps} />);
|
||||
|
||||
const refreshSpy = vi.spyOn(ConversationService, "getMicroagents");
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import { afterEach } from "node:test";
|
||||
import { useTerminal } from "#/hooks/use-terminal";
|
||||
import { Command, useCommandStore } from "#/state/command-store";
|
||||
import { AgentState } from "#/types/agent-state";
|
||||
import { renderWithQueryAndI18n } from "../../test-utils";
|
||||
import { renderWithProviders } from "../../test-utils";
|
||||
import { useAgentStore } from "#/stores/agent-store";
|
||||
|
||||
// Mock the WsClient context
|
||||
@ -60,7 +60,7 @@ describe("useTerminal", () => {
|
||||
});
|
||||
|
||||
it("should render", () => {
|
||||
renderWithQueryAndI18n(<TestTerminalComponent commands={[]} />);
|
||||
renderWithProviders(<TestTerminalComponent commands={[]} />);
|
||||
});
|
||||
|
||||
it("should render the commands in the terminal", () => {
|
||||
@ -69,7 +69,7 @@ describe("useTerminal", () => {
|
||||
{ content: "hello", type: "output" },
|
||||
];
|
||||
|
||||
renderWithQueryAndI18n(<TestTerminalComponent commands={commands} />);
|
||||
renderWithProviders(<TestTerminalComponent commands={commands} />);
|
||||
|
||||
expect(mockTerminal.writeln).toHaveBeenNthCalledWith(1, "echo hello");
|
||||
expect(mockTerminal.writeln).toHaveBeenNthCalledWith(2, "hello");
|
||||
@ -87,7 +87,7 @@ describe("useTerminal", () => {
|
||||
{ content: secret, type: "output" },
|
||||
];
|
||||
|
||||
renderWithQueryAndI18n(<TestTerminalComponent commands={commands} />);
|
||||
renderWithProviders(<TestTerminalComponent commands={commands} />);
|
||||
|
||||
// This test is no longer relevant as secrets filtering has been removed
|
||||
});
|
||||
|
||||
@ -3,8 +3,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { createRoutesStub } from "react-router";
|
||||
import { Provider } from "react-redux";
|
||||
import { createAxiosNotFoundErrorObject, setupStore } from "test-utils";
|
||||
import { createAxiosNotFoundErrorObject } from "test-utils";
|
||||
import HomeScreen from "#/routes/home";
|
||||
import { GitRepository } from "#/types/git";
|
||||
import SettingsService from "#/settings-service/settings-service.api";
|
||||
@ -66,11 +65,9 @@ const selectRepository = async (repoName: string) => {
|
||||
const renderHomeScreen = () =>
|
||||
render(<RouterStub />, {
|
||||
wrapper: ({ children }) => (
|
||||
<Provider store={setupStore()}>
|
||||
<QueryClientProvider client={new QueryClient()}>
|
||||
{children}
|
||||
</QueryClientProvider>
|
||||
</Provider>
|
||||
),
|
||||
});
|
||||
|
||||
|
||||
92
frontend/package-lock.json
generated
92
frontend/package-lock.json
generated
@ -15,7 +15,6 @@
|
||||
"@react-router/node": "^7.9.1",
|
||||
"@react-router/serve": "^7.9.1",
|
||||
"@react-types/shared": "^3.32.0",
|
||||
"@reduxjs/toolkit": "^2.9.0",
|
||||
"@stripe/react-stripe-js": "^4.0.2",
|
||||
"@stripe/stripe-js": "^7.9.0",
|
||||
"@tailwindcss/postcss": "^4.1.13",
|
||||
@ -47,7 +46,6 @@
|
||||
"react-i18next": "^15.7.2",
|
||||
"react-icons": "^5.5.0",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-redux": "^9.2.0",
|
||||
"react-router": "^7.9.1",
|
||||
"react-syntax-highlighter": "^15.6.6",
|
||||
"remark-breaks": "^4.0.0",
|
||||
@ -4977,32 +4975,6 @@
|
||||
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@reduxjs/toolkit": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.9.0.tgz",
|
||||
"integrity": "sha512-fSfQlSRu9Z5yBkvsNhYF2rPS8cGXn/TZVrlwN1948QyZ8xMZ0JvP50S2acZNaf+o63u6aEeMjipFyksjIcWrog==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@standard-schema/spec": "^1.0.0",
|
||||
"@standard-schema/utils": "^0.3.0",
|
||||
"immer": "^10.0.3",
|
||||
"redux": "^5.0.1",
|
||||
"redux-thunk": "^3.1.0",
|
||||
"reselect": "^5.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.9.0 || ^17.0.0 || ^18 || ^19",
|
||||
"react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react": {
|
||||
"optional": true
|
||||
},
|
||||
"react-redux": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/pluginutils": {
|
||||
"version": "1.0.0-beta.35",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.35.tgz",
|
||||
@ -5337,18 +5309,6 @@
|
||||
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@standard-schema/spec": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz",
|
||||
"integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@standard-schema/utils": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz",
|
||||
"integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@stripe/react-stripe-js": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-4.0.2.tgz",
|
||||
@ -6350,12 +6310,6 @@
|
||||
"integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/use-sync-external-store": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
|
||||
"integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.18.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
|
||||
@ -10830,6 +10784,8 @@
|
||||
"resolved": "https://registry.npmjs.org/immer/-/immer-10.1.3.tgz",
|
||||
"integrity": "sha512-tmjF/k8QDKydUlm3mZU+tjM6zeq9/fFpPqH9SzWmBnVVKsPBg/V66qsMwb3/Bo90cgUN+ghdVBess+hPsxUyRw==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/immer"
|
||||
@ -14754,29 +14710,6 @@
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/react-redux": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
|
||||
"integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/use-sync-external-store": "^0.0.6",
|
||||
"use-sync-external-store": "^1.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^18.2.25 || ^19",
|
||||
"react": "^18.0 || ^19",
|
||||
"redux": "^5.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"redux": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-refresh": {
|
||||
"version": "0.14.2",
|
||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
|
||||
@ -14879,21 +14812,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/redux": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
|
||||
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/redux-thunk": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz",
|
||||
"integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"redux": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/reflect.getprototypeof": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
||||
@ -15164,12 +15082,6 @@
|
||||
"node": ">=0.10.5"
|
||||
}
|
||||
},
|
||||
"node_modules/reselect": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
|
||||
"integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.10",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
"@react-router/node": "^7.9.1",
|
||||
"@react-router/serve": "^7.9.1",
|
||||
"@react-types/shared": "^3.32.0",
|
||||
"@reduxjs/toolkit": "^2.9.0",
|
||||
"@stripe/react-stripe-js": "^4.0.2",
|
||||
"@stripe/stripe-js": "^7.9.0",
|
||||
"@tailwindcss/postcss": "^4.1.13",
|
||||
@ -46,7 +45,6 @@
|
||||
"react-i18next": "^15.7.2",
|
||||
"react-icons": "^5.5.0",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-redux": "^9.2.0",
|
||||
"react-router": "^7.9.1",
|
||||
"react-syntax-highlighter": "^15.6.6",
|
||||
"remark-breaks": "^4.0.0",
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { PayloadAction } from "@reduxjs/toolkit";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
import Markdown from "react-markdown";
|
||||
@ -30,8 +29,8 @@ interface ExpandableMessageProps {
|
||||
message: string;
|
||||
type: string;
|
||||
success?: boolean;
|
||||
observation?: PayloadAction<OpenHandsObservation>;
|
||||
action?: PayloadAction<OpenHandsAction>;
|
||||
observation?: { payload: OpenHandsObservation };
|
||||
action?: { payload: OpenHandsAction };
|
||||
}
|
||||
|
||||
export function ExpandableMessage({
|
||||
|
||||
@ -8,11 +8,9 @@
|
||||
import { HydratedRouter } from "react-router/dom";
|
||||
import React, { startTransition, StrictMode } from "react";
|
||||
import { hydrateRoot } from "react-dom/client";
|
||||
import { Provider } from "react-redux";
|
||||
import posthog from "posthog-js";
|
||||
import "./i18n";
|
||||
import { QueryClientProvider } from "@tanstack/react-query";
|
||||
import store from "./store";
|
||||
import OptionService from "./api/option-service/option-service.api";
|
||||
import { displayErrorToast } from "./utils/custom-toast-handlers";
|
||||
import { queryClient } from "./query-client-config";
|
||||
@ -63,12 +61,10 @@ prepareApp().then(() =>
|
||||
hydrateRoot(
|
||||
document,
|
||||
<StrictMode>
|
||||
<Provider store={store}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<HydratedRouter />
|
||||
<PosthogInit />
|
||||
</QueryClientProvider>
|
||||
</Provider>
|
||||
<div id="modal-portal-exit" />
|
||||
</StrictMode>,
|
||||
);
|
||||
|
||||
5
frontend/src/message.d.ts
vendored
5
frontend/src/message.d.ts
vendored
@ -1,4 +1,3 @@
|
||||
import { PayloadAction } from "@reduxjs/toolkit";
|
||||
import { OpenHandsObservation } from "./types/core/observations";
|
||||
import { OpenHandsAction } from "./types/core/actions";
|
||||
|
||||
@ -12,6 +11,6 @@ export type Message = {
|
||||
pending?: boolean;
|
||||
translationID?: string;
|
||||
eventID?: number;
|
||||
observation?: PayloadAction<OpenHandsObservation>;
|
||||
action?: PayloadAction<OpenHandsAction>;
|
||||
observation?: { payload: OpenHandsObservation };
|
||||
action?: { payload: OpenHandsAction };
|
||||
};
|
||||
|
||||
@ -2,7 +2,6 @@ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import { handleStatusMessage } from "../actions";
|
||||
import { StatusMessage } from "#/types/message";
|
||||
import { queryClient } from "#/query-client-config";
|
||||
import store from "#/store";
|
||||
import { useStatusStore } from "#/state/status-store";
|
||||
import { trackError } from "#/utils/error-handler";
|
||||
|
||||
@ -13,12 +12,6 @@ vi.mock("#/query-client-config", () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock("#/store", () => ({
|
||||
default: {
|
||||
dispatch: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock("#/state/status-store", () => ({
|
||||
useStatusStore: {
|
||||
getState: vi.fn(() => ({
|
||||
@ -56,9 +49,6 @@ describe("handleStatusMessage", () => {
|
||||
expect(queryClient.invalidateQueries).toHaveBeenCalledWith({
|
||||
queryKey: ["user", "conversation", "conversation-123"],
|
||||
});
|
||||
|
||||
// Verify that store.dispatch was not called
|
||||
expect(store.dispatch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should call setCurStatusMessage for info messages without conversation_title", () => {
|
||||
@ -109,9 +99,6 @@ describe("handleStatusMessage", () => {
|
||||
metadata: { msgId: "ERROR_ID" },
|
||||
});
|
||||
|
||||
// Verify that store.dispatch was not called
|
||||
expect(store.dispatch).not.toHaveBeenCalled();
|
||||
|
||||
// Verify that queryClient.invalidateQueries was not called
|
||||
expect(queryClient.invalidateQueries).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
import { combineReducers, configureStore } from "@reduxjs/toolkit";
|
||||
|
||||
export const rootReducer = combineReducers({});
|
||||
|
||||
const store = configureStore({
|
||||
reducer: rootReducer,
|
||||
});
|
||||
|
||||
export type RootState = ReturnType<typeof store.getState>;
|
||||
export type AppStore = typeof store;
|
||||
export type AppDispatch = typeof store.dispatch;
|
||||
|
||||
export default store;
|
||||
@ -1,15 +1,12 @@
|
||||
// See https://redux.js.org/usage/writing-tests#setting-up-a-reusable-test-render-function for more information
|
||||
// Test utilities for React components
|
||||
|
||||
import React, { PropsWithChildren } from "react";
|
||||
import { Provider } from "react-redux";
|
||||
import { configureStore } from "@reduxjs/toolkit";
|
||||
import { RenderOptions, render } from "@testing-library/react";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { I18nextProvider, initReactI18next } from "react-i18next";
|
||||
import i18n from "i18next";
|
||||
import { vi } from "vitest";
|
||||
import { AxiosError } from "axios";
|
||||
import { AppStore, RootState, rootReducer } from "./src/store";
|
||||
|
||||
// Mock useParams before importing components
|
||||
vi.mock("react-router", async () => {
|
||||
@ -37,53 +34,14 @@ i18n.use(initReactI18next).init({
|
||||
},
|
||||
});
|
||||
|
||||
export const setupStore = (preloadedState?: Partial<RootState>): AppStore =>
|
||||
configureStore({
|
||||
reducer: rootReducer,
|
||||
preloadedState,
|
||||
});
|
||||
// This type interface extends the default options for render from RTL
|
||||
interface ExtendedRenderOptions extends Omit<RenderOptions, "queries"> {}
|
||||
|
||||
// This type interface extends the default options for render from RTL, as well
|
||||
// as allows the user to specify other things such as initialState, store.
|
||||
interface ExtendedRenderOptions extends Omit<RenderOptions, "queries"> {
|
||||
preloadedState?: Partial<RootState>;
|
||||
store?: AppStore;
|
||||
}
|
||||
|
||||
// Export our own customized renderWithProviders function that creates a new Redux store and renders a <Provider>
|
||||
// Note that this creates a separate Redux store instance for every test, rather than reusing the same store instance and resetting its state
|
||||
// Export our own customized renderWithProviders function that renders with QueryClient and i18next providers
|
||||
// Since we're using Zustand stores, we don't need a Redux Provider wrapper
|
||||
export function renderWithProviders(
|
||||
ui: React.ReactElement,
|
||||
{
|
||||
preloadedState = {},
|
||||
// Automatically create a store instance if no store was passed in
|
||||
store = setupStore(preloadedState),
|
||||
...renderOptions
|
||||
}: ExtendedRenderOptions = {},
|
||||
) {
|
||||
function Wrapper({ children }: PropsWithChildren) {
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<QueryClientProvider
|
||||
client={
|
||||
new QueryClient({
|
||||
defaultOptions: { queries: { retry: false } },
|
||||
})
|
||||
}
|
||||
>
|
||||
<I18nextProvider i18n={i18n}>{children}</I18nextProvider>
|
||||
</QueryClientProvider>
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
return { store, ...render(ui, { wrapper: Wrapper, ...renderOptions }) };
|
||||
}
|
||||
|
||||
// Export a render function for components that only need QueryClient and i18next providers
|
||||
// (without Redux store)
|
||||
export function renderWithQueryAndI18n(
|
||||
ui: React.ReactElement,
|
||||
renderOptions: Omit<RenderOptions, "wrapper"> = {},
|
||||
renderOptions: ExtendedRenderOptions = {},
|
||||
) {
|
||||
function Wrapper({ children }: PropsWithChildren) {
|
||||
return (
|
||||
|
||||
@ -35,11 +35,9 @@ export default defineConfig(({ mode }) => {
|
||||
include: [
|
||||
// Pre-bundle ALL dependencies to prevent runtime optimization and page reloads
|
||||
// These are discovered during initial app load:
|
||||
"react-redux",
|
||||
"posthog-js",
|
||||
"@tanstack/react-query",
|
||||
"react-hot-toast",
|
||||
"@reduxjs/toolkit",
|
||||
"i18next",
|
||||
"i18next-http-backend",
|
||||
"i18next-browser-languagedetector",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user