Skip to content

Commit

Permalink
#304 Add confirmation for deleting connection (#305)
Browse files Browse the repository at this point in the history
  • Loading branch information
nevendyulgerov authored Jan 20, 2025
1 parent 44cbf71 commit 59b60d9
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 51 deletions.
53 changes: 52 additions & 1 deletion apps/web/e2e/pages/connections.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});

Expand Down
98 changes: 66 additions & 32 deletions apps/web/src/components/connection/connectionInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -20,43 +23,74 @@ interface ConnectionInfoProps {
const ConnectionInfo: FC<ConnectionInfoProps> = ({ connection }) => {
const { removeConnection } = useConnectionConfig();
const theme = useMantineTheme();
const [opened, { open, close }] = useDisclosure(false);

return (
<Card
withBorder
py="lg"
radius="sm"
shadow="sm"
data-testid="connection-card"
>
<Card.Section inheritPadding withBorder>
<Flex justify="space-between">
<Address value={connection.address} shorten icon />
<>
<Modal
opened={opened}
onClose={close}
title="Delete connection?"
centered
>
<Text>
This will delete the data for this connection. Are you sure
you want to proceed?
</Text>

<Group mt="xl" justify="flex-end">
<Button variant="default" onClick={close}>
Cancel
</Button>
<Button
aria-label={`remove-${connection.address}`}
role="button"
justify="flex-end"
size="compact-sm"
variant="transparent"
color="red"
data-testid="remove-connection"
onClick={() => removeConnection(connection.address)}
onClick={() => {
removeConnection(connection.address);
close();
}}
>
<TbTrash size={theme.other.iconSize} />
<VisuallyHidden>
Remove connection for address {connection.address}
</VisuallyHidden>
Confirm
</Button>
</Flex>
</Card.Section>
</Group>
</Modal>

<Card
withBorder
py="lg"
radius="sm"
shadow="sm"
data-testid="connection-card"
>
<Card.Section inheritPadding withBorder>
<Flex justify="space-between">
<Address value={connection.address} shorten icon />
<Button
aria-label={`remove-${connection.address}`}
role="button"
justify="flex-end"
size="compact-sm"
variant="transparent"
color="red"
data-testid="remove-connection"
onClick={open}
>
<TbTrash size={theme.other.iconSize} />
<VisuallyHidden>
Remove connection for address{" "}
{connection.address}
</VisuallyHidden>
</Button>
</Flex>
</Card.Section>

<List pt="sm" center>
<List.Item icon={<TbNetwork size={theme.other.iconSize} />}>
<Text style={{ lineBreak: "anywhere" }}>
{connection.url}
</Text>
</List.Item>
</List>
</Card>
<List pt="sm" center>
<List.Item icon={<TbNetwork size={theme.other.iconSize} />}>
<Text style={{ lineBreak: "anywhere" }}>
{connection.url}
</Text>
</List.Item>
</List>
</Card>
</>
);
};

Expand Down
77 changes: 75 additions & 2 deletions apps/web/test/components/connection/connectionInfo.test.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -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(<ConnectionInfo connection={connections[0]} />, {
wrapper: StyleProvider,
});
Expand All @@ -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(<ConnectionInfo connection={connection} />, {
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(<ConnectionInfo connection={connection} />, {
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",
Expand Down
16 changes: 0 additions & 16 deletions apps/web/test/components/connection/connectionView.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(<View />);

fireEvent.click(
screen.getByText(
`Remove connection for address ${connections[0].address}`,
),
);

expect(removeConnection).toHaveBeenCalledWith(connections[0].address);
});
});

0 comments on commit 59b60d9

Please sign in to comment.