import { test } from 'node:test' import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' import { fileURLToPath } from 'node:url' import { resolve, dirname } from 'node:path' import { http } from '../src/shared/api/http.ts' import { http as httpAgain } from '../src/shared/api/http.ts' const moduleFiles = [ 'dedupe', 'split', 'convert', 'publish', 'similar-asin', 'appearance-patent', 'delete-brand', 'price-track', 'shop-match', 'query-asin', 'withdraw', 'collect-data', 'image-video', 'brand', 'permission', 'digital-human', ] const functionNames = [ 'runDedupe', 'getSplitHistory', 'runConvert', 'parsePublish', 'parseSimilarAsin', 'parseAppearancePatent', 'runDeleteBrand', 'listPriceTrackCandidates', 'listProductRiskCandidates', 'listShopMatchCandidates', 'listQueryAsinCandidates', 'listWithdrawCandidates', 'listShopDataCrawlCandidates', 'parseCollectData', 'getImageVideoSecretStatus', 'expandBrandFolderRecursive', 'getCurrentUserAppColumnKeys', 'getDigitalHumanVersions', 'uploadTempFileToJava', 'getJavaDownloadUrl', 'JAVA_API_PREFIX', 'http', ] test('test_reexport_all_symbols', async () => { const fromJavaModules = await import('../src/shared/api/java-modules.ts') for (const name of functionNames) { assert.ok(name in fromJavaModules, `${name} 应从 java-modules 导出`) } }) test('test_reexport_same_reference', async () => { const fromJavaModules = await import('../src/shared/api/java-modules.ts') for (const file of moduleFiles) { const fromModule = await import(`../src/shared/api/types/modules/${file}.ts`) const reexports = Object.keys(fromJavaModules).filter( (k) => k in fromModule && typeof fromJavaModules[k] === 'function', ) for (const name of reexports) { assert.equal(fromJavaModules[name], fromModule[name], `${file}:${name} 应为同一引用`) } } }) test('test_reexport_upload_helpers', async (t) => { ;(globalThis as Record).window = { localStorage: { getItem: () => '42' }, location: { origin: 'http://localhost' }, } const calls: { url?: string; method?: string; data?: unknown }[] = [] t.mock.method(http, 'post', ((url: string, data?: unknown, config?: unknown) => { calls.push({ url, method: 'POST', data }) return Promise.resolve({ data: { success: true, message: 'ok', data: { fileKey: 'f1', originalFilename: 'a.xlsx', localPath: '/tmp/a.xlsx', size: 1 } } }) }) as never) const { uploadTempFileToJava } = await import('../src/shared/api/java-modules.ts') const { uploadTempFileToJava: fromUpload } = await import('../src/shared/api/upload.ts') assert.equal(uploadTempFileToJava, fromUpload) const file = new File(['x'], 'a.xlsx') const result = await uploadTempFileToJava(file, 'sub/') assert.equal(calls[0].url, '/newApi/api/files/upload') assert.equal(calls[0].method, 'POST') assert.ok(calls[0].data instanceof FormData) assert.equal(result.success, true) assert.equal(result.data.fileKey, 'f1') }) test('test_reexport_download_and_constants', async () => { const fromJavaModules = await import('../src/shared/api/java-modules.ts') const { getJavaDownloadUrl } = await import('../src/shared/api/download-url.ts') const { JAVA_API_PREFIX } = await import('../src/shared/api/url.ts') assert.equal(fromJavaModules.getJavaDownloadUrl, getJavaDownloadUrl) assert.equal(fromJavaModules.JAVA_API_PREFIX, JAVA_API_PREFIX) assert.equal(fromJavaModules.http, httpAgain) }) test('test_reexport_no_dead_body', async () => { const here = dirname(fileURLToPath(import.meta.url)) const source = readFileSync(resolve(here, '../src/shared/api/java-modules.ts'), 'utf-8') const deadMarkers = [ 'function postTaskProgressBatch', 'const taskProgressResponseCache', 'function getCurrentUserId', 'function normalizeTaskIds', 'function buildTaskProgressRequestKey', 'async function uploadTempFileToJava', 'export function getJavaDownloadUrl', 'JAVA_API_PREFIX = "/newApi/api"', ] for (const marker of deadMarkers) { assert.ok(!source.includes(marker), `java-modules.ts 不应残留: ${marker}`) } }) test('test_reexport_no_duplicate_exports', async () => { const here = dirname(fileURLToPath(import.meta.url)) const source = readFileSync(resolve(here, '../src/shared/api/java-modules.ts'), 'utf-8') const exportLines = source .split('\n') .filter((line) => line.includes('export * from')) .map((line) => line.match(/export \* from "\.\/([^"]+)"/)?.[1]) .filter(Boolean) assert.ok(exportLines.length >= 13, `应有 ≥13 个模块 re-export,实际 ${exportLines.length}`) assert.equal(new Set(exportLines).size, exportLines.length, '不应有重复的 re-export') }) test('test_reexport_runtime_symbols', async (t) => { ;(globalThis as Record).window = { localStorage: { getItem: () => '42' }, location: { origin: 'http://localhost' }, } t.mock.method(http, 'request', (() => { return Promise.resolve({ data: { success: true, message: 'ok', data: { items: [] } } }) }) as never) const fromJavaModules = await import('../src/shared/api/java-modules.ts') const result = await fromJavaModules.getWithdrawHistory() assert.deepEqual(result.items, []) }) test('test_reexport_upload_types', async () => { const fromJavaModules = await import('../src/shared/api/java-modules.ts') const fromUpload = await import('../src/shared/api/upload.ts') assert.equal(fromJavaModules.UploadFileVo, fromUpload.UploadFileVo) assert.equal(fromJavaModules.UploadedFileRef, fromUpload.UploadedFileRef) assert.equal(fromJavaModules.UploadTempFileOptions, fromUpload.UploadTempFileOptions) })