Files
webstudio/apps/builder/app/shared/sync/sync-client.test.ts
Oleg Isonen 878d6f1de1 feat: Add asset folders to asset manager and improve asset manager UX (#5892)
Closes https://github.com/webstudio-is/webstudio/issues/5877
Closes https://github.com/webstudio-is/webstudio/issues/4775


- Organize assets into nested folders.
- Navigate folders with breadcrumbs and Back controls.
- Select and manage multiple assets and folders at once.
- Drag, copy, cut, paste, duplicate, move, and delete items.
- Use context menus and familiar keyboard shortcuts for common actions.
- Search and sort assets and folders, with folders grouped first.
- Upload files directly into the active folder.
- Manage folder placement from asset and folder settings.
- Automate asset and folder management through MCP.
2026-07-17 23:39:14 +02:00

93 lines
3.0 KiB
TypeScript

import { describe, expect, test } from "vitest";
import { __testing__ } from "./sync-client";
import type { LoadedBuilderData } from "~/shared/builder-data";
import { serverSyncStoreNames } from "./sync-stores";
const { getServerSyncState, resolveMultiplayerRelayUrl } = __testing__;
describe("getServerSyncState", () => {
test("keeps only server-synchronized builder data", () => {
const data = {
id: "build-1",
version: 1,
projectId: "project-1",
project: { id: "project-1" },
publisherHost: "example.com",
pages: "pages",
breakpoints: "breakpoints",
instances: "instances",
styles: "styles",
styleSources: "styleSources",
styleSourceSelections: "styleSourceSelections",
props: "props",
dataSources: "dataSources",
resources: "resources",
assets: "assets",
assetFolders: "assetFolders",
marketplaceProduct: "marketplaceProduct",
projectSettings: "projectSettings",
} as unknown as LoadedBuilderData;
const serverSyncState = getServerSyncState(data);
expect([...serverSyncState.keys()]).toEqual([...serverSyncStoreNames]);
expect(serverSyncState).toEqual(
new Map<string, unknown>([
["pages", "pages"],
["breakpoints", "breakpoints"],
["instances", "instances"],
["styles", "styles"],
["styleSources", "styleSources"],
["styleSourceSelections", "styleSourceSelections"],
["props", "props"],
["dataSources", "dataSources"],
["resources", "resources"],
["assets", "assets"],
["assetFolders", "assetFolders"],
["projectSettings", "projectSettings"],
["marketplaceProduct", "marketplaceProduct"],
])
);
expect([...serverSyncState.keys()]).not.toContain("project");
expect([...serverSyncState.keys()]).not.toContain("publisherHost");
});
});
describe("resolveMultiplayerRelayUrl", () => {
test("keeps configured absolute URL outside local wstd.dev", () => {
expect(
resolveMultiplayerRelayUrl(
"https://apps.webstudio.is/collab-relay",
"https://builder.webstudio.is/builder/project-id"
)
).toBe("https://apps.webstudio.is/collab-relay");
});
test("keeps configured absolute URL on local wstd.dev", () => {
expect(
resolveMultiplayerRelayUrl(
"https://apps.webstudio.is/collab-relay",
"https://p-project-id.wstd.dev:5173/builder/project-id"
)
).toBe("https://apps.webstudio.is/collab-relay");
});
test("proxies relative relay URLs through the local wstd.dev dev server", () => {
expect(
resolveMultiplayerRelayUrl(
"/collab-relay",
"https://p-project-id.wstd.dev:5173/builder/project-id"
)
).toBe("https://p-project-id.wstd.dev:5173/collab-relay");
});
test("supports relative relay URLs", () => {
expect(
resolveMultiplayerRelayUrl(
"/collab-relay",
"https://builder.webstudio.is/builder/project-id"
)
).toBe("https://builder.webstudio.is/collab-relay");
});
});