mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 02:35:49 +00:00
feature: convert to ESM
This commit is contained in:
parent
770a0812aa
commit
3e565109b3
26 changed files with 242 additions and 291 deletions
458
server/route.spec.mjs
Normal file
458
server/route.spec.mjs
Normal file
|
|
@ -0,0 +1,458 @@
|
|||
import path, {dirname} from 'node:path';
|
||||
import {fileURLToPath} from 'node:url';
|
||||
import {Readable} from 'node:stream';
|
||||
import fs from 'node:fs';
|
||||
import tryToCatch from 'try-to-catch';
|
||||
import {test, stub} from 'supertape';
|
||||
import serveOnce from 'serve-once';
|
||||
import cloudcmd from './cloudcmd.mjs';
|
||||
import {_getReadDir} from './route.js';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
const fixtureDir = path.join(__dirname, '..', 'test', 'fixture');
|
||||
const {createConfigManager} = cloudcmd;
|
||||
|
||||
const defaultConfig = {
|
||||
auth: false,
|
||||
dropbox: false,
|
||||
};
|
||||
|
||||
const {request} = serveOnce(cloudcmd, {
|
||||
config: defaultConfig,
|
||||
});
|
||||
|
||||
const {stringify} = JSON;
|
||||
const {assign} = Object;
|
||||
|
||||
test('cloudcmd: route: buttons: no console', async (t) => {
|
||||
const options = {
|
||||
config: {
|
||||
console: false,
|
||||
},
|
||||
};
|
||||
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.match(body, 'icon-console none', 'should hide console');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: buttons: console', async (t) => {
|
||||
const config = {
|
||||
console: true,
|
||||
};
|
||||
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.notOk(/icon-console none/.test(body), 'should not hide console');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: buttons: no config', async (t) => {
|
||||
const config = {
|
||||
configDialog: false,
|
||||
};
|
||||
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.match(body, 'icon-config none', 'should hide config');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: buttons: no contact', async (t) => {
|
||||
const config = {
|
||||
contact: false,
|
||||
};
|
||||
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.match(body, 'icon-contact none', 'should hide contact');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: buttons: one file panel: move', async (t) => {
|
||||
const config = {
|
||||
oneFilePanel: true,
|
||||
};
|
||||
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.match(body, 'icon-move none', 'should hide move button');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: buttons: one file panel: copy', async (t) => {
|
||||
const config = {
|
||||
oneFilePanel: true,
|
||||
};
|
||||
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.match(body, 'icon-copy none', 'should hide copy button');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: keys panel: hide', async (t) => {
|
||||
const config = {
|
||||
keysPanel: false,
|
||||
};
|
||||
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.match(body, 'keyspanel hidden', 'should hide keyspanel');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: keys panel', async (t) => {
|
||||
const config = {
|
||||
keysPanel: true,
|
||||
};
|
||||
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.notOk(/keyspanel hidden/.test(body), 'should show keyspanel');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: symlink', async (t) => {
|
||||
const emptyDir = path.join(fixtureDir, 'empty-dir');
|
||||
const root = fixtureDir;
|
||||
const symlink = path.join(root, 'symlink-dir');
|
||||
|
||||
const config = {
|
||||
root,
|
||||
};
|
||||
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
fs.symlinkSync(emptyDir, symlink);
|
||||
|
||||
const {body} = await request.get('/fs/symlink-dir', {
|
||||
options,
|
||||
});
|
||||
|
||||
fs.unlinkSync(symlink);
|
||||
|
||||
t.ok(body.length, 'should return html document');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: not found', async (t) => {
|
||||
const root = fixtureDir;
|
||||
const config = {
|
||||
root,
|
||||
};
|
||||
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
const {body} = await request.get('/fs/file-not-found', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.match(body, 'ENOENT: no such file or directory', 'should return error');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: sendIndex: encode', async (t) => {
|
||||
const name = '"><svg onload=alert(3);>';
|
||||
const nameEncoded = '"><svg onload=alert(3);>';
|
||||
const path = '/';
|
||||
|
||||
const files = [{
|
||||
name,
|
||||
}];
|
||||
|
||||
const stream = Readable.from(stringify({
|
||||
path,
|
||||
files,
|
||||
}));
|
||||
|
||||
assign(stream, {
|
||||
path,
|
||||
files,
|
||||
type: 'directory',
|
||||
});
|
||||
|
||||
const read = stub().resolves(stream);
|
||||
|
||||
cloudcmd.depStore('win32', {
|
||||
read,
|
||||
});
|
||||
|
||||
const {request} = serveOnce(cloudcmd, {
|
||||
configManager: createConfigManager(),
|
||||
});
|
||||
|
||||
const {body} = await request.get('/');
|
||||
|
||||
cloudcmd.depStore();
|
||||
|
||||
t.match(body, nameEncoded, 'should encode name');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: sendIndex: encode: not encoded', async (t) => {
|
||||
const name = '"><svg onload=alert(3);>';
|
||||
const path = '/';
|
||||
const files = [{
|
||||
name,
|
||||
}];
|
||||
|
||||
const stream = Readable.from(stringify({
|
||||
path,
|
||||
files,
|
||||
}));
|
||||
|
||||
assign(stream, {
|
||||
path,
|
||||
files,
|
||||
type: 'directory',
|
||||
});
|
||||
|
||||
const read = stub().resolves(stream);
|
||||
|
||||
cloudcmd.depStore('win32', {
|
||||
read,
|
||||
});
|
||||
|
||||
const {request} = serveOnce(cloudcmd);
|
||||
const {body} = await request.get('/');
|
||||
|
||||
cloudcmd.depStore();
|
||||
|
||||
t.notOk(body.includes(name), 'should not put not encoded name');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: sendIndex: ddos: render', async (t) => {
|
||||
const name = `$$$'"`;
|
||||
const path = '/';
|
||||
const files = [{
|
||||
name,
|
||||
}];
|
||||
|
||||
const stream = Readable.from(stringify({
|
||||
path,
|
||||
files,
|
||||
}));
|
||||
|
||||
assign(stream, {
|
||||
path,
|
||||
files,
|
||||
type: 'directory',
|
||||
});
|
||||
|
||||
const read = stub().resolves(stream);
|
||||
|
||||
cloudcmd.depStore('win32', {
|
||||
read,
|
||||
});
|
||||
const {request} = serveOnce(cloudcmd, {
|
||||
config: defaultConfig,
|
||||
});
|
||||
|
||||
const {status} = await request.get('/');
|
||||
|
||||
cloudcmd.depStore();
|
||||
|
||||
t.equal(status, 200, 'should not hang up');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: buttons: no terminal', async (t) => {
|
||||
const config = {
|
||||
terminal: false,
|
||||
};
|
||||
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.match(body, 'icon-terminal none', 'should hide terminal');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: no termianl: /fs', async (t) => {
|
||||
const config = {
|
||||
terminal: false,
|
||||
};
|
||||
|
||||
const options = {
|
||||
config,
|
||||
configManager: createConfigManager(),
|
||||
};
|
||||
|
||||
const {request} = serveOnce(cloudcmd);
|
||||
|
||||
const {body} = await request.get('/fs', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.match(body, 'icon-terminal none', 'should hide terminal');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: buttons: terminal: can not load', async (t) => {
|
||||
const config = {
|
||||
terminal: true,
|
||||
terminalPath: 'xxxxxxxxxxxx',
|
||||
};
|
||||
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.match(body, 'icon-terminal none', 'should not enable terminal');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: buttons: terminal', async (t) => {
|
||||
const config = {
|
||||
terminal: true,
|
||||
terminalPath: 'console-io',
|
||||
};
|
||||
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.notOk(/icon-terminal none/.test(body), 'should not enable terminal');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: buttons: contact', async (t) => {
|
||||
const config = {
|
||||
contact: true,
|
||||
};
|
||||
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
const {request} = serveOnce(cloudcmd);
|
||||
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.notOk(/icon-contact none/.test(body), 'should enable terminal');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: dropbox', async (t) => {
|
||||
const config = createConfigManager();
|
||||
config('dropbox', true);
|
||||
config('dropboxToken', '');
|
||||
|
||||
const readdir = _getReadDir(config);
|
||||
const [e] = await tryToCatch(readdir, '/root');
|
||||
|
||||
t.match(e.message, 'API', 'should contain word token in message');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: content length', async (t) => {
|
||||
const options = {
|
||||
root: fixtureDir,
|
||||
};
|
||||
|
||||
const {headers} = await request.get('/route.js', {
|
||||
options,
|
||||
});
|
||||
|
||||
const result = headers.get('content-length');
|
||||
|
||||
t.ok(result);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: read: root', async (t) => {
|
||||
const stream = Readable.from('hello');
|
||||
|
||||
stream.contentLength = 5;
|
||||
|
||||
const read = stub().returns(stream);
|
||||
cloudcmd.depStore('win32', {
|
||||
read,
|
||||
});
|
||||
|
||||
const configManager = createConfigManager();
|
||||
const root = '/hello';
|
||||
|
||||
configManager('root', root);
|
||||
|
||||
const {request} = serveOnce(cloudcmd, {
|
||||
configManager,
|
||||
});
|
||||
|
||||
await request.get('/fs/route.js');
|
||||
cloudcmd.depStore();
|
||||
|
||||
const expected = ['/hello/route.js', {
|
||||
root,
|
||||
}];
|
||||
|
||||
t.calledWith(read, expected);
|
||||
t.end();
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue