// createApp: the one entry both stortron (index.js) and the phone's worklet use.
import test from 'brittle'
import http from 'bare-http1'
import fs from 'bare-fs'
import os from 'bare-os'
import path from 'bare-path'
import EventEmitter from 'bare-events'
import { createApp } from '../lib/app.js'
import { buildAssets } from '../scripts/gen-assets.js'
import { ASSET_FILES } from '../lib/asset-files.js'
class FakeDiscovery extends EventEmitter {
constructor () { super(); this.available = true; this.reason = '' }
start () {}
stop () {}
}
function get (port, p) {
return new Promise((resolve, reject) => {
http.request({ host: '127.0.0.1', port, path: p }, (res) => {
const chunks = []
res.on('data', (d) => chunks.push(d))
res.on('end', () => resolve({ status: res.statusCode, type: res.headers['content-type'], body: Buffer.concat(chunks) }))
}).on('error', reject).end()
})
}
const tmp = () => path.join(os.tmpdir(), 'cthuloid-app-test-' + Date.now() + '-' + Math.random().toString(36).slice(2))
test('createApp starts, serves state, stops', async (t) => {
const app = createApp({ configDir: tmp(), port: 0, discovery: new FakeDiscovery() })
const { port } = await app.listen()
const r = await get(port, '/api/state')
t.is(r.status, 200)
t.is(JSON.parse(r.body).connected, false)
await app.close()
})
test('createApp works with no discovery at all (units added by hand)', async (t) => {
const app = createApp({ configDir: tmp(), port: 0 })
const { port } = await app.listen()
const st = JSON.parse((await get(port, '/api/state')).body)
t.is(st.discovery.available, true, 'no "discovery broken" banner')
await app.close()
})
test('generated assets are exactly the files in static/', (t) => {
const assets = buildAssets()
const dir = path.join(path.dirname(new URL(import.meta.url).pathname), '..', 'static')
for (const [url, [file, type]] of Object.entries(ASSET_FILES)) {
t.is(assets[url].type, type, url + ' type')
t.is(assets[url].body, fs.readFileSync(path.join(dir, file), 'utf8'), url + ' body')
}
})
test('embedded assets are served byte-identical to the disk ones', async (t) => {
const disk = createApp({ configDir: tmp(), port: 0 })
const packed = createApp({ configDir: tmp(), port: 0, assets: buildAssets() })
const a = (await disk.listen()).port
const b = (await packed.listen()).port
for (const url of Object.keys(ASSET_FILES)) {
const x = await get(a, url)
const y = await get(b, url)
t.is(y.status, 200, url)
t.is(y.type, x.type, url + ' type')
t.ok(Buffer.compare(x.body, y.body) === 0, url + ' bytes')
}
await disk.close()
await packed.close()
})