aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/client/components/EditDeckModal.test.tsx
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-25 23:02:35 +0900
committernsfisis <nsfisis@gmail.com>2026-02-25 23:02:35 +0900
commit38b8fc0e9927c4146b4c8b309b2bcc644abd63d0 (patch)
treef76ba23251645e552fccd201362064b06de50bdd /src/client/components/EditDeckModal.test.tsx
parent7a77e72bb49ed3990a0c4581292a37a8a4f35231 (diff)
downloadkioku-38b8fc0e9927c4146b4c8b309b2bcc644abd63d0.tar.gz
kioku-38b8fc0e9927c4146b4c8b309b2bcc644abd63d0.tar.zst
kioku-38b8fc0e9927c4146b4c8b309b2bcc644abd63d0.zip
feat(decks): add default note type setting per deckHEADmain
Allow each deck to specify a default note type that is auto-selected when creating new notes. Includes DB schema migration, server API updates, sync layer support, and UI for editing the default in the deck settings modal. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'src/client/components/EditDeckModal.test.tsx')
-rw-r--r--src/client/components/EditDeckModal.test.tsx58
1 files changed, 45 insertions, 13 deletions
diff --git a/src/client/components/EditDeckModal.test.tsx b/src/client/components/EditDeckModal.test.tsx
index b22cb1d..248c74f 100644
--- a/src/client/components/EditDeckModal.test.tsx
+++ b/src/client/components/EditDeckModal.test.tsx
@@ -8,6 +8,8 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const mockPut = vi.fn();
const mockHandleResponse = vi.fn();
+const mockGetNoteTypes = vi.fn();
+
vi.mock("../api/client", () => ({
apiClient: {
rpc: {
@@ -17,6 +19,9 @@ vi.mock("../api/client", () => ({
$put: (args: unknown) => mockPut(args),
},
},
+ "note-types": {
+ $get: () => mockGetNoteTypes(),
+ },
},
},
handleResponse: (res: unknown) => mockHandleResponse(res),
@@ -42,6 +47,7 @@ describe("EditDeckModal", () => {
id: "deck-123",
name: "Test Deck",
description: "Test description",
+ defaultNoteTypeId: null as string | null,
};
const defaultProps = {
@@ -51,15 +57,25 @@ describe("EditDeckModal", () => {
onDeckUpdated: vi.fn(),
};
+ const noteTypesResponse = { ok: true, _type: "noteTypes" };
+ const putResponse = { ok: true, _type: "put" };
+
beforeEach(() => {
vi.clearAllMocks();
- mockPut.mockResolvedValue({ ok: true });
- mockHandleResponse.mockResolvedValue({
- deck: {
- id: "deck-123",
- name: "Test Deck",
- description: "Test description",
- },
+ mockPut.mockResolvedValue(putResponse);
+ mockGetNoteTypes.mockResolvedValue(noteTypesResponse);
+ mockHandleResponse.mockImplementation((res: unknown) => {
+ if (res === noteTypesResponse) {
+ return Promise.resolve({ noteTypes: [] });
+ }
+ return Promise.resolve({
+ deck: {
+ id: "deck-123",
+ name: "Test Deck",
+ description: "Test description",
+ defaultNoteTypeId: null,
+ },
+ });
});
});
@@ -187,6 +203,7 @@ describe("EditDeckModal", () => {
json: {
name: "Updated Deck",
description: "Test description",
+ defaultNoteTypeId: null,
},
});
});
@@ -220,6 +237,7 @@ describe("EditDeckModal", () => {
json: {
name: "Test Deck",
description: "New description",
+ defaultNoteTypeId: null,
},
});
});
@@ -243,6 +261,7 @@ describe("EditDeckModal", () => {
json: {
name: "Test Deck",
description: null,
+ defaultNoteTypeId: null,
},
});
});
@@ -266,6 +285,7 @@ describe("EditDeckModal", () => {
json: {
name: "Deck",
description: "Description",
+ defaultNoteTypeId: null,
},
});
});
@@ -299,12 +319,16 @@ describe("EditDeckModal", () => {
it("displays API error message", async () => {
const user = userEvent.setup();
+ render(<EditDeckModal {...defaultProps} />);
+
+ // Wait for note types to load, then override handleResponse for the PUT
+ await waitFor(() => {
+ expect(mockGetNoteTypes).toHaveBeenCalled();
+ });
mockHandleResponse.mockRejectedValue(
new ApiClientError("Deck name already exists", 400),
);
- render(<EditDeckModal {...defaultProps} />);
-
await user.click(screen.getByRole("button", { name: "Save Changes" }));
await waitFor(() => {
@@ -333,12 +357,16 @@ describe("EditDeckModal", () => {
it("displays error when handleResponse throws", async () => {
const user = userEvent.setup();
+ render(<EditDeckModal {...defaultProps} />);
+
+ // Wait for note types to load, then override handleResponse for the PUT
+ await waitFor(() => {
+ expect(mockGetNoteTypes).toHaveBeenCalled();
+ });
mockHandleResponse.mockRejectedValue(
new ApiClientError("Not authenticated", 401),
);
- render(<EditDeckModal {...defaultProps} />);
-
await user.click(screen.getByRole("button", { name: "Save Changes" }));
await waitFor(() => {
@@ -374,12 +402,16 @@ describe("EditDeckModal", () => {
const user = userEvent.setup();
const onClose = vi.fn();
- mockHandleResponse.mockRejectedValue(new ApiClientError("Some error", 400));
-
const { rerender } = render(
<EditDeckModal {...defaultProps} onClose={onClose} />,
);
+ // Wait for note types to load, then override handleResponse for the PUT
+ await waitFor(() => {
+ expect(mockGetNoteTypes).toHaveBeenCalled();
+ });
+ mockHandleResponse.mockRejectedValue(new ApiClientError("Some error", 400));
+
// Trigger error
await user.click(screen.getByRole("button", { name: "Save Changes" }));
await waitFor(() => {