1
0
Fork 0
mirror of https://github.com/codex-team/codex.docs.git synced 2025-08-02 20:15:25 +02:00

Transport controller and file model (#42)

* Transport controller and file model

* Use randomBytes intead of pseudoRandomBytes

* Cover all lines with tests

* Update code style

* Update code style

* View for image block

* Fix serving static files

* Mkdir -p for uploads dirs

* Add default secret param

* Add image Tool

* Update src/utils/objects.js

Co-Authored-By: talyguryn <vitalik7tv@yandex.ru>

* Use vars for image tool colors

* Revert var

* Remove --color-gray-border var

* Update src/controllers/transport.js

Co-Authored-By: talyguryn <vitalik7tv@yandex.ru>

* Add mp4 support for Image Tool
This commit is contained in:
George Berezhnoy 2019-03-11 18:44:00 +03:00 committed by GitHub
parent 82a81ce96a
commit 404fb4642e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 1135 additions and 41 deletions

View file

@ -3,7 +3,7 @@ const fs = require('fs');
const path = require('path');
const config = require('../../config');
const Alias = require('../../src/models/alias');
const binaryMD5 = require('../../src/utils/crypto');
const {binaryMD5} = require('../../src/utils/crypto');
const {aliases} = require('../../src/utils/database');
describe('Alias model', () => {

233
test/models/file.js Normal file
View file

@ -0,0 +1,233 @@
const {expect} = require('chai');
const fs = require('fs');
const path = require('path');
const config = require('../../config');
const File = require('../../src/models/file');
const {files} = require('../../src/utils/database');
describe('File model', () => {
after(() => {
const pathToDB = path.resolve(__dirname, '../../', config.database, './files.db');
if (fs.existsSync(pathToDB)) {
fs.unlinkSync(pathToDB);
}
});
it('Working with empty model', async () => {
let file = new File();
expect(file.data).to.be.a('object');
let {data} = file;
expect(data._id).to.be.undefined;
expect(data.name).to.be.undefined;
expect(data.filename).to.be.undefined;
expect(data.path).to.be.undefined;
expect(data.size).to.be.undefined;
expect(data.mimetype).to.be.undefined;
file = new File(null);
data = file.data;
expect(data._id).to.be.undefined;
expect(data.name).to.be.undefined;
expect(data.filename).to.be.undefined;
expect(data.path).to.be.undefined;
expect(data.size).to.be.undefined;
expect(data.mimetype).to.be.undefined;
const initialData = {
_id: 'file_id',
name: 'filename',
filename: 'randomname',
path: '/uploads/randomname',
size: 1024,
mimetype: 'image/png'
};
file = new File(initialData);
const json = file.toJSON();
data = file.data;
expect(data._id).to.equal(initialData._id);
expect(data.name).to.equal(initialData.name);
expect(data.filename).to.equal(initialData.filename);
expect(data.path).to.equal(initialData.path);
expect(data.size).to.equal(initialData.size);
expect(data.mimetype).to.equal(initialData.mimetype);
const update = {
_id: 12345,
name: 'updated filename',
filename: 'updated randomname',
path: '/uploads/updated randomname',
size: 2048,
mimetype: 'image/jpeg'
};
file.data = update;
data = file.data;
expect(data._id).to.equal(initialData._id);
expect(data.name).to.equal(update.name);
expect(data.filename).to.equal(update.filename);
expect(data.path).to.equal(update.path);
expect(data.size).to.equal(update.size);
expect(data.mimetype).to.equal(update.mimetype);
});
it('Saving, updating and deleting model in the database', async () => {
const initialData = {
name: 'filename',
filename: 'randomname',
path: '/uploads/randomname',
size: 1024,
mimetype: 'image/png'
};
const file = new File(initialData);
let savedFile = await file.save();
expect(savedFile._id).not.be.undefined;
expect(savedFile.name).to.equal(initialData.name);
expect(savedFile.filename).to.equal(initialData.filename);
expect(savedFile.path).to.equal(initialData.path);
expect(savedFile.size).to.equal(initialData.size);
expect(savedFile.mimetype).to.equal(initialData.mimetype);
const insertedFile = await files.findOne({_id: file._id});
expect(insertedFile._id).to.equal(file._id);
expect(insertedFile.name).to.equal(file.name);
expect(insertedFile.filename).to.equal(file.filename);
expect(insertedFile.path).to.equal(file.path);
expect(insertedFile.size).to.equal(file.size);
expect(insertedFile.mimetype).to.equal(file.mimetype);
const updateData = {
_id: 12345,
name: 'updated filename',
filename: 'updated randomname',
path: '/uploads/updated randomname',
size: 2048,
mimetype: 'image/jpeg'
};
file.data = updateData;
await file.save();
expect(file._id).to.equal(insertedFile._id);
const updatedFile = await files.findOne({_id: file._id});
expect(updatedFile._id).to.equal(savedFile._id);
expect(updatedFile.name).to.equal(updateData.name);
expect(updatedFile.filename).to.equal(updateData.filename);
expect(updatedFile.path).to.equal(updateData.path);
expect(updatedFile.size).to.equal(updateData.size);
expect(updatedFile.mimetype).to.equal(updateData.mimetype);
await file.destroy();
expect(file._id).to.be.undefined;
const removedFile = await files.findOne({_id: updatedFile._id});
expect(removedFile).to.be.null;
});
it('Static get method', async () => {
const initialData = {
name: 'filename',
filename: 'randomname',
path: '/uploads/randomname',
size: 1024,
mimetype: 'image/png'
};
const file = new File(initialData);
const savedFile = await file.save();
const foundFile = await File.get(savedFile._id);
const {data} = foundFile;
expect(data._id).to.equal(savedFile._id);
expect(data.name).to.equal(savedFile.name);
expect(data.filename).to.equal(savedFile.filename);
expect(data.path).to.equal(savedFile.path);
expect(data.size).to.equal(savedFile.size);
expect(data.mimetype).to.equal(savedFile.mimetype);
await file.destroy();
});
it('Static getByFilename method', async () => {
const initialData = {
name: 'filename',
filename: 'randomname',
path: '/uploads/randomname',
size: 1024,
mimetype: 'image/png'
};
const file = new File(initialData);
const savedFile = await file.save();
const foundFile = await File.getByFilename(savedFile.filename);
const {data} = foundFile;
expect(data._id).to.equal(savedFile._id);
expect(data.name).to.equal(savedFile.name);
expect(data.filename).to.equal(savedFile.filename);
expect(data.path).to.equal(savedFile.path);
expect(data.size).to.equal(savedFile.size);
expect(data.mimetype).to.equal(savedFile.mimetype);
await file.destroy();
});
it('Static getAll method', async () => {
const filesToSave = [
new File({
name: 'filename1',
filename: 'randomname1',
path: '/uploads/randomname1',
size: 1024,
mimetype: 'image/png'
}),
new File({
name: 'filename2',
filename: 'randomname2',
path: '/uploads/randomname2',
size: 2048,
mimetype: 'image/jpeg'
}),
];
const savedFiles = await Promise.all(filesToSave.map(file => file.save()));
const foundFiles = await File.getAll({_id: {$in: savedFiles.map(file => file._id)}});
expect(foundFiles.length).to.equal(2);
foundFiles.forEach((file, i) => {
expect(file.name).to.equal(filesToSave[i].name);
expect(file.filename).to.equal(filesToSave[i].filename);
expect(file.path).to.equal(filesToSave[i].path);
expect(file.size).to.equal(filesToSave[i].size);
expect(file.mimetype).to.equal(filesToSave[i].mimetype);
});
});
});

3
test/rest/test_file.json Normal file
View file

@ -0,0 +1,3 @@
{
"Hello": "world"
}

BIN
test/rest/test_image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

259
test/rest/transport.js Normal file
View file

@ -0,0 +1,259 @@
const fs = require('fs');
const path = require('path');
const fileType = require('file-type');
const chai = require('chai');
const chaiHTTP = require('chai-http');
const rimraf = require('rimraf');
const {expect} = chai;
const {app} = require('../../bin/www');
const model = require('../../src/models/file');
const config = require('../../config');
chai.use(chaiHTTP);
describe('Transport routes: ', () => {
let agent;
before(async () => {
agent = chai.request.agent(app);
if (!fs.existsSync('./' + config.uploads)) {
fs.mkdirSync('./' + config.uploads);
}
});
after(async () => {
const pathToDB = path.resolve(__dirname, '../../', config.database, './files.db');
if (fs.existsSync(pathToDB)) {
fs.unlinkSync(pathToDB);
}
if (fs.existsSync('./' + config.uploads)) {
rimraf.sync('./' + config.uploads);
}
});
it('Uploading an image', async () => {
const name = 'test_image.png';
const image = fs.readFileSync(path.resolve(`./test/rest/${name}`));
const res = await agent
.post('/api/transport/image')
.attach('image', image, name);
expect(res).to.have.status(200);
expect(res).to.be.json;
const { body } = res;
const file = await model.get(body._id);
expect(body.success).to.equal(1);
expect(file._id).to.equal(body._id);
expect(file.name).to.equal(name);
expect(file.filename).to.equal(body.filename);
expect(file.path).to.equal(body.path);
expect(file.mimetype).to.equal(fileType(image).mime);
expect(file.size).to.equal(image.byteLength);
const getRes = await agent
.get(file.path);
expect(getRes).to.have.status(200);
expect(getRes).to.have.header('content-type', fileType(image).mime);
});
it('Uploading an image with map option', async () => {
const name = 'test_image.png';
const image = fs.readFileSync(path.resolve(`./test/rest/${name}`));
const res = await agent
.post('/api/transport/image')
.attach('image', image, name)
.field('map', JSON.stringify({_id: '_id', path: 'file:url', size: 'file:size', name: 'file:name'}));
expect(res).to.have.status(200);
expect(res).to.be.json;
const { body } = res;
const file = await model.get(body._id);
expect(body.success).to.equal(1);
expect(file.name).to.equal(body.file.name);
expect(file.path).to.equal(body.file.url);
expect(file.size).to.equal(body.file.size);
});
it('Uploading a file', async () => {
const name = 'test_file.json';
const json = fs.readFileSync(path.resolve(`./test/rest/${name}`));
const res = await agent
.post('/api/transport/file')
.attach('file', json, name);
expect(res).to.have.status(200);
expect(res).to.be.json;
const { body } = res;
const file = await model.get(body._id);
expect(body.success).to.equal(1);
expect(file._id).to.equal(body._id);
expect(file.name).to.equal(name);
expect(file.filename).to.equal(body.filename);
expect(file.path).to.equal(body.path);
expect(file.size).to.equal(json.byteLength);
const getRes = await agent
.get(file.path);
expect(getRes).to.have.status(200);
expect(getRes).to.have.header('content-type', new RegExp(`^${file.mimetype}`));
});
it('Uploading a file with map option', async () => {
const name = 'test_file.json';
const json = fs.readFileSync(path.resolve(`./test/rest/${name}`));
const res = await agent
.post('/api/transport/file')
.attach('file', json, name)
.field('map', JSON.stringify({_id: '_id', path: 'file:url', size: 'file:size', name: 'file:name'}));
expect(res).to.have.status(200);
expect(res).to.be.json;
const { body } = res;
const file = await model.get(body._id);
expect(body.success).to.equal(1);
expect(file.name).to.equal(body.file.name);
expect(file.path).to.equal(body.file.url);
expect(file.size).to.equal(body.file.size);
});
it('Send file URL to fetch', async () => {
const url = 'https://codex.so/public/app/img/codex-logo.svg';
const res = await agent
.post('/api/transport/fetch')
.field('url', url);
expect(res).to.have.status(200);
expect(res).to.be.json;
const { body } = res;
const file = await model.get(body._id);
expect(body.success).to.equal(1);
expect(file._id).to.equal(body._id);
expect(file.name).to.equal(body.name);
expect(file.filename).to.equal(body.filename);
expect(file.path).to.equal(body.path);
expect(file.size).to.equal(body.size);
const getRes = await agent
.get(file.path);
expect(getRes).to.have.status(200);
expect(getRes).to.have.header('content-type', file.mimetype);
});
it('Send an file URL to fetch with map option', async () => {
const url = 'https://codex.so/public/app/img/codex-logo.svg';
const res = await agent
.post('/api/transport/fetch')
.field('url', url)
.field('map', JSON.stringify({_id: '_id', path: 'file:url', size: 'file:size', name: 'file:name'}));
expect(res).to.have.status(200);
expect(res).to.be.json;
const { body } = res;
const file = await model.get(body._id);
expect(body.success).to.equal(1);
expect(file.name).to.equal(body.file.name);
expect(file.path).to.equal(body.file.url);
expect(file.size).to.equal(body.file.size);
});
it('Negative tests for file uploading', async () => {
let res = await agent
.post('/api/transport/file')
.send();
let {body} = res;
expect(res).to.have.status(400);
expect(body.success).to.equal(0);
const name = 'test_file.json';
const json = fs.readFileSync(path.resolve(`./test/rest/${name}`));
res = await agent
.post('/api/transport/file')
.attach('file', json, name)
.field('map', '{unvalid_json)');
body = res.body;
expect(res).to.have.status(500);
expect(body.success).to.equal(0);
});
it('Negative tests for image uploading', async () => {
let res = await agent
.post('/api/transport/image')
.send();
let {body} = res;
expect(res).to.have.status(400);
expect(body.success).to.equal(0);
let name = 'test_file.json';
const json = fs.readFileSync(path.resolve(`./test/rest/${name}`));
res = await agent
.post('/api/transport/image')
.attach('image', json, name);
expect(res).to.have.status(400);
name = 'test_image.png';
const image = fs.readFileSync(path.resolve(`./test/rest/${name}`));
res = await agent
.post('/api/transport/image')
.attach('image', image, name)
.field('map', '{unvalid_json)');
body = res.body;
expect(res).to.have.status(500);
expect(body.success).to.equal(0);
});
it('Negative tests for file fetching', async () => {
let res = await agent
.post('/api/transport/fetch')
.send();
let {body} = res;
expect(res).to.have.status(400);
expect(body.success).to.equal(0);
const url = 'https://invalidurl';
res = await agent
.post('/api/transport/fetch')
.field('url', url);
body = res.body;
expect(res).to.have.status(500);
expect(body.success).to.equal(0);
}).timeout(50000);
});