const test = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const Module = require('node:module'); const ts = require('typescript'); const pagePath = path.join(__dirname, '../src/pages/creator/competitors/index.tsx'); function createPage() { let filters = {}; const gallery = 'WorksGallery'; const element = (type, props) => ({ type, props }); const mocks = { react: { useMemo: (factory) => factory(), useState: () => [filters, (update) => { filters = update(filters); }], }, 'react/jsx-runtime': { jsx: element, jsxs: element }, antd: { Card: 'Card', DatePicker: 'DatePicker', Flex: 'Flex', InputNumber: 'InputNumber', Select: 'Select', Space: 'Space', Typography: { Text: 'Text' }, }, '@/components/creator/WorksGallery': { __esModule: true, default: gallery }, }; const compiled = ts.transpileModule(fs.readFileSync(pagePath, 'utf8'), { fileName: pagePath, compilerOptions: { module: ts.ModuleKind.CommonJS, jsx: ts.JsxEmit.ReactJSX, esModuleInterop: true, inlineSourceMap: true, inlineSources: true, }, }).outputText; const loaded = new Module(pagePath, module); loaded.filename = pagePath; loaded.paths = Module._nodeModulePaths(path.dirname(pagePath)); loaded.require = (name) => Object.hasOwn(mocks, name) ? mocks[name] : module.require(name); loaded._compile(compiled, pagePath); function descendants(node) { if (!node || typeof node !== 'object') return []; return [node, ...[node.props?.children].flat(Infinity).flatMap(descendants)]; } return () => { const nodes = descendants(loaded.exports.default()); return { gallery: nodes.find((node) => node.type === gallery).props, controls: nodes.filter((node) => node.props.onChange), }; }; } function assertCompetitorOnly(props) { assert.equal(props.sourceType, 'competitor', '竞品分析必须排除自有账号作品'); assert.equal(props.sourceId, undefined, '竞品分析应包含所有监测账号,而非限定某个账号'); } test('竞品分析首次加载只查询监测账号作品', () => { const render = createPage(); assertCompetitorOnly(render().gallery); }); test('调整及清空各项筛选后仍只查询监测账号作品', () => { const render = createPage(); const date = { format: (pattern) => { assert.equal(pattern, 'YYYY-MM-DD'); return '2026-05-18'; } }; const cases = [ ['最低点赞', 'min_likes', 12, 12], ['最低评论', 'min_comments', 3, 3], ['最低转发', 'min_shares', 5, 5], ['全部状态', 'published_at_status', 'verified', 'verified'], ['发布开始日期', 'published_after', date, '2026-05-18T00:00:00Z'], ['发布结束日期', 'published_before', date, '2026-05-18T23:59:59Z'], ]; for (const [placeholder, key, value, expected] of cases) { render().controls.find((control) => control.props.placeholder === placeholder).props.onChange(value); assertCompetitorOnly(render().gallery); assert.equal(render().gallery.extraFilters[key], expected); } for (const [placeholder, key] of cases) { const clearValue = key === 'published_at_status' ? undefined : null; render().controls.find((control) => control.props.placeholder === placeholder).props.onChange(clearValue); assertCompetitorOnly(render().gallery); assert.equal(render().gallery.extraFilters[key], undefined); } });