mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 02:35:49 +00:00
feature(package) add dropbox support
This commit is contained in:
parent
ef116a9a53
commit
0908837392
14 changed files with 366 additions and 229 deletions
|
|
@ -33,6 +33,7 @@
|
|||
"com",
|
||||
"dev",
|
||||
"deepword",
|
||||
"dropbox",
|
||||
"dword",
|
||||
"edward",
|
||||
"favicon",
|
||||
|
|
|
|||
113
HELP.md
113
HELP.md
|
|
@ -107,6 +107,8 @@ Cloud Commander supports command line parameters:
|
|||
| `--import-token` | authorization token used to connect to export server
|
||||
| `--import-url` | url of an import server
|
||||
| `--import-listen` | enable listen on config updates from import server
|
||||
| `--dropbox` | enable dropbox integration
|
||||
| `--dropbox-token` | set dropbox token
|
||||
| `--log` | enable logging
|
||||
| `--no-show-config` | do not show config values
|
||||
| `--no-server` | do not start server
|
||||
|
|
@ -132,8 +134,10 @@ Cloud Commander supports command line parameters:
|
|||
| `--no-export` | disable export config through a server
|
||||
| `--no-import` | disable import of config
|
||||
| `--no-import-listen` | disable listen on config updates from import server
|
||||
| `--no-log` | disable logging
|
||||
| `--no-show-file-name` | do not show file name in view and edit
|
||||
| `--no-dropbox` | disable dropbox integration
|
||||
| `--no-dropbox-token` | unset dropbox token
|
||||
| `--no-log` | disable logging
|
||||
|
||||
If no parameters given Cloud Commander reads information from `~/.cloudcmd.json` and use
|
||||
port from it (`8000` default). if port variables `PORT` isn't exist.
|
||||
|
|
@ -374,49 +378,51 @@ Here is description of options:
|
|||
|
||||
```js
|
||||
{
|
||||
"name" : "", /* set tab name in web browser */
|
||||
"auth" : false, /* enable http authentication */
|
||||
"username" : "root", /* username for authentication */
|
||||
"password" : "toor", /* password hash for authentication */
|
||||
"algo" : "sha512WithRSAEncryption", /* cryptographic algorithm */
|
||||
"editor" : "edward", /* default, could be "dword" or "edward" */
|
||||
"packer" : "tar", /* default, could be "tar" or "zip" */
|
||||
"diff" : true, /* when save - send patch, not whole file */
|
||||
"zip" : true, /* zip text before send / unzip before save */
|
||||
"buffer" : true, /* buffer for copying files */
|
||||
"dirStorage" : true, /* store directory listing */
|
||||
"online" : false, /* do not load js files from cdn */
|
||||
"open" : true, /* open web browser when server started */
|
||||
"oneFilePanel" : false, /* show one file panel */
|
||||
"keysPanel" : true, /* show classic panel with buttons of keys */
|
||||
"port" : 8000, /* http port */
|
||||
"ip" : null, /* ip or null(default) */
|
||||
"root" : "/", /* root directory */
|
||||
"prefix" : "", /* url prefix */
|
||||
"prefixSocket" : "", /* prefix for socket connection */
|
||||
"progress" : true, /* show progress of file operations */
|
||||
"confirmCopy" : true, /* confirm copy */
|
||||
"confirmMove" : true, /* confirm move */
|
||||
"showConfig" : false, /* show config at startap */
|
||||
"showFileName" : false /* do not show file name in view and edit */
|
||||
"contact" : true, /* enable contact */
|
||||
"configDialog" : true, /* enable config dialog */
|
||||
"configAuth" : true, /* enable auth change in config dialog */
|
||||
"console" : true, /* enable console */
|
||||
"syncConsolePath" : false /* do not sync console path */
|
||||
"terminal" : false, /* disable terminal */
|
||||
"terminalPath" : '', /* path of a terminal */
|
||||
"terminalCommand" : '', /* set command to run in terminal */
|
||||
"terminalAutoRestart" : true, /* restart command on exit */
|
||||
"vim" : false, /* disable vim hot keys */
|
||||
"columns" : "name-size-date-owner-mode", /* set visible columns */
|
||||
"export" : false, /* enable export of config through a server */
|
||||
"exportToken" : "root", /* token used by export server */
|
||||
"import" : false, /* enable import of config */
|
||||
"import-url" : "http://localhost:8000", /* url of an export server */
|
||||
"importToken" : "root", /* token used to connect to export server */
|
||||
"importListen" : false, /* listen on config updates */
|
||||
"log" : true /* logging */
|
||||
"name" : "", // set tab name in web browser
|
||||
"auth" : false, // enable http authentication
|
||||
"username" : "root", // username for authentication
|
||||
"password" : "toor", // password hash for authentication
|
||||
"algo" : "sha512WithRSAEncryption", // cryptographic algorithm
|
||||
"editor" : "edward", // default, could be "dword" or "edward"
|
||||
"packer" : "tar", // default, could be "tar" or "zip"
|
||||
"diff" : true, // when save - send patch, not whole file
|
||||
"zip" : true, // zip text before send / unzip before save
|
||||
"buffer" : true, // buffer for copying files
|
||||
"dirStorage" : true, // store directory listing
|
||||
"online" : false, // do not load js files from cdn
|
||||
"open" : true, // open web browser when server started
|
||||
"oneFilePanel" : false, // show one file panel
|
||||
"keysPanel" : true, // show classic panel with buttons of keys
|
||||
"port" : 8000, // http port
|
||||
"ip" : null, // ip or null(default)
|
||||
"root" : "/", // root directory
|
||||
"prefix" : "", // url prefix
|
||||
"prefixSocket" : "", // prefix for socket connection
|
||||
"progress" : true, // show progress of file operations
|
||||
"confirmCopy" : true, // confirm copy
|
||||
"confirmMove" : true, // confirm move
|
||||
"showConfig" : false, // show config at startup
|
||||
"showFileName" : false // do not show file name in view and edit
|
||||
"contact" : true, // enable contact
|
||||
"configDialog" : true, // enable config dialog
|
||||
"configAuth" : true, // enable auth change in config dialog
|
||||
"console" : true, // enable console
|
||||
"syncConsolePath" : false // do not sync console path
|
||||
"terminal" : false, // disable terminal
|
||||
"terminalPath" : '', // path of a terminal
|
||||
"terminalCommand" : '', // set command to run in terminal
|
||||
"terminalAutoRestart" : true, // restart command on exit
|
||||
"vim" : false, // disable vim hot keys
|
||||
"columns" : "name-size-date-owner-mode", // set visible columns
|
||||
"export" : false, // enable export of config through a server
|
||||
"exportToken" : "root", // token used by export server
|
||||
"import" : false, // enable import of config
|
||||
"import-url" : "http://localhost:8000", // url of an export server
|
||||
"importToken" : "root", // token used to connect to export server
|
||||
"importListen" : false, // listen on config updates
|
||||
"dropbox" : false, // disable dropbox integration
|
||||
"dropboxToken" : "", // unset dropbox token
|
||||
"log" : true // logging
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -785,6 +791,25 @@ When you create this file run:
|
|||
docker-compose up
|
||||
```
|
||||
|
||||
# Dropbox
|
||||
|
||||
Dropbox support integrated into Cloud Commander and you can switch from local file system to a dropbox account.
|
||||
All you need to do is set `--dropbox` option and [generate dropbox token](https://blogs.dropbox.com/developers/2014/05/generate-an-access-token-for-your-own-account/) for you account.
|
||||
|
||||
This can look like this:
|
||||
|
||||
```sh
|
||||
cloudcmd --dropbox --dropbox-token your-dropbox-token
|
||||
```
|
||||
|
||||
Using `dropbox` remember that there is no remote support of a `console` and `terminal. Progress of file operation also not supported. There is only basic support, but you can do next things with `files` and `directories`:
|
||||
|
||||
- create
|
||||
- remove
|
||||
- rename/move
|
||||
- view
|
||||
- edit
|
||||
|
||||
Get involved
|
||||
---------------
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ const args = require('minimist')(argv.slice(2), {
|
|||
'import-url',
|
||||
'import-token',
|
||||
'export-token',
|
||||
'dropbox-token',
|
||||
],
|
||||
boolean: [
|
||||
'auth',
|
||||
|
|
@ -71,6 +72,7 @@ const args = require('minimist')(argv.slice(2), {
|
|||
'import',
|
||||
'import-listen',
|
||||
'log',
|
||||
'dropbox',
|
||||
],
|
||||
default: {
|
||||
server : true,
|
||||
|
|
@ -112,6 +114,9 @@ const args = require('minimist')(argv.slice(2), {
|
|||
'keys-panel': env.bool('keys_panel') || config('keysPanel'),
|
||||
'import-token': env('import_token') || config('importToken'),
|
||||
'export-token': env('export_token') || config('exportToken'),
|
||||
|
||||
'dropbox': config('dropbox'),
|
||||
'dropbox-token': config('dropboxToken'),
|
||||
},
|
||||
alias: {
|
||||
v: 'version',
|
||||
|
|
@ -177,6 +182,9 @@ function main() {
|
|||
config('importListen', args['import-listen']);
|
||||
config('importUrl', args['import-url']);
|
||||
|
||||
config('dropbox', args['dropbox']);
|
||||
config('dropboxToken', args['dropbox-token'] || '');
|
||||
|
||||
readConfig(args.config);
|
||||
|
||||
const options = {
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ function CloudCmdProto(DOM) {
|
|||
};
|
||||
|
||||
CloudCmd.prefix = prefix;
|
||||
CloudCmd.prefixURL = prefix + apiURL;
|
||||
CloudCmd.prefixURL = `${prefix}${apiURL}`;
|
||||
CloudCmd.prefixSocket = config.prefixSocket;
|
||||
|
||||
CloudCmd.config = (key) => config[key];
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ const uploadFiles = require('../dom/upload-files');
|
|||
|
||||
const {
|
||||
FS,
|
||||
apiURL,
|
||||
} = require('../../common/cloudfunc');
|
||||
|
||||
const NBSP_REG = RegExp(String.fromCharCode(160), 'g');
|
||||
|
|
@ -303,6 +302,7 @@ function onTouch(event) {
|
|||
* in Chrome (HTML5)
|
||||
*/
|
||||
function onDragStart(event) {
|
||||
const {prefixURL} = CloudCmd;
|
||||
const element = getLIElement(event.target);
|
||||
const isDir = Info.isDir;
|
||||
let link = DOM.getCurrentLink(element);
|
||||
|
|
@ -313,7 +313,7 @@ function onDragStart(event) {
|
|||
name += EXT;
|
||||
link = document.createElement('a');
|
||||
link.textContent = name;
|
||||
link.href = apiURL + '/pack' + Info.path + EXT;
|
||||
link.href = prefixURL + '/pack' + Info.path + EXT;
|
||||
}
|
||||
|
||||
event.dataTransfer.setData('DownloadURL',
|
||||
|
|
|
|||
|
|
@ -61,14 +61,14 @@ const noFilesCheck = () => {
|
|||
|
||||
return is;
|
||||
};
|
||||
|
||||
|
||||
module.exports.init = promisify((callback) => {
|
||||
showLoad();
|
||||
|
||||
exec.series([
|
||||
DOM.loadSocket,
|
||||
(callback) => {
|
||||
if (!config('progress'))
|
||||
if (!config('progress') || config('dropbox'))
|
||||
return callback();
|
||||
|
||||
load(initOperations(CloudCmd.prefix, callback));
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@
|
|||
"importToken": "root",
|
||||
"importUrl": "http://localhost:8000",
|
||||
"importListen": false,
|
||||
"log": true
|
||||
"log": true,
|
||||
"dropbox": false,
|
||||
"dropboxToken": ""
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
"--import-url ": "url of an export server",
|
||||
"--import-token ": "authorization token used to connect to export server",
|
||||
"--import-listen ": "enable listen on config updates from import server",
|
||||
"--dropbox ": "enable dropbox integration",
|
||||
"--dropbox-token ": "set dropbox token",
|
||||
"--log ": "enable logging",
|
||||
"--no-show-config ": "do not show config values",
|
||||
"--no-server ": "do not start server",
|
||||
|
|
@ -63,6 +65,8 @@
|
|||
"--no-export ": "disable export config through a server",
|
||||
"--no-import ": "disable import of config",
|
||||
"--no-import-listen ": "disable listen on config updates from import server",
|
||||
"--no-log ": "disable logging",
|
||||
"--no-show-file-name ": "do not show file name in view and edit"
|
||||
"--no-show-file-name ": "do not show file name in view and edit",
|
||||
"--no-dropbox ": "disable dropbox integration",
|
||||
"--no-dropbox-token ": "unset dropbox token",
|
||||
"--no-log ": "disable logging"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ programs in browser from any computer, mobile or tablet device.
|
|||
--import-url url of an import server
|
||||
--import-token authorization token used to connect to export server
|
||||
--import-listen enable listen on config updates from import server
|
||||
--dropbox enable dropbox integration
|
||||
--dropbox-token set dropbox token
|
||||
--log enable logging
|
||||
--no-show-config do not show config values
|
||||
--no-server do not start server
|
||||
|
|
@ -88,8 +90,10 @@ programs in browser from any computer, mobile or tablet device.
|
|||
--no-import disable import of config
|
||||
--no-import-url url of an import server
|
||||
--no-import-listen disable listen on config updates from import server
|
||||
--no-log disable logging
|
||||
--no-show-file-name do not show file name in view and edit modes
|
||||
--no-dropbox disable dropbox integration
|
||||
--no-dropbox-token unset dropbox token
|
||||
--no-log disable logging
|
||||
|
||||
.SH RESOURCES AND DOCUMENTATION
|
||||
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@
|
|||
},
|
||||
"subdomain": "cloudcmd",
|
||||
"dependencies": {
|
||||
"@cloudcmd/dropbox": "^4.0.1",
|
||||
"@cloudcmd/fileop": "^2.0.0",
|
||||
"@cloudcmd/move-files": "^2.0.1",
|
||||
"@cloudcmd/read-files-sync": "^2.0.0",
|
||||
|
|
@ -120,9 +121,9 @@
|
|||
"criton": "^2.0.0",
|
||||
"currify": "^3.0.0",
|
||||
"deepmerge": "^2.0.0",
|
||||
"deepword": "^5.0.0",
|
||||
"dword": "^9.0.0",
|
||||
"edward": "^9.0.0",
|
||||
"deepword": "^5.1.0",
|
||||
"dword": "^9.1.0",
|
||||
"edward": "^9.1.0",
|
||||
"execon": "^1.2.0",
|
||||
"express": "^4.13.0",
|
||||
"files-io": "^3.0.0",
|
||||
|
|
@ -147,6 +148,7 @@
|
|||
"pullout": "^2.0.0",
|
||||
"rendy": "^2.0.0",
|
||||
"restafary": "^5.0.0",
|
||||
"restbox": "^1.0.1",
|
||||
"shortdate": "^1.2.0",
|
||||
"socket.io": "^2.0.3",
|
||||
"socket.io-client": "^2.1.1",
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ const currify = require('currify');
|
|||
const apart = require('apart');
|
||||
const ponse = require('ponse');
|
||||
const restafary = require('restafary');
|
||||
const restbox = require('restbox');
|
||||
const konsole = require('console-io');
|
||||
const edward = require('edward');
|
||||
const dword = require('dword');
|
||||
|
|
@ -164,6 +165,9 @@ function cloudcmd(prefix, plugins, modules) {
|
|||
const dir = DIR_ROOT;
|
||||
|
||||
const ponseStatic = ponse.static(dir, {cache});
|
||||
|
||||
const dropbox = config('dropbox');
|
||||
const dropboxToken = config('dropboxToken');
|
||||
|
||||
const funcs = clean([
|
||||
config('console') && konsole({
|
||||
|
|
@ -177,25 +181,29 @@ function cloudcmd(prefix, plugins, modules) {
|
|||
online,
|
||||
diff,
|
||||
zip,
|
||||
dropbox,
|
||||
dropboxToken,
|
||||
}),
|
||||
|
||||
dword({
|
||||
online,
|
||||
diff,
|
||||
zip,
|
||||
dropbox,
|
||||
dropboxToken,
|
||||
}),
|
||||
|
||||
deepword({
|
||||
online,
|
||||
diff,
|
||||
zip,
|
||||
dropbox,
|
||||
dropboxToken,
|
||||
}),
|
||||
|
||||
fileop({
|
||||
}),
|
||||
fileop(),
|
||||
|
||||
nomine({
|
||||
}),
|
||||
nomine(),
|
||||
|
||||
setUrl,
|
||||
setSW,
|
||||
|
|
@ -205,6 +213,12 @@ function cloudcmd(prefix, plugins, modules) {
|
|||
|
||||
modules && modulas(modules),
|
||||
|
||||
config('dropbox') && restbox({
|
||||
prefix: cloudfunc.apiURL,
|
||||
root,
|
||||
token: dropboxToken,
|
||||
}),
|
||||
|
||||
restafary({
|
||||
prefix: cloudfunc.apiURL + '/fs',
|
||||
root
|
||||
|
|
|
|||
|
|
@ -35,10 +35,20 @@ const sendIndex = (params, data) => {
|
|||
|
||||
const {FS} = CloudFunc;
|
||||
|
||||
const Columns = require('./columns');
|
||||
const Template = require('./template');
|
||||
const Columns = require(`${DIR_SERVER}/columns`);
|
||||
const Template = require(`${DIR_SERVER}/template`);
|
||||
|
||||
const read = promisify(flop.read);
|
||||
const getReadDir = () => {
|
||||
if (!config('dropbox'))
|
||||
return promisify(flop.read);
|
||||
|
||||
const tokenize = (fn, a) => (b) => fn(a, b);
|
||||
const {readDir} = require('@cloudcmd/dropbox');
|
||||
|
||||
return tokenize(readDir, config('dropboxToken'));
|
||||
};
|
||||
|
||||
const read = getReadDir();
|
||||
const realpath = promisify(fs.realpath);
|
||||
|
||||
/**
|
||||
|
|
@ -55,6 +65,8 @@ module.exports = currify((options, request, response, next) => {
|
|||
.catch(next);
|
||||
});
|
||||
|
||||
module.exports._getReadDir = getReadDir;
|
||||
|
||||
async function route(options, request, response) {
|
||||
const name = ponse.getPathName(request);
|
||||
const gzip = true;
|
||||
|
|
|
|||
|
|
@ -3,48 +3,37 @@
|
|||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const test = require('tape');
|
||||
const {promisify} = require('util');
|
||||
const pullout = require('pullout');
|
||||
const request = require('request');
|
||||
const tryToCatch = require('try-to-catch');
|
||||
const tryToTape = require('try-to-tape');
|
||||
const test = tryToTape(require('tape'));
|
||||
const mockRequire = require('mock-require');
|
||||
const {reRequire} = mockRequire;
|
||||
const clear = require('clear-module');
|
||||
|
||||
const rootDir = path.join(__dirname, '../..');
|
||||
const fixtureDir = path.join(__dirname, '..', 'test', 'fixture');
|
||||
|
||||
const routePath = './route';
|
||||
const cloudcmdPath = './cloudcmd';
|
||||
const beforePath = path.join(__dirname, '../test/before');
|
||||
|
||||
const {connect} = require(beforePath);
|
||||
|
||||
const warp = (fn, ...a) => (...b) => fn(...b, ...a);
|
||||
const _pullout = promisify(pullout);
|
||||
|
||||
const get = promisify((url, fn) => {
|
||||
fn(null, request(url));
|
||||
});
|
||||
|
||||
const getStr = (url) => {
|
||||
return get(url)
|
||||
.then(warp(_pullout, 'string'))
|
||||
.catch(console.error);
|
||||
};
|
||||
const cloudcmd = require(cloudcmdPath);
|
||||
const serveOnce = require('serve-once');
|
||||
const {request} = serveOnce(cloudcmd);
|
||||
|
||||
test('cloudcmd: route: buttons: no console', async (t) => {
|
||||
const config = {
|
||||
console: false
|
||||
console: false,
|
||||
};
|
||||
|
||||
const {port, done} = await connect({config});
|
||||
const result = await getStr(`http://localhost:${port}`);
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
t.ok(/icon-console none/.test(result), 'should hide console');
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.ok(/icon-console none/.test(body), 'should hide console');
|
||||
t.end();
|
||||
|
||||
await done();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: buttons: console', async (t) => {
|
||||
|
|
@ -52,13 +41,16 @@ test('cloudcmd: route: buttons: console', async (t) => {
|
|||
console: true,
|
||||
};
|
||||
|
||||
const {port, done} = await connect({config});
|
||||
const result = await getStr(`http://localhost:${port}`);
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
t.notOk(/icon-console none/.test(result), 'should not hide console');
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.notOk(/icon-console none/.test(body), 'should not hide console');
|
||||
t.end();
|
||||
|
||||
await done();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: buttons: no config', async (t) => {
|
||||
|
|
@ -66,13 +58,16 @@ test('cloudcmd: route: buttons: no config', async (t) => {
|
|||
configDialog: false
|
||||
};
|
||||
|
||||
const {port, done} = await connect({config});
|
||||
const result = await getStr(`http://localhost:${port}`);
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
t.ok(/icon-config none/.test(result), 'should hide config');
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.ok(/icon-config none/.test(body), 'should hide config');
|
||||
t.end();
|
||||
|
||||
await done();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: buttons: no contact', async (t) => {
|
||||
|
|
@ -80,13 +75,16 @@ test('cloudcmd: route: buttons: no contact', async (t) => {
|
|||
contact: false
|
||||
};
|
||||
|
||||
const {port, done} = await connect({config});
|
||||
const result = await getStr(`http://localhost:${port}`);
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
t.ok(/icon-contact none/.test(result), 'should hide contact');
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.ok(/icon-contact none/.test(body), 'should hide contact');
|
||||
t.end();
|
||||
|
||||
await done();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: buttons: one file panel: move', async (t) => {
|
||||
|
|
@ -94,13 +92,16 @@ test('cloudcmd: route: buttons: one file panel: move', async (t) => {
|
|||
oneFilePanel: true
|
||||
};
|
||||
|
||||
const {port, done} = await connect({config});
|
||||
const result = await getStr(`http://localhost:${port}`);
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
t.ok(/icon-move none/.test(result), 'should hide move button');
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.ok(/icon-move none/.test(body), 'should hide move button');
|
||||
t.end();
|
||||
|
||||
await done();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: buttons: no one file panel: move', async (t) => {
|
||||
|
|
@ -108,13 +109,16 @@ test('cloudcmd: route: buttons: no one file panel: move', async (t) => {
|
|||
oneFilePanel: false
|
||||
};
|
||||
|
||||
const {port, done} = await connect({config});
|
||||
const result = await getStr(`http://localhost:${port}`);
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
t.notOk(/icon-move none/.test(result), 'should not hide move button');
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.notOk(/icon-move none/.test(body), 'should not hide move button');
|
||||
t.end();
|
||||
|
||||
await done();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: buttons: one file panel: move', async (t) => {
|
||||
|
|
@ -122,13 +126,16 @@ test('cloudcmd: route: buttons: one file panel: move', async (t) => {
|
|||
oneFilePanel: true
|
||||
};
|
||||
|
||||
const {port, done} = await connect({config});
|
||||
const result = await getStr(`http://localhost:${port}`);
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
t.ok(/icon-copy none/.test(result), 'should hide copy button');
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.ok(/icon-copy none/.test(body), 'should hide copy button');
|
||||
t.end();
|
||||
|
||||
await done();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: keys panel: hide', async (t) => {
|
||||
|
|
@ -136,13 +143,16 @@ test('cloudcmd: route: keys panel: hide', async (t) => {
|
|||
keysPanel: false
|
||||
};
|
||||
|
||||
const {port, done} = await connect({config});
|
||||
const result = await getStr(`http://localhost:${port}`);
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
t.ok(/keyspanel hidden/.test(result), 'should hide keyspanel');
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.ok(/keyspanel hidden/.test(body), 'should hide keyspanel');
|
||||
t.end();
|
||||
|
||||
await done();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: keys panel', async (t) => {
|
||||
|
|
@ -150,13 +160,16 @@ test('cloudcmd: route: keys panel', async (t) => {
|
|||
keysPanel: true
|
||||
};
|
||||
|
||||
const {port, done} = await connect({config});
|
||||
const result = await getStr(`http://localhost:${port}`);
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
t.notOk(/keyspanel hidden/.test(result), 'should show keyspanel');
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.notOk(/keyspanel hidden/.test(body), 'should show keyspanel');
|
||||
t.end();
|
||||
|
||||
await done();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: file: fs', async (t) => {
|
||||
|
|
@ -165,13 +178,16 @@ test('cloudcmd: route: file: fs', async (t) => {
|
|||
root,
|
||||
};
|
||||
|
||||
const {port, done} = await connect({config});
|
||||
const empty = await getStr(`http://localhost:${port}/fs`);
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
t.equal(empty, '', 'should equal');
|
||||
const {body} = await request.get('/', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.equal(body, '', 'should equal');
|
||||
t.end();
|
||||
|
||||
await done();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: symlink', async (t) => {
|
||||
|
|
@ -183,16 +199,22 @@ test('cloudcmd: route: symlink', async (t) => {
|
|||
root,
|
||||
};
|
||||
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
fs.symlinkSync(emptyDir, symlink);
|
||||
|
||||
const {port, done} = await connect({config});
|
||||
const data = await getStr(`http://localhost:${port}/fs/symlink-dir`);
|
||||
const {body} = await request.get('/fs/symlink-dir', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.ok(data.length, 'should return html document');
|
||||
fs.unlinkSync(symlink);
|
||||
t.end();
|
||||
|
||||
await done();
|
||||
console.log(body);
|
||||
|
||||
t.ok(body.length, 'should return html document');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: not found', async (t) => {
|
||||
|
|
@ -201,13 +223,16 @@ test('cloudcmd: route: not found', async (t) => {
|
|||
root,
|
||||
};
|
||||
|
||||
const {port, done} = await connect({config});
|
||||
const data = await getStr(`http://localhost:${port}/fs/file-not-found`);
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
t.ok(~data.indexOf('ENOENT: no such file or directory'), 'should return error');
|
||||
const {body} = await request.get('/fs/file-not-found', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.ok(~body.indexOf('ENOENT: no such file or directory'), 'should return error');
|
||||
t.end();
|
||||
|
||||
await done();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: realpath: error', async (t) => {
|
||||
|
|
@ -223,19 +248,22 @@ test('cloudcmd: route: realpath: error', async (t) => {
|
|||
root: fixtureDir,
|
||||
};
|
||||
|
||||
reRequire('./route');
|
||||
reRequire('./cloudcmd');
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
const {connect} = reRequire(beforePath);
|
||||
const {port, done} = await connect({config});
|
||||
const data = await getStr(`http://localhost:${port}/fs/empty-file`);
|
||||
reRequire(routePath);
|
||||
const cloudcmd = reRequire(cloudcmdPath);
|
||||
|
||||
const {request} = serveOnce(cloudcmd);
|
||||
const {body} = await request.get('/fs/empty-file', {
|
||||
options,
|
||||
});
|
||||
|
||||
fs.realpath = realpath;
|
||||
|
||||
t.ok(/^ENOENT/.test(data), 'should return error');
|
||||
t.ok(/^ENOENT/.test(body), 'should return error');
|
||||
t.end();
|
||||
|
||||
await done();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: sendIndex: encode', async (t) => {
|
||||
|
|
@ -255,17 +283,14 @@ test('cloudcmd: route: sendIndex: encode', async (t) => {
|
|||
});
|
||||
|
||||
reRequire(routePath);
|
||||
reRequire(cloudcmdPath);
|
||||
const cloudcmd = reRequire(cloudcmdPath);
|
||||
|
||||
const {connect} = reRequire(beforePath);
|
||||
const {port, done} = await connect();
|
||||
const data = await getStr(`http://localhost:${port}`);
|
||||
|
||||
t.ok(data.includes(nameEncoded), 'should encode name');
|
||||
const {request} = serveOnce(cloudcmd);
|
||||
const {body} = await request.get('/');
|
||||
|
||||
mockRequire.stop('flop');
|
||||
|
||||
await done();
|
||||
t.ok(body.includes(nameEncoded), 'should encode name');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
@ -284,22 +309,15 @@ test('cloudcmd: route: sendIndex: encode: not encoded', async (t) => {
|
|||
read
|
||||
});
|
||||
|
||||
clear(routePath);
|
||||
clear(cloudcmdPath);
|
||||
clear(beforePath);
|
||||
reRequire(routePath);
|
||||
const cloudcmd = reRequire(cloudcmdPath);
|
||||
|
||||
const {connect} = require(beforePath);
|
||||
const {port, done} = await connect();
|
||||
const data = await getStr(`http://localhost:${port}`);
|
||||
|
||||
t.notOk(data.includes(name), 'should not put not encoded name');
|
||||
const {request} = serveOnce(cloudcmd);
|
||||
const {body} = await request.get('/');
|
||||
|
||||
mockRequire.stop('flop');
|
||||
clear(routePath);
|
||||
clear(cloudcmdPath);
|
||||
clear(beforePath);
|
||||
|
||||
await done();
|
||||
t.notOk(body.includes(name), 'should not put not encoded name');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
@ -318,23 +336,15 @@ test('cloudcmd: route: sendIndex: ddos: render', async (t) => {
|
|||
read
|
||||
});
|
||||
|
||||
clear(routePath);
|
||||
clear(cloudcmdPath);
|
||||
clear(beforePath);
|
||||
reRequire(routePath);
|
||||
const cloudcmd = reRequire(cloudcmdPath);
|
||||
|
||||
const {connect} = require(beforePath);
|
||||
const {port, done} = await connect();
|
||||
|
||||
await getStr(`http://localhost:${port}`);
|
||||
|
||||
t.pass('should not hang up');
|
||||
const {request} = serveOnce(cloudcmd);
|
||||
const {body} = await request.get('/');
|
||||
|
||||
mockRequire.stop('flo');
|
||||
clear(routePath);
|
||||
clear(cloudcmdPath);
|
||||
clear(beforePath);
|
||||
|
||||
await done();
|
||||
t.pass('should not hang up');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
@ -343,12 +353,34 @@ test('cloudcmd: route: buttons: no terminal', async (t) => {
|
|||
terminal: false
|
||||
};
|
||||
|
||||
const {port, done} = await connect({config});
|
||||
const result = await getStr(`http://localhost:${port}`);
|
||||
const options = {
|
||||
config,
|
||||
}
|
||||
|
||||
t.ok(/icon-terminal none/.test(result), 'should hide terminal');
|
||||
const {request} = serveOnce(cloudcmd);
|
||||
const {body} = await request.get('/', {
|
||||
options
|
||||
});
|
||||
|
||||
await done();
|
||||
t.ok(/icon-terminal none/.test(body), 'should hide terminal');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: no termianl: /fs', async (t) => {
|
||||
const config = {
|
||||
terminal: false
|
||||
};
|
||||
|
||||
const options = {
|
||||
config,
|
||||
}
|
||||
|
||||
const {request} = serveOnce(cloudcmd);
|
||||
const {body} = await request.get('/fs', {
|
||||
options,
|
||||
});
|
||||
|
||||
t.ok(/icon-terminal none/.test(body), 'should hide terminal');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
@ -358,12 +390,54 @@ test('cloudcmd: route: buttons: terminal', async (t) => {
|
|||
terminalPath: 'gritty',
|
||||
};
|
||||
|
||||
const {port, done} = await connect({config});
|
||||
const result = await getStr(`http://localhost:${port}`);
|
||||
const options = {
|
||||
config,
|
||||
}
|
||||
|
||||
t.notOk(/icon-terminal none/.test(result), 'should enable terminal');
|
||||
const {request} = serveOnce(cloudcmd);
|
||||
const {body} = await request.get('/', {
|
||||
options
|
||||
});
|
||||
|
||||
await done();
|
||||
t.notOk(/icon-terminal none/.test(body), 'should 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 = require('./config');
|
||||
const dropbox = config('dropbox');
|
||||
const dropboxToken = config('dropboxToken');
|
||||
|
||||
config('dropbox', true);
|
||||
config('dropboxToken', '');
|
||||
|
||||
const {_getReadDir} = reRequire(routePath);
|
||||
|
||||
const readdir = _getReadDir();
|
||||
const [e] = await tryToCatch(readdir, '/root');
|
||||
|
||||
config('dropbox', dropbox);
|
||||
config('dropboxToken', dropboxToken);
|
||||
|
||||
t.ok(/token/.test(e.message), 'should contain word token in message');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,47 +1,39 @@
|
|||
'use strict';
|
||||
|
||||
const test = require('tape');
|
||||
const mock = require('mock-require');
|
||||
const diff = require('sinon-called-with-diff');
|
||||
const sinon = diff(require('sinon'));
|
||||
|
||||
const stub = require('mock-require');
|
||||
const clean = require('clear-module');
|
||||
const mockRequire = require('mock-require');
|
||||
const {reRequire} = mockRequire;
|
||||
|
||||
const configPath = '../../server/config';
|
||||
const terminalPath = '../../server/terminal';
|
||||
|
||||
test('cloudcmd: terminal: disabled', (t) => {
|
||||
clean(terminalPath);
|
||||
stub(configPath, () => {
|
||||
mockRequire(configPath, () => {
|
||||
return false;
|
||||
});
|
||||
|
||||
const terminal = require('../../server/terminal');
|
||||
|
||||
const terminal = reRequire('../../server/terminal');
|
||||
const fn = terminal();
|
||||
|
||||
mockRequire.stop(configPath);
|
||||
|
||||
t.notOk(fn(), 'should return noop');
|
||||
|
||||
clean(configPath);
|
||||
require(configPath);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: terminal: disabled: listen', (t) => {
|
||||
clean(terminalPath);
|
||||
stub(configPath, () => false);
|
||||
|
||||
const terminal = require(terminalPath);
|
||||
mockRequire(configPath, () => false);
|
||||
|
||||
const terminal = reRequire(terminalPath);
|
||||
const fn = terminal().listen();
|
||||
|
||||
mockRequire.stop(configPath);
|
||||
reRequire(terminalPath);
|
||||
|
||||
t.notOk(fn, 'should return noop');
|
||||
|
||||
clean(configPath);
|
||||
require(configPath);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
@ -49,13 +41,15 @@ test('cloudcmd: terminal: enabled', (t) => {
|
|||
const term = sinon.stub();
|
||||
const arg = 'hello';
|
||||
|
||||
clean(terminalPath);
|
||||
stub(configPath, () => '/terminal');
|
||||
stub('/terminal', term);
|
||||
mockRequire(configPath, () => '/terminal');
|
||||
mockRequire(terminalPath, term);
|
||||
|
||||
const terminal = require(terminalPath);
|
||||
terminal(arg);
|
||||
|
||||
mockRequire.stop(configPath);
|
||||
mockRequire.stop(terminalPath);
|
||||
|
||||
t.ok(term.calledWith(arg), 'should call terminal');
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -64,44 +58,41 @@ test('cloudcmd: terminal: enabled: no string', (t) => {
|
|||
const {log:originalLog} = console;
|
||||
const log = sinon.stub();
|
||||
|
||||
clean(terminalPath);
|
||||
stub(configPath, () => 'hello');
|
||||
mockRequire(configPath, () => 'hello');
|
||||
|
||||
console.log = log;
|
||||
const terminal = require(terminalPath);
|
||||
const terminal = reRequire(terminalPath);
|
||||
terminal();
|
||||
console.log = originalLog;
|
||||
|
||||
mockRequire.stop(configPath);
|
||||
reRequire(terminalPath);
|
||||
|
||||
const msg = 'cloudcmd --terminal: Cannot find module \'hello\'';
|
||||
|
||||
t.ok(log.calledWith(msg), 'should call exit');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: terminal: no arg', (t) => {
|
||||
const gritty = {};
|
||||
|
||||
mock('gritty', gritty);
|
||||
|
||||
clean(terminalPath);
|
||||
stub(configPath, (a) => {
|
||||
mockRequire('gritty', gritty);
|
||||
mockRequire(configPath, (a) => {
|
||||
if (a === 'terminal')
|
||||
return true;
|
||||
|
||||
return 'gritty';
|
||||
});
|
||||
|
||||
const terminal = require(terminalPath);
|
||||
const terminal = reRequire(terminalPath);
|
||||
const result = terminal();
|
||||
|
||||
mockRequire.stop('gritty');
|
||||
mockRequire.stop(configPath);
|
||||
reRequire(terminalPath);
|
||||
|
||||
t.equal(result, gritty, 'should equal');
|
||||
|
||||
mock.stop('gritty');
|
||||
|
||||
clean(configPath);
|
||||
require(configPath);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue