UNPKG

@sensinum/astro-strapi-loader

Version:
314 lines (313 loc) 15.5 kB
import { generateCollection } from "../strapi"; import { strapiLoader } from "../loader"; import { z } from "zod"; jest.mock("../loader"); jest.mock("astro:content", () => ({ defineCollection: jest.fn((config) => config), })); describe("Strapi Extended Features", () => { const mockOptions = { url: "http://test-strapi.com", token: "test-token", }; const mockStrapiLoader = strapiLoader; beforeEach(() => { jest.clearAllMocks(); mockStrapiLoader.mockImplementation((contentType, options, _query) => ({ name: options.collectionName || "strapi-loader", load: jest.fn(), })); }); describe("generateCollection with Extended Options", () => { const testSchema = z.object({ documentId: z.string(), title: z.string(), }); it("should create collection with custom name", () => { const collection = generateCollection("pages", testSchema, mockOptions, { collectionName: "pagesEN" }); expect(collection).toBeDefined(); expect(mockStrapiLoader).toHaveBeenCalledWith("pages", expect.objectContaining({ collectionName: "pagesEN" }), {}); }); it("should create collection with custom ID generator", () => { const idGenerator = (data) => data.slug; const collection = generateCollection("pages", testSchema, mockOptions, { idGenerator }); expect(collection).toBeDefined(); expect(mockStrapiLoader).toHaveBeenCalledWith("pages", expect.objectContaining({ idGenerator }), {}); }); it("should create collection with single locale", () => { const collection = generateCollection("pages", testSchema, mockOptions, { locale: "en" }); expect(collection).toBeDefined(); expect(mockStrapiLoader).toHaveBeenCalledWith("pages", expect.objectContaining({ locale: "en" }), {}); }); it("should create collection with multiple locales", () => { const collection = generateCollection("pages", testSchema, mockOptions, { locale: ["en", "de"] }); expect(collection).toBeDefined(); expect(mockStrapiLoader).toHaveBeenCalledWith("pages", expect.objectContaining({ locale: ["en", "de"] }), {}); }); it("should create collection with all options", () => { const idGenerator = (data) => data.slug; const collection = generateCollection("pages", testSchema, mockOptions, { collectionName: "pagesMultilang", idGenerator, locale: ["en", "de"], query: { filters: { published: true } }, }); expect(collection).toBeDefined(); expect(mockStrapiLoader).toHaveBeenCalledWith("pages", expect.objectContaining({ collectionName: "pagesMultilang", idGenerator, locale: ["en", "de"], }), { filters: { published: true } }); }); it("should create collection without additional options (backward compatible)", () => { const collection = generateCollection("pages", testSchema, mockOptions); expect(collection).toBeDefined(); expect(mockStrapiLoader).toHaveBeenCalledWith("pages", expect.objectContaining({ url: mockOptions.url }), {}); }); }); describe("StrapiCollection Interface", () => { it("should accept old format (backward compatibility)", () => { // Old format still works const collection = { name: "homepage", query: { populate: { seo: true }, filters: { published: true } }, }; expect(collection.name).toBe("homepage"); expect(collection.query).toEqual({ populate: { seo: true }, filters: { published: true } }); expect(collection.collectionName).toBeUndefined(); expect(collection.idGenerator).toBeUndefined(); expect(collection.locale).toBeUndefined(); }); it("should accept configuration with all new fields", () => { const idGenerator = (data) => data.slug; const collection = { name: "pages", query: { filters: { published: true } }, collectionName: "pagesEN", idGenerator, locale: ["en", "de"], }; expect(collection.name).toBe("pages"); expect(collection.collectionName).toBe("pagesEN"); expect(collection.locale).toEqual(["en", "de"]); expect(collection.idGenerator).toBe(idGenerator); }); it("should accept configuration with single locale as string", () => { const collection = { name: "pages", locale: "en", }; expect(collection.locale).toBe("en"); }); it("should accept minimal configuration (backward compatible)", () => { const collection = { name: "pages", }; expect(collection.name).toBe("pages"); expect(collection.query).toBeUndefined(); expect(collection.collectionName).toBeUndefined(); expect(collection.idGenerator).toBeUndefined(); expect(collection.locale).toBeUndefined(); }); }); describe("Multiple Collections from Same Endpoint", () => { it("should allow creating multiple collections from same endpoint", () => { const testSchema = z.object({ documentId: z.string(), title: z.string(), }); const collectionEN = generateCollection("pages", testSchema, mockOptions, { collectionName: "pagesEN", locale: "en", }); const collectionDE = generateCollection("pages", testSchema, mockOptions, { collectionName: "pagesDE", locale: "de", }); expect(collectionEN).toBeDefined(); expect(collectionDE).toBeDefined(); expect(mockStrapiLoader).toHaveBeenCalledWith("pages", expect.objectContaining({ collectionName: "pagesEN", locale: "en" }), {}); expect(mockStrapiLoader).toHaveBeenCalledWith("pages", expect.objectContaining({ collectionName: "pagesDE", locale: "de" }), {}); }); it("should allow different ID generators for different collections", () => { const testSchema = z.object({ documentId: z.string(), slug: z.string(), title: z.string(), }); const idGeneratorSlug = (data) => data.slug; const idGeneratorId = (data) => data.documentId; const collection1 = generateCollection("pages", testSchema, mockOptions, { collectionName: "pagesBySlug", idGenerator: idGeneratorSlug, }); const collection2 = generateCollection("pages", testSchema, mockOptions, { collectionName: "pagesById", idGenerator: idGeneratorId, }); expect(collection1).toBeDefined(); expect(collection2).toBeDefined(); expect(mockStrapiLoader).toHaveBeenCalledWith("pages", expect.objectContaining({ collectionName: "pagesBySlug", idGenerator: idGeneratorSlug }), {}); expect(mockStrapiLoader).toHaveBeenCalledWith("pages", expect.objectContaining({ collectionName: "pagesById", idGenerator: idGeneratorId }), {}); }); }); describe("Locale Query Parameter Handling", () => { it("should pass locale to loader", () => { const testSchema = z.object({ documentId: z.string(), title: z.string(), }); const collection = generateCollection("pages", testSchema, mockOptions, { locale: "en", query: { filters: { published: true } }, }); expect(collection).toBeDefined(); expect(mockStrapiLoader).toHaveBeenCalledWith("pages", expect.objectContaining({ locale: "en" }), { filters: { published: true } }); }); it("should pass array of locales to loader", () => { const testSchema = z.object({ documentId: z.string(), title: z.string(), }); const collection = generateCollection("pages", testSchema, mockOptions, { locale: ["en", "de", "fr"], }); expect(collection).toBeDefined(); expect(mockStrapiLoader).toHaveBeenCalledWith("pages", expect.objectContaining({ locale: ["en", "de", "fr"] }), {}); }); }); describe("Backward Compatibility with generateCollections", () => { it("should work with classic array of objects format", () => { const testSchema = z.object({ documentId: z.string(), title: z.string(), }); // Simulate old usage pattern const homepageQuery = { populate: { seo: true } }; const layoutQuery = { populate: { header: true, footer: true } }; const homepage = generateCollection("homepage", testSchema, mockOptions, { name: "homepage", query: homepageQuery }); const layout = generateCollection("layout", testSchema, mockOptions, { name: "layout", query: layoutQuery }); expect(homepage).toBeDefined(); expect(layout).toBeDefined(); // Verify queries are passed correctly expect(mockStrapiLoader).toHaveBeenCalledWith("homepage", expect.objectContaining({ url: mockOptions.url }), homepageQuery); expect(mockStrapiLoader).toHaveBeenCalledWith("layout", expect.objectContaining({ url: mockOptions.url }), layoutQuery); }); it("should allow mixing old and new format in single call", () => { const testSchema = z.object({ documentId: z.string(), title: z.string(), slug: z.string().optional(), }); const idGenerator = (data) => data.slug; // Mix old and new formats const collections = [ // Old format - just name and query generateCollection("homepage", testSchema, mockOptions, { name: "homepage", query: { populate: { seo: true } } }), // New format with locale generateCollection("pages", testSchema, mockOptions, { name: "pages", collectionName: "pagesEN", locale: "en", query: { sort: ['publishedAt:desc'] } }), // New format with custom ID generateCollection("blog-posts", testSchema, mockOptions, { name: "blog-posts", idGenerator, query: { filters: { published: true } } }), // New format with all features generateCollection("articles", testSchema, mockOptions, { name: "articles", collectionName: "articlesDE", locale: ["de", "fr"], idGenerator, }), ]; // All should be defined expect(collections[0]).toBeDefined(); // homepage - old format expect(collections[1]).toBeDefined(); // pagesEN - new with locale expect(collections[2]).toBeDefined(); // blog-posts - new with idGenerator expect(collections[3]).toBeDefined(); // articlesDE - new with all // Verify each was called correctly expect(mockStrapiLoader).toHaveBeenCalledWith("homepage", expect.objectContaining({ url: mockOptions.url }), { populate: { seo: true } }); expect(mockStrapiLoader).toHaveBeenCalledWith("pages", expect.objectContaining({ collectionName: "pagesEN", locale: "en" }), { sort: ['publishedAt:desc'] }); expect(mockStrapiLoader).toHaveBeenCalledWith("blog-posts", expect.objectContaining({ idGenerator }), { filters: { published: true } }); expect(mockStrapiLoader).toHaveBeenCalledWith("articles", expect.objectContaining({ collectionName: "articlesDE", locale: ["de", "fr"], idGenerator }), {}); }); }); describe("Integration Example Scenarios", () => { it("scenario: multilingual blog with custom slugs", () => { const testSchema = z.object({ documentId: z.string(), slug: z.string(), title: z.string(), }); const idGenerator = (data) => data.slug; const blogEN = generateCollection("blog-posts", testSchema, mockOptions, { collectionName: "blogEN", locale: "en", idGenerator, query: { sort: ["publishedAt:desc"] }, }); const blogDE = generateCollection("blog-posts", testSchema, mockOptions, { collectionName: "blogDE", locale: "de", idGenerator, query: { sort: ["publishedAt:desc"] }, }); expect(blogEN).toBeDefined(); expect(blogDE).toBeDefined(); expect(mockStrapiLoader).toHaveBeenCalledWith("blog-posts", expect.objectContaining({ collectionName: "blogEN", locale: "en" }), { sort: ["publishedAt:desc"] }); expect(mockStrapiLoader).toHaveBeenCalledWith("blog-posts", expect.objectContaining({ collectionName: "blogDE", locale: "de" }), { sort: ["publishedAt:desc"] }); }); it("scenario: single collection for multiple languages", () => { const testSchema = z.object({ documentId: z.string(), slug: z.string(), title: z.string(), }); const idGenerator = (data) => data.slug; const pagesMultilang = generateCollection("pages", testSchema, mockOptions, { collectionName: "pagesAll", locale: ["en", "de", "fr"], idGenerator, }); expect(pagesMultilang).toBeDefined(); expect(mockStrapiLoader).toHaveBeenCalledWith("pages", expect.objectContaining({ collectionName: "pagesAll", locale: ["en", "de", "fr"], idGenerator }), {}); }); it("scenario: categories with custom ID based on path", () => { const testSchema = z.object({ documentId: z.string(), category: z.string(), slug: z.string(), title: z.string(), }); const idGenerator = (data) => `${data.category}/${data.slug}`; const posts = generateCollection("posts", testSchema, mockOptions, { idGenerator, query: { populate: "*" }, }); expect(posts).toBeDefined(); expect(mockStrapiLoader).toHaveBeenCalledWith("posts", expect.objectContaining({ idGenerator }), { populate: "*" }); }); }); });