Files
star-chart-search-enhancer/tests/audience-profile-field-dialog.test.ts
T

184 lines
5.6 KiB
TypeScript

/** @vitest-environment jsdom */
import { describe, expect, test } from "vitest";
import { promptForAudienceProfileFields } from "../src/content/market/audience-profile-field-dialog";
describe("audience-profile-field-dialog", () => {
test("keeps an explicitly empty field selection empty", async () => {
const result = promptForAudienceProfileFields(
document,
[
{
headers: ["粉丝数", "观众画像-男性占比"],
label: "测试字段"
}
],
[]
);
const fields = Array.from(
document.querySelectorAll(
'[data-audience-profile-field-dialog-field="checkbox"]'
)
) as HTMLInputElement[];
expect(fields).toHaveLength(2);
expect(fields.every((field) => !field.checked)).toBe(true);
expect(
document.querySelectorAll(
"[data-audience-profile-field-dialog-selected-field]"
)
).toHaveLength(0);
expect(
document.querySelector(
'[data-audience-profile-field-dialog-selected-empty="text"]'
)?.hidden
).toBe(false);
clickSave();
await expect(result).resolves.toEqual([]);
});
test("keeps selected fields visible while searching and synchronizes both panes", async () => {
const result = promptForAudienceProfileFields(
document,
[
{
headers: ["粉丝数"],
label: "列表字段"
},
{
headers: ["内容数据-近30天-完播率", "内容数据-近30天-播放量"],
label: "内容数据"
}
],
["粉丝数", "内容数据-近30天-播放量"]
);
expect(readSelectedFieldNames()).toEqual([
"粉丝数",
"内容数据-近30天-播放量"
]);
expect(
document.querySelector(
'[data-audience-profile-field-dialog-selected-count="text"]'
)?.textContent
).toBe("2 个");
const search = document.querySelector(
'[data-audience-profile-field-dialog-search="input"]'
) as HTMLInputElement;
search.value = "完播率";
search.dispatchEvent(new Event("input"));
expect(readResultItem("内容数据-近30天-完播率")?.hidden).toBe(false);
expect(readResultItem("粉丝数")?.hidden).toBe(true);
expect(readSelectedFieldNames()).toEqual([
"粉丝数",
"内容数据-近30天-播放量"
]);
expect(
document.querySelector(
'[data-audience-profile-field-dialog-result-count="text"]'
)?.textContent
).toBe("找到 1 个");
const finishRateInput = readResultInput("内容数据-近30天-完播率");
finishRateInput.checked = true;
finishRateInput.dispatchEvent(new Event("change"));
expect(readSelectedFieldNames()).toEqual([
"粉丝数",
"内容数据-近30天-完播率",
"内容数据-近30天-播放量"
]);
const selectedFansInput = readSelectedInput("粉丝数");
selectedFansInput.checked = false;
selectedFansInput.dispatchEvent(new Event("change"));
expect(readResultInput("粉丝数").checked).toBe(false);
expect(readSelectedFieldNames()).toEqual([
"内容数据-近30天-完播率",
"内容数据-近30天-播放量"
]);
clickSave();
await expect(result).resolves.toEqual([
"内容数据-近30天-完播率",
"内容数据-近30天-播放量"
]);
});
test("shows a dedicated empty state when no field matches the keyword", async () => {
const result = promptForAudienceProfileFields(
document,
[{ headers: ["粉丝数"], label: "列表字段" }],
undefined
);
const search = document.querySelector(
'[data-audience-profile-field-dialog-search="input"]'
) as HTMLInputElement;
search.value = "不存在的字段";
search.dispatchEvent(new Event("input"));
expect(
document.querySelector(
'[data-audience-profile-field-dialog-result-empty="text"]'
)?.hidden
).toBe(false);
expect(
document.querySelector(
'[data-audience-profile-field-dialog-result-count="text"]'
)?.textContent
).toBe("找到 0 个");
expect(readSelectedFieldNames()).toEqual(["粉丝数"]);
clickSave();
await expect(result).resolves.toEqual(["粉丝数"]);
});
});
function clickSave(): void {
const saveButton = document.querySelector(
'[data-audience-profile-field-dialog-save="button"]'
) as HTMLButtonElement;
saveButton.click();
}
function readResultItem(field: string): HTMLElement | undefined {
return Array.from(
document.querySelectorAll<HTMLElement>(
"[data-audience-profile-field-dialog-result]"
)
).find(
(element) => element.dataset.audienceProfileFieldDialogResult === field
);
}
function readResultInput(field: string): HTMLInputElement {
const input = Array.from(
document.querySelectorAll<HTMLInputElement>(
'[data-audience-profile-field-dialog-field="checkbox"]'
)
).find((element) => element.value === field);
if (!input) throw new Error(`Missing result field input: ${field}`);
return input;
}
function readSelectedInput(field: string): HTMLInputElement {
const input = Array.from(
document.querySelectorAll<HTMLInputElement>(
'[data-audience-profile-field-dialog-selected-checkbox="checkbox"]'
)
).find((element) => element.value === field);
if (!input) throw new Error(`Missing selected field input: ${field}`);
return input;
}
function readSelectedFieldNames(): string[] {
return Array.from(
document.querySelectorAll<HTMLElement>(
"[data-audience-profile-field-dialog-selected-field]"
)
).map((element) => element.dataset.audienceProfileFieldDialogSelectedField ?? "");
}