diff --git a/client/src/components/__tests__/ElicitationRequest.test.tsx b/client/src/components/__tests__/ElicitationRequest.test.tsx
new file mode 100644
index 00000000..c18fe3eb
--- /dev/null
+++ b/client/src/components/__tests__/ElicitationRequest.test.tsx
@@ -0,0 +1,202 @@
+import { render, screen, fireEvent, act } from "@testing-library/react";
+import "@testing-library/jest-dom";
+import { describe, it, jest, beforeEach, afterEach } from "@jest/globals";
+import ElicitationRequest from "../ElicitationRequest";
+import { PendingElicitationRequest } from "../ElicitationTab";
+
+jest.mock("../DynamicJsonForm", () => {
+ return function MockDynamicJsonForm({
+ value,
+ onChange,
+ }: {
+ value: unknown;
+ onChange: (value: unknown) => void;
+ }) {
+ return (
+
+ {
+ try {
+ const parsed = JSON.parse(e.target.value);
+ onChange(parsed);
+ } catch {
+ onChange(e.target.value);
+ }
+ }}
+ />
+
+ );
+ };
+});
+
+describe("ElicitationRequest", () => {
+ const mockOnResolve = jest.fn();
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ afterEach(() => {
+ jest.clearAllMocks();
+ });
+
+ const createMockRequest = (
+ overrides: Partial = {},
+ ): PendingElicitationRequest => ({
+ id: 1,
+ request: {
+ id: 1,
+ message: "Please provide your information",
+ requestedSchema: {
+ type: "object",
+ properties: {
+ name: { type: "string", description: "Your name" },
+ email: { type: "string", format: "email", description: "Your email" },
+ },
+ required: ["name"],
+ },
+ },
+ ...overrides,
+ });
+
+ const renderElicitationRequest = (
+ request: PendingElicitationRequest = createMockRequest(),
+ ) => {
+ return render(
+ ,
+ );
+ };
+
+ describe("Rendering", () => {
+ it("should render the component", () => {
+ renderElicitationRequest();
+ expect(screen.getByTestId("elicitation-request")).toBeInTheDocument();
+ });
+
+ it("should display request message", () => {
+ const message = "Please provide your GitHub username";
+ renderElicitationRequest(
+ createMockRequest({
+ request: {
+ id: 1,
+ message,
+ requestedSchema: {
+ type: "object",
+ properties: { name: { type: "string" } },
+ },
+ },
+ }),
+ );
+ expect(screen.getByText(message)).toBeInTheDocument();
+ });
+
+ it("should render all three action buttons", () => {
+ renderElicitationRequest();
+ expect(
+ screen.getByRole("button", { name: /cancel/i }),
+ ).toBeInTheDocument();
+ expect(
+ screen.getByRole("button", { name: /decline/i }),
+ ).toBeInTheDocument();
+ expect(
+ screen.getByRole("button", { name: /submit/i }),
+ ).toBeInTheDocument();
+ });
+
+ it("should render DynamicJsonForm component", () => {
+ renderElicitationRequest();
+ expect(screen.getByTestId("dynamic-json-form")).toBeInTheDocument();
+ });
+ });
+
+ describe("User Interactions", () => {
+ it("should call onResolve with accept action when Submit button is clicked", async () => {
+ renderElicitationRequest();
+
+ const input = screen.getByTestId("form-input");
+ await act(async () => {
+ fireEvent.change(input, {
+ target: {
+ value: '{"name": "John Doe", "email": "john@example.com"}',
+ },
+ });
+ });
+
+ await act(async () => {
+ fireEvent.click(screen.getByRole("button", { name: /submit/i }));
+ });
+
+ expect(mockOnResolve).toHaveBeenCalledWith(1, {
+ action: "accept",
+ content: { name: "John Doe", email: "john@example.com" },
+ });
+ });
+
+ it("should call onResolve with reject action when Decline button is clicked", async () => {
+ renderElicitationRequest();
+
+ await act(async () => {
+ fireEvent.click(screen.getByRole("button", { name: /decline/i }));
+ });
+
+ expect(mockOnResolve).toHaveBeenCalledWith(1, { action: "reject" });
+ });
+
+ it("should call onResolve with cancel action when Cancel button is clicked", async () => {
+ renderElicitationRequest();
+
+ await act(async () => {
+ fireEvent.click(screen.getByRole("button", { name: /cancel/i }));
+ });
+
+ expect(mockOnResolve).toHaveBeenCalledWith(1, { action: "cancel" });
+ });
+ });
+
+ describe("Form Validation", () => {
+ it("should show validation error for missing required fields", async () => {
+ renderElicitationRequest();
+
+ await act(async () => {
+ fireEvent.click(screen.getByRole("button", { name: /submit/i }));
+ });
+
+ expect(
+ screen.getByText(/Required field missing: name/),
+ ).toBeInTheDocument();
+ expect(mockOnResolve).not.toHaveBeenCalledWith(
+ 1,
+ expect.objectContaining({ action: "accept" }),
+ );
+ });
+
+ it("should show validation error for invalid email format", async () => {
+ renderElicitationRequest();
+
+ const input = screen.getByTestId("form-input");
+ await act(async () => {
+ fireEvent.change(input, {
+ target: { value: '{"name": "John", "email": "invalid-email"}' },
+ });
+ });
+
+ await act(async () => {
+ fireEvent.click(screen.getByRole("button", { name: /submit/i }));
+ });
+
+ expect(
+ screen.getByText(/Invalid email format: email/),
+ ).toBeInTheDocument();
+ expect(mockOnResolve).not.toHaveBeenCalledWith(
+ 1,
+ expect.objectContaining({ action: "accept" }),
+ );
+ });
+ });
+});