fix(custom-widgets): address v2 merge review
This commit is contained in:
1 parent
6aceb2fd1f
commit
48ce83806d
122 files changed
+8534
-1447
No files matched your search
@@ -9,7 +9,6 @@ import {
|
||||
useQueryClient,
|
||||
} from "@tanstack/react-query";
|
||||
|
||||
import { CUSTOM_WIDGET_SCHEMA } from "@homarr/custom-widgets/core";
|
||||
import type { HomarrCustomWidgetV2 } from "@homarr/custom-widgets/core";
|
||||
|
||||
import type {
|
||||
@@ -34,7 +33,6 @@ import {
|
||||
workshopScreenshotsSchema,
|
||||
workshopUserSchema,
|
||||
workshopVoteSchema,
|
||||
WORKSHOP_CSS_SCHEMA,
|
||||
} from "./schema";
|
||||
|
||||
export interface WorkshopListOptions {
|
||||
@@ -458,9 +456,7 @@ export class WorkshopBackend {
|
||||
workshopScreenshotsSchema.parse(screenshots);
|
||||
const data = new FormData();
|
||||
Object.entries(parsed).forEach(([key, value]) => data.set(key, typeof value === "string" ? value : String(value)));
|
||||
data.set("widgetSchema", parsed.type === "customCss" ? WORKSHOP_CSS_SCHEMA : CUSTOM_WIDGET_SCHEMA);
|
||||
data.set("author", this.currentUser?.id ?? "");
|
||||
data.set("revision", "1");
|
||||
screenshots.forEach((file) => data.append("screenshots", file));
|
||||
try {
|
||||
const result = await this.pocketBase.collection("submissions").create(data);
|
||||
@@ -483,8 +479,7 @@ export class WorkshopBackend {
|
||||
|
||||
const data: Record<string, unknown> = {
|
||||
...parsed,
|
||||
widgetSchema: parsed.type === "customCss" ? WORKSHOP_CSS_SCHEMA : CUSTOM_WIDGET_SCHEMA,
|
||||
revision: current.revision + 1,
|
||||
expectedRevision: current.revision,
|
||||
};
|
||||
if (additions.length > 0) data["screenshots+"] = additions;
|
||||
if (removals.length > 0) data["screenshots-"] = removals;
|
||||
|
||||
@@ -3,6 +3,7 @@ import { beforeEach, describe, expect, expectTypeOf, test, vi } from "vitest";
|
||||
const mocks = vi.hoisted(() => ({
|
||||
autoCancellation: vi.fn(),
|
||||
authWithOAuth2: vi.fn(),
|
||||
create: vi.fn(),
|
||||
getFullList: vi.fn(),
|
||||
getList: vi.fn(),
|
||||
update: vi.fn(),
|
||||
@@ -47,11 +48,18 @@ import type { RecordService } from "pocketbase";
|
||||
|
||||
import { WorkshopBackend } from "./backend";
|
||||
import type { WorkshopSubmissionRecord } from "./backend";
|
||||
import * as workshopClient from "./client";
|
||||
|
||||
describe("WorkshopBackend", () => {
|
||||
test("resolves the advertised client module", () => {
|
||||
expect(workshopClient.WorkshopBackend).toBe(WorkshopBackend);
|
||||
expect(workshopClient.validateWorkshopContent).toBeTypeOf("function");
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
mocks.autoCancellation.mockReset();
|
||||
mocks.authWithOAuth2.mockReset();
|
||||
mocks.create.mockReset();
|
||||
mocks.getFullList.mockReset();
|
||||
mocks.getList.mockReset();
|
||||
mocks.update.mockReset();
|
||||
@@ -82,6 +90,27 @@ describe("WorkshopBackend", () => {
|
||||
expect(mocks.autoCancellation).toHaveBeenCalledWith(false);
|
||||
});
|
||||
|
||||
test("leaves schema and initial revision ownership to PocketBase", async () => {
|
||||
const client = new WorkshopBackend("https://workshop.example.com");
|
||||
client.pocketBase.authStore.save("token", { id: "author-id" } as never);
|
||||
mocks.create.mockResolvedValue({ id: "submission-id" });
|
||||
vi.spyOn(client, "get").mockResolvedValue(listingRecord() as never);
|
||||
|
||||
await client.create({
|
||||
type: "customCss",
|
||||
title: "Dashboard theme",
|
||||
description: "A theme",
|
||||
content: ".dashboard { color: red; }",
|
||||
changelog: "",
|
||||
outdated: false,
|
||||
});
|
||||
|
||||
const payload = mocks.create.mock.calls[0]?.[0] as FormData;
|
||||
expect(payload.get("author")).toBe("author-id");
|
||||
expect(payload.get("widgetSchema")).toBeNull();
|
||||
expect(payload.get("revision")).toBeNull();
|
||||
});
|
||||
|
||||
test("appends and removes screenshots without replacing retained files", async () => {
|
||||
const client = new WorkshopBackend("https://workshop.example.com");
|
||||
const current = {
|
||||
@@ -113,9 +142,12 @@ describe("WorkshopBackend", () => {
|
||||
expect.objectContaining({
|
||||
"screenshots+": [addition],
|
||||
"screenshots-": ["remove.png"],
|
||||
revision: 3,
|
||||
expectedRevision: 2,
|
||||
}),
|
||||
);
|
||||
const payload = mocks.update.mock.calls[0]?.[1];
|
||||
expect(payload).not.toHaveProperty("revision");
|
||||
expect(payload).not.toHaveProperty("widgetSchema");
|
||||
});
|
||||
|
||||
test("uses PocketBase filtering and pagination when the listing view is current", async () => {
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./backend";
|
||||
export * from "./schema";
|
||||
Reference in new issue
Block a user