Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8526be1f4 | ||
|
|
e0b11ff480 | ||
|
|
58b9d8db9d | ||
|
|
fa121ba0fd | ||
|
|
2e02dc20ad | ||
|
|
8aeb6976d2 | ||
|
|
84a68ae03c | ||
|
|
9dfc80b99d | ||
|
|
090e3d8105 | ||
|
|
c3b0dbf5b0 | ||
|
|
69a5133936 | ||
|
|
5394908a6b | ||
|
|
3e7bd5bcf9 | ||
|
|
175b422c5f | ||
|
|
b2a9851204 | ||
|
|
977dd1579a | ||
|
|
176b2b7ca8 | ||
|
|
63777c0d74 | ||
|
|
9be8ffa60d | ||
|
|
b8cd6022e1 | ||
|
|
0618a3c675 |
22
LICENSE
22
LICENSE
@@ -1,9 +1,21 @@
|
||||
ftp-srv Copyright (c) 2017 Tyler Stewart
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
Copyright (c) 2017 Tyler Stewart
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
14
README.md
14
README.md
@@ -192,13 +192,17 @@ __Used in:__ `CWD`, `CDUP`
|
||||
Returns a path to a newly created directory
|
||||
__Used in:__ `MKD`
|
||||
|
||||
#### [`write(fileName, {append = false})`](src/fs.js#L68)
|
||||
#### [`write(fileName, {append, start})`](src/fs.js#L68)
|
||||
Returns a writable stream
|
||||
Options: `append` if true, append to existing file
|
||||
Options:
|
||||
`append` if true, append to existing file
|
||||
`start` if set, specifies the byte offset to write to
|
||||
__Used in:__ `STOR`, `APPE`
|
||||
|
||||
#### [`read(fileName)`](src/fs.js#L75)
|
||||
#### [`read(fileName, {start})`](src/fs.js#L75)
|
||||
Returns a readable stream
|
||||
Options:
|
||||
`start` if set, specifies the byte offset to read from
|
||||
__Used in:__ `RETR`
|
||||
|
||||
#### [`delete(path)`](src/fs.js#L87)
|
||||
@@ -206,11 +210,11 @@ Delete a file or directory
|
||||
__Used in:__ `DELE`
|
||||
|
||||
#### [`rename(from, to)`](src/fs.js#L102)
|
||||
Rename a file or directory
|
||||
Renames a file or directory
|
||||
__Used in:__ `RNFR`, `RNTO`
|
||||
|
||||
#### [`chmod(path)`](src/fs.js#L108)
|
||||
Modify a file or directory's permissions
|
||||
Modifies a file or directory's permissions
|
||||
__Used in:__ `SITE CHMOD`
|
||||
|
||||
#### [`getUniqueName()`](src/fs.js#L113)
|
||||
|
||||
@@ -15,12 +15,7 @@ module.exports = {
|
||||
{value: 'WIP', name: 'WIP: Work in progress'}
|
||||
],
|
||||
|
||||
scopes: [
|
||||
{name: 'accounts'},
|
||||
{name: 'admin'},
|
||||
{name: 'exampleScope'},
|
||||
{name: 'changeMe'}
|
||||
],
|
||||
scopes: [],
|
||||
|
||||
// it needs to match the value for field type. Eg.: 'fix'
|
||||
/*
|
||||
@@ -39,5 +34,5 @@ module.exports = {
|
||||
allowBreakingChanges: ['feat', 'fix'],
|
||||
|
||||
// Appends the branch name to the footer of the commit. Useful for tracking commits after branches have been merged
|
||||
appendBranchNameToCommitMessage: true
|
||||
appendBranchNameToCommitMessage: false
|
||||
};
|
||||
|
||||
12
package-lock.json
generated
12
package-lock.json
generated
@@ -3722,9 +3722,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"sinon": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/sinon/-/sinon-2.3.2.tgz",
|
||||
"integrity": "sha1-xDqcVw8yuqwRWVBc/u0ZEIhV34k=",
|
||||
"version": "2.3.5",
|
||||
"resolved": "https://registry.npmjs.org/sinon/-/sinon-2.3.5.tgz",
|
||||
"integrity": "sha1-mi/A/41SbacW8wlTqixl1RiRf2w=",
|
||||
"dev": true
|
||||
},
|
||||
"slash": {
|
||||
@@ -4210,9 +4210,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz",
|
||||
"integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE="
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
|
||||
"integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g=="
|
||||
},
|
||||
"validate-npm-package-license": {
|
||||
"version": "3.0.1",
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
"bunyan": "^1.8.10",
|
||||
"lodash": "^4.17.4",
|
||||
"moment": "^2.18.1",
|
||||
"uuid": "^3.0.1",
|
||||
"uuid": "^3.1.0",
|
||||
"when": "^3.7.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -76,7 +76,7 @@
|
||||
"npm-run-all": "4.0.2",
|
||||
"rimraf": "2.6.1",
|
||||
"semantic-release": "^6.3.6",
|
||||
"sinon": "^2.3.2"
|
||||
"sinon": "^2.3.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.x",
|
||||
|
||||
@@ -20,7 +20,8 @@ module.exports = {
|
||||
};
|
||||
|
||||
function handleTLS() {
|
||||
if (!this.server._tls) return this.reply(504);
|
||||
if (!this.server._tls) return this.reply(502);
|
||||
if (this.secure) return this.reply(202);
|
||||
|
||||
return this.reply(234)
|
||||
.then(() => {
|
||||
|
||||
@@ -9,8 +9,11 @@ module.exports = {
|
||||
const feat = _.get(registry[cmd], 'flags.feat', null);
|
||||
if (feat) return _.concat(feats, feat);
|
||||
return feats;
|
||||
}, [])
|
||||
.map(feat => ` ${feat}`);
|
||||
}, ['UTF8'])
|
||||
.map(feat => ({
|
||||
message: ` ${feat}`,
|
||||
raw: true
|
||||
}));
|
||||
return features.length
|
||||
? this.reply(211, 'Extensions supported', ...features, 'End')
|
||||
: this.reply(211, 'No features');
|
||||
|
||||
@@ -1,8 +1,34 @@
|
||||
const _ = require('lodash');
|
||||
|
||||
const OPTIONS = {
|
||||
UTF8: utf8,
|
||||
'UTF-8': utf8
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
directive: 'OPTS',
|
||||
handler: function () {
|
||||
return this.reply(501);
|
||||
handler: function ({command} = {}) {
|
||||
if (!_.has(command, 'arg')) return this.reply(501);
|
||||
|
||||
const [_option, ...args] = command.arg.split(' ');
|
||||
const option = _.toUpper(_option);
|
||||
|
||||
if (!OPTIONS.hasOwnProperty(option)) return this.reply(500);
|
||||
return OPTIONS[option].call(this, args);
|
||||
},
|
||||
syntax: '{{cmd}}',
|
||||
description: 'Select options for a feature'
|
||||
};
|
||||
|
||||
function utf8([setting] = []) {
|
||||
switch (_.toUpper(setting)) {
|
||||
case 'ON':
|
||||
this.encoding = 'utf8';
|
||||
return this.reply(200, 'UTF8 encoding on');
|
||||
case 'OFF':
|
||||
this.encoding = 'ascii';
|
||||
return this.reply(200, 'UTF8 encoding off');
|
||||
default:
|
||||
return this.reply(501, 'Unknown setting for option');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ module.exports = {
|
||||
syntax: '{{cmd}}',
|
||||
description: 'Protection Buffer Size',
|
||||
flags: {
|
||||
no_auth: true
|
||||
no_auth: true,
|
||||
feat: 'PBSZ'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -17,6 +17,7 @@ module.exports = {
|
||||
syntax: '{{cmd}}',
|
||||
description: 'Data Channel Protection Level',
|
||||
flags: {
|
||||
no_auth: true
|
||||
no_auth: true,
|
||||
feat: 'PROT'
|
||||
}
|
||||
};
|
||||
|
||||
16
src/commands/registration/rest.js
Normal file
16
src/commands/registration/rest.js
Normal file
@@ -0,0 +1,16 @@
|
||||
const _ = require('lodash');
|
||||
|
||||
module.exports = {
|
||||
directive: 'REST',
|
||||
handler: function ({command} = {}) {
|
||||
const arg = _.get(command, 'arg');
|
||||
const byteCount = parseInt(arg, 10);
|
||||
|
||||
if (isNaN(byteCount) || byteCount < 0) return this.reply(501, 'Byte count must be 0 or greater');
|
||||
|
||||
this.restByteCount = byteCount;
|
||||
return this.reply(350, `Resarting next transfer at ${byteCount}`);
|
||||
},
|
||||
syntax: '{{cmd}} <byte-count>',
|
||||
description: 'Restart transfer from the specified point. Resets after any STORE or RETRIEVE'
|
||||
};
|
||||
@@ -12,12 +12,13 @@ module.exports = {
|
||||
this.commandSocket.pause();
|
||||
dataSocket = socket;
|
||||
})
|
||||
.then(() => when.try(this.fs.read.bind(this.fs), command.arg))
|
||||
.then(() => when.try(this.fs.read.bind(this.fs), command.arg, {start: this.restByteCount}))
|
||||
.then(stream => {
|
||||
this.restByteCount = 0;
|
||||
return when.promise((resolve, reject) => {
|
||||
dataSocket.on('error', err => stream.emit('error', err));
|
||||
|
||||
stream.on('data', data => dataSocket.write(data, this.encoding));
|
||||
stream.on('data', data => dataSocket.write(data, this.transferType));
|
||||
stream.on('end', () => resolve(this.reply(226)));
|
||||
stream.on('error', err => reject(err));
|
||||
this.reply(150).then(() => dataSocket.resume());
|
||||
|
||||
@@ -15,8 +15,9 @@ module.exports = {
|
||||
this.commandSocket.pause();
|
||||
dataSocket = socket;
|
||||
})
|
||||
.then(() => when.try(this.fs.write.bind(this.fs), fileName, {append}))
|
||||
.then(() => when.try(this.fs.write.bind(this.fs), fileName, {append, start: this.restByteCount}))
|
||||
.then(stream => {
|
||||
this.restByteCount = 0;
|
||||
return when.promise((resolve, reject) => {
|
||||
stream.once('error', err => dataSocket.emit('error', err));
|
||||
stream.once('finish', () => resolve(this.reply(226, fileName)));
|
||||
@@ -25,7 +26,7 @@ module.exports = {
|
||||
// It is assumed that the `close` handler will call the end() method
|
||||
dataSocket.once('end', () => stream.listenerCount('close') ? stream.emit('close') : stream.end());
|
||||
dataSocket.once('error', err => reject(err));
|
||||
dataSocket.on('data', data => stream.write(data, this.encoding));
|
||||
dataSocket.on('data', data => stream.write(data, this.transferType));
|
||||
|
||||
this.reply(150).then(() => dataSocket.resume());
|
||||
})
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
const _ = require('lodash');
|
||||
|
||||
const ENCODING_TYPES = {
|
||||
A: 'utf8',
|
||||
I: 'binary',
|
||||
L: 'binary'
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
directive: 'TYPE',
|
||||
handler: function ({command} = {}) {
|
||||
const encoding = _.upperCase(command.arg);
|
||||
if (!ENCODING_TYPES.hasOwnProperty(encoding)) return this.reply(501);
|
||||
|
||||
this.encoding = ENCODING_TYPES[encoding];
|
||||
return this.reply(200);
|
||||
if (/^A[0-9]?$/i.test(command.arg)) {
|
||||
this.transferType = 'ascii';
|
||||
} else if (/^L[0-9]?$/i.test(command.arg) || /^I$/i.test(command.arg)) {
|
||||
this.transferType = 'binary';
|
||||
} else {
|
||||
return this.reply(501);
|
||||
}
|
||||
return this.reply(200, `Switch to "${this.transferType}" transfer mode.`);
|
||||
},
|
||||
syntax: '{{cmd}} <mode>',
|
||||
description: 'Set the transfer mode, binary (I) or utf8 (A)'
|
||||
description: 'Set the transfer mode, binary (I) or ascii (A)',
|
||||
flags: {
|
||||
feat: 'TYPE A,I,L'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -21,6 +21,7 @@ const commands = [
|
||||
require('./registration/port'),
|
||||
require('./registration/pwd'),
|
||||
require('./registration/quit'),
|
||||
require('./registration/rest'),
|
||||
require('./registration/retr'),
|
||||
require('./registration/rmd'),
|
||||
require('./registration/rnfr'),
|
||||
|
||||
@@ -15,8 +15,11 @@ class FtpConnection {
|
||||
this.id = uuid.v4();
|
||||
this.log = options.log.child({id: this.id, ip: this.ip});
|
||||
this.commands = new Commands(this);
|
||||
this.transferType = 'binary';
|
||||
this.encoding = 'utf8';
|
||||
this.bufferSize = false;
|
||||
this._restByteCount = 0;
|
||||
this._secure = false;
|
||||
|
||||
this.connector = new BaseConnector(this);
|
||||
|
||||
@@ -34,7 +37,7 @@ class FtpConnection {
|
||||
}
|
||||
|
||||
_handleData(data) {
|
||||
const messages = _.compact(data.toString('utf8').split('\r\n'));
|
||||
const messages = _.compact(data.toString(this.encoding).split('\r\n'));
|
||||
this.log.trace(messages);
|
||||
return sequence(messages.map(message => this.commands.handle.bind(this.commands, message)));
|
||||
}
|
||||
@@ -47,6 +50,20 @@ class FtpConnection {
|
||||
}
|
||||
}
|
||||
|
||||
get restByteCount() {
|
||||
return this._restByteCount > 0 ? this._restByteCount : undefined;
|
||||
}
|
||||
set restByteCount(rbc) {
|
||||
this._restByteCount = rbc;
|
||||
}
|
||||
|
||||
get secure() {
|
||||
return this.server.isTLS || this._secure;
|
||||
}
|
||||
set secure(sec) {
|
||||
this._secure = sec;
|
||||
}
|
||||
|
||||
close(code = 421, message = 'Closing connection') {
|
||||
return when
|
||||
.resolve(code)
|
||||
@@ -58,7 +75,7 @@ class FtpConnection {
|
||||
return when.try(() => {
|
||||
const loginListeners = this.server.listeners('login');
|
||||
if (!loginListeners || !loginListeners.length) {
|
||||
if (!this.server.options.anoymous) throw new errors.GeneralError('No "login" listener setup', 500);
|
||||
if (!this.server.options.anonymous) throw new errors.GeneralError('No "login" listener setup', 500);
|
||||
} else {
|
||||
return this.server.emitPromise('login', {connection: this, username, password});
|
||||
}
|
||||
@@ -102,7 +119,7 @@ class FtpConnection {
|
||||
const packet = !letter.raw ? _.compact([letter.code || options.code, letter.message]).join(seperator) : letter.message;
|
||||
|
||||
if (letter.socket && letter.socket.writable) {
|
||||
this.log.trace({port: letter.socket.address().port, packet}, 'Reply');
|
||||
this.log.trace({port: letter.socket.address().port, encoding: letter.encoding, packet}, 'Reply');
|
||||
letter.socket.write(packet + '\r\n', letter.encoding, err => {
|
||||
if (err) {
|
||||
this.log.error(err);
|
||||
|
||||
@@ -26,7 +26,7 @@ class Active extends Connector {
|
||||
return closeExistingServer()
|
||||
.then(() => {
|
||||
this.dataSocket = new Socket();
|
||||
this.dataSocket.setEncoding(this.encoding);
|
||||
this.dataSocket.setEncoding(this.connection.transferType);
|
||||
this.dataSocket.on('error', err => this.server.emit('client-error', {connection: this.connection, context: 'dataSocket', error: err}));
|
||||
this.dataSocket.connect({ host, port, family }, () => {
|
||||
this.dataSocket.pause();
|
||||
|
||||
@@ -41,7 +41,7 @@ class Passive extends Connector {
|
||||
return this.connection.reply(550, 'Remote addresses do not match')
|
||||
.finally(() => this.connection.close());
|
||||
}
|
||||
this.log.debug({port}, 'Passive connection fulfilled.');
|
||||
this.log.trace({port, remoteAddress: socket.remoteAddress}, 'Passive connection fulfilled.');
|
||||
|
||||
if (this.connection.secure) {
|
||||
const secureContext = tls.createSecureContext(this.server._tls);
|
||||
@@ -54,10 +54,10 @@ class Passive extends Connector {
|
||||
this.dataSocket = socket;
|
||||
}
|
||||
this.dataSocket.connected = true;
|
||||
this.dataSocket.setEncoding(this.connection.encoding);
|
||||
this.dataSocket.setEncoding(this.connection.transferType);
|
||||
this.dataSocket.on('error', err => this.server.emit('client-error', {connection: this.connection, context: 'dataSocket', error: err}));
|
||||
this.dataSocket.on('close', () => {
|
||||
this.log.debug('Passive connection closed');
|
||||
this.log.trace('Passive connection closed');
|
||||
this.end();
|
||||
});
|
||||
};
|
||||
@@ -67,7 +67,7 @@ class Passive extends Connector {
|
||||
this.dataServer.maxConnections = 1;
|
||||
this.dataServer.on('error', err => this.server.emit('client-error', {connection: this.connection, context: 'dataServer', error: err}));
|
||||
this.dataServer.on('close', () => {
|
||||
this.log.debug('Passive server closed');
|
||||
this.log.trace('Passive server closed');
|
||||
this.dataServer = null;
|
||||
});
|
||||
|
||||
@@ -75,7 +75,7 @@ class Passive extends Connector {
|
||||
this.dataServer.listen(port, err => {
|
||||
if (err) reject(err);
|
||||
else {
|
||||
this.log.info({port}, 'Passive connection listening');
|
||||
this.log.debug({port}, 'Passive connection listening');
|
||||
resolve(this.dataServer);
|
||||
}
|
||||
});
|
||||
@@ -89,7 +89,8 @@ class Passive extends Connector {
|
||||
this.server.options.pasv_range.split('-').map(v => v ? parseInt(v) : v) :
|
||||
[this.server.options.pasv_range];
|
||||
return findPort(min, max);
|
||||
} else return undefined;
|
||||
}
|
||||
throw new errors.ConnectorError('Invalid pasv_range');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -65,22 +65,22 @@ class FileSystem {
|
||||
});
|
||||
}
|
||||
|
||||
write(fileName, {append = false} = {}) {
|
||||
write(fileName, {append = false, start = undefined} = {}) {
|
||||
const {fsPath} = this._resolvePath(fileName);
|
||||
const stream = syncFs.createWriteStream(fsPath, {flags: !append ? 'w+' : 'a+'});
|
||||
const stream = syncFs.createWriteStream(fsPath, {flags: !append ? 'w+' : 'a+', start});
|
||||
stream.once('error', () => fs.unlink(fsPath));
|
||||
stream.once('close', () => stream.end());
|
||||
return stream;
|
||||
}
|
||||
|
||||
read(fileName) {
|
||||
read(fileName, {start = undefined} = {}) {
|
||||
const {fsPath} = this._resolvePath(fileName);
|
||||
return fs.stat(fsPath)
|
||||
.tap(stat => {
|
||||
if (stat.isDirectory()) throw new errors.FileSystemError('Cannot read a directory');
|
||||
})
|
||||
.then(() => {
|
||||
const stream = syncFs.createReadStream(fsPath, {flags: 'r'});
|
||||
const stream = syncFs.createReadStream(fsPath, {flags: 'r', start});
|
||||
return stream;
|
||||
});
|
||||
}
|
||||
|
||||
10
src/index.js
10
src/index.js
@@ -47,17 +47,13 @@ class FtpServer {
|
||||
|
||||
this.server = (this.isTLS ? tls : net).createServer(serverOptions, serverConnectionHandler);
|
||||
this.server.on('error', err => this.log.error(err, '[Event] error'));
|
||||
if (this.isTLS) {
|
||||
this.server.on('tlsClientError', err => this.log.error(err, '[Event] tlsClientError'));
|
||||
}
|
||||
this.on = this.server.on.bind(this.server);
|
||||
this.once = this.server.once.bind(this.server);
|
||||
this.listeners = this.server.listeners.bind(this.server);
|
||||
|
||||
process.on('SIGTERM', () => this.close());
|
||||
process.on('SIGINT', () => this.close());
|
||||
process.on('SIGBREAK', () => this.close());
|
||||
process.on('SIGHUP', () => this.close());
|
||||
process.on('SIGQUIT', () => this.close());
|
||||
}
|
||||
|
||||
get isTLS() {
|
||||
@@ -94,8 +90,8 @@ class FtpServer {
|
||||
}
|
||||
|
||||
setupTLS(_tls) {
|
||||
if (!tls) return false;
|
||||
return _.assign(_tls, {
|
||||
if (!_tls) return false;
|
||||
return _.assign({}, _tls, {
|
||||
cert: _tls.cert ? fs.readFileSync(_tls.cert) : undefined,
|
||||
key: _tls.key ? fs.readFileSync(_tls.key) : undefined,
|
||||
ca: _tls.ca ? Array.isArray(_tls.ca) ? _tls.ca.map(_ca => fs.readFileSync(_ca)) : [fs.readFileSync(_tls.ca)] : undefined
|
||||
|
||||
@@ -25,29 +25,25 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('// successful | no active connection', done => {
|
||||
it('// successful | no active connection', () => {
|
||||
mockClient.connector.waitForConnection.restore();
|
||||
sandbox.stub(mockClient.connector, 'waitForConnection').rejects();
|
||||
|
||||
cmdFn()
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.connector.waitForConnection.callCount).to.equal(1);
|
||||
expect(mockClient.connector.end.callCount).to.equal(0);
|
||||
expect(mockClient.reply.args[0][0]).to.equal(226);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// successful | active connection', done => {
|
||||
cmdFn()
|
||||
it('// successful | active connection', () => {
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.connector.waitForConnection.callCount).to.equal(1);
|
||||
expect(mockClient.connector.end.callCount).to.equal(1);
|
||||
expect(mockClient.reply.args[0][0]).to.equal(426);
|
||||
expect(mockClient.reply.args[1][0]).to.equal(226);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,12 +19,10 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('// successful', done => {
|
||||
cmdFn()
|
||||
it('// successful', () => {
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(202);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,31 +22,25 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('TLS // supported', done => {
|
||||
cmdFn({command: { arg: 'TLS', directive: CMD}})
|
||||
it('TLS // supported', () => {
|
||||
return cmdFn({command: { arg: 'TLS', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(234);
|
||||
expect(mockClient.secure).to.equal(true);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('SSL // not supported', done => {
|
||||
cmdFn({command: { arg: 'SSL', directive: CMD}})
|
||||
it('SSL // not supported', () => {
|
||||
return cmdFn({command: { arg: 'SSL', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(504);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('bad // bad', done => {
|
||||
cmdFn({command: { arg: 'bad', directive: CMD}})
|
||||
it('bad // bad', () => {
|
||||
return cmdFn({command: { arg: 'bad', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(504);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,13 +25,11 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('.. // successful', done => {
|
||||
cmdFn({log, command: {directive: CMD}})
|
||||
it('.. // successful', () => {
|
||||
return cmdFn({log, command: {directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(250);
|
||||
expect(mockClient.fs.chdir.args[0][0]).to.equal('..');
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,63 +23,56 @@ describe(CMD, function () {
|
||||
});
|
||||
|
||||
describe('// check', function () {
|
||||
it('fails on no fs', done => {
|
||||
it('fails on no fs', () => {
|
||||
const badMockClient = { reply: () => {} };
|
||||
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
|
||||
sandbox.stub(badMockClient, 'reply').resolves();
|
||||
badCmdFn()
|
||||
|
||||
return badCmdFn()
|
||||
.then(() => {
|
||||
expect(badMockClient.reply.args[0][0]).to.equal(550);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('fails on no fs chdir command', done => {
|
||||
it('fails on no fs chdir command', () => {
|
||||
const badMockClient = { reply: () => {}, fs: {} };
|
||||
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
|
||||
sandbox.stub(badMockClient, 'reply').resolves();
|
||||
badCmdFn()
|
||||
|
||||
return badCmdFn()
|
||||
.then(() => {
|
||||
expect(badMockClient.reply.args[0][0]).to.equal(402);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('test // successful', done => {
|
||||
cmdFn({log, command: { arg: 'test', directive: CMD}})
|
||||
it('test // successful', () => {
|
||||
return cmdFn({log, command: { arg: 'test', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(250);
|
||||
expect(mockClient.fs.chdir.args[0][0]).to.equal('test');
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('test // successful', done => {
|
||||
it('test // successful', () => {
|
||||
mockClient.fs.chdir.restore();
|
||||
sandbox.stub(mockClient.fs, 'chdir').resolves('/test');
|
||||
cmdFn({log, command: { arg: 'test', directive: CMD}})
|
||||
|
||||
return cmdFn({log, command: { arg: 'test', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(250);
|
||||
expect(mockClient.fs.chdir.args[0][0]).to.equal('test');
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('bad // unsuccessful', done => {
|
||||
it('bad // unsuccessful', () => {
|
||||
mockClient.fs.chdir.restore();
|
||||
sandbox.stub(mockClient.fs, 'chdir').rejects(new Error('Bad'));
|
||||
|
||||
cmdFn({log, command: { arg: 'bad', directive: CMD}})
|
||||
return cmdFn({log, command: { arg: 'bad', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(550);
|
||||
expect(mockClient.fs.chdir.args[0][0]).to.equal('bad');
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,51 +23,45 @@ describe(CMD, function () {
|
||||
});
|
||||
|
||||
describe('// check', function () {
|
||||
it('fails on no fs', done => {
|
||||
it('fails on no fs', () => {
|
||||
const badMockClient = { reply: () => {} };
|
||||
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
|
||||
sandbox.stub(badMockClient, 'reply').resolves();
|
||||
badCmdFn()
|
||||
|
||||
return badCmdFn()
|
||||
.then(() => {
|
||||
expect(badMockClient.reply.args[0][0]).to.equal(550);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('fails on no fs delete command', done => {
|
||||
it('fails on no fs delete command', () => {
|
||||
const badMockClient = { reply: () => {}, fs: {} };
|
||||
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
|
||||
sandbox.stub(badMockClient, 'reply').resolves();
|
||||
badCmdFn()
|
||||
|
||||
return badCmdFn()
|
||||
.then(() => {
|
||||
expect(badMockClient.reply.args[0][0]).to.equal(402);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('test // successful', done => {
|
||||
cmdFn({log, command: { arg: 'test', directive: CMD}})
|
||||
it('test // successful', () => {
|
||||
return cmdFn({log, command: { arg: 'test', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(250);
|
||||
expect(mockClient.fs.delete.args[0][0]).to.equal('test');
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('bad // unsuccessful', done => {
|
||||
it('bad // unsuccessful', () => {
|
||||
mockClient.fs.delete.restore();
|
||||
sandbox.stub(mockClient.fs, 'delete').rejects(new Error('Bad'));
|
||||
|
||||
cmdFn({log, command: { arg: 'bad', directive: CMD}})
|
||||
return cmdFn({log, command: { arg: 'bad', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(550);
|
||||
expect(mockClient.fs.delete.args[0][0]).to.equal('bad');
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,39 +19,31 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('// successful', done => {
|
||||
cmdFn({command: { directive: CMD }})
|
||||
it('// successful', () => {
|
||||
return cmdFn({command: { directive: CMD }})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(211);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('help // successful', done => {
|
||||
cmdFn({command: { arg: 'help', directive: CMD}})
|
||||
it('help // successful', () => {
|
||||
return cmdFn({command: { arg: 'help', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(214);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('help // successful', done => {
|
||||
cmdFn({command: { arg: 'allo', directive: CMD}})
|
||||
it('allo // successful', () => {
|
||||
return cmdFn({command: { arg: 'allo', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(214);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('bad // unsuccessful', done => {
|
||||
cmdFn({command: { arg: 'bad', directive: CMD}})
|
||||
it('bad // unsuccessful', () => {
|
||||
return cmdFn({command: { arg: 'bad', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(502);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -87,33 +87,31 @@ describe(CMD, function () {
|
||||
});
|
||||
|
||||
describe('// check', function () {
|
||||
it('fails on no fs', done => {
|
||||
it('fails on no fs', () => {
|
||||
const badMockClient = { reply: () => {} };
|
||||
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
|
||||
sandbox.stub(badMockClient, 'reply').resolves();
|
||||
badCmdFn()
|
||||
|
||||
return badCmdFn()
|
||||
.then(() => {
|
||||
expect(badMockClient.reply.args[0][0]).to.equal(550);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('fails on no fs list command', done => {
|
||||
it('fails on no fs list command', () => {
|
||||
const badMockClient = { reply: () => {}, fs: {} };
|
||||
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
|
||||
sandbox.stub(badMockClient, 'reply').resolves();
|
||||
badCmdFn()
|
||||
|
||||
return badCmdFn()
|
||||
.then(() => {
|
||||
expect(badMockClient.reply.args[0][0]).to.equal(402);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('. // successful', done => {
|
||||
cmdFn({log, command: {directive: CMD}})
|
||||
it('. // successful', () => {
|
||||
return cmdFn({log, command: {directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(150);
|
||||
expect(mockClient.reply.args[1].length).to.equal(3);
|
||||
@@ -121,12 +119,10 @@ describe(CMD, function () {
|
||||
expect(mockClient.reply.args[1][1]).to.have.property('message');
|
||||
expect(mockClient.reply.args[1][1]).to.have.property('socket');
|
||||
expect(mockClient.reply.args[2][0]).to.equal(226);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('testfile.txt // successful', done => {
|
||||
it('testfile.txt // successful', () => {
|
||||
mockClient.fs.get.restore();
|
||||
sandbox.stub(mockClient.fs, 'get').resolves({
|
||||
name: 'testfile.txt',
|
||||
@@ -147,7 +143,7 @@ describe(CMD, function () {
|
||||
isDirectory: () => false
|
||||
});
|
||||
|
||||
cmdFn({log, command: {directive: CMD, arg: 'testfile.txt'}})
|
||||
return cmdFn({log, command: {directive: CMD, arg: 'testfile.txt'}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(150);
|
||||
expect(mockClient.reply.args[1].length).to.equal(2);
|
||||
@@ -155,31 +151,25 @@ describe(CMD, function () {
|
||||
expect(mockClient.reply.args[1][1]).to.have.property('message');
|
||||
expect(mockClient.reply.args[1][1]).to.have.property('socket');
|
||||
expect(mockClient.reply.args[2][0]).to.equal(226);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('. // unsuccessful', done => {
|
||||
it('. // unsuccessful', () => {
|
||||
mockClient.fs.list.restore();
|
||||
sandbox.stub(mockClient.fs, 'list').rejects(new Error());
|
||||
|
||||
cmdFn({log, command: {directive: CMD}})
|
||||
return cmdFn({log, command: {directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(451);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('. // unsuccessful (timeout)', done => {
|
||||
it('. // unsuccessful (timeout)', () => {
|
||||
sandbox.stub(mockClient.connector, 'waitForConnection').returns(when.reject(new when.TimeoutError()));
|
||||
|
||||
cmdFn({log, command: {directive: CMD}})
|
||||
return cmdFn({log, command: {directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(425);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,50 +23,44 @@ describe(CMD, function () {
|
||||
});
|
||||
|
||||
describe('// check', function () {
|
||||
it('fails on no fs', done => {
|
||||
it('fails on no fs', () => {
|
||||
const badMockClient = { reply: () => {} };
|
||||
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
|
||||
sandbox.stub(badMockClient, 'reply').resolves();
|
||||
badCmdFn()
|
||||
|
||||
return badCmdFn()
|
||||
.then(() => {
|
||||
expect(badMockClient.reply.args[0][0]).to.equal(550);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('fails on no fs get command', done => {
|
||||
it('fails on no fs get command', () => {
|
||||
const badMockClient = { reply: () => {}, fs: {} };
|
||||
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
|
||||
sandbox.stub(badMockClient, 'reply').resolves();
|
||||
badCmdFn()
|
||||
|
||||
return badCmdFn()
|
||||
.then(() => {
|
||||
expect(badMockClient.reply.args[0][0]).to.equal(402);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('. // successful', done => {
|
||||
cmdFn({log, command: {directive: CMD}})
|
||||
it('. // successful', () => {
|
||||
return cmdFn({log, command: {directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(213);
|
||||
//expect(mockClient.reply.args[0][1]).to.equal('20111010172411.000');
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('. // unsuccessful', done => {
|
||||
it('. // unsuccessful', () => {
|
||||
mockClient.fs.get.restore();
|
||||
sandbox.stub(mockClient.fs, 'get').rejects(new Error());
|
||||
|
||||
cmdFn({log, command: {directive: CMD}})
|
||||
return cmdFn({log, command: {directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(550);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,63 +23,56 @@ describe(CMD, function () {
|
||||
});
|
||||
|
||||
describe('// check', function () {
|
||||
it('fails on no fs', done => {
|
||||
it('fails on no fs', () => {
|
||||
const badMockClient = { reply: () => {} };
|
||||
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
|
||||
sandbox.stub(badMockClient, 'reply').resolves();
|
||||
badCmdFn()
|
||||
|
||||
return badCmdFn()
|
||||
.then(() => {
|
||||
expect(badMockClient.reply.args[0][0]).to.equal(550);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('fails on no fs mkdir command', done => {
|
||||
it('fails on no fs mkdir command', () => {
|
||||
const badMockClient = { reply: () => {}, fs: {} };
|
||||
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
|
||||
sandbox.stub(badMockClient, 'reply').resolves();
|
||||
badCmdFn()
|
||||
|
||||
return badCmdFn()
|
||||
.then(() => {
|
||||
expect(badMockClient.reply.args[0][0]).to.equal(402);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('test // successful', done => {
|
||||
cmdFn({log, command: {arg: 'test', directive: CMD}})
|
||||
it('test // successful', () => {
|
||||
return cmdFn({log, command: {arg: 'test', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(257);
|
||||
expect(mockClient.fs.mkdir.args[0][0]).to.equal('test');
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('test // successful', done => {
|
||||
it('test // successful', () => {
|
||||
mockClient.fs.mkdir.restore();
|
||||
sandbox.stub(mockClient.fs, 'mkdir').resolves('test');
|
||||
cmdFn({log, command: {arg: 'test', directive: CMD}})
|
||||
|
||||
return cmdFn({log, command: {arg: 'test', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(257);
|
||||
expect(mockClient.fs.mkdir.args[0][0]).to.equal('test');
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('bad // unsuccessful', done => {
|
||||
it('bad // unsuccessful', () => {
|
||||
mockClient.fs.mkdir.restore();
|
||||
sandbox.stub(mockClient.fs, 'mkdir').rejects(new Error('Bad'));
|
||||
|
||||
cmdFn({log, command: {arg: 'bad', directive: CMD}})
|
||||
return cmdFn({log, command: {arg: 'bad', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(550);
|
||||
expect(mockClient.fs.mkdir.args[0][0]).to.equal('bad');
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,21 +19,17 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('S // successful', done => {
|
||||
cmdFn({command: {arg: 'S'}})
|
||||
it('S // successful', () => {
|
||||
return cmdFn({command: {arg: 'S'}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(200);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('Q // unsuccessful', done => {
|
||||
cmdFn({command: {arg: 'Q'}})
|
||||
it('Q // unsuccessful', () => {
|
||||
return cmdFn({command: {arg: 'Q'}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(504);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -86,8 +86,8 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('. // successful', done => {
|
||||
cmdFn({log, command: {directive: CMD}})
|
||||
it('. // successful', () => {
|
||||
return cmdFn({log, command: {directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(150);
|
||||
expect(mockClient.reply.args[1].length).to.equal(3);
|
||||
@@ -95,12 +95,10 @@ describe(CMD, function () {
|
||||
expect(mockClient.reply.args[1][1]).to.have.property('message');
|
||||
expect(mockClient.reply.args[1][1]).to.have.property('socket');
|
||||
expect(mockClient.reply.args[2][0]).to.equal(226);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('testfile.txt // successful', done => {
|
||||
it('testfile.txt // successful', () => {
|
||||
mockClient.fs.get.restore();
|
||||
sandbox.stub(mockClient.fs, 'get').resolves({
|
||||
name: 'testfile.txt',
|
||||
@@ -121,7 +119,7 @@ describe(CMD, function () {
|
||||
isDirectory: () => false
|
||||
});
|
||||
|
||||
cmdFn({log, command: {directive: CMD, arg: 'testfile.txt'}})
|
||||
return cmdFn({log, command: {directive: CMD, arg: 'testfile.txt'}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(150);
|
||||
expect(mockClient.reply.args[1].length).to.equal(2);
|
||||
@@ -129,8 +127,6 @@ describe(CMD, function () {
|
||||
expect(mockClient.reply.args[1][1]).to.have.property('message');
|
||||
expect(mockClient.reply.args[1][1]).to.have.property('socket');
|
||||
expect(mockClient.reply.args[2][0]).to.equal(226);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,12 +19,10 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('// successful', done => {
|
||||
cmdFn()
|
||||
it('// successful', () => {
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(200);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,12 +19,40 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('// successful', done => {
|
||||
cmdFn()
|
||||
it('// unsuccessful', () => {
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(501);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('BAD // unsuccessful', () => {
|
||||
return cmdFn({command: {arg: 'BAD', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(500);
|
||||
});
|
||||
});
|
||||
|
||||
it('UTF8 BAD // unsuccessful', () => {
|
||||
return cmdFn({command: {arg: 'UTF8 BAD', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(501);
|
||||
});
|
||||
});
|
||||
|
||||
it('UTF8 OFF // successful', () => {
|
||||
return cmdFn({command: {arg: 'UTF8 OFF', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.encoding).to.equal('ascii');
|
||||
expect(mockClient.reply.args[0][0]).to.equal(200);
|
||||
});
|
||||
});
|
||||
|
||||
it('UTF8 ON // successful', () => {
|
||||
return cmdFn({command: {arg: 'UTF8 ON', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.encoding).to.equal('utf8');
|
||||
expect(mockClient.reply.args[0][0]).to.equal(200);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -24,61 +24,51 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('pass // successful', done => {
|
||||
cmdFn({log, command: {arg: 'pass', directive: CMD}})
|
||||
it('pass // successful', () => {
|
||||
return cmdFn({log, command: {arg: 'pass', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(230);
|
||||
expect(mockClient.login.args[0]).to.eql(['anonymous', 'pass']);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// successful (already authenticated)', done => {
|
||||
it('// successful (already authenticated)', () => {
|
||||
mockClient.server.options.anonymous = true;
|
||||
mockClient.authenticated = true;
|
||||
cmdFn({log, command: {directive: CMD}})
|
||||
return cmdFn({log, command: {directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(202);
|
||||
expect(mockClient.login.callCount).to.equal(0);
|
||||
mockClient.server.options.anonymous = false;
|
||||
mockClient.authenticated = false;
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('bad // unsuccessful', done => {
|
||||
it('bad // unsuccessful', () => {
|
||||
mockClient.login.restore();
|
||||
sandbox.stub(mockClient, 'login').rejects('bad');
|
||||
|
||||
cmdFn({log, command: {arg: 'bad', directive: CMD}})
|
||||
return cmdFn({log, command: {arg: 'bad', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(530);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('bad // unsuccessful', done => {
|
||||
it('bad // unsuccessful', () => {
|
||||
mockClient.login.restore();
|
||||
sandbox.stub(mockClient, 'login').rejects({});
|
||||
|
||||
cmdFn({log, command: {arg: 'bad', directive: CMD}})
|
||||
return cmdFn({log, command: {arg: 'bad', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(530);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('bad // unsuccessful', done => {
|
||||
it('bad // unsuccessful', () => {
|
||||
delete mockClient.username;
|
||||
cmdFn({log, command: {arg: 'bad', directive: CMD}})
|
||||
return cmdFn({log, command: {arg: 'bad', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(503);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,38 +20,32 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('// unsuccessful', done => {
|
||||
cmdFn()
|
||||
it('// unsuccessful', () => {
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(202);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// successful', done => {
|
||||
it('// successful', () => {
|
||||
mockClient.secure = true;
|
||||
mockClient.server._tls = {};
|
||||
|
||||
cmdFn({command: {arg: '0'}})
|
||||
return cmdFn({command: {arg: '0'}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(200);
|
||||
expect(mockClient.bufferSize).to.equal(0);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// successful', done => {
|
||||
it('// successful', () => {
|
||||
mockClient.secure = true;
|
||||
mockClient.server._tls = {};
|
||||
|
||||
cmdFn({command: {arg: '10'}})
|
||||
return cmdFn({command: {arg: '10'}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(200);
|
||||
expect(mockClient.bufferSize).to.equal(10);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,33 +22,27 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('// unsuccessful | no argument', done => {
|
||||
cmdFn()
|
||||
it('// unsuccessful | no argument', () => {
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(425);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful | invalid argument', done => {
|
||||
cmdFn({ command: { arg: '1,2,3,4,5' } })
|
||||
it('// unsuccessful | invalid argument', () => {
|
||||
return cmdFn({ command: { arg: '1,2,3,4,5' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(425);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// successful', done => {
|
||||
cmdFn({ command: { arg: '192,168,0,100,137,214' } })
|
||||
it('// successful', () => {
|
||||
return cmdFn({ command: { arg: '192,168,0,100,137,214' } })
|
||||
.then(() => {
|
||||
const [ip, port] = ActiveConnector.prototype.setupConnection.args[0];
|
||||
expect(mockClient.reply.args[0][0]).to.equal(200);
|
||||
expect(ip).to.equal('192.168.0.100');
|
||||
expect(port).to.equal(35286);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,56 +20,46 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('// unsuccessful', done => {
|
||||
cmdFn()
|
||||
it('// unsuccessful', () => {
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(202);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful - no bufferSize', done => {
|
||||
it('// unsuccessful - no bufferSize', () => {
|
||||
mockClient.server._tls = {};
|
||||
mockClient.secure = true;
|
||||
|
||||
cmdFn({command: {arg: 'P'}})
|
||||
return cmdFn({command: {arg: 'P'}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(503);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// successful', done => {
|
||||
it('// successful', () => {
|
||||
mockClient.bufferSize = 0;
|
||||
mockClient.secure = true;
|
||||
|
||||
cmdFn({command: {arg: 'p'}})
|
||||
return cmdFn({command: {arg: 'p'}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(200);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful - unsupported', done => {
|
||||
it('// unsuccessful - unsupported', () => {
|
||||
mockClient.secure = true;
|
||||
cmdFn({command: {arg: 'C'}})
|
||||
return cmdFn({command: {arg: 'C'}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(536);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful - unknown', done => {
|
||||
it('// unsuccessful - unknown', () => {
|
||||
mockClient.secure = true;
|
||||
cmdFn({command: {arg: 'QQ'}})
|
||||
return cmdFn({command: {arg: 'QQ'}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(504);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,61 +23,53 @@ describe(CMD, function () {
|
||||
});
|
||||
|
||||
describe('// check', function () {
|
||||
it('fails on no fs', done => {
|
||||
it('fails on no fs', () => {
|
||||
const badMockClient = { reply: () => {} };
|
||||
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
|
||||
sandbox.stub(badMockClient, 'reply').resolves();
|
||||
badCmdFn()
|
||||
|
||||
return badCmdFn()
|
||||
.then(() => {
|
||||
expect(badMockClient.reply.args[0][0]).to.equal(550);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('fails on no fs currentDirectory command', done => {
|
||||
it('fails on no fs currentDirectory command', () => {
|
||||
const badMockClient = { reply: () => {}, fs: {} };
|
||||
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
|
||||
sandbox.stub(badMockClient, 'reply').resolves();
|
||||
badCmdFn()
|
||||
|
||||
return badCmdFn()
|
||||
.then(() => {
|
||||
expect(badMockClient.reply.args[0][0]).to.equal(402);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('// successful', done => {
|
||||
cmdFn({log, command: { arg: 'test', directive: CMD}})
|
||||
it('// successful', () => {
|
||||
return cmdFn({log, command: { arg: 'test', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(257);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// successful', done => {
|
||||
it('// successful', () => {
|
||||
mockClient.fs.currentDirectory.restore();
|
||||
sandbox.stub(mockClient.fs, 'currentDirectory').resolves('/test');
|
||||
|
||||
cmdFn({log, command: {arg: 'test', directive: CMD}})
|
||||
return cmdFn({log, command: {arg: 'test', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(257);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful', done => {
|
||||
it('// unsuccessful', () => {
|
||||
mockClient.fs.currentDirectory.restore();
|
||||
sandbox.stub(mockClient.fs, 'currentDirectory').rejects(new Error('Bad'));
|
||||
|
||||
cmdFn({log, command: {arg: 'bad', directive: CMD}})
|
||||
return cmdFn({log, command: {arg: 'bad', directive: CMD}})
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(550);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -18,12 +18,10 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('// successful', done => {
|
||||
cmdFn()
|
||||
it('// successful', () => {
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.close.callCount).to.equal(1);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
58
test/commands/registration/rest.spec.js
Normal file
58
test/commands/registration/rest.spec.js
Normal file
@@ -0,0 +1,58 @@
|
||||
const {expect} = require('chai');
|
||||
const sinon = require('sinon');
|
||||
const when = require('when');
|
||||
|
||||
const CMD = 'REST';
|
||||
describe(CMD, function () {
|
||||
let sandbox;
|
||||
const mockClient = {
|
||||
reply: () => when.resolve()
|
||||
};
|
||||
const cmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(mockClient);
|
||||
|
||||
beforeEach(() => {
|
||||
sandbox = sinon.sandbox.create();
|
||||
|
||||
sandbox.spy(mockClient, 'reply');
|
||||
});
|
||||
afterEach(() => {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('// unsuccessful', () => {
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(501);
|
||||
});
|
||||
});
|
||||
|
||||
it('-1 // unsuccessful', () => {
|
||||
return cmdFn({command: { arg: '-1', directive: CMD } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(501);
|
||||
});
|
||||
});
|
||||
|
||||
it('bad // unsuccessful', () => {
|
||||
return cmdFn({command: { arg: 'bad', directive: CMD } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(501);
|
||||
});
|
||||
});
|
||||
|
||||
it('1 // successful', () => {
|
||||
return cmdFn({command: { arg: '1', directive: CMD } })
|
||||
.then(() => {
|
||||
expect(mockClient.restByteCount).to.equal(1);
|
||||
expect(mockClient.reply.args[0][0]).to.equal(350);
|
||||
});
|
||||
});
|
||||
|
||||
it('0 // successful', () => {
|
||||
return cmdFn({command: { arg: '0', directive: CMD } })
|
||||
.then(() => {
|
||||
expect(mockClient.restByteCount).to.equal(0);
|
||||
expect(mockClient.reply.args[0][0]).to.equal(350);
|
||||
});
|
||||
});
|
||||
});
|
||||
75
test/commands/registration/retr.spec.js
Normal file
75
test/commands/registration/retr.spec.js
Normal file
@@ -0,0 +1,75 @@
|
||||
const when = require('when');
|
||||
const bunyan = require('bunyan');
|
||||
const {expect} = require('chai');
|
||||
const sinon = require('sinon');
|
||||
|
||||
const CMD = 'RETR';
|
||||
describe(CMD, function () {
|
||||
let sandbox;
|
||||
let log = bunyan.createLogger({name: CMD});
|
||||
const mockClient = {
|
||||
commandSocket: {
|
||||
pause: () => {},
|
||||
resume: () => {}
|
||||
},
|
||||
reply: () => when.resolve(),
|
||||
connector: {
|
||||
waitForConnection: () => when.resolve({
|
||||
resume: () => {}
|
||||
}),
|
||||
end: () => {}
|
||||
}
|
||||
};
|
||||
const cmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(mockClient);
|
||||
|
||||
beforeEach(() => {
|
||||
sandbox = sinon.sandbox.create();
|
||||
|
||||
mockClient.fs = {
|
||||
read: () => {}
|
||||
};
|
||||
|
||||
sandbox.spy(mockClient, 'reply');
|
||||
});
|
||||
afterEach(() => sandbox.restore());
|
||||
|
||||
it('// unsuccessful | no file system', () => {
|
||||
delete mockClient.fs;
|
||||
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(550);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful | file system does not have functions', () => {
|
||||
mockClient.fs = {};
|
||||
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(402);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful | connector times out', () => {
|
||||
sandbox.stub(mockClient.connector, 'waitForConnection').callsFake(function () {
|
||||
return when.reject(new when.TimeoutError());
|
||||
});
|
||||
|
||||
return cmdFn({log, command: {arg: 'test.txt'} })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(425);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful | connector errors out', () => {
|
||||
sandbox.stub(mockClient.connector, 'waitForConnection').callsFake(function () {
|
||||
return when.reject(new Error('test'));
|
||||
});
|
||||
|
||||
return cmdFn({log, command: {arg: 'test.txt'} })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(551);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -24,47 +24,39 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('// unsuccessful | no file system', done => {
|
||||
it('// unsuccessful | no file system', () => {
|
||||
delete mockClient.fs;
|
||||
|
||||
cmdFn()
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(550);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful | file system does not have functions', done => {
|
||||
it('// unsuccessful | file system does not have functions', () => {
|
||||
mockClient.fs = {};
|
||||
|
||||
cmdFn()
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(402);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('test // unsuccessful | file get fails', done => {
|
||||
it('test // unsuccessful | file get fails', () => {
|
||||
mockClient.fs.get.restore();
|
||||
sandbox.stub(mockClient.fs, 'get').rejects(new Error('test'));
|
||||
|
||||
cmdFn({ log: mockLog, command: { arg: 'test' } })
|
||||
return cmdFn({ log: mockLog, command: { arg: 'test' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(550);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('test // successful', done => {
|
||||
cmdFn({ log: mockLog, command: { arg: 'test' } })
|
||||
it('test // successful', () => {
|
||||
return cmdFn({ log: mockLog, command: { arg: 'test' } })
|
||||
.then(() => {
|
||||
expect(mockClient.fs.get.args[0][0]).to.equal('test');
|
||||
expect(mockClient.reply.args[0][0]).to.equal(350);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,58 +25,48 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('// unsuccessful | no renameFrom set', done => {
|
||||
it('// unsuccessful | no renameFrom set', () => {
|
||||
delete mockClient.renameFrom;
|
||||
|
||||
cmdFn()
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(503);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful | no file system', done => {
|
||||
it('// unsuccessful | no file system', () => {
|
||||
delete mockClient.fs;
|
||||
|
||||
cmdFn()
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(550);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful | file system does not have functions', done => {
|
||||
it('// unsuccessful | file system does not have functions', () => {
|
||||
mockClient.fs = {};
|
||||
|
||||
cmdFn()
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(402);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('new // unsuccessful | rename fails', done => {
|
||||
it('new // unsuccessful | rename fails', () => {
|
||||
mockClient.fs.rename.restore();
|
||||
sandbox.stub(mockClient.fs, 'rename').rejects(new Error('test'));
|
||||
|
||||
cmdFn({ log: mockLog, command: { arg: 'new' } })
|
||||
return cmdFn({ log: mockLog, command: { arg: 'new' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(550);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('new // successful', done => {
|
||||
cmdFn({ command: { arg: 'new' } })
|
||||
it('new // successful', () => {
|
||||
return cmdFn({ command: { arg: 'new' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(250);
|
||||
expect(mockClient.fs.rename.args[0]).to.eql(['test', 'new']);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,45 +22,37 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('// unsuccessful | no file system', done => {
|
||||
it('// unsuccessful | no file system', () => {
|
||||
delete mockClient.fs;
|
||||
|
||||
cmdFn()
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(550);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful | file system does not have functions', done => {
|
||||
it('// unsuccessful | file system does not have functions', () => {
|
||||
mockClient.fs = {};
|
||||
|
||||
cmdFn()
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(402);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful | file get fails', done => {
|
||||
it('// unsuccessful | file get fails', () => {
|
||||
sandbox.stub(mockClient.fs, 'get').rejects(new Error('test'));
|
||||
|
||||
cmdFn({ log: mockLog, command: { arg: 'test' } })
|
||||
return cmdFn({ log: mockLog, command: { arg: 'test' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(550);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// successful', done => {
|
||||
cmdFn({ command: { arg: 'test' } })
|
||||
it('// successful', () => {
|
||||
return cmdFn({ command: { arg: 'test' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(213);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,49 +23,41 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('// successful', done => {
|
||||
cmdFn()
|
||||
it('// successful', () => {
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(211);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful | no file system', done => {
|
||||
it('// unsuccessful | no file system', () => {
|
||||
delete mockClient.fs;
|
||||
|
||||
cmdFn({ command: { arg: 'test' } })
|
||||
return cmdFn({ command: { arg: 'test' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(550);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful | file system does not have functions', done => {
|
||||
it('// unsuccessful | file system does not have functions', () => {
|
||||
mockClient.fs = {};
|
||||
|
||||
cmdFn({ command: { arg: 'test' } })
|
||||
return cmdFn({ command: { arg: 'test' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(402);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful | file get fails', done => {
|
||||
it('// unsuccessful | file get fails', () => {
|
||||
sandbox.stub(mockClient.fs, 'get').rejects(new Error('test'));
|
||||
|
||||
cmdFn({ log: mockLog, command: { arg: 'test' } })
|
||||
return cmdFn({ log: mockLog, command: { arg: 'test' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(450);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// successful | file', done => {
|
||||
it('// successful | file', () => {
|
||||
sandbox.stub(mockClient.fs, 'get').returns({
|
||||
name: 'test_file',
|
||||
dev: 2114,
|
||||
@@ -85,15 +77,13 @@ describe(CMD, function () {
|
||||
isDirectory: () => false
|
||||
});
|
||||
|
||||
cmdFn({ command: { arg: 'test' } })
|
||||
return cmdFn({ command: { arg: 'test' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(212);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// successful | directory', done => {
|
||||
it('// successful | directory', () => {
|
||||
sandbox.stub(mockClient.fs, 'list').returns([{
|
||||
name: 'test_file',
|
||||
dev: 2114,
|
||||
@@ -132,11 +122,9 @@ describe(CMD, function () {
|
||||
isDirectory: () => true
|
||||
});
|
||||
|
||||
cmdFn({ command: { arg: 'test' } })
|
||||
return cmdFn({ command: { arg: 'test' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(213);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
75
test/commands/registration/stor.spec.js
Normal file
75
test/commands/registration/stor.spec.js
Normal file
@@ -0,0 +1,75 @@
|
||||
const when = require('when');
|
||||
const bunyan = require('bunyan');
|
||||
const {expect} = require('chai');
|
||||
const sinon = require('sinon');
|
||||
|
||||
const CMD = 'STOR';
|
||||
describe(CMD, function () {
|
||||
let sandbox;
|
||||
let log = bunyan.createLogger({name: CMD});
|
||||
const mockClient = {
|
||||
commandSocket: {
|
||||
pause: () => {},
|
||||
resume: () => {}
|
||||
},
|
||||
reply: () => when.resolve(),
|
||||
connector: {
|
||||
waitForConnection: () => when.resolve({
|
||||
resume: () => {}
|
||||
}),
|
||||
end: () => {}
|
||||
}
|
||||
};
|
||||
const cmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(mockClient);
|
||||
|
||||
beforeEach(() => {
|
||||
sandbox = sinon.sandbox.create();
|
||||
|
||||
mockClient.fs = {
|
||||
write: () => {}
|
||||
};
|
||||
|
||||
sandbox.spy(mockClient, 'reply');
|
||||
});
|
||||
afterEach(() => sandbox.restore());
|
||||
|
||||
it('// unsuccessful | no file system', () => {
|
||||
delete mockClient.fs;
|
||||
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(550);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful | file system does not have functions', () => {
|
||||
mockClient.fs = {};
|
||||
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(402);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful | connector times out', () => {
|
||||
sandbox.stub(mockClient.connector, 'waitForConnection').callsFake(function () {
|
||||
return when.reject(new when.TimeoutError());
|
||||
});
|
||||
|
||||
return cmdFn({log, command: {arg: 'test.txt'} })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(425);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful | connector errors out', () => {
|
||||
sandbox.stub(mockClient.connector, 'waitForConnection').callsFake(function () {
|
||||
return when.reject(new Error('test'));
|
||||
});
|
||||
|
||||
return cmdFn({log, command: {arg: 'test.txt'} })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(550);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -30,54 +30,46 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('// unsuccessful | no file system', done => {
|
||||
it('// unsuccessful | no file system', () => {
|
||||
delete mockClient.fs;
|
||||
|
||||
cmdFn()
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(550);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful | file system does not have functions', done => {
|
||||
it('// unsuccessful | file system does not have functions', () => {
|
||||
mockClient.fs = {};
|
||||
|
||||
cmdFn()
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(402);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// successful | given name is unique', done => {
|
||||
it('// successful | given name is unique', () => {
|
||||
mockClient.fs.get.restore();
|
||||
sandbox.stub(mockClient.fs, 'get').rejects({});
|
||||
|
||||
cmdFn({ command: { arg: 'good' } })
|
||||
return cmdFn({ command: { arg: 'good' } })
|
||||
.then(() => {
|
||||
const call = stor.handler.call.args[0][1];
|
||||
expect(call).to.have.property('command');
|
||||
expect(call.command).to.have.property('arg');
|
||||
expect(call.command.arg).to.eql('good');
|
||||
expect(mockClient.fs.getUniqueName.callCount).to.equal(0);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// successful | generates unique name', done => {
|
||||
cmdFn({ command: { arg: 'bad' } })
|
||||
it('// successful | generates unique name', () => {
|
||||
return cmdFn({ command: { arg: 'bad' } })
|
||||
.then(() => {
|
||||
const call = stor.handler.call.args[0][1];
|
||||
expect(call).to.have.property('command');
|
||||
expect(call.command).to.have.property('arg');
|
||||
expect(call.command.arg).to.eql('4');
|
||||
expect(mockClient.fs.getUniqueName.callCount).to.equal(1);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,21 +19,17 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('// successful', done => {
|
||||
cmdFn({command: { arg: 'F' } })
|
||||
it('// successful', () => {
|
||||
return cmdFn({command: { arg: 'F' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(200);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('// unsuccessful', done => {
|
||||
cmdFn({command: { arg: 'X' } })
|
||||
it('// unsuccessful', () => {
|
||||
return cmdFn({command: { arg: 'X' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(504);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,12 +19,10 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('// successful', done => {
|
||||
cmdFn()
|
||||
it('// successful', () => {
|
||||
return cmdFn()
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(215);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,50 +13,42 @@ describe(CMD, function () {
|
||||
beforeEach(() => {
|
||||
sandbox = sinon.sandbox.create();
|
||||
|
||||
mockClient.encoding = null;
|
||||
mockClient.transferType = null;
|
||||
sandbox.spy(mockClient, 'reply');
|
||||
});
|
||||
afterEach(() => {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('A // successful', done => {
|
||||
cmdFn({ command: { arg: 'A' } })
|
||||
it('A // successful', () => {
|
||||
return cmdFn({ command: { arg: 'A' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(200);
|
||||
expect(mockClient.encoding).to.equal('utf8');
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
expect(mockClient.transferType).to.equal('ascii');
|
||||
});
|
||||
});
|
||||
|
||||
it('I // successful', done => {
|
||||
cmdFn({ command: { arg: 'I' } })
|
||||
it('I // successful', () => {
|
||||
return cmdFn({ command: { arg: 'I' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(200);
|
||||
expect(mockClient.encoding).to.equal('binary');
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
expect(mockClient.transferType).to.equal('binary');
|
||||
});
|
||||
});
|
||||
|
||||
it('L // successful', done => {
|
||||
cmdFn({ command: { arg: 'L' } })
|
||||
it('L // successful', () => {
|
||||
return cmdFn({ command: { arg: 'L' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(200);
|
||||
expect(mockClient.encoding).to.equal('binary');
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
expect(mockClient.transferType).to.equal('binary');
|
||||
});
|
||||
});
|
||||
|
||||
it('X // successful', done => {
|
||||
cmdFn({ command: { arg: 'X' } })
|
||||
it('X // successful', () => {
|
||||
return cmdFn({ command: { arg: 'X' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(501);
|
||||
expect(mockClient.encoding).to.equal(null);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
expect(mockClient.transferType).to.equal(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,70 +28,80 @@ describe(CMD, function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('test // successful | prompt for password', done => {
|
||||
cmdFn({ command: { arg: 'test' } })
|
||||
it('test // successful | prompt for password', () => {
|
||||
return cmdFn({ command: { arg: 'test' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(331);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('test // successful | anonymous login', done => {
|
||||
it('test // successful | anonymous login', () => {
|
||||
mockClient.server.options = {anonymous: true};
|
||||
|
||||
cmdFn({ command: { arg: 'anonymous' } })
|
||||
return cmdFn({ command: { arg: 'anonymous' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(230);
|
||||
expect(mockClient.login.callCount).to.equal(1);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('test // unsuccessful | no username provided', done => {
|
||||
cmdFn({ command: { } })
|
||||
it('test // unsuccessful | no username provided', () => {
|
||||
return cmdFn({ command: { } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(501);
|
||||
expect(mockClient.login.callCount).to.equal(0);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('test // unsuccessful | already set username', done => {
|
||||
it('test // unsuccessful | already set username', () => {
|
||||
mockClient.username = 'test';
|
||||
|
||||
cmdFn({ command: { arg: 'test' } })
|
||||
return cmdFn({ command: { arg: 'test' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(530);
|
||||
expect(mockClient.login.callCount).to.equal(0);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('test // successful | regular login if anonymous is true', done => {
|
||||
it('test // successful | regular login if anonymous is true', () => {
|
||||
mockClient.server.options = {anonymous: true};
|
||||
|
||||
cmdFn({ log: mockLog, command: { arg: 'test' } })
|
||||
return cmdFn({ log: mockLog, command: { arg: 'test' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(331);
|
||||
expect(mockClient.login.callCount).to.equal(0);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('test // successful | anonymous login with set username', done => {
|
||||
it('test // successful | anonymous login with set username', () => {
|
||||
mockClient.server.options = {anonymous: 'sillyrabbit'};
|
||||
|
||||
cmdFn({ log: mockLog, command: { arg: 'sillyrabbit' } })
|
||||
return cmdFn({ log: mockLog, command: { arg: 'sillyrabbit' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(230);
|
||||
expect(mockClient.login.callCount).to.equal(1);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('test // unsuccessful | anonymous login fails', () => {
|
||||
mockClient.server.options = {anonymous: true};
|
||||
mockClient.login.restore();
|
||||
sandbox.stub(mockClient, 'login').rejects(new Error('test'));
|
||||
|
||||
return cmdFn({ log: mockLog, command: { arg: 'anonymous' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(530);
|
||||
expect(mockClient.login.callCount).to.equal(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('test // successful | does not login if already authenticated', () => {
|
||||
mockClient.authenticated = true;
|
||||
|
||||
return cmdFn({ log: mockLog, command: { arg: 'sillyrabbit' } })
|
||||
.then(() => {
|
||||
expect(mockClient.reply.args[0][0]).to.equal(230);
|
||||
expect(mockClient.login.callCount).to.equal(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@ const {expect} = require('chai');
|
||||
const sinon = require('sinon');
|
||||
|
||||
const net = require('net');
|
||||
const tls = require('tls');
|
||||
|
||||
const ActiveConnector = require('../../src/connector/active');
|
||||
const findPort = require('../../src/helpers/find-port');
|
||||
@@ -33,34 +34,49 @@ describe('Connector - Active //', function () {
|
||||
server.close(done);
|
||||
});
|
||||
|
||||
it('sets up a connection', function (done) {
|
||||
active.setupConnection('127.0.0.1', PORT)
|
||||
it('sets up a connection', function () {
|
||||
return active.setupConnection('127.0.0.1', PORT)
|
||||
.then(() => {
|
||||
expect(active.dataSocket).to.exist;
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('destroys existing connection, then sets up a connection', function (done) {
|
||||
it('destroys existing connection, then sets up a connection', function () {
|
||||
const destroyFnSpy = sandbox.spy(active.dataSocket, 'destroy');
|
||||
|
||||
active.setupConnection('127.0.0.1', PORT)
|
||||
return active.setupConnection('127.0.0.1', PORT)
|
||||
.then(() => {
|
||||
expect(destroyFnSpy.callCount).to.equal(1);
|
||||
expect(active.dataSocket).to.exist;
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('waits for connection', function (done) {
|
||||
active.setupConnection('127.0.0.1', PORT)
|
||||
it('waits for connection', function () {
|
||||
return active.setupConnection('127.0.0.1', PORT)
|
||||
.then(() => {
|
||||
expect(active.dataSocket).to.exist;
|
||||
return active.waitForConnection();
|
||||
})
|
||||
.then(() => done())
|
||||
.catch(done);
|
||||
.then(dataSocket => {
|
||||
expect(dataSocket.connected).to.equal(true);
|
||||
expect(dataSocket instanceof net.Socket).to.equal(true);
|
||||
expect(dataSocket instanceof tls.TLSSocket).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('upgrades to a secure connection', function () {
|
||||
mockConnection.secure = true;
|
||||
mockConnection.server = { _tls: {} };
|
||||
|
||||
return active.setupConnection('127.0.0.1', PORT)
|
||||
.then(() => {
|
||||
expect(active.dataSocket).to.exist;
|
||||
return active.waitForConnection();
|
||||
})
|
||||
.then(dataSocket => {
|
||||
expect(dataSocket.connected).to.equal(true);
|
||||
expect(dataSocket instanceof net.Socket).to.equal(true);
|
||||
expect(dataSocket instanceof tls.TLSSocket).to.equal(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,6 +20,10 @@ describe('Connector - Passive //', function () {
|
||||
};
|
||||
let sandbox;
|
||||
|
||||
function shouldNotResolve() {
|
||||
throw new Error('Should not resolve');
|
||||
}
|
||||
|
||||
before(() => {
|
||||
passive = new PassiveConnector(mockConnection);
|
||||
});
|
||||
@@ -36,45 +40,49 @@ describe('Connector - Passive //', function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('cannot wait for connection with no server', function (done) {
|
||||
passive.waitForConnection()
|
||||
.then(() => done('should not happen'))
|
||||
it('cannot wait for connection with no server', function () {
|
||||
return passive.waitForConnection()
|
||||
.then(shouldNotResolve)
|
||||
.catch(err => {
|
||||
expect(err.name).to.equal('ConnectorError');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('has invalid pasv range', function (done) {
|
||||
it('no pasv range provided', function () {
|
||||
delete mockConnection.server.options.pasv_range;
|
||||
|
||||
return passive.setupServer()
|
||||
.then(shouldNotResolve)
|
||||
.catch(err => {
|
||||
expect(err.name).to.equal('ConnectorError');
|
||||
});
|
||||
});
|
||||
|
||||
it('has invalid pasv range', function () {
|
||||
mockConnection.server.options.pasv_range = -1;
|
||||
|
||||
passive.setupServer()
|
||||
.then(() => done('should not happen'))
|
||||
return passive.setupServer()
|
||||
.then(shouldNotResolve)
|
||||
.catch(err => {
|
||||
expect(err.name).to.equal('RangeError');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('sets up a server', function (done) {
|
||||
passive.setupServer()
|
||||
it('sets up a server', function () {
|
||||
return passive.setupServer()
|
||||
.then(() => {
|
||||
expect(passive.dataServer).to.exist;
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('destroys existing server, then sets up a server', function (done) {
|
||||
it('destroys existing server, then sets up a server', function () {
|
||||
const closeFnSpy = sandbox.spy(passive.dataServer, 'close');
|
||||
|
||||
passive.setupServer()
|
||||
return passive.setupServer()
|
||||
.then(() => {
|
||||
expect(closeFnSpy.callCount).to.equal(1);
|
||||
expect(passive.dataServer).to.exist;
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('refuses connection with different remote address', function (done) {
|
||||
@@ -97,8 +105,8 @@ describe('Connector - Passive //', function () {
|
||||
.catch(done);
|
||||
});
|
||||
|
||||
it('accepts connection', function (done) {
|
||||
passive.setupServer()
|
||||
it('accepts connection', function () {
|
||||
return passive.setupServer()
|
||||
.then(() => {
|
||||
expect(passive.dataServer).to.exist;
|
||||
|
||||
@@ -109,8 +117,6 @@ describe('Connector - Passive //', function () {
|
||||
.then(() => {
|
||||
expect(passive.dataSocket).to.exist;
|
||||
passive.end();
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,10 +2,9 @@ const {expect} = require('chai');
|
||||
const escapePath = require('../../src/helpers/escape-path');
|
||||
|
||||
describe('helpers // escape-path', function () {
|
||||
it('escapes quotes', done => {
|
||||
it('escapes quotes', () => {
|
||||
const string = '"test"';
|
||||
const escapedString = escapePath(string);
|
||||
expect(escapedString).to.equal('""test""');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -17,22 +17,19 @@ describe('helpers // find-port', function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('finds a port', done => {
|
||||
findPort(1)
|
||||
it('finds a port', () => {
|
||||
return findPort(1)
|
||||
.then(port => {
|
||||
expect(Server.prototype.listen.callCount).to.be.above(1);
|
||||
expect(port).to.be.above(1);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('does not find a port', done => {
|
||||
findPort(1, 2)
|
||||
.then(() => done('no'))
|
||||
it('does not find a port', () => {
|
||||
return findPort(1, 2)
|
||||
.then(() => expect(1).to.equal(2)) // should not happen
|
||||
.catch(err => {
|
||||
expect(err).to.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,36 +1,51 @@
|
||||
const {expect} = require('chai');
|
||||
const sinon = require('sinon');
|
||||
const resolveHost = require('../../src/helpers/resolve-host');
|
||||
|
||||
describe('helpers //resolve-host', function () {
|
||||
this.timeout(4000);
|
||||
|
||||
it('fetches ip address', done => {
|
||||
let sandbox;
|
||||
beforeEach(() => {
|
||||
sandbox = sinon.sandbox.create();
|
||||
});
|
||||
afterEach(() => sandbox.restore());
|
||||
|
||||
it('fetches ip address', () => {
|
||||
const hostname = '0.0.0.0';
|
||||
resolveHost(hostname)
|
||||
return resolveHost(hostname)
|
||||
.then(resolvedHostname => {
|
||||
expect(resolvedHostname).to.match(/^\d+\.\d+\.\d+\.\d+$/);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('fetches ip address', done => {
|
||||
it('fetches ip address', () => {
|
||||
const hostname = null;
|
||||
resolveHost(hostname)
|
||||
return resolveHost(hostname)
|
||||
.then(resolvedHostname => {
|
||||
expect(resolvedHostname).to.match(/^\d+\.\d+\.\d+\.\d+$/);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('does nothing', done => {
|
||||
it('does nothing', () => {
|
||||
const hostname = '127.0.0.1';
|
||||
resolveHost(hostname)
|
||||
return resolveHost(hostname)
|
||||
.then(resolvedHostname => {
|
||||
expect(resolvedHostname).to.equal(hostname);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('fails on getting hostname', () => {
|
||||
sandbox.stub(require('http'), 'get').callsFake(function (url, cb) {
|
||||
cb({
|
||||
statusCode: 420
|
||||
});
|
||||
});
|
||||
|
||||
return resolveHost(null)
|
||||
.then(() => expect(1).to.equal(2))
|
||||
.catch(err => {
|
||||
expect(err.code).to.equal(420);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@ describe('FtpServer', function () {
|
||||
let server;
|
||||
let client;
|
||||
|
||||
before(done => {
|
||||
before(() => {
|
||||
server = new FtpServer(process.env.FTP_URL, {
|
||||
log,
|
||||
pasv_range: process.env.PASV_RANGE,
|
||||
@@ -22,14 +22,14 @@ describe('FtpServer', function () {
|
||||
key: `${process.cwd()}/test/cert/server.key`,
|
||||
cert: `${process.cwd()}/test/cert/server.crt`,
|
||||
ca: `${process.cwd()}/test/cert/server.csr`
|
||||
}
|
||||
},
|
||||
greeting: ['hello', 'world']
|
||||
});
|
||||
server.on('login', (data, resolve) => {
|
||||
resolve({root: process.cwd()});
|
||||
});
|
||||
|
||||
server.listen()
|
||||
.then(() => done());
|
||||
return server.listen();
|
||||
});
|
||||
after(() => {
|
||||
server.close();
|
||||
@@ -109,12 +109,12 @@ describe('FtpServer', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('STOR test.txt', done => {
|
||||
it('STOR tést.txt', done => {
|
||||
const buffer = Buffer.from('test text file');
|
||||
client.put(buffer, 'test.txt', err => {
|
||||
client.put(buffer, 'tést.txt', err => {
|
||||
expect(err).to.not.exist;
|
||||
expect(fs.existsSync('./test/test.txt')).to.equal(true);
|
||||
fs.readFile('./test/test.txt', (fserr, data) => {
|
||||
expect(fs.existsSync('./test/tést.txt')).to.equal(true);
|
||||
fs.readFile('./test/tést.txt', (fserr, data) => {
|
||||
expect(fserr).to.not.exist;
|
||||
expect(data.toString()).to.equal('test text file');
|
||||
done();
|
||||
@@ -122,11 +122,11 @@ describe('FtpServer', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('APPE test.txt', done => {
|
||||
it('APPE tést.txt', done => {
|
||||
const buffer = Buffer.from(', awesome!');
|
||||
client.append(buffer, 'test.txt', err => {
|
||||
client.append(buffer, 'tést.txt', err => {
|
||||
expect(err).to.not.exist;
|
||||
fs.readFile('./test/test.txt', (fserr, data) => {
|
||||
fs.readFile('./test/tést.txt', (fserr, data) => {
|
||||
expect(fserr).to.not.exist;
|
||||
expect(data.toString()).to.equal('test text file, awesome!');
|
||||
done();
|
||||
@@ -134,8 +134,8 @@ describe('FtpServer', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('RETR test.txt', done => {
|
||||
client.get('test.txt', (err, stream) => {
|
||||
it('RETR tést.txt', done => {
|
||||
client.get('tést.txt', (err, stream) => {
|
||||
expect(err).to.not.exist;
|
||||
let text = '';
|
||||
stream.on('data', data => {
|
||||
@@ -148,10 +148,10 @@ describe('FtpServer', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('RNFR test.txt, RNTO awesome.txt', done => {
|
||||
client.rename('test.txt', 'awesome.txt', err => {
|
||||
it('RNFR tést.txt, RNTO awesome.txt', done => {
|
||||
client.rename('tést.txt', 'awesome.txt', err => {
|
||||
expect(err).to.not.exist;
|
||||
expect(fs.existsSync('./test/test.txt')).to.equal(false);
|
||||
expect(fs.existsSync('./test/tést.txt')).to.equal(false);
|
||||
expect(fs.existsSync('./test/awesome.txt')).to.equal(true);
|
||||
fs.readFile('./test/awesome.txt', (fserr, data) => {
|
||||
expect(fserr).to.not.exist;
|
||||
@@ -196,19 +196,19 @@ describe('FtpServer', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('MKD tmp', done => {
|
||||
if (fs.existsSync('./test/tmp')) {
|
||||
fs.rmdirSync('./test/tmp');
|
||||
it('MKD témp', done => {
|
||||
if (fs.existsSync('./test/témp')) {
|
||||
fs.rmdirSync('./test/témp');
|
||||
}
|
||||
client.mkdir('tmp', err => {
|
||||
client.mkdir('témp', err => {
|
||||
expect(err).to.not.exist;
|
||||
expect(fs.existsSync('./test/tmp')).to.equal(true);
|
||||
expect(fs.existsSync('./test/témp')).to.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('CWD tmp', done => {
|
||||
client.cwd('tmp', (err, data) => {
|
||||
it('CWD témp', done => {
|
||||
client.cwd('témp', (err, data) => {
|
||||
expect(err).to.not.exist;
|
||||
expect(data).to.be.a('string');
|
||||
done();
|
||||
@@ -222,10 +222,10 @@ describe('FtpServer', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('RMD tmp', done => {
|
||||
client.rmdir('tmp', err => {
|
||||
it('RMD témp', done => {
|
||||
client.rmdir('témp', err => {
|
||||
expect(err).to.not.exist;
|
||||
expect(fs.existsSync('./test/tmp')).to.equal(false);
|
||||
expect(fs.existsSync('./test/témp')).to.equal(false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user