UNPKG

@budibase/server

Version:
203 lines (177 loc) • 5.51 kB
import { BINDING_TOKEN_PREFIX, buildKeyValueRequestBody, buildRequestBodyFromFormDataParameters, buildSerializableRequestBody, generateRequestBodyFromExample, generateRequestBodyFromSchema, serialiseRequestBody, type FormDataParameter, } from "./requestBody" const createPlaceholder = ( key: string, type: "string" | "integer" = "string" ) => ({ toJSON: () => `${BINDING_TOKEN_PREFIX}${type}__${key}__`, }) describe("generateRequestBodyFromSchema", () => { it("creates sanitized bindings and respects the total limit", () => { const schema = { type: "object", properties: { "user-name": { type: "string", default: "Jane" }, "123value": { type: "integer" }, }, required: ["user-name"], } const result = generateRequestBodyFromSchema(schema, "body", { totalLimit: 1, }) expect(result).toBeDefined() expect(result?.bindings).toEqual({ user_name: "Jane" }) const serialised = serialiseRequestBody(result?.body) expect(serialised).toMatch(/"user-name":\s*"\{\{ user_name \}\}"/) expect(serialised).not.toMatch(/123value/) }) it("builds array and nested object values using schema defaults", () => { const schema = { type: "object", properties: { tags: { type: "array", items: { type: "string", enum: ["news", "tech"] }, }, details: { type: "object", required: ["count"], properties: { count: { type: "integer", default: 3 }, }, }, }, required: ["tags", "details"], } const result = generateRequestBodyFromSchema(schema) expect(result).toBeDefined() expect(result?.bindings).toMatchObject({ tags: "news", details_count: "3", }) const body = result?.body as Record<string, unknown> expect(Array.isArray(body.tags)).toBe(true) expect(body.tags).toHaveLength(1) expect(body.details).toBeDefined() }) }) describe("generateRequestBodyFromExample", () => { it("creates bindings from primitive examples and deduplicates arrays", () => { const example = { name: "Alice", active: true, nested: { count: 2, }, tags: [ { label: "primary", }, ], } const result = generateRequestBodyFromExample(example) expect(result).toBeDefined() expect(result?.bindings).toMatchObject({ name: "Alice", active: "true", nested_count: "2", tags_label: "primary", }) const body = result?.body as Record<string, unknown> expect(Array.isArray(body.tags)).toBe(true) expect(body.tags).toHaveLength(1) }) }) describe("serialiseRequestBody", () => { it("converts binding placeholders into moustache expressions", () => { const schema = { type: "object", properties: { message: { type: "string", example: "hello" }, attempts: { type: "integer", default: 1 }, }, required: ["message", "attempts"], } const generated = generateRequestBodyFromSchema(schema) const serialised = serialiseRequestBody(generated?.body) expect(serialised).toMatch(/"message":\s*"\{\{ message \}\}"/) expect(serialised).toMatch(/"attempts":\s*\{\{ attempts \}\}/) }) }) describe("buildSerializableRequestBody", () => { it("returns undefined when no body is provided", () => { expect(buildSerializableRequestBody(undefined)).toBeUndefined() }) it("preserves structure and converts bindings into moustache tokens", () => { const schema = { type: "object", properties: { name: { type: "string" }, nested: { type: "object", properties: { count: { type: "integer" }, }, required: ["count"], }, }, required: ["name", "nested"], } const generated = generateRequestBodyFromSchema(schema) const serializable = buildSerializableRequestBody(generated?.body) expect(serializable).toEqual({ name: "{{ name }}", nested: { count: "{{ nested_count }}", }, }) }) }) describe("buildKeyValueRequestBody", () => { it("flattens nested objects, arrays and bindings", () => { const body = { form: { field: createPlaceholder("field"), attachments: [createPlaceholder("file")], notes: "plain", }, } const result = buildKeyValueRequestBody(body) expect(result).toEqual({ "form[field]": "{{ field }}", "form[attachments][]": "{{ file }}", "form[notes]": "plain", }) }) it("returns undefined for non-objects", () => { expect(buildKeyValueRequestBody(undefined)).toBeUndefined() expect(buildKeyValueRequestBody("foo")).toBeUndefined() }) }) describe("buildRequestBodyFromFormDataParameters", () => { it("builds bindings for each form data parameter", () => { const params: FormDataParameter[] = [ { in: "formData", name: "username", type: "string", default: "buddy" }, { in: "formData", name: "age", type: "integer" }, { in: "formData", name: "notes" }, ] const result = buildRequestBodyFromFormDataParameters(params) expect(result).toBeDefined() expect(result?.bindings).toMatchObject({ username: "buddy", age: "0", notes: "", }) }) it("returns undefined for empty parameter lists", () => { expect(buildRequestBodyFromFormDataParameters([])).toBeUndefined() }) })