aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/server/routes
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/routes')
-rw-r--r--src/server/routes/cards.test.ts1
-rw-r--r--src/server/routes/decks.test.ts59
-rw-r--r--src/server/routes/decks.ts20
-rw-r--r--src/server/routes/study.test.ts1
4 files changed, 72 insertions, 9 deletions
diff --git a/src/server/routes/cards.test.ts b/src/server/routes/cards.test.ts
index 66ba601..e5fb0d4 100644
--- a/src/server/routes/cards.test.ts
+++ b/src/server/routes/cards.test.ts
@@ -25,6 +25,7 @@ function createMockCardRepo(): CardRepository {
softDelete: vi.fn(),
softDeleteByNoteId: vi.fn(),
findDueCards: vi.fn(),
+ countDueCards: vi.fn(),
findDueCardsWithNoteData: vi.fn(),
findDueCardsForStudy: vi.fn(),
updateFSRSFields: vi.fn(),
diff --git a/src/server/routes/decks.test.ts b/src/server/routes/decks.test.ts
index 8f5be9d..55aca2d 100644
--- a/src/server/routes/decks.test.ts
+++ b/src/server/routes/decks.test.ts
@@ -2,7 +2,11 @@ import { Hono } from "hono";
import { sign } from "hono/jwt";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { errorHandler } from "../middleware/index.js";
-import type { Deck, DeckRepository } from "../repositories/index.js";
+import type {
+ CardRepository,
+ Deck,
+ DeckRepository,
+} from "../repositories/index.js";
import { createDecksRouter } from "./decks.js";
function createMockDeckRepo(): DeckRepository {
@@ -15,6 +19,24 @@ function createMockDeckRepo(): DeckRepository {
};
}
+function createMockCardRepo(): CardRepository {
+ return {
+ findByDeckId: vi.fn(),
+ findById: vi.fn(),
+ findByIdWithNoteData: vi.fn(),
+ findByNoteId: vi.fn(),
+ create: vi.fn(),
+ update: vi.fn(),
+ softDelete: vi.fn(),
+ softDeleteByNoteId: vi.fn(),
+ findDueCards: vi.fn(),
+ countDueCards: vi.fn().mockResolvedValue(0),
+ findDueCardsWithNoteData: vi.fn(),
+ findDueCardsForStudy: vi.fn(),
+ updateFSRSFields: vi.fn(),
+ };
+}
+
const JWT_SECRET = process.env.JWT_SECRET || "test-secret";
async function createTestToken(userId: string): Promise<string> {
@@ -57,12 +79,17 @@ interface DeckResponse {
describe("GET /api/decks", () => {
let app: Hono;
let mockDeckRepo: ReturnType<typeof createMockDeckRepo>;
+ let mockCardRepo: ReturnType<typeof createMockCardRepo>;
let authToken: string;
beforeEach(async () => {
vi.clearAllMocks();
mockDeckRepo = createMockDeckRepo();
- const decksRouter = createDecksRouter({ deckRepo: mockDeckRepo });
+ mockCardRepo = createMockCardRepo();
+ const decksRouter = createDecksRouter({
+ deckRepo: mockDeckRepo,
+ cardRepo: mockCardRepo,
+ });
app = new Hono();
app.onError(errorHandler);
app.route("/api/decks", decksRouter);
@@ -112,12 +139,17 @@ describe("GET /api/decks", () => {
describe("POST /api/decks", () => {
let app: Hono;
let mockDeckRepo: ReturnType<typeof createMockDeckRepo>;
+ let mockCardRepo: ReturnType<typeof createMockCardRepo>;
let authToken: string;
beforeEach(async () => {
vi.clearAllMocks();
mockDeckRepo = createMockDeckRepo();
- const decksRouter = createDecksRouter({ deckRepo: mockDeckRepo });
+ mockCardRepo = createMockCardRepo();
+ const decksRouter = createDecksRouter({
+ deckRepo: mockDeckRepo,
+ cardRepo: mockCardRepo,
+ });
app = new Hono();
app.onError(errorHandler);
app.route("/api/decks", decksRouter);
@@ -220,12 +252,17 @@ describe("POST /api/decks", () => {
describe("GET /api/decks/:id", () => {
let app: Hono;
let mockDeckRepo: ReturnType<typeof createMockDeckRepo>;
+ let mockCardRepo: ReturnType<typeof createMockCardRepo>;
let authToken: string;
beforeEach(async () => {
vi.clearAllMocks();
mockDeckRepo = createMockDeckRepo();
- const decksRouter = createDecksRouter({ deckRepo: mockDeckRepo });
+ mockCardRepo = createMockCardRepo();
+ const decksRouter = createDecksRouter({
+ deckRepo: mockDeckRepo,
+ cardRepo: mockCardRepo,
+ });
app = new Hono();
app.onError(errorHandler);
app.route("/api/decks", decksRouter);
@@ -285,12 +322,17 @@ describe("GET /api/decks/:id", () => {
describe("PUT /api/decks/:id", () => {
let app: Hono;
let mockDeckRepo: ReturnType<typeof createMockDeckRepo>;
+ let mockCardRepo: ReturnType<typeof createMockCardRepo>;
let authToken: string;
beforeEach(async () => {
vi.clearAllMocks();
mockDeckRepo = createMockDeckRepo();
- const decksRouter = createDecksRouter({ deckRepo: mockDeckRepo });
+ mockCardRepo = createMockCardRepo();
+ const decksRouter = createDecksRouter({
+ deckRepo: mockDeckRepo,
+ cardRepo: mockCardRepo,
+ });
app = new Hono();
app.onError(errorHandler);
app.route("/api/decks", decksRouter);
@@ -410,12 +452,17 @@ describe("PUT /api/decks/:id", () => {
describe("DELETE /api/decks/:id", () => {
let app: Hono;
let mockDeckRepo: ReturnType<typeof createMockDeckRepo>;
+ let mockCardRepo: ReturnType<typeof createMockCardRepo>;
let authToken: string;
beforeEach(async () => {
vi.clearAllMocks();
mockDeckRepo = createMockDeckRepo();
- const decksRouter = createDecksRouter({ deckRepo: mockDeckRepo });
+ mockCardRepo = createMockCardRepo();
+ const decksRouter = createDecksRouter({
+ deckRepo: mockDeckRepo,
+ cardRepo: mockCardRepo,
+ });
app = new Hono();
app.onError(errorHandler);
app.route("/api/decks", decksRouter);
diff --git a/src/server/routes/decks.ts b/src/server/routes/decks.ts
index 2450bcd..2e170db 100644
--- a/src/server/routes/decks.ts
+++ b/src/server/routes/decks.ts
@@ -2,11 +2,17 @@ import { zValidator } from "@hono/zod-validator";
import { Hono } from "hono";
import { z } from "zod";
import { authMiddleware, Errors, getAuthUser } from "../middleware/index.js";
-import { type DeckRepository, deckRepository } from "../repositories/index.js";
+import {
+ type CardRepository,
+ cardRepository,
+ type DeckRepository,
+ deckRepository,
+} from "../repositories/index.js";
import { createDeckSchema, updateDeckSchema } from "../schemas/index.js";
export interface DeckDependencies {
deckRepo: DeckRepository;
+ cardRepo: CardRepository;
}
const deckIdParamSchema = z.object({
@@ -14,14 +20,21 @@ const deckIdParamSchema = z.object({
});
export function createDecksRouter(deps: DeckDependencies) {
- const { deckRepo } = deps;
+ const { deckRepo, cardRepo } = deps;
return new Hono()
.use("*", authMiddleware)
.get("/", async (c) => {
const user = getAuthUser(c);
const decks = await deckRepo.findByUserId(user.id);
- return c.json({ decks }, 200);
+ const now = new Date();
+ const decksWithDueCount = await Promise.all(
+ decks.map(async (deck) => {
+ const dueCardCount = await cardRepo.countDueCards(deck.id, now);
+ return { ...deck, dueCardCount };
+ }),
+ );
+ return c.json({ decks: decksWithDueCount }, 200);
})
.post("/", zValidator("json", createDeckSchema), async (c) => {
const user = getAuthUser(c);
@@ -79,4 +92,5 @@ export function createDecksRouter(deps: DeckDependencies) {
export const decks = createDecksRouter({
deckRepo: deckRepository,
+ cardRepo: cardRepository,
});
diff --git a/src/server/routes/study.test.ts b/src/server/routes/study.test.ts
index e2fb457..a5ac817 100644
--- a/src/server/routes/study.test.ts
+++ b/src/server/routes/study.test.ts
@@ -25,6 +25,7 @@ function createMockCardRepo(): CardRepository {
softDelete: vi.fn(),
softDeleteByNoteId: vi.fn(),
findDueCards: vi.fn(),
+ countDueCards: vi.fn(),
findDueCardsWithNoteData: vi.fn(),
findDueCardsForStudy: vi.fn(),
updateFSRSFields: vi.fn(),