import fs from 'node:fs' import os from 'node:os' import path from 'node:path' import Fastify from 'fastify' import { afterAll, describe, expect, it } from 'vitest' import { registerMobileApp } from '../src/http/mobile-app' const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'mobile-app-')) let published = false const f = Fastify() registerMobileApp(f, () => (published ? dir : undefined)) afterAll(() => fs.rmSync(dir, { recursive: true, force: true })) describe('Android App 下载页', () => { it('还没有发布时页面提示,安装包与 index.json 返回 404', async () => { const page = await f.inject({ method: 'GET', url: '/app' }) expect(page.statusCode).toBe(200) expect(page.headers['content-type']).toContain('text/html') expect(page.body).toContain('还没有发布安装包') expect((await f.inject({ method: 'GET', url: '/app/index.json' })).statusCode).toBe(404) expect((await f.inject({ method: 'GET', url: '/app/agent-0.1.0.apk' })).statusCode).toBe(404) }) it('发布后显示版本与下载链接,安装包按附件下载', async () => { fs.writeFileSync(path.join(dir, 'agent-0.2.0.apk'), 'apk-bytes') fs.writeFileSync(path.join(dir, 'index.json'), JSON.stringify({ version: '0.2.0', file: 'agent-0.2.0.apk', size: 9, sha256: 'x', publishedAt: '2026-10-27T08:00:00Z' })) published = true const page = await f.inject({ method: 'GET', url: '/app', headers: { host: 'agent.example.com' } }) expect(page.body).toContain('href="/app/agent-0.2.0.apk"') expect(page.body).toContain('版本 0.2.0') expect(page.body).toContain('http://agent.example.com') expect(page.body).toContain(' { fs.writeFileSync(path.join(dir, 'secret.txt'), 'x') expect((await f.inject({ method: 'GET', url: '/app/secret.txt' })).statusCode).toBe(404) expect((await f.inject({ method: 'GET', url: '/app/..%2Findex.json.apk' })).statusCode).toBe(404) }) })