mirror of https://github.com/01-edu/public.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
4.8 KiB
197 lines
4.8 KiB
import { once } from 'node:events' |
|
import { spawn } from 'node:child_process' |
|
import { mkdir, writeFile, chmod } from 'fs/promises' |
|
import { join } from 'path' |
|
import fs from 'node:fs/promises' |
|
|
|
export const tests = [] |
|
const fetch = _fetch // to redefine the real fetch |
|
|
|
const port = 5000 |
|
|
|
export const setup = async ({ randStr }) => { |
|
const dir = '.' |
|
|
|
await mkdir(`${dir}/guests`, { recursive: true }) |
|
|
|
const randomName = randStr() |
|
|
|
const createFilesIn = ({ files, dirPath }) => { |
|
Promise.all( |
|
files.map(([fileName, content]) => |
|
writeFile(`${dirPath}/${fileName}`, JSON.stringify(content), { |
|
flag: 'wx', |
|
}), |
|
), |
|
).catch(reason => console.log(reason)) |
|
|
|
return true |
|
} |
|
|
|
const sendRequest = async (path, options) => { |
|
const response = await fetch(`http://localhost:${port}${path}`, options) |
|
const { status } = response |
|
const headers = Object.fromEntries(response.headers) |
|
let body = '' |
|
try { |
|
body = await response.json() |
|
} catch (err) { |
|
body = err |
|
} |
|
return { status, body, headers } |
|
} |
|
|
|
const startServer = async path => { |
|
const server = spawn('node', [`${path}`]) |
|
const message = await Promise.race([ |
|
once(server.stdout, 'data'), |
|
Promise.race([ |
|
once(server.stderr, 'data').then(String).then(Error), |
|
once(server, 'error'), |
|
]).then(result => Promise.reject(result)), |
|
]) |
|
return { server, message } |
|
} |
|
|
|
return { tmpPath: dir, createFilesIn, randomName, sendRequest, startServer } |
|
} |
|
|
|
const testServerRunning = async ({ path, ctx }) => { |
|
const { server, message } = await ctx.startServer(path) |
|
server.kill() |
|
return message[0].toString().includes(port) |
|
} |
|
|
|
const testRightStatusCode = async ({ path, ctx, randStr }) => { |
|
const { server } = await ctx.startServer(path) |
|
const { status } = await ctx.sendRequest(`/${ctx.randomName}`, { |
|
method: 'POST', |
|
headers: { |
|
'content-type': 'application/json', |
|
}, |
|
body: randStr(), |
|
}) |
|
server.kill() |
|
|
|
if (status != 201) return false |
|
return true |
|
} |
|
|
|
const testRightContentType = async ({ path, ctx, randStr }) => { |
|
const { server } = await ctx.startServer(path) |
|
const { headers } = await ctx.sendRequest(`/${ctx.randomName}`, { |
|
method: 'POST', |
|
headers: { |
|
'content-type': 'application/json', |
|
}, |
|
body: randStr(), |
|
}) |
|
server.kill() |
|
if (headers['content-type'] != 'application/json') return false |
|
return true |
|
} |
|
|
|
const testServerFail = async ({ path, eq, ctx, randStr }) => { |
|
const { server } = await ctx.startServer(path) |
|
await chmod(`${ctx.tmpPath}/guests`, 0).catch(reason => console.log(reason)) |
|
const { status, body, headers } = await ctx.sendRequest( |
|
`/${ctx.randomName}`, |
|
{ |
|
method: 'POST', |
|
body: randStr(), |
|
}, |
|
) |
|
await chmod(`${ctx.tmpPath}/guests`, 0o777) |
|
server.kill() |
|
return eq( |
|
{ |
|
status: status, |
|
body: body, |
|
'content-type': headers['content-type'], |
|
}, |
|
{ |
|
status: 500, |
|
body: { error: 'server failed' }, |
|
'content-type': 'application/json', |
|
}, |
|
) |
|
} |
|
|
|
const testFileCreated = async ({ path, ctx, randStr }) => { |
|
const { server } = await ctx.startServer(path) |
|
const randomName = randStr() |
|
await ctx.sendRequest(`/${randomName}`, { |
|
body: randStr(), |
|
method: 'POST', |
|
}) |
|
const dirName = 'guests' |
|
const dirPath = join(ctx.tmpPath, dirName) |
|
let accessWorked = true |
|
server.kill() |
|
await fs |
|
.access(`${dirPath}/${randomName}.json`, fs.constants.F_OK) |
|
.catch(reason => { |
|
accessWorked = false |
|
console.log(reason) |
|
}) |
|
return accessWorked |
|
} |
|
|
|
const testFileContent = async ({ path, ctx, randStr }) => { |
|
const { server } = await ctx.startServer(path) |
|
const randomName = randStr() |
|
const body = randStr() |
|
await ctx.sendRequest(`/${randomName}`, { |
|
body: body, |
|
method: 'POST', |
|
}) |
|
const dirName = 'guests' |
|
const dirPath = join(ctx.tmpPath, dirName) |
|
server.kill() |
|
let content = '' |
|
await fs |
|
.readFile(`./${dirPath}/${randomName}.json`, 'utf8', (err, data) => { |
|
if (err) { |
|
console.error(err) |
|
return 'error when reading file' |
|
} |
|
return data |
|
}) |
|
.then(data => { |
|
if (data === 'error when reading file') return |
|
content = data |
|
}) |
|
return body === content |
|
} |
|
|
|
const testBodyOnSuccess = async ({ path, ctx, eq, randStr }) => { |
|
const { server } = await ctx.startServer(path) |
|
const randomBody = { message: randStr() } |
|
const { body } = await ctx.sendRequest(`/${ctx.randomName}`, { |
|
method: 'POST', |
|
headers: { |
|
'content-type': 'application/json', |
|
}, |
|
body: JSON.stringify(randomBody), |
|
}) |
|
server.kill() |
|
return eq( |
|
{ |
|
body: body, |
|
}, |
|
{ |
|
body: randomBody, |
|
}, |
|
) |
|
} |
|
tests.push( |
|
testServerRunning, |
|
testRightStatusCode, |
|
testRightContentType, |
|
testBodyOnSuccess, |
|
testFileCreated, |
|
testFileContent, |
|
testServerFail, |
|
) |
|
|
|
Object.freeze(tests)
|
|
|