Skip to content

Commit

Permalink
Mock service, data-testid, and a test
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidSouther committed Oct 11, 2022
1 parent bd3d381 commit 06a3e4d
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { fireEvent, render, screen } from "@testing-library/react";
import { MockWorkItemService } from "./testing/MockWorkItemService";
import { WorkItemControls } from "./WorkItemListComponent";
import * as service from "./WorkItemService";

jest.mock("./WorkItemService");
const mocked = jest.mocked(service);

const FAKE_EMAIL = "[email protected]";

test("AddWorkItemComponent sends report", async () => {
mocked.workItemService = new MockWorkItemService();
await render(<WorkItemControls />);

await fireEvent.change(
screen.getByPlaceholderText(/Recipient's email/),
FAKE_EMAIL
);
await fireEvent.click(screen.getByTestId("send-report"));

expect(mocked.workItemService.mailItem).toHaveBeenCalledWith(FAKE_EMAIL);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { useCallback, useEffect, useState } from "react";
import { WorkItemStatus } from "./WorkItemService";
import { workItemService as service } from "./WorkItemService";
import {
Button,
FormField,
Input,
Select,
SpaceBetween,
} from "@cloudscape-design/components";
import { OptionDefinition } from "@cloudscape-design/components/internal/components/option/interfaces";
import { useItemTrackerAction } from "../ItemTrackerStore";

const STATUS_OPTIONS: OptionDefinition[] = [
{ value: "active", label: "Active" },
{ value: "archived", label: "Archived" },
{ value: "", label: "All" },
];

export const WorkItemControls = () => {
const [email, setEmail] = useState("");
const [status, setStatus] = useState(STATUS_OPTIONS[0]);
const { setStatus: handleStatusChange, setError } = useItemTrackerAction();

const sendReport = useCallback(
async (email: string) => {
try {
service.mailItem(email);
} catch (e) {
setError((e as Error).message);
}
},
[setError]
);

useEffect(() => {
handleStatusChange((status.value as WorkItemStatus) ?? "");
}, [status, handleStatusChange]);

return (
<SpaceBetween size="s">
<FormField>
<Select
selectedOption={status}
onChange={(event) => setStatus(event.detail.selectedOption)}
options={STATUS_OPTIONS}
/>
</FormField>
<FormField
label="Email Report"
description="Register the recipient's email with Amazon SES."
>
<Input
value={email}
onChange={(event) => setEmail(event.detail.value)}
placeholder="Recipient's email"
/>
</FormField>
<Button
data-testid="send-report"
disabled={email === ""}
onClick={() => sendReport(email)}
>
Send report
</Button>
</SpaceBetween>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { WorkItem, WorkItemService } from "../WorkItemService";

export class MockWorkItemService extends WorkItemService {
id = 0;
nextId() {
this.id += 1;
return String(this.id);
}
items: Record<string, WorkItem> = {};

override archiveItem: (itemId: string) => Promise<unknown> = jest
.fn()
.mockResolvedValue({});

override mailItem: (email: string) => Promise<Response> = jest
.fn()
.mockResolvedValue({});

override create: (item: Omit<WorkItem, "id">) => Promise<WorkItem> = jest.fn(
(item: Omit<WorkItem, "id">) => {
let workItem: WorkItem = {
...item,
id: this.nextId(),
};
this.items[workItem.id] = workItem;
return Promise.resolve(workItem);
}
);

override list: (
params?: Partial<Record<keyof WorkItem, string>>
) => Promise<WorkItem[]> = jest.fn(
(params?: Partial<Record<keyof WorkItem, string>>) =>
Promise.resolve([...Object.values(this.items)])
);

override retrieve: (
id: string,
params?: Partial<Record<keyof WorkItem, string>>
) => Promise<WorkItem> = jest.fn(
(id: string, params?: Partial<Record<keyof WorkItem, string>>) =>
Promise.resolve(this.items[id])
);

override update: (id: string, body: Partial<WorkItem>) => Promise<WorkItem> =
jest.fn((id: string, body: Partial<WorkItem>) => {
this.items[id] = body as WorkItem;
return Promise.resolve(this.items[id]);
});

override delete: (id: string) => Promise<void> = jest.fn((id: string) => {
delete this.items[id];
return Promise.resolve();
});
}

0 comments on commit 06a3e4d

Please sign in to comment.