diff --git a/src/components/artifact-selection-box.tsx b/src/components/artifact-selection-box.tsx index 8cab0c9..aa94a18 100644 --- a/src/components/artifact-selection-box.tsx +++ b/src/components/artifact-selection-box.tsx @@ -11,32 +11,35 @@ type ArtifactSelectionBoxProps = { isSelected: boolean; title: string; onSelect: () => void; + disabled?: boolean; }; export function ArtifactSelectionBox({ artifact, isSelected, title, - onSelect + onSelect, + disabled = false }: ArtifactSelectionBoxProps): JSX.Element { return ( - {title} + {title} {artifact ? ( {artifact.name} diff --git a/src/components/chat/artifact-modal.test.tsx b/src/components/chat/artifact-modal.test.tsx index 3944ad5..d59b736 100644 --- a/src/components/chat/artifact-modal.test.tsx +++ b/src/components/chat/artifact-modal.test.tsx @@ -1,16 +1,16 @@ import React from "react"; -import { render } from "@testing-library/react"; +import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import "@testing-library/jest-dom"; import { MockedProvider } from "@apollo/client/testing"; import { ArtifactModal } from "./artifact-modal"; -import { MeDocument, ArtifactAttributeType } from "src/generated/graphql"; +import { ArtifactAttributeType } from "src/generated/graphql"; -const mockArtifact = { +const equippedArtifact = { __typename: "ArtifactItem" as const, - id: "test-id", + id: "current-id", owner: "test-owner", - name: "Test Artifact", + name: "Super Equipped Test Artifact", level: 1, attributes: { __typename: "ArtifactAttributes" as const, @@ -22,71 +22,62 @@ const mockArtifact = { }, }; -const mocks = [ - { - request: { - query: MeDocument, - }, - result: { - data: { - me: { - account: { - hero: { - equipment: { - artifact: { - ...mockArtifact, - id: "current-id", - name: "Current Artifact", - }, - }, - }, - }, - }, - }, - }, +const newArtifact = { + __typename: "ArtifactItem" as const, + id: "test-id", + owner: "test-owner", + name: "Goofy Test Artifact of Testing", + level: 1, + attributes: { + __typename: "ArtifactAttributes" as const, + namePrefix: { __typename: "ArtifactAttribute" as const, type: ArtifactAttributeType.BonusPhysicalDamage, magnitude: 1 }, + namePostfix: { __typename: "ArtifactAttribute" as const, type: ArtifactAttributeType.BonusHealth, magnitude: 1 }, + bonusAffixes: [], + titlePrefix: null, + titlePostfix: null, }, -]; +}; describe("ArtifactModal", () => { - it("renders both artifacts and allows selection", async () => { + it("handles artifact selection and confirmation flow when current artifact exists", async () => { const user = userEvent.setup(); - const { getByText } = render( - - + + render( + + ); - // Check that both artifacts are rendered - expect(getByText("Current Artifact")).toBeInTheDocument(); - expect(getByText("Test Artifact")).toBeInTheDocument(); - - // Continue button should be disabled initially - const continueButton = getByText("Continue with Selected"); - expect(continueButton).toBeDisabled(); + // Initial state: both artifacts rendered, button disabled + expect(screen.getByText(equippedArtifact.name)).toBeInTheDocument(); + expect(screen.getByText(newArtifact.name)).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /continue with selected/i })).toBeDisabled(); - // Select new artifact - await user.click(getByText("Test Artifact")); - expect(continueButton).toBeEnabled(); + // Select new artifact and verify button enables + await user.click(screen.getByText(newArtifact.name)); + expect(screen.getByRole('button', { name: /continue with selected/i })).toBeEnabled(); - // Open confirmation dialog - await user.click(continueButton); - expect(getByText("Confirm Your Choice")).toBeInTheDocument(); - expect(getByText(/Are you sure you want to keep the new artifact/)).toBeInTheDocument(); + // Open and verify confirmation dialog with warning + await user.click(screen.getByRole('button', { name: /continue with selected/i })); + expect(screen.getByText("Are you sure you want to keep the new artifact?")).toBeInTheDocument(); + expect(screen.getByText("This action cannot be undone.")).toBeInTheDocument(); }); - it("shows warning message in confirmation dialog", async () => { + it("automatically selects new artifact when no current artifact exists", async () => { const user = userEvent.setup(); - const { getByText } = render( - - + render( + + ); - // Select new artifact and open confirmation - await user.click(getByText("Test Artifact")); - await user.click(getByText("Continue with Selected")); + // Verify initial state + expect(screen.getByText("You have no artifact equipped. The new artifact will be automatically equipped.")).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /accept new artifact/i })).toBeEnabled(); - // Check warning message - expect(getByText("This action cannot be undone.")).toBeInTheDocument(); + // Open and verify confirmation dialog + await user.click(screen.getByRole('button', { name: /accept new artifact/i })); + expect(screen.getByText("Are you sure you want to equip the new artifact?")).toBeInTheDocument(); + expect(screen.queryByText("This action cannot be undone.")).not.toBeInTheDocument(); }); }); \ No newline at end of file diff --git a/src/components/chat/artifact-modal.tsx b/src/components/chat/artifact-modal.tsx index 56bcc13..be247ab 100644 --- a/src/components/chat/artifact-modal.tsx +++ b/src/components/chat/artifact-modal.tsx @@ -6,26 +6,29 @@ import Button from "@mui/material/Button"; import { ArtifactItem, - useMeQuery, useAcceptArtifactMutation, useRejectArtifactMutation, } from "src/generated/graphql"; import { ArtifactSelectionBox } from "../artifact-selection-box"; import { ConfirmationDialog } from "../confirmation-dialog"; +type ArtifactModalProps = { + currentArtifact: ArtifactItem | null; + newArtifact: ArtifactItem; +}; + export function ArtifactModal({ - artifact, -}: { - artifact: ArtifactItem; -}): JSX.Element { + currentArtifact, + newArtifact, +}: ArtifactModalProps): JSX.Element { const [showConfirm, setShowConfirm] = useState(false); - const [selectedArtifact, setSelectedArtifact] = useState<"current" | "new" | null>(null); - const { data } = useMeQuery(); + const [selectedArtifact, setSelectedArtifact] = useState<"current" | "new" | null>( + currentArtifact ? null : "new" + ); + const [acceptArtifact] = useAcceptArtifactMutation(); const [rejectArtifact] = useRejectArtifactMutation(); - const currentArtifact = data?.me?.account?.hero?.equipment?.artifact; - const handleConfirm = async () => { if (selectedArtifact === "new") { await acceptArtifact(); @@ -39,20 +42,23 @@ export function ArtifactModal({ Choose Your Artifact - Select which artifact you want to keep. This choice cannot be undone. + {currentArtifact + ? "Select which artifact you want to keep. This choice cannot be undone." + : "You have no artifact equipped. The new artifact will be automatically equipped."} setSelectedArtifact("current")} + onSelect={() => currentArtifact && setSelectedArtifact("current")} + disabled={!currentArtifact} /> setSelectedArtifact("new")} @@ -67,15 +73,17 @@ export function ArtifactModal({ onClick={() => setShowConfirm(true)} sx={{ minWidth: 200 }} > - Continue with Selected + {currentArtifact ? "Continue with Selected" : "Accept New Artifact"} setShowConfirm(false)} /> diff --git a/src/components/chat/index.tsx b/src/components/chat/index.tsx index 88b522d..6cc1574 100644 --- a/src/components/chat/index.tsx +++ b/src/components/chat/index.tsx @@ -355,7 +355,8 @@ export function Chat(): JSX.Element { > {pendingArtifact && ( )}