aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/server/routes/study.test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/routes/study.test.ts')
-rw-r--r--src/server/routes/study.test.ts100
1 files changed, 33 insertions, 67 deletions
diff --git a/src/server/routes/study.test.ts b/src/server/routes/study.test.ts
index 77cb15c..41abecd 100644
--- a/src/server/routes/study.test.ts
+++ b/src/server/routes/study.test.ts
@@ -5,12 +5,10 @@ import { CardState, Rating } from "../db/schema.js";
import { errorHandler } from "../middleware/index.js";
import type {
Card,
+ CardForStudy,
CardRepository,
- CardWithNoteData,
Deck,
DeckRepository,
- Note,
- NoteFieldValue,
ReviewLog,
ReviewLogRepository,
} from "../repositories/index.js";
@@ -28,6 +26,7 @@ function createMockCardRepo(): CardRepository {
softDeleteByNoteId: vi.fn(),
findDueCards: vi.fn(),
findDueCardsWithNoteData: vi.fn(),
+ findDueCardsForStudy: vi.fn(),
updateFSRSFields: vi.fn(),
};
}
@@ -118,47 +117,19 @@ function createMockReviewLog(overrides: Partial<ReviewLog> = {}): ReviewLog {
};
}
-function createMockCardWithNoteData(
- overrides: Partial<CardWithNoteData> = {},
-): CardWithNoteData {
+function createMockCardForStudy(
+ overrides: Partial<CardForStudy> = {},
+): CardForStudy {
return {
...createMockCard(overrides),
- note: overrides.note ?? null,
- fieldValues: overrides.fieldValues ?? [],
- };
-}
-
-function createMockNote(overrides: Partial<Note> = {}): Note {
- return {
- id: "note-uuid-123",
- deckId: "deck-uuid-123",
- noteTypeId: "note-type-uuid-123",
- createdAt: new Date("2024-01-01"),
- updatedAt: new Date("2024-01-01"),
- deletedAt: null,
- syncVersion: 0,
- ...overrides,
- };
-}
-
-function createMockNoteFieldValue(
- overrides: Partial<NoteFieldValue> = {},
-): NoteFieldValue {
- return {
- id: "field-value-uuid-123",
- noteId: "note-uuid-123",
- noteFieldTypeId: "field-type-uuid-123",
- value: "Test value",
- createdAt: new Date("2024-01-01"),
- updatedAt: new Date("2024-01-01"),
- syncVersion: 0,
- ...overrides,
+ noteType: overrides.noteType ?? null,
+ fieldValuesMap: overrides.fieldValuesMap ?? {},
};
}
interface StudyResponse {
card?: Card;
- cards?: CardWithNoteData[];
+ cards?: CardForStudy[];
error?: {
code: string;
message: string;
@@ -195,7 +166,7 @@ describe("GET /api/decks/:deckId/study", () => {
vi.mocked(mockDeckRepo.findById).mockResolvedValue(
createMockDeck({ id: DECK_ID }),
);
- vi.mocked(mockCardRepo.findDueCardsWithNoteData).mockResolvedValue([]);
+ vi.mocked(mockCardRepo.findDueCardsForStudy).mockResolvedValue([]);
const res = await app.request(`/api/decks/${DECK_ID}/study`, {
method: "GET",
@@ -209,36 +180,34 @@ describe("GET /api/decks/:deckId/study", () => {
DECK_ID,
"user-uuid-123",
);
- expect(mockCardRepo.findDueCardsWithNoteData).toHaveBeenCalledWith(
+ expect(mockCardRepo.findDueCardsForStudy).toHaveBeenCalledWith(
DECK_ID,
expect.any(Date),
100,
);
});
- it("returns due cards with note data", async () => {
+ it("returns due cards (legacy cards without note)", async () => {
const mockCards = [
- createMockCardWithNoteData({
+ createMockCardForStudy({
id: "card-1",
front: "Q1",
back: "A1",
- note: null,
- fieldValues: [],
+ noteType: null,
+ fieldValuesMap: {},
}),
- createMockCardWithNoteData({
+ createMockCardForStudy({
id: "card-2",
front: "Q2",
back: "A2",
- note: null,
- fieldValues: [],
+ noteType: null,
+ fieldValuesMap: {},
}),
];
vi.mocked(mockDeckRepo.findById).mockResolvedValue(
createMockDeck({ id: DECK_ID }),
);
- vi.mocked(mockCardRepo.findDueCardsWithNoteData).mockResolvedValue(
- mockCards,
- );
+ vi.mocked(mockCardRepo.findDueCardsForStudy).mockResolvedValue(mockCards);
const res = await app.request(`/api/decks/${DECK_ID}/study`, {
method: "GET",
@@ -248,32 +217,29 @@ describe("GET /api/decks/:deckId/study", () => {
expect(res.status).toBe(200);
const body = (await res.json()) as StudyResponse;
expect(body.cards).toHaveLength(2);
+ expect(body.cards?.[0]?.noteType).toBeNull();
});
- it("returns due cards with note and field values when available", async () => {
- const mockNote = createMockNote({ id: "note-1" });
- const mockFieldValues = [
- createMockNoteFieldValue({ noteId: "note-1", value: "Front" }),
- createMockNoteFieldValue({
- id: "fv-2",
- noteId: "note-1",
- value: "Back",
- }),
- ];
+ it("returns due cards with note type and field values when available", async () => {
const mockCards = [
- createMockCardWithNoteData({
+ createMockCardForStudy({
id: "card-1",
noteId: "note-1",
- note: mockNote,
- fieldValues: mockFieldValues,
+ isReversed: false,
+ noteType: {
+ frontTemplate: "{{Front}}",
+ backTemplate: "{{Back}}",
+ },
+ fieldValuesMap: {
+ Front: "Question",
+ Back: "Answer",
+ },
}),
];
vi.mocked(mockDeckRepo.findById).mockResolvedValue(
createMockDeck({ id: DECK_ID }),
);
- vi.mocked(mockCardRepo.findDueCardsWithNoteData).mockResolvedValue(
- mockCards,
- );
+ vi.mocked(mockCardRepo.findDueCardsForStudy).mockResolvedValue(mockCards);
const res = await app.request(`/api/decks/${DECK_ID}/study`, {
method: "GET",
@@ -283,8 +249,8 @@ describe("GET /api/decks/:deckId/study", () => {
expect(res.status).toBe(200);
const body = (await res.json()) as StudyResponse;
expect(body.cards).toHaveLength(1);
- expect(body.cards?.[0]?.note?.id).toBe("note-1");
- expect(body.cards?.[0]?.fieldValues).toHaveLength(2);
+ expect(body.cards?.[0]?.noteType?.frontTemplate).toBe("{{Front}}");
+ expect(body.cards?.[0]?.fieldValuesMap?.Front).toBe("Question");
});
it("returns 404 for non-existent deck", async () => {