fix(custom-widgets): harden v2 authoring
This commit is contained in:
171 files changed
+20311
-50527
No files matched your search
@@ -2,11 +2,59 @@ import { describe, expect, test } from "vitest";
|
||||
|
||||
import { CUSTOM_WIDGET_STARTER } from "@homarr/custom-widgets/core";
|
||||
|
||||
import { validateWorkshopWidget } from "./schema";
|
||||
import { validateWorkshopWidget, workshopSubmissionInputSchema } from "./schema";
|
||||
|
||||
describe("Workshop widget validation", () => {
|
||||
test("accepts a canonical credential-free widget", () => {
|
||||
expect(validateWorkshopWidget(JSON.stringify(CUSTOM_WIDGET_STARTER)).success).toBe(true);
|
||||
expect(
|
||||
workshopSubmissionInputSchema.safeParse({
|
||||
title: "Starter widget",
|
||||
description: "",
|
||||
content: JSON.stringify(CUSTOM_WIDGET_STARTER),
|
||||
}).success,
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test("uses canonical option-binding validation before publication", () => {
|
||||
const request = {
|
||||
id: "data",
|
||||
sourceId: "default",
|
||||
kind: "query" as const,
|
||||
method: "GET" as const,
|
||||
pathTemplate: "/data/{endpointId}",
|
||||
parameters: { endpointId: "string" as const, limit: "number" as const },
|
||||
optionsBinding: { endpointId: { $option: "endpointId" }, limit: 5 },
|
||||
queryTemplate: { limit: { $param: "limit" } },
|
||||
auth: "inherit" as const,
|
||||
minimumBoardPermission: "view" as const,
|
||||
trigger: "load" as const,
|
||||
};
|
||||
const widget = {
|
||||
...CUSTOM_WIDGET_STARTER,
|
||||
requests: [request],
|
||||
optionsSchema: {
|
||||
type: "object" as const,
|
||||
properties: { endpointId: { type: "string" as const } },
|
||||
required: ["endpointId"],
|
||||
additionalProperties: false as const,
|
||||
},
|
||||
defaultOptions: { endpointId: "local" },
|
||||
};
|
||||
|
||||
expect(validateWorkshopWidget(JSON.stringify(widget)).success).toBe(true);
|
||||
expect(
|
||||
validateWorkshopWidget(JSON.stringify({ ...widget, requests: [{ ...request, optionsBinding: { limit: 5 } }] }))
|
||||
.success,
|
||||
).toBe(false);
|
||||
expect(
|
||||
validateWorkshopWidget(
|
||||
JSON.stringify({
|
||||
...widget,
|
||||
requests: [{ ...request, optionsBinding: { endpointId: { $option: "missing" }, limit: 5 } }],
|
||||
}),
|
||||
).success,
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test("rejects literal credentials in templates and icon URLs", () => {
|
||||
|
||||
Reference in new issue
Block a user