-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Drawer for Generation #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5eed28a
20130fe
2cc9106
cc5ce24
b1f172a
d8f2755
d4dbbcd
f65f026
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,70 +1,78 @@ | ||
| import { parseBookMetadata } from "@/lib/book-utils" | ||
| import { BookMetadata } from "@/lib/types" | ||
| import { POST } from "@/app/api/books/generate/route" | ||
| import { NextResponse } from "next/server" | ||
|
|
||
| describe("parseBookMetadata", () => { | ||
| it("should parse Google Books data correctly", () => { | ||
| const googleBook: BookMetadata = { | ||
| title: "Google Book Title", | ||
| authors: ["Author One", "Author Two"], | ||
| coverUrl: "http://example.com/cover.jpg", | ||
| isbn: "1234567890", | ||
| googleId: "g1", | ||
| } | ||
| // Mock NextResponse | ||
| jest.mock("next/server", () => ({ | ||
| NextResponse: { | ||
| json: jest.fn().mockImplementation((body, options) => ({ | ||
| status: options?.status || 200, | ||
| json: async () => body, | ||
| ...body, | ||
| })), | ||
| }, | ||
| })) | ||
|
|
||
| const result = parseBookMetadata(googleBook) | ||
|
|
||
| expect(result).toEqual({ | ||
| title: "Google Book Title", | ||
| author: "Author One, Author Two", | ||
| cover_url: "http://example.com/cover.jpg", | ||
| isbn: "1234567890", | ||
| // Mock next/headers | ||
| jest.mock("next/headers", () => ({ | ||
| cookies: jest.fn().mockReturnValue( | ||
| Promise.resolve({ | ||
| getAll: jest.fn().mockReturnValue([]), | ||
| get: jest.fn().mockReturnValue(undefined), | ||
| }) | ||
| }) | ||
| ), | ||
| })) | ||
|
|
||
| it("should parse OpenLibrary data correctly", () => { | ||
| const olBook: BookMetadata = { | ||
| title: "OL Book Title", | ||
| author_name: ["OL Author"], | ||
| cover_edition_key: "OL123M", | ||
| isbn: ["0987654321"], | ||
| key: "/works/OL123W", | ||
| // Force type to satisfy simplified mock if needed, but the structure matches | ||
| edition_key: ["OL123M"], | ||
| publish_year: [2021], | ||
| } as any // Cast as any because OpenLibraryDoc has many required fields | ||
| jest.mock("@supabase/auth-helpers-nextjs", () => ({ | ||
| createRouteHandlerClient: jest.fn().mockReturnValue({ | ||
| auth: { | ||
| getSession: jest.fn().mockResolvedValue({ data: { session: null } }), | ||
| }, | ||
| }), | ||
| })) | ||
|
|
||
| const result = parseBookMetadata(olBook) | ||
|
|
||
| expect(result).toEqual({ | ||
| title: "OL Book Title", | ||
| author: "OL Author", | ||
| cover_url: "https://covers.openlibrary.org/b/olid/OL123M-M.jpg", // Expecting getBookCover logic | ||
| isbn: "0987654321", | ||
| }) | ||
| }) | ||
| jest.mock("@supabase/supabase-js", () => ({ | ||
| createClient: jest.fn().mockReturnValue({ | ||
| from: jest.fn().mockReturnValue({ | ||
| insert: jest.fn().mockReturnValue({ | ||
| select: jest.fn().mockReturnValue({ | ||
| single: jest.fn().mockResolvedValue({ data: { id: "test-id" }, error: null }), | ||
| }), | ||
| }), | ||
| }), | ||
| }), | ||
| })) | ||
|
|
||
| it("should handle missing optional fields gracefully", () => { | ||
| const minimalBook: BookMetadata = { | ||
| title: "Minimal Book", | ||
| } as any | ||
| jest.mock("@/lib/id_generator", () => ({ | ||
| generateBookId: jest.fn().mockResolvedValue("TEST-CODE"), | ||
| })) | ||
|
|
||
| const result = parseBookMetadata(minimalBook) | ||
| jest.mock("@/lib/book-utils", () => ({ | ||
| parseBookMetadata: jest.fn().mockReturnValue({ | ||
| title: "Test Title", | ||
| author: "Test Author", | ||
| cover_url: "http://test.com/cover.jpg", | ||
| isbn: "1234567890", | ||
| }), | ||
| })) | ||
|
|
||
| expect(result).toEqual({ | ||
| title: "Minimal Book", | ||
| author: "Unknown Author", | ||
| cover_url: null, | ||
| isbn: null, | ||
| describe("POST /api/books/generate", () => { | ||
| it("should generate a book code successfully", async () => { | ||
| const request = new Request("http://localhost:3000/api/books/generate", { | ||
| method: "POST", | ||
| headers: { | ||
| "Content-Type": "application/json", | ||
| }, | ||
| }) | ||
| }) | ||
|
|
||
| it("should return defaults for null input", () => { | ||
| const result = parseBookMetadata(null as any) | ||
| expect(result).toEqual({ | ||
| title: "Unknown Title", | ||
| author: "Unknown Author", | ||
| cover_url: null, | ||
| isbn: null, | ||
| jest.spyOn(request, "json").mockResolvedValue({ | ||
| location: { lat: 40.7128, long: -74.006 }, | ||
| book: { title: "Test Book" }, | ||
| anonymousId: "anon-123", | ||
| }) | ||
|
|
||
| const response = await POST(request) | ||
| const data = await response.json() | ||
|
|
||
| expect(data.code).toBe("TEST-CODE") | ||
| }) | ||
| }) | ||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -21,8 +21,8 @@ export async function POST(request: Request) { | |||||||
|
|
||||||||
| // 1. Check user session (optional but good context) | ||||||||
| // Use defaults (implicitly uses NEXT_PUBLIC_SUPABASE_ANON_KEY) | ||||||||
| const cookieStore = cookies() | ||||||||
| const supabase = createRouteHandlerClient({ cookies: () => cookieStore }) | ||||||||
| const cookieStore = await cookies() | ||||||||
| const supabase = createRouteHandlerClient({ cookies: () => cookieStore } as any) | ||||||||
|
Comment on lines
+24
to
+25
|
||||||||
| const cookieStore = await cookies() | |
| const supabase = createRouteHandlerClient({ cookies: () => cookieStore } as any) | |
| const supabase = createRouteHandlerClient({ cookies }) |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -38,14 +38,11 @@ export async function POST(request: Request) { | |||||||||||||||||||||||||||
| const { bookId, location } = await request.json() | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // Auth Check: Use Anon Key with Session | ||||||||||||||||||||||||||||
| const cookieStore = cookies() | ||||||||||||||||||||||||||||
| const supabase = createRouteHandlerClient( | ||||||||||||||||||||||||||||
| { cookies: () => cookieStore }, | ||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||
| supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL, | ||||||||||||||||||||||||||||
| supabaseKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
| const cookieStore = await cookies() | ||||||||||||||||||||||||||||
| const supabase = createRouteHandlerClient({ cookies: () => cookieStore } as any, { | ||||||||||||||||||||||||||||
| supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL, | ||||||||||||||||||||||||||||
| supabaseKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, | ||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||
|
Comment on lines
+41
to
+45
|
||||||||||||||||||||||||||||
| const cookieStore = await cookies() | |
| const supabase = createRouteHandlerClient({ cookies: () => cookieStore } as any, { | |
| supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL, | |
| supabaseKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, | |
| }) | |
| const cookieStore = cookies() | |
| const supabase = createRouteHandlerClient( | |
| { cookies: () => cookieStore }, | |
| { | |
| supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL, | |
| supabaseKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, | |
| } | |
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused import NextResponse.