131 lines
3.6 KiB
TypeScript
131 lines
3.6 KiB
TypeScript
import anyTest, { TestFn } from 'ava'
|
|
import { promises as fs } from 'fs'
|
|
import http from 'http'
|
|
import { AddressInfo } from 'net'
|
|
import path from 'path'
|
|
import proxyquire from 'proxyquire'
|
|
import { ensureDirectoryExists } from '../app/javascripts/Main/Utils/FileUtils'
|
|
import { initializeStrings } from '../app/javascripts/Main/strings'
|
|
import { createTmpDir } from './testUtils'
|
|
import makeFakePaths from './fakePaths'
|
|
|
|
const test = anyTest as TestFn<{
|
|
server: http.Server
|
|
host: string
|
|
}>
|
|
|
|
const tmpDir = createTmpDir(__filename)
|
|
const FakePaths = makeFakePaths(tmpDir.path)
|
|
|
|
let server: http.Server
|
|
|
|
const { createExtensionsServer, normalizeFilePath } = proxyquire('../app/javascripts/Main/ExtensionsServer', {
|
|
'./paths': {
|
|
Paths: FakePaths,
|
|
'@noCallThru': true,
|
|
},
|
|
electron: {
|
|
app: {
|
|
getPath() {
|
|
return tmpDir.path
|
|
},
|
|
},
|
|
},
|
|
http: {
|
|
createServer(...args: any) {
|
|
server = http.createServer(...args)
|
|
return server
|
|
},
|
|
},
|
|
})
|
|
|
|
const extensionsDir = path.join(tmpDir.path, 'Extensions')
|
|
|
|
initializeStrings('en')
|
|
|
|
const log = console.log
|
|
const error = console.error
|
|
|
|
test.before(async (t) => {
|
|
/** Prevent the extensions server from outputting anything */
|
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
// console.log = () => {}
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
// console.error = () => {}
|
|
|
|
await ensureDirectoryExists(extensionsDir)
|
|
await new Promise((resolve) => {
|
|
createExtensionsServer(resolve)
|
|
t.context.server = server
|
|
server.once('listening', () => {
|
|
const { address, port } = server.address() as AddressInfo
|
|
t.context.host = `http://${address}:${port}/`
|
|
resolve(null)
|
|
})
|
|
})
|
|
})
|
|
|
|
test.after((t): Promise<any> => {
|
|
/** Restore the console's functionality */
|
|
console.log = log
|
|
console.error = error
|
|
|
|
return Promise.all([tmpDir.clean(), new Promise((resolve) => t.context.server.close(resolve))])
|
|
})
|
|
|
|
test('serves the files in the Extensions directory over HTTP', (t) => {
|
|
const data = {
|
|
name: 'Boxes',
|
|
meter: {
|
|
4: 4,
|
|
},
|
|
syncopation: true,
|
|
instruments: ['Drums', 'Bass', 'Vocals', { name: 'Piano', type: 'Electric' }],
|
|
}
|
|
|
|
return fs.writeFile(path.join(extensionsDir, 'file.json'), JSON.stringify(data)).then(
|
|
() =>
|
|
new Promise((resolve) => {
|
|
let serverData = ''
|
|
http.get(t.context.host + 'Extensions/file.json').on('response', (response) => {
|
|
response
|
|
.setEncoding('utf-8')
|
|
.on('data', (chunk) => {
|
|
serverData += chunk
|
|
})
|
|
.on('end', () => {
|
|
t.deepEqual(data, JSON.parse(serverData))
|
|
resolve()
|
|
})
|
|
})
|
|
}),
|
|
)
|
|
})
|
|
|
|
test('does not serve files outside the Extensions directory', async (t) => {
|
|
await new Promise((resolve) => {
|
|
http.get(t.context.host + 'Extensions/../../../package.json').on('response', (response) => {
|
|
t.is(response.statusCode, 500)
|
|
resolve(true)
|
|
})
|
|
})
|
|
})
|
|
|
|
test('returns a 404 for files that are not present', async (t) => {
|
|
await new Promise((resolve) => {
|
|
http.get(t.context.host + 'Extensions/nothing').on('response', (response) => {
|
|
t.is(response.statusCode, 404)
|
|
resolve(true)
|
|
})
|
|
})
|
|
})
|
|
|
|
test('normalizes file paths to always point somewhere in the Extensions directory', (t) => {
|
|
t.is(normalizeFilePath('/Extensions/test/yes', '127.0.0.1'), path.join(tmpDir.path, 'Extensions', 'test', 'yes'))
|
|
t.is(
|
|
normalizeFilePath('/Extensions/../../data/outside/the/extensions/directory'),
|
|
path.join(tmpDir.path, 'Extensions', 'data', 'outside', 'the', 'extensions', 'directory'),
|
|
)
|
|
})
|