aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/client/pages/NoteTypesPage.test.tsx
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-12-31 02:49:55 +0900
committernsfisis <nsfisis@gmail.com>2025-12-31 02:49:55 +0900
commit6aa496b60879526b51fdf736c38f09aede283bde (patch)
treeeaeb4bc61ae10cd81f76e48047ad5f2193a53c38 /src/client/pages/NoteTypesPage.test.tsx
parentb51d4efaa1e5e0417d4306c02797f424938766cb (diff)
downloadkioku-6aa496b60879526b51fdf736c38f09aede283bde.tar.gz
kioku-6aa496b60879526b51fdf736c38f09aede283bde.tar.zst
kioku-6aa496b60879526b51fdf736c38f09aede283bde.zip
feat(client): add NoteTypeEditor component with field management
Add a comprehensive editor for note types that allows users to: - Edit note type name and templates - Add, remove, and reorder fields - Toggle the reversible card option The editor fetches note type details including fields from the API, enabling full CRUD operations for note type configuration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'src/client/pages/NoteTypesPage.test.tsx')
-rw-r--r--src/client/pages/NoteTypesPage.test.tsx90
1 files changed, 69 insertions, 21 deletions
diff --git a/src/client/pages/NoteTypesPage.test.tsx b/src/client/pages/NoteTypesPage.test.tsx
index 0cf8615..c2df7f5 100644
--- a/src/client/pages/NoteTypesPage.test.tsx
+++ b/src/client/pages/NoteTypesPage.test.tsx
@@ -95,9 +95,7 @@ describe("NoteTypesPage", () => {
renderWithProviders();
- expect(
- screen.getByRole("heading", { name: "Note Types" }),
- ).toBeDefined();
+ expect(screen.getByRole("heading", { name: "Note Types" })).toBeDefined();
expect(screen.getByRole("link", { name: "Back to Home" })).toBeDefined();
});
@@ -137,9 +135,7 @@ describe("NoteTypesPage", () => {
renderWithProviders();
await waitFor(() => {
- expect(
- screen.getByRole("heading", { name: "Basic" }),
- ).toBeDefined();
+ expect(screen.getByRole("heading", { name: "Basic" })).toBeDefined();
});
expect(
screen.getByRole("heading", { name: "Basic (and reversed card)" }),
@@ -279,9 +275,7 @@ describe("NoteTypesPage", () => {
expect(screen.getByText("No note types yet")).toBeDefined();
});
- await user.click(
- screen.getByRole("button", { name: /New Note Type/i }),
- );
+ await user.click(screen.getByRole("button", { name: /New Note Type/i }));
expect(screen.getByRole("dialog")).toBeDefined();
expect(
@@ -322,9 +316,7 @@ describe("NoteTypesPage", () => {
});
// Open modal
- await user.click(
- screen.getByRole("button", { name: /New Note Type/i }),
- );
+ await user.click(screen.getByRole("button", { name: /New Note Type/i }));
// Fill in form
await user.type(screen.getByLabelText("Name"), "New Note Type");
@@ -367,10 +359,35 @@ describe("NoteTypesPage", () => {
it("opens edit modal when Edit button is clicked", async () => {
const user = userEvent.setup();
- mockFetch.mockResolvedValue({
- ok: true,
- json: async () => ({ noteTypes: mockNoteTypes }),
- });
+ const mockNoteTypeWithFields = {
+ ...mockNoteTypes[0],
+ fields: [
+ {
+ id: "field-1",
+ noteTypeId: "note-type-1",
+ name: "Front",
+ order: 0,
+ fieldType: "text",
+ },
+ {
+ id: "field-2",
+ noteTypeId: "note-type-1",
+ name: "Back",
+ order: 1,
+ fieldType: "text",
+ },
+ ],
+ };
+
+ mockFetch
+ .mockResolvedValueOnce({
+ ok: true,
+ json: async () => ({ noteTypes: mockNoteTypes }),
+ })
+ .mockResolvedValueOnce({
+ ok: true,
+ json: async () => ({ noteType: mockNoteTypeWithFields }),
+ });
renderWithProviders();
@@ -387,11 +404,33 @@ describe("NoteTypesPage", () => {
expect(
screen.getByRole("heading", { name: "Edit Note Type" }),
).toBeDefined();
- expect(screen.getByLabelText("Name")).toHaveProperty("value", "Basic");
+
+ await waitFor(() => {
+ expect(screen.getByLabelText("Name")).toHaveProperty("value", "Basic");
+ });
});
it("edits note type and refreshes list", async () => {
const user = userEvent.setup();
+ const mockNoteTypeWithFields = {
+ ...mockNoteTypes[0],
+ fields: [
+ {
+ id: "field-1",
+ noteTypeId: "note-type-1",
+ name: "Front",
+ order: 0,
+ fieldType: "text",
+ },
+ {
+ id: "field-2",
+ noteTypeId: "note-type-1",
+ name: "Back",
+ order: 1,
+ fieldType: "text",
+ },
+ ],
+ };
const updatedNoteType = {
...mockNoteTypes[0],
name: "Updated Basic",
@@ -404,11 +443,17 @@ describe("NoteTypesPage", () => {
})
.mockResolvedValueOnce({
ok: true,
+ json: async () => ({ noteType: mockNoteTypeWithFields }),
+ })
+ .mockResolvedValueOnce({
+ ok: true,
json: async () => ({ noteType: updatedNoteType }),
})
.mockResolvedValueOnce({
ok: true,
- json: async () => ({ noteTypes: [updatedNoteType, mockNoteTypes[1]] }),
+ json: async () => ({
+ noteTypes: [updatedNoteType, mockNoteTypes[1]],
+ }),
});
renderWithProviders();
@@ -423,6 +468,11 @@ describe("NoteTypesPage", () => {
});
await user.click(editButtons.at(0) as HTMLElement);
+ // Wait for the editor to load
+ await waitFor(() => {
+ expect(screen.getByLabelText("Name")).toHaveProperty("value", "Basic");
+ });
+
// Update name
const nameInput = screen.getByLabelText("Name");
await user.clear(nameInput);
@@ -539,9 +589,7 @@ describe("NoteTypesPage", () => {
// Note type list should be refreshed without deleted note type
await waitFor(() => {
- expect(
- screen.queryByRole("heading", { name: "Basic" }),
- ).toBeNull();
+ expect(screen.queryByRole("heading", { name: "Basic" })).toBeNull();
});
expect(
screen.getByRole("heading", { name: "Basic (and reversed card)" }),