'use strict'; const assert = require('assert/strict'); const fs = require('fs'); const http = require('http'); const os = require('os'); const path = require('path'); const { readLocalVersion, compareVersions, checkForUpdate, isCompiledDelivery, spawnUpdateHelper, } = require('../mcp/src/core/update-service'); async function main() { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'qiwei-update-smoke-')); const runtime = path.join(root, 'outputs', 'runtime'); fs.mkdirSync(runtime, { recursive: true }); fs.writeFileSync(path.join(root, 'version.json'), JSON.stringify({ product: 'fmode-qiwei-training', version: '0.5.2', platform: 'win-x64' }), 'utf8'); const server = http.createServer((req, res) => { res.writeHead(200, { 'content-type': 'application/json' }); res.end(JSON.stringify({ product: 'fmode-qiwei-training', version: '0.5.3', notes: 'smoke', platforms: { 'win-x64': { url: 'https://example.invalid/update.zip', sha256: '0'.repeat(64) } }, })); }); await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)); const url = `http://127.0.0.1:${server.address().port}/latest.json`; try { assert.equal(readLocalVersion(root).version, '0.5.2'); assert.equal(compareVersions('0.5.3', '0.5.2'), 1); assert.equal(compareVersions('0.5.2', '0.5.2'), 0); const result = await checkForUpdate({ root, manifestUrl: url, timeoutMs: 2000 }); assert.equal(result.status, 'update_available'); assert.equal(result.latest.version, '0.5.3'); assert.equal(result.release.url, 'https://example.invalid/update.zip'); assert.equal(fs.existsSync(path.join(runtime, 'update-status.json')), true); if (!isCompiledDelivery()) { assert.throws(() => spawnUpdateHelper('missing.zip', root), /开发源码模式/); } process.stdout.write(JSON.stringify({ status: 'passed', checks: ['version-read', 'semver-compare', 'manifest-check', 'source-replacement-guard'] }, null, 2) + '\n'); } finally { await new Promise(resolve => server.close(resolve)); fs.rmSync(root, { recursive: true, force: true }); } } main().catch(error => { process.stderr.write(JSON.stringify({ status: 'failed', message: error.message, stack: error.stack }, null, 2) + '\n'); process.exitCode = 1; });