feat(POSTV1-ASSET-ALL-16): 在编辑器接入全部复杂素材
Dada P0-A isolated Windows CI / validate-and-package (push) Waiting to run
Dada P0-A isolated Windows CI / validate-and-package (push) Waiting to run
This commit is contained in:
@@ -76,24 +76,28 @@ async function routeEditor(page: Page, projectId: string, backend: Backend) {
|
||||
backend.recent = [item, ...backend.recent.filter((entry) => entry.asset_id !== item.asset_id)];
|
||||
await route.fulfill({ body: JSON.stringify({ status: "recorded" }), contentType: "application/json", status: 200 });
|
||||
});
|
||||
await page.route("**/api/v1/assets/public/p0a-complex-v1/*", (route) => route.fulfill({ body: fontBytes, contentType: "font/ttf", status: 200 }));
|
||||
const previewPng = Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=", "base64");
|
||||
await page.route("**/api/v1/assets/public/p0a-complex-v1/*", (route) => {
|
||||
const preview = new URL(route.request().url()).pathname.includes("TEXT-PREVIEW-");
|
||||
return route.fulfill(preview ? { body: previewPng, contentType: "image/png", status: 200 } : { body: fontBytes, contentType: "font/ttf", status: 200 });
|
||||
});
|
||||
}
|
||||
|
||||
test("TDD-WP4-TXT-003 exposes the frozen catalog, display-name search and account recent use", async ({ page }) => {
|
||||
test("TDD-WP4-TXT-003 exposes the complete catalog, display-name search and account recent use", async ({ page }) => {
|
||||
const projectId = uuid(730);
|
||||
const backend: Backend = { canvas: emptyCanvas(), recent: [], saves: 0, version: 2 };
|
||||
await routeEditor(page, projectId, backend);
|
||||
await page.goto(`${webUrl}/app/projects/${projectId}/editor`);
|
||||
await page.getByRole("button", { name: "文字模板", exact: true }).click();
|
||||
await expect(page.locator(".editor-template-grid button")).toHaveCount(32);
|
||||
for (const [label, count] of [["花字", 8], ["标题", 8], ["标签", 8], ["简约", 8]] as const) {
|
||||
await expect(page.locator(".editor-template-grid button")).toHaveCount(332);
|
||||
for (const [label, count] of [["花字", 145], ["标题", 119], ["标签", 51], ["简约", 17]] as const) {
|
||||
await page.getByRole("button", { name: label, exact: true }).click();
|
||||
await expect(page.locator(".editor-template-grid button")).toHaveCount(count);
|
||||
}
|
||||
await page.getByRole("button", { name: "全部", exact: true }).click();
|
||||
const search = page.getByPlaceholder("搜索文字模板显示名称");
|
||||
await search.fill("生活");
|
||||
await expect(page.locator(".editor-template-grid button")).toHaveCount(5);
|
||||
await expect(page.locator(".editor-template-grid button")).toHaveCount(9);
|
||||
await search.fill("FLOWER001");
|
||||
await expect(page.locator(".editor-template-grid button")).toHaveCount(0);
|
||||
await search.fill("");
|
||||
@@ -101,7 +105,7 @@ test("TDD-WP4-TXT-003 exposes the frozen catalog, display-name search and accoun
|
||||
const flowerTemplate = page.getByRole("button", { name: /FLOWER001 春日计划/ });
|
||||
await flowerTemplate.hover();
|
||||
await expect(flowerTemplate).toHaveCSS("background-color", "rgb(255, 255, 214)");
|
||||
await expect(flowerTemplate.locator(".editor-template-mark")).toHaveCSS("transform", "matrix(1.03, 0, 0, 1.03, 0, 0)");
|
||||
await expect(flowerTemplate.locator(".editor-template-preview")).toHaveCSS("transform", "matrix(1.03, 0, 0, 1.03, 0, 0)");
|
||||
await flowerTemplate.click();
|
||||
await expect(page.getByText("对象 1 / 50")).toBeVisible();
|
||||
await expect.poll(() => backend.recent).toEqual([{ asset_id: "FLOWER001", asset_kind: "text_template", resource_version: "p0a-complex-v1" }]);
|
||||
@@ -110,8 +114,8 @@ test("TDD-WP4-TXT-003 exposes the frozen catalog, display-name search and accoun
|
||||
await expect(page.getByLabel("最近使用文字模板").getByText("FLOWER001", { exact: true })).toBeVisible();
|
||||
await page.getByRole("button", { name: "普通贴纸", exact: true }).click();
|
||||
expect(page.getByPlaceholder("搜索普通贴纸")).toHaveCount(0);
|
||||
writeEvidence("TDD-WP4-TXT-003-catalog-search-recent", "catalog.json", { categories: { flower: 8, simple: 8, tag: 8, title: 8 }, count: 32, first: "FLOWER001", last: "SIMPLE008" });
|
||||
writeEvidence("TDD-WP4-TXT-003-catalog-search-recent", "response.json", { public_count: 32, recent: backend.recent, unavailable_is_disabled: true });
|
||||
writeEvidence("TDD-WP4-TXT-003-catalog-search-recent", "catalog.json", { categories: { flower: 145, simple: 17, tag: 51, title: 119 }, count: 332, first: "FLOWER001", last: "SIMPLE017" });
|
||||
writeEvidence("TDD-WP4-TXT-003-catalog-search-recent", "response.json", { public_count: 332, recent: backend.recent, unavailable_count: 0 });
|
||||
writeEvidence("TDD-WP4-TXT-003-catalog-search-recent", "db-diff.json", { account_user_id: userId, recent: backend.recent, search_did_not_write: true });
|
||||
});
|
||||
|
||||
@@ -228,7 +232,7 @@ test("POSTV1-07 keeps the canvas anchored when the text template panel opens", a
|
||||
if (!before) throw new Error("Canvas geometry is unavailable before opening text templates.");
|
||||
|
||||
await page.getByRole("button", { name: "文字模板", exact: true }).click();
|
||||
await expect(page.locator(".editor-template-grid button")).toHaveCount(32);
|
||||
await expect(page.locator(".editor-template-grid button")).toHaveCount(332);
|
||||
const after = await stage.boundingBox();
|
||||
if (!after) throw new Error("Canvas geometry is unavailable after opening text templates.");
|
||||
const assetsPanelScroll = await page.getByLabel("素材与底图来源").evaluate((panel) => ({
|
||||
|
||||
@@ -64,7 +64,10 @@ async function routeEditor(page: Page, backend: Backend) {
|
||||
});
|
||||
await page.route("**/api/v1/assets/recent?asset_kind=text_template", (route) => route.fulfill({ body: JSON.stringify({ items: [] }), contentType: "application/json" }));
|
||||
await page.route("**/api/v1/assets/recent", (route) => route.fulfill({ body: JSON.stringify({ status: "recorded" }), contentType: "application/json" }));
|
||||
await page.route("**/api/v1/assets/public/p0a-complex-v1/*", (route) => route.fulfill({ body: fontBytes, contentType: "font/ttf" }));
|
||||
await page.route("**/api/v1/assets/public/p0a-complex-v1/*", (route) => {
|
||||
const preview = new URL(route.request().url()).pathname.includes("TEXT-PREVIEW-");
|
||||
return route.fulfill(preview ? { body: png, contentType: "image/png" } : { body: fontBytes, contentType: "font/ttf" });
|
||||
});
|
||||
await page.route("**/api/v1/assets/public/p0a-static-v1/*", (route) => route.fulfill({ body: png, contentType: "image/png" }));
|
||||
await page.route(`**/api/v1/private-assets/projects/${projectId}/images/${backgroundId}`, (route) => route.fulfill({ body: rawSvg(), contentType: "image/svg+xml" }));
|
||||
}
|
||||
@@ -91,7 +94,7 @@ test.beforeAll(async () => {
|
||||
|
||||
test.afterAll(async () => vite.close());
|
||||
|
||||
test("TDD-WP5-WHITE-001 exposes only the P0-A public allowlist", async ({ page }) => {
|
||||
test("POSTV1-ASSET-ALL-16 exposes the complete complex asset catalog", async ({ page }) => {
|
||||
const backend: Backend = { canvas: canvas(), saves: 0, version: 1 };
|
||||
await routeEditor(page, backend);
|
||||
await page.goto(`${webUrl}/app/projects/${projectId}/editor`);
|
||||
@@ -99,7 +102,6 @@ test("TDD-WP5-WHITE-001 exposes only the P0-A public allowlist", async ({ page }
|
||||
await page.getByRole("button", { name: "文字模板", exact: true }).click();
|
||||
const textIds = await page.locator(".editor-template-grid button strong").allTextContents();
|
||||
expect(textIds).toEqual(P0A_TEXT_TEMPLATE_IDS);
|
||||
expect(textIds).not.toContain("FLOWER009");
|
||||
await page.getByRole("button", { name: /FLOWER001 春日计划/ }).click();
|
||||
await expect(page.getByText("对象 1 / 50")).toBeVisible();
|
||||
await expect(page.getByLabel("字体覆盖")).toBeVisible();
|
||||
@@ -109,12 +111,12 @@ test("TDD-WP5-WHITE-001 exposes only the P0-A public allowlist", async ({ page }
|
||||
await page.getByRole("button", { name: "色卡", exact: true }).click();
|
||||
const colorIds = await page.locator(".editor-provider-grid button strong").allTextContents();
|
||||
expect(colorIds).toEqual(P0A_COLOR_CARD_IDS);
|
||||
expect(colorIds).not.toContain("COLOR003");
|
||||
|
||||
await page.getByRole("button", { name: "动态贴纸", exact: true }).click();
|
||||
const dynamicIds = await page.locator(".editor-provider-grid button strong").allTextContents();
|
||||
expect([...dynamicIds].sort()).toEqual([...P0A_DYNAMIC_STICKER_IDS].sort());
|
||||
expect(dynamicIds).not.toContain("DYN005");
|
||||
await page.getByRole("button", { name: /添加动态贴纸 DYN035/ }).click();
|
||||
await expect.poll(() => backend.canvas.elements.some((element) => element.template_or_asset_id === "DYN035")).toBe(true);
|
||||
|
||||
await page.getByRole("button", { name: "普通贴纸", exact: true }).click();
|
||||
await expect(page.getByText("共 1,407 张", { exact: true })).toBeVisible();
|
||||
@@ -130,27 +132,22 @@ test("TDD-WP5-WHITE-001 exposes only the P0-A public allowlist", async ({ page }
|
||||
}
|
||||
});
|
||||
|
||||
test("TDD-WP5-COL-001 renders four layouts from one shared five-color snapshot", async ({ page }) => {
|
||||
test("POSTV1-ASSET-ALL-16 renders sixteen layouts from one shared five-color snapshot", async ({ page }) => {
|
||||
test.setTimeout(60_000);
|
||||
const backend: Backend = { canvas: canvas(), saves: 0, version: 1 };
|
||||
await routeEditor(page, backend);
|
||||
await page.goto(`${webUrl}/app/projects/${projectId}/editor`);
|
||||
await page.getByRole("button", { name: "色卡", exact: true }).click();
|
||||
const placements = [
|
||||
[["ArrowLeft", 10], ["ArrowUp", 8]],
|
||||
[["ArrowRight", 10], ["ArrowUp", 8]],
|
||||
[["ArrowLeft", 10], ["ArrowDown", 8]],
|
||||
[["ArrowRight", 10], ["ArrowDown", 8]],
|
||||
] as const;
|
||||
for (const [index, id] of P0A_COLOR_CARD_IDS.entries()) {
|
||||
await page.getByRole("button", { name: new RegExp(`添加色卡 ${id}`) }).click();
|
||||
await expect.poll(() => backend.canvas.elements.length).toBe(index + 1);
|
||||
for (const [key, times] of placements[index]!) {
|
||||
for (let press = 0; press < times; press += 1) await page.getByLabel("编辑画布").press(`Shift+${key}`);
|
||||
}
|
||||
await expect(page.getByText(`对象 ${index + 1} / 50`)).toBeVisible();
|
||||
}
|
||||
await expect.poll(() => backend.canvas.elements.length, { timeout: 10_000 }).toBe(16);
|
||||
const palettes = backend.canvas.elements.map((element) => element.colors);
|
||||
expect(palettes.every((palette) => JSON.stringify(palette) === JSON.stringify(palettes[0]))).toBe(true);
|
||||
expect(backend.canvas.elements.map((element) => element.style_id)).toEqual(["style_01", "style_02", "style_08", "style_16"]);
|
||||
expect(backend.canvas.elements.map((element) => element.style_id)).toEqual(
|
||||
Array.from({ length: 16 }, (_, index) => `style_${String(index + 1).padStart(2, "0")}`),
|
||||
);
|
||||
const pixels = await page.getByLabel("编辑画布").evaluate((stage: HTMLCanvasElement) => {
|
||||
const context = stage.getContext("2d");
|
||||
if (!context) throw new Error("canvas context unavailable");
|
||||
@@ -161,7 +158,7 @@ test("TDD-WP5-COL-001 renders four layouts from one shared five-color snapshot",
|
||||
});
|
||||
mergeEvidence(evidencePath("color", "palette.json"), { browser_palettes: palettes, same_palette_snapshot: true });
|
||||
mergeEvidence(evidencePath("color", "pixel-diff.json"), {
|
||||
...pixels, four_renderers_visible: true, significant_pixel_ratio: 0, status: pixels.opaque_pixels > 0 ? "passed" : "failed",
|
||||
...pixels, sixteen_renderers_available: true, significant_pixel_ratio: 0, status: pixels.opaque_pixels > 0 ? "passed" : "failed",
|
||||
});
|
||||
const screenshot = evidencePath("color", "screenshots/color-cards.png");
|
||||
if (screenshot) {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import complexAssetCatalog from "../../apps/web/src/generated/complex-assets.json";
|
||||
import { P0A_DYNAMIC_STICKERS } from "../../apps/web/src/dynamic-provider.js";
|
||||
import { DYNAMIC_RENDER_MODELS } from "../../apps/web/src/dynamic-render-models.js";
|
||||
import { P0A_COLOR_CARDS } from "../../apps/web/src/palette-provider.js";
|
||||
import { P0A_FONT_OPTIONS, P0A_TEXT_TEMPLATES } from "../../apps/web/src/text-assets.js";
|
||||
import {
|
||||
P0A_COLOR_CARD_IDS,
|
||||
P0A_DYNAMIC_STICKER_IDS,
|
||||
@@ -36,4 +40,13 @@ describe("POSTV1-ASSET-ALL-16 complete asset catalog", () => {
|
||||
expect(complexAssetCatalog.text_templates.every((item) => item.available)).toBe(true);
|
||||
expect(JSON.stringify(complexAssetCatalog)).not.toMatch(/[A-Z]:[\\/]/i);
|
||||
});
|
||||
|
||||
it("exposes every generated definition to the editor", () => {
|
||||
expect(P0A_TEXT_TEMPLATES).toHaveLength(332);
|
||||
expect(P0A_TEXT_TEMPLATES.every((item) => item.available && item.fontUrl)).toBe(true);
|
||||
expect(P0A_FONT_OPTIONS).toHaveLength(86);
|
||||
expect(P0A_COLOR_CARDS).toHaveLength(16);
|
||||
expect(P0A_DYNAMIC_STICKERS).toHaveLength(35);
|
||||
expect(Object.keys(DYNAMIC_RENDER_MODELS)).toHaveLength(35);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { CanvasState } from "@dada/shared-contracts";
|
||||
|
||||
import {
|
||||
P0A_TEXT_TEMPLATES,
|
||||
P0A_FONT_OPTIONS,
|
||||
TextEditSession,
|
||||
createTextTemplateElement,
|
||||
effectiveFontSize,
|
||||
@@ -13,19 +14,15 @@ import { elementHalfExtents } from "../../apps/web/src/editor-elements.js";
|
||||
const identity = { createdAt: "2026-08-03T03:00:00.000Z", elementId: "00000000-0000-4000-8000-000000000701" };
|
||||
|
||||
describe("TASK-WP4-03 text templates and properties", () => {
|
||||
it("keeps the frozen 32-template allowlist in catalog order and searches display names only", () => {
|
||||
expect(P0A_TEXT_TEMPLATES).toHaveLength(32);
|
||||
expect(P0A_TEXT_TEMPLATES.map((template) => template.templateId)).toEqual([
|
||||
"FLOWER001", "FLOWER002", "FLOWER003", "FLOWER004", "FLOWER005", "FLOWER006", "FLOWER007", "FLOWER008",
|
||||
"H001", "H002", "H003", "H004", "H005", "H006", "H007", "H008",
|
||||
"TAG001", "TAG002", "TAG003", "TAG004", "TAG005", "TAG006", "TAG007", "TAG051",
|
||||
"SIMPLE001", "SIMPLE002", "SIMPLE003", "SIMPLE004", "SIMPLE005", "SIMPLE006", "SIMPLE007", "SIMPLE008",
|
||||
]);
|
||||
it("keeps the complete 332-template catalog order and searches display names only", () => {
|
||||
expect(P0A_TEXT_TEMPLATES).toHaveLength(332);
|
||||
expect(P0A_TEXT_TEMPLATES[0]?.templateId).toBe("FLOWER001");
|
||||
expect(P0A_TEXT_TEMPLATES.at(-1)?.templateId).toBe("SIMPLE017");
|
||||
expect(P0A_TEXT_TEMPLATES.reduce<Record<string, number>>((counts, template) => {
|
||||
counts[template.category] = (counts[template.category] ?? 0) + 1;
|
||||
return counts;
|
||||
}, {})).toEqual({ flower: 8, simple: 8, tag: 8, title: 8 });
|
||||
expect(searchTextTemplates(P0A_TEXT_TEMPLATES, { query: "生活" }).map((item) => item.templateId)).toEqual(["FLOWER004", "FLOWER005", "H001", "H003", "H006"]);
|
||||
}, {})).toEqual({ flower: 145, simple: 17, tag: 51, title: 119 });
|
||||
expect(searchTextTemplates(P0A_TEXT_TEMPLATES, { query: "生活" }).map((item) => item.templateId)).toEqual(expect.arrayContaining(["FLOWER004", "FLOWER005", "H001", "H003", "H006"]));
|
||||
expect(searchTextTemplates(P0A_TEXT_TEMPLATES, { category: "tag", query: "TAG006" })).toEqual([]);
|
||||
});
|
||||
|
||||
@@ -100,11 +97,11 @@ describe("TASK-WP4-03 text templates and properties", () => {
|
||||
expect(bounds.y).toBeGreaterThan(0.16);
|
||||
});
|
||||
|
||||
it("does not add unavailable templates or silently replace their archived font", () => {
|
||||
const unavailable = P0A_TEXT_TEMPLATES.find((template) => !template.available)!;
|
||||
expect(unavailable).toBeDefined();
|
||||
expect(() => createTextTemplateElement(unavailable, identity, 0)).toThrowError("text_template_unavailable");
|
||||
const available = P0A_TEXT_TEMPLATES.find((template) => template.available)!;
|
||||
it("adds every template with a registered catalog font", () => {
|
||||
expect(P0A_TEXT_TEMPLATES.every((template) => template.available && template.fontUrl)).toBe(true);
|
||||
const registeredFonts = new Set(P0A_FONT_OPTIONS.map((font) => font.fontId));
|
||||
expect(P0A_TEXT_TEMPLATES.every((template) => registeredFonts.has(template.defaultFontId))).toBe(true);
|
||||
const available = P0A_TEXT_TEMPLATES[0]!;
|
||||
const element = createTextTemplateElement(available, identity, 0);
|
||||
expect(element.font_override).toBeUndefined();
|
||||
expect((element.style_parameters as Record<string, unknown>).default_font_id).toBe(available.defaultFontId);
|
||||
|
||||
@@ -45,8 +45,10 @@ describe("TASK-WP4-04 deterministic color cards", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("uses the four-item P0-A allowlist and produces a stable five-color MMCQ palette", () => {
|
||||
expect(P0A_COLOR_CARDS.map((item) => item.cardId)).toEqual(["COLOR001", "COLOR002", "COLOR008", "COLOR016"]);
|
||||
it("uses all sixteen color-card layouts and produces a stable five-color MMCQ palette", () => {
|
||||
expect(P0A_COLOR_CARDS).toHaveLength(16);
|
||||
expect(P0A_COLOR_CARDS[0]?.cardId).toBe("COLOR001");
|
||||
expect(P0A_COLOR_CARDS.at(-1)?.cardId).toBe("COLOR016");
|
||||
const pixels = colorPixels([
|
||||
{ count: 50, rgb: [244, 32, 32] }, { count: 40, rgb: [32, 210, 96] }, { count: 30, rgb: [24, 96, 220] },
|
||||
{ count: 20, rgb: [248, 210, 48] }, { count: 10, rgb: [120, 64, 180] },
|
||||
@@ -78,10 +80,10 @@ describe("TASK-WP4-04 dynamic providers", () => {
|
||||
profile: { creatorName: "Dada Creator", socialId: "@@dada" },
|
||||
};
|
||||
|
||||
it("exposes exactly ten P0-A providers and snapshots time and identity", () => {
|
||||
expect(P0A_DYNAMIC_STICKERS.map((item) => item.templateId)).toEqual([
|
||||
"DYN001", "DYN002", "DYN003", "DYN004", "DYN007", "DYN008", "DYN011", "DYN012", "DYN015", "DYN016",
|
||||
]);
|
||||
it("exposes all thirty-five providers and snapshots time and identity", () => {
|
||||
expect(P0A_DYNAMIC_STICKERS).toHaveLength(35);
|
||||
expect(P0A_DYNAMIC_STICKERS[0]?.templateId).toBe("DYN001");
|
||||
expect(P0A_DYNAMIC_STICKERS.at(-1)?.templateId).toBe("DYN035");
|
||||
const time = createDynamicStickerElement("DYN012", context, identity, 0);
|
||||
expect(time.formatted_value).toBe("09:07");
|
||||
expect(time.dynamic_fields).toMatchObject({ font_substitution: "FONT081", hour: "09", minute: "07" });
|
||||
@@ -92,11 +94,10 @@ describe("TASK-WP4-04 dynamic providers", () => {
|
||||
});
|
||||
|
||||
it("uses the archived template categories and only the fields visibly consumed by each source", () => {
|
||||
expect(P0A_DYNAMIC_STICKERS.map(({ category, templateId }) => [templateId, category])).toEqual([
|
||||
["DYN001", "location"], ["DYN002", "location"], ["DYN003", "location"], ["DYN004", "location"],
|
||||
["DYN007", "other"], ["DYN008", "time"], ["DYN011", "time"], ["DYN012", "time"],
|
||||
["DYN015", "identity"], ["DYN016", "identity"],
|
||||
]);
|
||||
expect(P0A_DYNAMIC_STICKERS.reduce<Record<string, number>>((counts, item) => {
|
||||
counts[item.category] = (counts[item.category] ?? 0) + 1;
|
||||
return counts;
|
||||
}, {})).toEqual({ identity: 21, location: 6, other: 1, time: 7 });
|
||||
const other = createDynamicStickerElement("DYN007", context, identity, 0);
|
||||
expect(other.dynamic_fields).toEqual({ nickname: "@dada" });
|
||||
expect(other.formatted_value).toBe("@dada");
|
||||
@@ -105,11 +106,10 @@ describe("TASK-WP4-04 dynamic providers", () => {
|
||||
});
|
||||
|
||||
it("maps every enabled dynamic sticker to its archived source candidate and original resource version", () => {
|
||||
expect(Object.entries(DYNAMIC_RENDER_MODELS).map(([id, model]) => [id, model.sourceCandidateId])).toEqual([
|
||||
["DYN001", "l_POI01"], ["DYN002", "l_POI02"], ["DYN003", "l_POI03"], ["DYN004", "l_POI04"],
|
||||
["DYN007", "diaoyu"], ["DYN008", "l_shijian2"], ["DYN011", "l_shijian6"], ["DYN012", "l_shijian7"],
|
||||
["DYN015", "0721userna"], ["DYN016", "l_username00"],
|
||||
]);
|
||||
expect(Object.keys(DYNAMIC_RENDER_MODELS)).toHaveLength(35);
|
||||
expect(DYNAMIC_RENDER_MODELS.DYN001?.sourceCandidateId).toBe("l_POI01");
|
||||
expect(DYNAMIC_RENDER_MODELS.DYN012?.sourceCandidateId).toBe("l_shijian7");
|
||||
expect(DYNAMIC_RENDER_MODELS.DYN035?.sourceCandidateId).toBe("l_username23");
|
||||
const element = createDynamicStickerElement("DYN001", { ...context, location: { formattedValue: "温州" } }, identity, 0);
|
||||
expect(element.resource_version).toBe(DYNAMIC_RESOURCE_VERSION);
|
||||
expect(DYNAMIC_RENDER_MODELS.DYN001.imageLayers).toEqual([
|
||||
|
||||
Reference in New Issue
Block a user