Jonatan Nilsson
68eef3a6b6
Removed large amount of dependencies. Added vips support and automatically resizing based on any criteria. Faster and leaner. Added ability to fetch listing of files in folders.
386 lines
12 KiB
JavaScript
386 lines
12 KiB
JavaScript
import sharp from 'sharp-lite'
|
|
import { Eltro as t, assert} from 'eltro'
|
|
import fs from 'fs/promises'
|
|
import { fileURLToPath } from 'url'
|
|
import path from 'path'
|
|
|
|
import { server, resetLog } from '../helper.server.mjs'
|
|
import Client from '../helper.client.mjs'
|
|
import encode from '../../api/jwt/encode.mjs'
|
|
|
|
let __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
|
|
function resolve(file) {
|
|
return path.resolve(path.join(__dirname, file))
|
|
}
|
|
|
|
t.describe('Media (API)', () => {
|
|
const client = new Client()
|
|
const secret = 'asdf1234'
|
|
let testFiles = []
|
|
|
|
t.after(function() {
|
|
return Promise.all(testFiles.map(function(file) {
|
|
return fs.unlink(resolve(`../../public/${file}`)).catch(function() {})
|
|
}))
|
|
})
|
|
|
|
t.timeout(10000).describe('POST /media', function temp() {
|
|
t.test('should require authentication', async () => {
|
|
resetLog()
|
|
assert.strictEqual(server.log.error.callCount, 0)
|
|
assert.strictEqual(server.log.warn.callCount, 0)
|
|
let err = await assert.isRejected(
|
|
client.upload('/media',
|
|
resolve('test.png')
|
|
)
|
|
)
|
|
|
|
assert.strictEqual(err.status, 422)
|
|
assert.match(err.message, /[Tt]oken/)
|
|
assert.match(err.message, /[Mm]issing/)
|
|
|
|
assert.strictEqual(server.log.error.callCount, 0)
|
|
assert.strictEqual(server.log.warn.callCount, 2)
|
|
assert.strictEqual(typeof(server.log.warn.firstCall[0]), 'string')
|
|
assert.match(server.log.warn.firstCall[0], /[Tt]oken/)
|
|
assert.match(server.log.warn.firstCall[0], /[Mm]issing/)
|
|
})
|
|
|
|
t.test('should verify token correctly', async () => {
|
|
const assertToken = 'asdf.asdf.asdf'
|
|
resetLog()
|
|
assert.strictEqual(server.log.error.callCount, 0)
|
|
assert.strictEqual(server.log.warn.callCount, 0)
|
|
assert.strictEqual(server.log.info.callCount, 0)
|
|
|
|
let err = await assert.isRejected(
|
|
client.upload('/media?token=' + assertToken,
|
|
resolve('test.png')
|
|
)
|
|
)
|
|
|
|
assert.strictEqual(err.status, 422)
|
|
assert.match(err.message, /[Tt]oken/)
|
|
assert.match(err.message, /[Ii]nvalid/)
|
|
|
|
assert.strictEqual(server.log.error.callCount, 1)
|
|
assert.strictEqual(server.log.warn.callCount, 2)
|
|
assert.strictEqual(typeof(server.log.warn.firstCall[0]), 'string')
|
|
assert.match(server.log.warn.firstCall[0], /[Tt]oken/)
|
|
assert.match(server.log.warn.firstCall[0], /[Ii]nvalid/)
|
|
assert.ok(server.log.error.lastCall[0] instanceof Error)
|
|
assert.match(server.log.error.lastCall[1], new RegExp(assertToken))
|
|
})
|
|
|
|
t.test('should upload file and create file', async () => {
|
|
let token = encode(null, { iss: 'development' }, secret)
|
|
|
|
let data = await assert.isFulfilled(
|
|
client.upload(
|
|
`/media?token=${token}`,
|
|
resolve('test.png')
|
|
)
|
|
)
|
|
|
|
assert.ok(data)
|
|
assert.ok(data.filename)
|
|
assert.ok(data.path)
|
|
|
|
testFiles.push(data.path)
|
|
|
|
let stats = await Promise.all([
|
|
fs.stat(resolve('test.png')),
|
|
fs.stat(resolve(`../../public/${data.path}`)),
|
|
])
|
|
assert.strictEqual(stats[0].size, stats[1].size)
|
|
|
|
let img = await sharp(resolve(`../../public/${data.path}`)).metadata()
|
|
assert.strictEqual(img.width, 600)
|
|
assert.strictEqual(img.height, 700)
|
|
assert.strictEqual(img.format, 'png')
|
|
})
|
|
})
|
|
|
|
t.timeout(10000).describe('POST /media/resize', function temp() {
|
|
t.test('should require authentication', async () => {
|
|
resetLog()
|
|
assert.strictEqual(server.log.error.callCount, 0)
|
|
assert.strictEqual(server.log.warn.callCount, 0)
|
|
let err = await assert.isRejected(
|
|
client.upload('/media/resize',
|
|
resolve('test.png')
|
|
)
|
|
)
|
|
|
|
assert.strictEqual(err.status, 422)
|
|
assert.match(err.message, /[Tt]oken/)
|
|
assert.match(err.message, /[Mm]issing/)
|
|
|
|
assert.strictEqual(server.log.error.callCount, 0)
|
|
assert.strictEqual(server.log.warn.callCount, 2)
|
|
assert.strictEqual(typeof(server.log.warn.firstCall[0]), 'string')
|
|
assert.match(server.log.warn.firstCall[0], /[Tt]oken/)
|
|
assert.match(server.log.warn.firstCall[0], /[Mm]issing/)
|
|
})
|
|
|
|
t.test('should verify token correctly', async () => {
|
|
const assertToken = 'asdf.asdf.asdf'
|
|
resetLog()
|
|
assert.strictEqual(server.log.error.callCount, 0)
|
|
assert.strictEqual(server.log.warn.callCount, 0)
|
|
assert.strictEqual(server.log.info.callCount, 0)
|
|
|
|
let err = await assert.isRejected(
|
|
client.upload('/media/resize?token=' + assertToken,
|
|
resolve('test.png')
|
|
)
|
|
)
|
|
|
|
assert.strictEqual(err.status, 422)
|
|
assert.match(err.message, /[Tt]oken/)
|
|
assert.match(err.message, /[Ii]nvalid/)
|
|
|
|
assert.strictEqual(server.log.error.callCount, 1)
|
|
assert.strictEqual(server.log.warn.callCount, 2)
|
|
assert.strictEqual(typeof(server.log.warn.firstCall[0]), 'string')
|
|
assert.match(server.log.warn.firstCall[0], /[Tt]oken/)
|
|
assert.match(server.log.warn.firstCall[0], /[Ii]nvalid/)
|
|
assert.ok(server.log.error.lastCall[0] instanceof Error)
|
|
assert.match(server.log.error.lastCall[1], new RegExp(assertToken))
|
|
})
|
|
|
|
t.test('should upload file and create file', async () => {
|
|
let token = encode(null, { iss: 'development' }, secret)
|
|
|
|
let data = await assert.isFulfilled(
|
|
client.upload(
|
|
`/media/resize?token=${token}`,
|
|
resolve('test.png'),
|
|
'POST',
|
|
{ }
|
|
)
|
|
)
|
|
|
|
assert.ok(data)
|
|
assert.ok(data.original)
|
|
assert.ok(data.original.filename)
|
|
assert.ok(data.original.path)
|
|
|
|
testFiles.push(data.original.path)
|
|
|
|
let stats = await Promise.all([
|
|
fs.stat(resolve('test.png')),
|
|
fs.stat(resolve(`../../public/${data.original.path}`)),
|
|
])
|
|
assert.strictEqual(stats[0].size, stats[1].size)
|
|
|
|
let img = await sharp(resolve(`../../public/${data.original.path}`)).metadata()
|
|
assert.strictEqual(img.width, 600)
|
|
assert.strictEqual(img.height, 700)
|
|
assert.strictEqual(img.format, 'png')
|
|
})
|
|
|
|
t.test('should upload file and create multiple sizes for file', async () => {
|
|
let token = encode(null, { iss: 'development' }, secret)
|
|
|
|
let data = await assert.isFulfilled(
|
|
client.upload(
|
|
`/media/resize?token=${token}`,
|
|
resolve('test.png'),
|
|
'POST',
|
|
{
|
|
test1: {
|
|
format: 'jpeg',
|
|
resize: {
|
|
width: 300,
|
|
},
|
|
jpeg: {
|
|
quality: 80,
|
|
mozjpeg: true,
|
|
}
|
|
},
|
|
test2: {
|
|
format: 'png',
|
|
resize: {
|
|
width: 150,
|
|
},
|
|
png: {
|
|
compressionLevel: 9,
|
|
}
|
|
},
|
|
}
|
|
)
|
|
)
|
|
|
|
assert.ok(data)
|
|
assert.ok(data.original)
|
|
assert.ok(data.original.filename)
|
|
assert.ok(data.original.path)
|
|
assert.ok(data.test1.filename)
|
|
assert.ok(data.test1.path)
|
|
assert.ok(data.test2.filename)
|
|
assert.ok(data.test2.path)
|
|
|
|
|
|
testFiles.push(data.original.path)
|
|
testFiles.push(data.test1.path)
|
|
testFiles.push(data.test2.path)
|
|
|
|
let stats = await Promise.all([
|
|
fs.stat(resolve('test.png')),
|
|
fs.stat(resolve(`../../public/${data.original.path}`)),
|
|
])
|
|
assert.strictEqual(stats[0].size, stats[1].size)
|
|
|
|
let img = await sharp(resolve(`../../public/${data.original.path}`)).metadata()
|
|
assert.strictEqual(img.width, 600)
|
|
assert.strictEqual(img.height, 700)
|
|
assert.strictEqual(img.format, 'png')
|
|
|
|
img = await sharp(resolve(`../../public/${data.test1.path}`)).metadata()
|
|
assert.strictEqual(img.width, 300)
|
|
assert.strictEqual(img.height, 350)
|
|
assert.strictEqual(img.format, 'jpeg')
|
|
|
|
img = await sharp(resolve(`../../public/${data.test2.path}`)).metadata()
|
|
assert.strictEqual(img.width, 150)
|
|
assert.strictEqual(img.height, 175)
|
|
assert.strictEqual(img.format, 'png')
|
|
})
|
|
|
|
|
|
t.test('should upload file and support base64 output', async () => {
|
|
let token = encode(null, { iss: 'development' }, secret)
|
|
|
|
let data = await assert.isFulfilled(
|
|
client.upload(
|
|
`/media/resize?token=${token}`,
|
|
resolve('test.png'),
|
|
'POST',
|
|
{
|
|
outtest: {
|
|
out: 'base64',
|
|
format: 'jpeg',
|
|
resize: {
|
|
width: 10,
|
|
},
|
|
jpeg: {
|
|
quality: 80,
|
|
mozjpeg: true,
|
|
}
|
|
},
|
|
}
|
|
)
|
|
)
|
|
|
|
assert.ok(data)
|
|
assert.ok(data.original)
|
|
assert.ok(data.original.filename)
|
|
assert.ok(data.original.path)
|
|
assert.ok(data.outtest.base64)
|
|
|
|
|
|
testFiles.push(data.original.path)
|
|
|
|
let stats = await Promise.all([
|
|
fs.stat(resolve('test.png')),
|
|
fs.stat(resolve(`../../public/${data.original.path}`)),
|
|
])
|
|
assert.strictEqual(stats[0].size, stats[1].size)
|
|
|
|
let img = await sharp(resolve(`../../public/${data.original.path}`)).metadata()
|
|
assert.strictEqual(img.width, 600)
|
|
assert.strictEqual(img.height, 700)
|
|
assert.strictEqual(img.format, 'png')
|
|
|
|
let bufferBase64 = Buffer.from(data.outtest.base64.slice(data.outtest.base64.indexOf(',')), 'base64')
|
|
|
|
img = await sharp(bufferBase64).metadata()
|
|
assert.strictEqual(img.width, 10)
|
|
assert.strictEqual(img.height, 12)
|
|
assert.strictEqual(img.format, 'jpeg')
|
|
})
|
|
})
|
|
|
|
t.describe('GET /media', function() {
|
|
t.test('should require authentication', async () => {
|
|
resetLog()
|
|
assert.strictEqual(server.log.error.callCount, 0)
|
|
assert.strictEqual(server.log.warn.callCount, 0)
|
|
let err = await assert.isRejected(client.get('/media'))
|
|
|
|
assert.strictEqual(err.status, 422)
|
|
assert.match(err.message, /[Tt]oken/)
|
|
assert.match(err.message, /[Mm]issing/)
|
|
|
|
assert.strictEqual(server.log.error.callCount, 0)
|
|
assert.strictEqual(server.log.warn.callCount, 2)
|
|
assert.strictEqual(typeof(server.log.warn.firstCall[0]), 'string')
|
|
assert.match(server.log.warn.firstCall[0], /[Tt]oken/)
|
|
assert.match(server.log.warn.firstCall[0], /[Mm]issing/)
|
|
})
|
|
|
|
t.test('should verify token correctly', async () => {
|
|
const assertToken = 'asdf.asdf.asdf'
|
|
resetLog()
|
|
assert.strictEqual(server.log.error.callCount, 0)
|
|
assert.strictEqual(server.log.warn.callCount, 0)
|
|
assert.strictEqual(server.log.info.callCount, 0)
|
|
|
|
let err = await assert.isRejected(client.get('/media?token=' + assertToken))
|
|
|
|
assert.strictEqual(err.status, 422)
|
|
assert.match(err.message, /[Tt]oken/)
|
|
assert.match(err.message, /[Ii]nvalid/)
|
|
|
|
assert.strictEqual(server.log.error.callCount, 1)
|
|
assert.strictEqual(server.log.warn.callCount, 2)
|
|
assert.strictEqual(typeof(server.log.warn.firstCall[0]), 'string')
|
|
assert.match(server.log.warn.firstCall[0], /[Tt]oken/)
|
|
assert.match(server.log.warn.firstCall[0], /[Ii]nvalid/)
|
|
assert.ok(server.log.error.lastCall[0] instanceof Error)
|
|
assert.match(server.log.error.lastCall[1], new RegExp(assertToken))
|
|
})
|
|
|
|
t.test('should return list of files in specified folder', async () => {
|
|
let token = encode(null, { iss: 'development' }, secret)
|
|
|
|
let data = await client.get('/media?token=' + token)
|
|
|
|
assert.ok(data.length)
|
|
let found = false
|
|
for (let file of data) {
|
|
if (file.name === '.gitkeep' && file.size === 0) {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
assert.ok(found)
|
|
})
|
|
})
|
|
|
|
t.describe('GET /media/:site', function() {
|
|
t.test('should give 404 on invalid sites', async () => {
|
|
let err = await assert.isRejected(client.get('/media/development'))
|
|
|
|
assert.strictEqual(err.status, 404)
|
|
|
|
err = await assert.isRejected(client.get('/media/nonexisting'))
|
|
|
|
assert.strictEqual(err.status, 404)
|
|
|
|
err = await assert.isRejected(client.get('/media/blabla'))
|
|
|
|
assert.strictEqual(err.status, 404)
|
|
})
|
|
|
|
t.test('should otherwise return list of files for a public site', async () => {
|
|
let files = await client.get('/media/existing')
|
|
assert.strictEqual(files[0].name, '20220105_101610_test1.jpg')
|
|
assert.strictEqual(files[0].size, 15079)
|
|
assert.strictEqual(files[1].name, '20220105_101610_test2.png')
|
|
assert.strictEqual(files[1].size, 31705)
|
|
})
|
|
})
|
|
})
|