| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 |
- 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('<svg')
- expect((await f.inject({ method: 'GET', url: '/app/index.json' })).json().version).toBe('0.2.0')
- const apk = await f.inject({ method: 'GET', url: '/app/agent-0.2.0.apk' })
- expect(apk.statusCode).toBe(200)
- expect(apk.headers['content-type']).toBe('application/vnd.android.package-archive')
- expect(apk.headers['content-disposition']).toContain('attachment')
- expect(apk.body).toBe('apk-bytes')
- })
- it('只提供 .apk 文件', async () => {
- 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)
- })
- })
|