diff --git a/apps/web/e2e/pages/connections.spec.ts b/apps/web/e2e/pages/connections.spec.ts index 4014219d..c4342c33 100644 --- a/apps/web/e2e/pages/connections.spec.ts +++ b/apps/web/e2e/pages/connections.spec.ts @@ -30,12 +30,63 @@ test("should be able to add a connection", async ({ page }) => { await createConnection(page, "0x60a7048c3136293071605a4eaffef49923e981cc"); }); -test("should be able to remove a connection", async ({ page }) => { +test("should display a confirmation modal for removing a connection", async ({ + page, +}) => { await createConnection(page, "0x60a7048c3136293071605a4eaffef49923e981cc"); const deleteButton = page.getByTestId("remove-connection"); await deleteButton.click(); + await expect(page.getByText("Delete connection?")).toBeVisible(); + await expect( + page.getByText( + "This will delete the data for this connection. Are you sure you want to proceed?", + ), + ).toBeVisible(); +}); + +test("should close the confirmation modal when canceling the connection deletion", async ({ + page, +}) => { + await createConnection(page, "0x60a7048c3136293071605a4eaffef49923e981cc"); + + const deleteButton = page.getByTestId("remove-connection"); + await deleteButton.click(); + + await expect(page.getByText("Delete connection?")).toBeVisible(); + await expect( + page.getByText( + "This will delete the data for this connection. Are you sure you want to proceed?", + ), + ).toBeVisible(); + + const cancelButton = page.getByText("Cancel"); + await cancelButton.click(); + + await expect(page.getByText("Delete connection?")).not.toBeVisible(); + await expect(page.getByText("No connections found.")).not.toBeVisible(); +}); + +test("should remove the connection when the delete action was confirmed", async ({ + page, +}) => { + await createConnection(page, "0x60a7048c3136293071605a4eaffef49923e981cc"); + + const deleteButton = page.getByTestId("remove-connection"); + await deleteButton.click(); + + await expect(page.getByText("Delete connection?")).toBeVisible(); + await expect( + page.getByText( + "This will delete the data for this connection. Are you sure you want to proceed?", + ), + ).toBeVisible(); + + const cancelButton = page.getByText("Confirm"); + await cancelButton.click(); + + await expect(page.getByText("Delete connection?")).not.toBeVisible(); await expect(page.getByText("No connections found.")).toBeVisible(); }); diff --git a/apps/web/src/components/connection/connectionInfo.tsx b/apps/web/src/components/connection/connectionInfo.tsx index 1dd2830b..a2e643ed 100644 --- a/apps/web/src/components/connection/connectionInfo.tsx +++ b/apps/web/src/components/connection/connectionInfo.tsx @@ -2,11 +2,14 @@ import { Button, Card, Flex, + Group, List, + Modal, Text, VisuallyHidden, useMantineTheme, } from "@mantine/core"; +import { useDisclosure } from "@mantine/hooks"; import { FC } from "react"; import { TbNetwork, TbTrash } from "react-icons/tb"; import { useConnectionConfig } from "../../providers/connectionConfig/hooks"; @@ -20,43 +23,74 @@ interface ConnectionInfoProps { const ConnectionInfo: FC = ({ connection }) => { const { removeConnection } = useConnectionConfig(); const theme = useMantineTheme(); + const [opened, { open, close }] = useDisclosure(false); + return ( - - - -
+ <> + + + This will delete the data for this connection. Are you sure + you want to proceed? + + + + - - + + + + + + +
+ + + - - }> - - {connection.url} - - - - + + }> + + {connection.url} + + + + + ); }; diff --git a/apps/web/test/components/connection/connectionInfo.test.tsx b/apps/web/test/components/connection/connectionInfo.test.tsx index d3dc5c9a..2dd8534d 100644 --- a/apps/web/test/components/connection/connectionInfo.test.tsx +++ b/apps/web/test/components/connection/connectionInfo.test.tsx @@ -1,4 +1,10 @@ -import { cleanup, fireEvent, render, screen } from "@testing-library/react"; +import { + cleanup, + fireEvent, + render, + screen, + waitFor, +} from "@testing-library/react"; import { describe, it } from "vitest"; import ConnectionInfo from "../../../src/components/connection/connectionInfo"; import { useConnectionConfig } from "../../../src/providers/connectionConfig/hooks"; @@ -41,7 +47,7 @@ describe("Connection info component", () => { ).toBeInTheDocument(); }); - it("should call the remove action when clicking on the trash icon", async () => { + it("should open the confirmation modal when clicking on the trash icon", async () => { render(, { wrapper: StyleProvider, }); @@ -52,6 +58,73 @@ describe("Connection info component", () => { fireEvent.click(button); + await waitFor(() => screen.getByText("Delete connection?")); + expect( + screen.getByText( + "This will delete the data for this connection. Are you sure you want to proceed?", + ), + ).toBeInTheDocument(); + }); + + it("should close the confirmation modal when clicking on cancel button", async () => { + const [connection] = connections; + render(, { + wrapper: StyleProvider, + }); + + const button = screen.getByRole("button", { + name: `remove-${connection.address}`, + }); + + fireEvent.click(button); + + await waitFor(() => screen.getByText("Delete connection?")); + expect( + screen.getByText( + "This will delete the data for this connection. Are you sure you want to proceed?", + ), + ).toBeInTheDocument(); + + const cancelButton = screen.getByText("Cancel"); + fireEvent.click(cancelButton); + + await waitFor(() => + expect(() => screen.getByText("Delete connection?")).toThrow( + "Unable to find an element with the text: Delete connection?", + ), + ); + + expect(screen.getByText(connection.url)).toBeInTheDocument(); + }); + + it("should call the remove action when confirming the connection deletion", async () => { + const [connection] = connections; + render(, { + wrapper: StyleProvider, + }); + + const button = screen.getByRole("button", { + name: `remove-${connection.address}`, + }); + + fireEvent.click(button); + + await waitFor(() => screen.getByText("Delete connection?")); + expect( + screen.getByText( + "This will delete the data for this connection. Are you sure you want to proceed?", + ), + ).toBeInTheDocument(); + + const confirmButton = screen.getByText("Confirm"); + fireEvent.click(confirmButton); + + await waitFor(() => + expect(() => screen.getByText("Delete connection?")).toThrow( + "Unable to find an element with the text: Delete connection?", + ), + ); + expect(useConnMock().removeConnection).toHaveBeenCalledOnce(); expect(useConnMock().removeConnection).toHaveBeenCalledWith( "0x70ac08179605AF2D9e75782b8DEcDD3c22aA4D0C", diff --git a/apps/web/test/components/connection/connectionView.test.tsx b/apps/web/test/components/connection/connectionView.test.tsx index 3b4e83a0..ea446377 100644 --- a/apps/web/test/components/connection/connectionView.test.tsx +++ b/apps/web/test/components/connection/connectionView.test.tsx @@ -81,20 +81,4 @@ describe("Connection view component", () => { ); expect(screen.getByText(connections[1].url)).toBeInTheDocument(); }); - - it("should call the remove connection correctly when clicking the trash can", () => { - const { removeConnection, listConnections } = - useConnectionConfigReturnStub; - listConnections.mockReturnValue(connections); - - render(); - - fireEvent.click( - screen.getByText( - `Remove connection for address ${connections[0].address}`, - ), - ); - - expect(removeConnection).toHaveBeenCalledWith(connections[0].address); - }); });