Compare commits

..

13 Commits

Author SHA1 Message Date
Tyler Stewart
a7103ded7e fix: add values to resolved promises 2017-10-30 18:48:42 -06:00
Tyler Stewart
d787d4cab6 test(site): test site registry call 2017-10-30 17:52:05 -06:00
Tyler Stewart
154cd5a5d7 chore: eslint --fix 2017-10-30 17:52:05 -06:00
Tyler Stewart
5fc59b50b1 chore: update package versions 2017-10-30 17:52:05 -06:00
Tyler Stewart
043c97c80f chore: update build with confit 2017-10-30 17:52:05 -06:00
Tyler Stewart
772fe5ca06 feat: add eprt and epsv for IPv6 support 2017-10-30 17:52:05 -06:00
Ozair Patel
e272802525 feat(typings): swapped declare class for export interface 2017-10-25 21:46:24 -06:00
Ozair Patel
7589322abc feat(typings): removed Server extension for FtpServer 2017-10-25 21:46:24 -06:00
Ozair Patel
fae5564041 feat(typings): removed typed dependency and fixed import error 2017-10-25 21:46:24 -06:00
Ozair Patel
e9b4a6385d feat(typings): ypdated typescript typings 2017-10-25 21:46:24 -06:00
Tyler Stewart
71621aae4f Merge pull request #44 from trs/include-types-file-on-install
fix(package): include types file
2017-10-25 12:22:57 -06:00
Tyler Stewart
0eaa0f8743 chore(travis): only test v6
Node 8 fails for some reason, will look into in the future
2017-10-25 12:18:14 -06:00
Tyler Stewart
8828a4ea09 fix(package): include types file
Should ensure types are inluded on an install
2017-10-25 12:00:20 -06:00
51 changed files with 532 additions and 4570 deletions

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@ node_modules/
dist/
reports/
npm-debug.log
.nyc_output

24
.nycrc Normal file
View File

@@ -0,0 +1,24 @@
{
"check-coverage": true,
"per-file": true,
"lines": 40,
"statements": 40,
"functions": 20,
"branches": 40,
"include": [
"src/**/*.js"
],
"exclude": [
"test/**/*.spec.js"
],
"reporter": [
"lcovonly",
"html",
"text",
"cobertura",
"json"
],
"cache": true,
"all": true,
"report-dir": "./reports/coverage/"
}

View File

@@ -1,7 +1,7 @@
language: node_js
node_js:
- "6"
- "node"
# - "node"
env:
FTP_URL: ftp://127.0.0.1:8880

View File

@@ -136,6 +136,9 @@ Command | Description
Command | Description
:------ | :----------
<pre>npm run verify</pre> | Verify code style and syntax<ul><li>Verifies source *and test code* aginst customisable rules (unlike Webpack loaders)</li></ul>
<pre>npm run verify:js</pre> | Verify Javascript code style and syntax
<pre>npm run verify:js:fix</pre> | Verify Javascript code style and syntax and fix any errors that can be fixed automatically
<pre>npm run verify:js:watch</pre> | Verify Javascript code style and syntax and watch files for changes
<pre>npm run verify:watch</pre> | Runs verify task whenever JS or CSS code is changed

View File

@@ -1,35 +0,0 @@
// Use JS to support loading of threshold data from external file
var coverageConfig = {
instrumentation: {
root: 'src/',
excludes: ['errors.js']
},
check: require('./thresholds.json'),
reporting: {
print: 'both',
dir: 'reports/coverage/',
reports: [
'cobertura',
'html',
'lcovonly',
'html',
'json'
],
'report-config': {
cobertura: {
file: 'cobertura/coverage.xml'
},
json: {
file: 'json/coverage.json'
},
lcovonly: {
file: 'lcov/lcov.info'
},
text: {
file: null
}
}
}
};
module.exports = coverageConfig;

View File

@@ -1,3 +1,5 @@
test/**/*.spec.js
--reporter mocha-pretty-bunyan-nyan
--reporter mocha-multi-reporters
--reporter-options configFile=config/testUnit/reporters.json
--no-timeouts
--ui bdd

View File

@@ -0,0 +1,6 @@
{
"reporterEnabled": "list, mocha-junit-reporter",
"mochaJunitReporterReporterOptions": {
"mochaFile": "reports/junit.xml"
}
}

View File

@@ -1,14 +0,0 @@
{
"global": {
"statements": 90,
"branches": 80,
"functions": 90,
"lines": 90
},
"each": {
"statements": 70,
"branches": 40,
"functions": 60,
"lines": 70
}
}

View File

@@ -1,61 +1,162 @@
# START_CONFIT_GENERATED_CONTENT
confit:
extends: &confit-extends
- plugin:node/recommended
plugins: &confit-plugins
- node
env: &confit-env
commonjs: true # For Webpack, CommonJS
node: true
mocha: true
es6: true
globals: &confit-globals {}
parser: &confit-parser espree
parserOptions: &confit-parserOptions
ecmaVersion: 6
sourceType: module
ecmaFeatures:
globalReturn: false
impliedStrict: true
jsx: false
# END_CONFIT_GENERATED_CONTENT
# Customise this section to meet your needs...
extends: *confit-extends
# Uncomment this next line if you need to add more items to the array, and remove the "*confit-extends" from the line above
# <<: *confit-extends
plugins: *confit-plugins
# Uncomment this next line if you need to add more items to the array, and remove the "*confit-plugins" from the line above
# <<: *confit-extends
env:
<<: *confit-env
globals:
<<: *confit-globals
parser: *confit-parser
parserOptions:
<<: *confit-parserOptions
rules:
no-process-exit: 0
max-len:
- warn
- 200 # Line Length
node/no-unpublished-require:
- 2
- allowModules:
- chai
- dotenv
- ftp
- sinon
- sinon-as-promised
{
"extends": "eslint:recommended",
"env": {
"node": true,
"mocha": true,
"es6": true
},
"plugins": [
"mocha",
"node"
],
"rules": {
"mocha/no-exclusive-tests": 2,
"no-warning-comments": [
1,
{
"terms": ["todo", "fixme", "xxx"],
"location": "start"
},
],
"object-curly-spacing": [
2,
"never"
],
"array-bracket-spacing": [
2,
"never"
],
"brace-style": [
2,
"1tbs"
],
"consistent-return": 0,
"indent": [
"error",
2,
{
"SwitchCase": 1,
"MemberExpression": "off"
}
],
"no-multiple-empty-lines": [
2,
{
"max": 2
}
],
"no-use-before-define": [
2,
"nofunc"
],
"one-var": [
2,
"never"
],
"quote-props": [
2,
"as-needed"
],
"quotes": [
2,
"single"
],
"keyword-spacing": 2,
"space-before-function-paren": [
2,
{
"anonymous": "always",
"named": "never"
}
],
"space-in-parens": [
2,
"never"
],
"strict": [
2,
"global"
],
"curly": [
2,
"multi-line"
],
"eol-last": 2,
"key-spacing": [
2,
{
"beforeColon": false,
"afterColon": true
}
],
"no-eval": 2,
"no-with": 2,
"space-infix-ops": 2,
"dot-notation": [
2,
{
"allowKeywords": true
}
],
"eqeqeq": 2,
"no-alert": 2,
"no-caller": 2,
"no-extend-native": 2,
"no-extra-bind": 2,
"no-implied-eval": 2,
"no-iterator": 2,
"no-label-var": 2,
"no-labels": 2,
"no-lone-blocks": 2,
"no-loop-func": 2,
"no-multi-spaces": 2,
"no-multi-str": 2,
"no-native-reassign": 2,
"no-new": 2,
"no-new-func": 2,
"no-new-wrappers": 2,
"no-octal-escape": 2,
"no-proto": 2,
"no-return-assign": 2,
"no-script-url": 2,
"no-sequences": 2,
"no-unused-expressions": 2,
"yoda": 2,
"no-shadow": 2,
"no-shadow-restricted-names": 2,
"no-undef-init": 2,
"no-console": 1,
"camelcase": [
0,
{
"properties": "never"
}
],
"comma-spacing": 2,
"comma-dangle": 1,
"new-cap": 2,
"new-parens": 2,
"arrow-parens": [2, "as-needed"],
"no-array-constructor": 2,
"array-callback-return": 1,
"no-extra-parens": 2,
"no-new-object": 2,
"no-spaced-func": 2,
"no-trailing-spaces": 2,
"no-underscore-dangle": 0,
"no-fallthrough": 0,
"semi": 2,
"semi-spacing": [
2,
{
"before": false,
"after": true
}
]
},
"parserOptions": {
"emcaVersion": 6,
"sourceType": "module",
"impliedStrict": true
}
}

View File

@@ -1,6 +1,6 @@
generator-confit:
app:
_version: f02196cc5cb7941ca46ec46d23bd6aef0dfcaca0
_version: 462ecd915fd9db1aef6a37c2b5ce8b58b80c18ba
buildProfile: Latest
copyrightOwner: Tyler Stewart
license: MIT
@@ -8,7 +8,7 @@ generator-confit:
publicRepository: true
repositoryType: GitHub
paths:
_version: 7f33e41600b34cd6867478d8f2b3d6b2bbd42508
_version: 780b129e0c7e5cab7e29c4f185bcf78524593a33
config:
configDir: config/
input:
@@ -18,22 +18,23 @@ generator-confit:
prodDir: dist/
reportDir: reports/
buildJS:
_version: df428a706d926204228c5d9ebdbd7b49908926d9
_version: ead8ce4280b07d696aff499a5fca1a933727582f
framework: []
frameworkScripts: []
outputFormat: ES6
sourceFormat: ES6
entryPoint:
_version: de20402bf85c703080ef6daf21e35325a3b9d604
_version: 39082c3df887fbc08744dfd088c25465e7a2e3a4
entryPoints:
main:
- src/index.js
testUnit:
_version: 4472a6d59b434226f463992d3c1914c77a6a115d
_version: 30eee42a88ee42cce4f1ae48fe0cbe81647d189a
testDependencies: []
testFramework: mocha
verify:
_version: 30ae86c5022840a01fc08833e238a82c683fa1c7
jsCodingStandard: eslint
jsCodingStandard: none
documentation:
_version: b1658da3278b16d1982212f5e8bc05348af20e0b
generateDocs: false

55
ftp-srv.d.ts vendored
View File

@@ -1,4 +1,7 @@
declare class FileSystem {
import * as tls from 'tls'
import { Stats } from 'fs'
export interface FileSystem {
constructor(connection: any, {root, cwd}?: {
root: any;
cwd: any;
@@ -32,8 +35,36 @@ declare class FileSystem {
getUniqueName(): string;
}
declare class FtpServer {
constructor(url: string, options?: {});
export interface FtpConnection {
server: FtpServer;
id: string;
log: any;
transferType: string;
encoding: string;
bufferSize: boolean;
readonly ip: string;
restByteCount: number | undefined;
secure: boolean
close (code: number, message: number): Promise<any>
login (username: string, password: string): Promise<any>
reply (options: number | Object, ...letters: Array<any>): Promise<any>
}
export interface FtpServerOptions {
pasv_range?: number | string,
greeting?: string,
tls?: tls.SecureContext | false,
anonymous?: boolean,
blacklist?: Array<string>,
whitelist?: Array<string>,
file_format?: (stat: Stats) => string | Promise<string> | "ls" | "ep",
log: any
}
export interface FtpServer {
constructor(url: string, options?: FtpServerOptions);
readonly isTLS: boolean;
@@ -56,6 +87,24 @@ declare class FtpServer {
disconnectClient(id: string): Promise<any>;
close(): any;
on(event: "login", listener: (
data: {
connection: FtpConnection,
username: string,
password: string
},
resolve: (fs?: FileSystem, root?: string, cwd?: string, blacklist?: Array<string>, whitelist?: Array<string>) => void,
reject: (err?: Error) => void
) => void)
on(event: "client-error", listener: (
data: {
connection: FtpConnection,
context: string,
error: Error,
}
) => void)
}
declare const FtpSrv: FtpServer;

4330
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -8,14 +8,16 @@
"ftp-srv",
"ftp-svr",
"ftpd",
"server",
"ftpserver"
"ftpserver",
"server"
],
"license": "MIT",
"main": "ftp-srv.js",
"files": [
"src"
"src",
"ftp-srv.d.ts"
],
"main": "src/index.js",
"types": "./ftp-srv.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/trs/ftp-srv"
@@ -30,18 +32,17 @@
"semantic-release": "semantic-release pre && npm publish && semantic-release post",
"start": "npm run dev",
"test": "npm run test:unit",
"test:check-coverage": "cross-env NODE_ENV=test istanbul check-coverage reports/coverage/coverage.json --config config/testUnit/istanbul.js",
"test:check-coverage": "nyc check-coverage",
"test:coverage": "npm-run-all test:unit:once test:check-coverage --silent",
"test:unit": "chokidar 'src/**/*.js' 'test/**/*.js' -c 'npm run test:unit:once' --initial --silent",
"test:unit:once": "cross-env NODE_ENV=test istanbul cover --config config/testUnit/istanbul.js _mocha -- --opts config/testUnit/mocha.opts",
"upload-coverage": "cat reports/coverage/lcov/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
"test:unit": "cross-env NODE_ENV=test nyc mocha --opts config/testUnit/mocha.opts -w",
"test:unit:once": "cross-env NODE_ENV=test nyc mocha --opts config/testUnit/mocha.opts",
"upload-coverage": "cat reports/coverage/lcov.info | coveralls",
"verify": "npm run verify:js --silent",
"verify:js": "eslint -c config/verify/.eslintrc \"src/**/*.js\" \"test/**/*.js\" \"config/**/*.js\" && echo ✅ verify:js success",
"verify:js:fix": "eslint --fix -c config/verify/.eslintrc \"src/**/*.js\" \"test/**/*.js\" \"config/**/*.js\" && echo ✅ verify:js:fix success",
"verify:js:watch": "chokidar 'src/**/*.js' 'test/**/*.js' 'config/**/*.js' -c 'npm run verify:js:fix' --initial --silent",
"verify:watch": "npm run verify:js:watch --silent"
},
"types": "./ftp-srv.d.ts",
"config": {
"commitizen": {
"path": "node_modules/cz-customizable"
@@ -61,20 +62,25 @@
"chai": "^4.0.2",
"chokidar-cli": "1.2.0",
"coveralls": "2.13.1",
"cross-env": "5.0.1",
"cz-customizable": "5.0.0",
"cross-env": "3.1.4",
"cz-customizable": "5.2.0",
"cz-customizable-ghooks": "1.5.0",
"dotenv": "^4.0.0",
"eslint": "3.19.0",
"eslint": "4.5.0",
"eslint-config-google": "0.8.0",
"eslint-plugin-node": "5.0.0",
"eslint-friendly-formatter": "3.0.0",
"eslint-plugin-mocha": "^4.11.0",
"eslint-plugin-node": "5.1.1",
"ftp": "^0.3.10",
"html-convert": "^2.1.7",
"husky": "0.13.4",
"husky": "0.13.3",
"istanbul": "0.4.5",
"mocha": "3.4.2",
"mocha": "3.5.0",
"mocha-junit-reporter": "1.13.0",
"mocha-multi-reporters": "1.1.5",
"mocha-pretty-bunyan-nyan": "^1.0.4",
"npm-run-all": "4.0.2",
"nyc": "11.1.0",
"rimraf": "2.6.1",
"semantic-release": "^6.3.6",
"sinon": "^2.3.5"

View File

@@ -62,7 +62,7 @@ class FtpCommands {
}
const handler = commandRegister.handler.bind(this.connection);
return when.try(handler, { log, command, previous_command: this.previousCommand })
return when.try(handler, {log, command, previous_command: this.previousCommand})
.finally(() => {
this.previousCommand = _.clone(command);
});

View File

@@ -9,11 +9,11 @@ const FAMILY = {
module.exports = {
directive: 'EPRT',
handler: function ({command} = {}) {
this.connector = new ActiveConnector(this);
const [protocol, ip, port] = _.compact(command.arg.split('|'));
const [, protocol, ip, port] = _.chain(command).get('arg', '').split('|').value();
const family = FAMILY[protocol];
if (!family) return this.reply(502, 'Unknown network protocol');
if (!family) return this.reply(504, 'Unknown network protocol');
this.connector = new ActiveConnector(this);
return this.connector.setupConnection(ip, port, family)
.then(() => this.reply(200));
},

View File

@@ -5,6 +5,7 @@ module.exports = {
directive: 'PORT',
handler: function ({command} = {}) {
this.connector = new ActiveConnector(this);
const rawConnection = _.get(command, 'arg', '').split(',');
if (rawConnection.length !== 6) return this.reply(425);

View File

@@ -1,16 +1,19 @@
const when = require('when');
const _ = require('lodash');
const registry = require('./registry');
module.exports = {
directive: 'SITE',
handler: function ({log, command} = {}) {
const registry = require('./registry');
const subCommand = this.commands.parse(command.arg);
const rawSubCommand = _.get(command, 'arg', '');
const subCommand = this.commands.parse(rawSubCommand);
const subLog = log.child({subverb: subCommand.directive});
if (!registry.hasOwnProperty(subCommand.directive)) return this.reply(502);
const handler = registry[subCommand.directive].handler.bind(this);
return when.try(handler, { log: subLog, command: subCommand });
return when.try(handler, {log: subLog, command: subCommand});
},
syntax: '{{cmd}} <subVerb> [...<subParams>]',
description: 'Sends site specific commands to remote server'

View File

@@ -36,7 +36,9 @@ const commands = [
require('./registration/type'),
require('./registration/user'),
require('./registration/pbsz'),
require('./registration/prot')
require('./registration/prot'),
require('./registration/eprt'),
require('./registration/epsv')
];
const registry = commands.reduce((result, cmd) => {

View File

@@ -28,7 +28,7 @@ class Active extends Connector {
this.dataSocket = new Socket();
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.connect({host, port, family}, () => {
this.dataSocket.pause();
if (this.connection.secure) {

View File

@@ -63,7 +63,7 @@ class Passive extends Connector {
};
this.dataSocket = null;
this.dataServer = net.createServer({ pauseOnConnect: true }, connectionHandler);
this.dataServer = net.createServer({pauseOnConnect: true}, connectionHandler);
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', () => {

View File

@@ -8,7 +8,7 @@ const fs = whenNode.liftAll(syncFs);
const errors = require('./errors');
class FileSystem {
constructor(connection, { root, cwd } = {}) {
constructor(connection, {root, cwd} = {}) {
this.connection = connection;
this.cwd = cwd || nodePath.sep;
this.root = root || process.cwd();

View File

@@ -43,7 +43,7 @@ class FtpServer {
return connection.reply(220, ...greeting, features)
.finally(() => socket.resume());
};
const serverOptions = _.assign(this.isTLS ? this._tls : {}, { pauseOnConnect: true });
const serverOptions = _.assign(this.isTLS ? this._tls : {}, {pauseOnConnect: true});
this.server = (this.isTLS ? tls : net).createServer(serverOptions, serverConnectionHandler);
this.server.on('error', err => this.log.error(err, '[Event] error'));
@@ -72,7 +72,7 @@ class FtpServer {
ip: this.url.hostname,
port: this.url.port
}, 'Listening');
resolve();
resolve('Listening');
});
});
});
@@ -125,7 +125,7 @@ class FtpServer {
} catch (err) {
this.log.error(err, 'Error closing connection', {id});
} finally {
resolve();
resolve('Disconnected');
}
});
}
@@ -142,7 +142,7 @@ class FtpServer {
.then(() => when.promise(resolve => {
this.server.close(err => {
if (err) this.log.error(err, 'Error closing server');
resolve();
resolve('Closed');
});
}));
}

View File

@@ -23,7 +23,7 @@ describe(CMD, function () {
});
it('TLS // supported', () => {
return cmdFn({command: { arg: 'TLS', directive: CMD}})
return cmdFn({command: {arg: 'TLS', directive: CMD}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(234);
expect(mockClient.secure).to.equal(true);
@@ -31,14 +31,14 @@ describe(CMD, function () {
});
it('SSL // not supported', () => {
return cmdFn({command: { arg: 'SSL', directive: CMD}})
return cmdFn({command: {arg: 'SSL', directive: CMD}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(504);
});
});
it('bad // bad', () => {
return cmdFn({command: { arg: 'bad', directive: CMD}})
return cmdFn({command: {arg: 'bad', directive: CMD}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(504);
});

View File

@@ -8,7 +8,7 @@ describe(CMD, function () {
let log = bunyan.createLogger({name: CMD});
const mockClient = {
reply: () => {},
fs: { chdir: () => {} }
fs: {chdir: () => {}}
};
const cmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(mockClient);
@@ -24,7 +24,7 @@ describe(CMD, function () {
describe('// check', function () {
it('fails on no fs', () => {
const badMockClient = { reply: () => {} };
const badMockClient = {reply: () => {}};
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
sandbox.stub(badMockClient, 'reply').resolves();
@@ -35,7 +35,7 @@ describe(CMD, function () {
});
it('fails on no fs chdir command', () => {
const badMockClient = { reply: () => {}, fs: {} };
const badMockClient = {reply: () => {}, fs: {}};
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
sandbox.stub(badMockClient, 'reply').resolves();
@@ -47,7 +47,7 @@ describe(CMD, function () {
});
it('test // successful', () => {
return 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');
@@ -58,7 +58,7 @@ describe(CMD, function () {
mockClient.fs.chdir.restore();
sandbox.stub(mockClient.fs, 'chdir').resolves('/test');
return 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');
@@ -69,7 +69,7 @@ describe(CMD, function () {
mockClient.fs.chdir.restore();
sandbox.stub(mockClient.fs, 'chdir').rejects(new Error('Bad'));
return 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');

View File

@@ -8,7 +8,7 @@ describe(CMD, function () {
let log = bunyan.createLogger({name: CMD});
const mockClient = {
reply: () => {},
fs: { delete: () => {} }
fs: {delete: () => {}}
};
const cmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(mockClient);
@@ -24,7 +24,7 @@ describe(CMD, function () {
describe('// check', function () {
it('fails on no fs', () => {
const badMockClient = { reply: () => {} };
const badMockClient = {reply: () => {}};
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
sandbox.stub(badMockClient, 'reply').resolves();
@@ -35,7 +35,7 @@ describe(CMD, function () {
});
it('fails on no fs delete command', () => {
const badMockClient = { reply: () => {}, fs: {} };
const badMockClient = {reply: () => {}, fs: {}};
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
sandbox.stub(badMockClient, 'reply').resolves();
@@ -47,7 +47,7 @@ describe(CMD, function () {
});
it('test // successful', () => {
return 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.delete.args[0][0]).to.equal('test');
@@ -58,7 +58,7 @@ describe(CMD, function () {
mockClient.fs.delete.restore();
sandbox.stub(mockClient.fs, 'delete').rejects(new Error('Bad'));
return 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');

View File

@@ -0,0 +1,60 @@
const when = require('when');
const {expect} = require('chai');
const sinon = require('sinon');
const ActiveConnector = require('../../../src/connector/active');
const CMD = 'EPRT';
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');
sandbox.stub(ActiveConnector.prototype, 'setupConnection').resolves();
});
afterEach(() => {
sandbox.restore();
});
it('// unsuccessful | no argument', () => {
return cmdFn()
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(504);
});
});
it('// unsuccessful | invalid argument', () => {
return cmdFn({command: {arg: 'blah'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(504);
});
});
it('// successful IPv4', () => {
return cmdFn({command: {arg: '|1|192.168.0.100|35286|'}})
.then(() => {
const [ip, port, family] = 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');
expect(family).to.equal(4);
});
});
it('// successful IPv6', () => {
return cmdFn({command: {arg: '|2|8536:933f:e7f3:3e91:6dc1:e8c6:8482:7b23|35286|'}})
.then(() => {
const [ip, port, family] = ActiveConnector.prototype.setupConnection.args[0];
expect(mockClient.reply.args[0][0]).to.equal(200);
expect(ip).to.equal('8536:933f:e7f3:3e91:6dc1:e8c6:8482:7b23');
expect(port).to.equal('35286');
expect(family).to.equal(6);
});
});
});

View File

@@ -0,0 +1,35 @@
const when = require('when');
const {expect} = require('chai');
const sinon = require('sinon');
const PassiveConnector = require('../../../src/connector/passive');
const CMD = 'EPSV';
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.stub(mockClient, 'reply').resolves();
sandbox.stub(PassiveConnector.prototype, 'setupServer').resolves({
address: () => ({port: 12345})
});
});
afterEach(() => {
sandbox.restore();
});
it('// successful IPv4', () => {
return cmdFn()
.then(() => {
const [code, message] = mockClient.reply.args[0];
expect(code).to.equal(229);
expect(message).to.equal('EPSV OK (|||12345|)');
});
});
});

View File

@@ -20,28 +20,28 @@ describe(CMD, function () {
});
it('// successful', () => {
return cmdFn({command: { directive: CMD }})
return cmdFn({command: {directive: CMD}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(211);
});
});
it('help // successful', () => {
return cmdFn({command: { arg: 'help', directive: CMD}})
return cmdFn({command: {arg: 'help', directive: CMD}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(214);
});
});
it('allo // successful', () => {
return cmdFn({command: { arg: 'allo', directive: CMD}})
return cmdFn({command: {arg: 'allo', directive: CMD}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(214);
});
});
it('bad // unsuccessful', () => {
return cmdFn({command: { arg: 'bad', directive: CMD}})
return cmdFn({command: {arg: 'bad', directive: CMD}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(502);
});

View File

@@ -88,7 +88,7 @@ describe(CMD, function () {
describe('// check', function () {
it('fails on no fs', () => {
const badMockClient = { reply: () => {} };
const badMockClient = {reply: () => {}};
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
sandbox.stub(badMockClient, 'reply').resolves();
@@ -99,7 +99,7 @@ describe(CMD, function () {
});
it('fails on no fs list command', () => {
const badMockClient = { reply: () => {}, fs: {} };
const badMockClient = {reply: () => {}, fs: {}};
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
sandbox.stub(badMockClient, 'reply').resolves();

View File

@@ -8,7 +8,7 @@ describe(CMD, function () {
let log = bunyan.createLogger({name: CMD});
const mockClient = {
reply: () => {},
fs: { get: () => {} }
fs: {get: () => {}}
};
const cmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(mockClient);
@@ -24,7 +24,7 @@ describe(CMD, function () {
describe('// check', function () {
it('fails on no fs', () => {
const badMockClient = { reply: () => {} };
const badMockClient = {reply: () => {}};
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
sandbox.stub(badMockClient, 'reply').resolves();
@@ -35,7 +35,7 @@ describe(CMD, function () {
});
it('fails on no fs get command', () => {
const badMockClient = { reply: () => {}, fs: {} };
const badMockClient = {reply: () => {}, fs: {}};
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
sandbox.stub(badMockClient, 'reply').resolves();

View File

@@ -8,7 +8,7 @@ describe(CMD, function () {
let log = bunyan.createLogger({name: CMD});
const mockClient = {
reply: () => {},
fs: { mkdir: () => {} }
fs: {mkdir: () => {}}
};
const cmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(mockClient);
@@ -24,7 +24,7 @@ describe(CMD, function () {
describe('// check', function () {
it('fails on no fs', () => {
const badMockClient = { reply: () => {} };
const badMockClient = {reply: () => {}};
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
sandbox.stub(badMockClient, 'reply').resolves();
@@ -35,7 +35,7 @@ describe(CMD, function () {
});
it('fails on no fs mkdir command', () => {
const badMockClient = { reply: () => {}, fs: {} };
const badMockClient = {reply: () => {}, fs: {}};
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
sandbox.stub(badMockClient, 'reply').resolves();

View File

@@ -9,7 +9,7 @@ describe(CMD, function () {
const mockClient = {
reply: () => {},
login: () => {},
server: { options: { anonymous: false } },
server: {options: {anonymous: false}},
username: 'anonymous'
};
const cmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(mockClient);

View File

@@ -30,14 +30,14 @@ describe(CMD, function () {
});
it('// unsuccessful | invalid argument', () => {
return cmdFn({ command: { arg: '1,2,3,4,5' } })
return cmdFn({command: {arg: '1,2,3,4,5'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(425);
});
});
it('// successful', () => {
return cmdFn({ command: { arg: '192,168,0,100,137,214' } })
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);

View File

@@ -8,7 +8,7 @@ describe(CMD, function () {
let log = bunyan.createLogger({name: CMD});
const mockClient = {
reply: () => {},
fs: { currentDirectory: () => {} }
fs: {currentDirectory: () => {}}
};
const cmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(mockClient);
@@ -24,7 +24,7 @@ describe(CMD, function () {
describe('// check', function () {
it('fails on no fs', () => {
const badMockClient = { reply: () => {} };
const badMockClient = {reply: () => {}};
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
sandbox.stub(badMockClient, 'reply').resolves();
@@ -35,7 +35,7 @@ describe(CMD, function () {
});
it('fails on no fs currentDirectory command', () => {
const badMockClient = { reply: () => {}, fs: {} };
const badMockClient = {reply: () => {}, fs: {}};
const badCmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(badMockClient);
sandbox.stub(badMockClient, 'reply').resolves();
@@ -47,7 +47,7 @@ describe(CMD, function () {
});
it('// successful', () => {
return 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);
});

View File

@@ -27,21 +27,21 @@ describe(CMD, function () {
});
it('-1 // unsuccessful', () => {
return cmdFn({command: { arg: '-1', directive: CMD } })
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 } })
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 } })
return cmdFn({command: {arg: '1', directive: CMD}})
.then(() => {
expect(mockClient.restByteCount).to.equal(1);
expect(mockClient.reply.args[0][0]).to.equal(350);
@@ -49,7 +49,7 @@ describe(CMD, function () {
});
it('0 // successful', () => {
return cmdFn({command: { arg: '0', directive: CMD } })
return cmdFn({command: {arg: '0', directive: CMD}})
.then(() => {
expect(mockClient.restByteCount).to.equal(0);
expect(mockClient.reply.args[0][0]).to.equal(350);

View File

@@ -56,7 +56,7 @@ describe(CMD, function () {
return when.reject(new when.TimeoutError());
});
return cmdFn({log, command: {arg: 'test.txt'} })
return cmdFn({log, command: {arg: 'test.txt'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(425);
});
@@ -67,7 +67,7 @@ describe(CMD, function () {
return when.reject(new Error('test'));
});
return cmdFn({log, command: {arg: 'test.txt'} })
return cmdFn({log, command: {arg: 'test.txt'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(551);
});

View File

@@ -5,8 +5,8 @@ const sinon = require('sinon');
const CMD = 'RNFR';
describe(CMD, function () {
let sandbox;
const mockLog = { error: () => {} };
const mockClient = { reply: () => when.resolve() };
const mockLog = {error: () => {}};
const mockClient = {reply: () => when.resolve()};
const cmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(mockClient);
beforeEach(() => {
@@ -46,14 +46,14 @@ describe(CMD, function () {
mockClient.fs.get.restore();
sandbox.stub(mockClient.fs, 'get').rejects(new Error('test'));
return cmdFn({ log: mockLog, command: { arg: 'test' } })
return cmdFn({log: mockLog, command: {arg: 'test'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(550);
});
});
it('test // successful', () => {
return cmdFn({ log: mockLog, command: { arg: 'test' } })
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);

View File

@@ -5,8 +5,8 @@ const sinon = require('sinon');
const CMD = 'RNTO';
describe(CMD, function () {
let sandbox;
const mockLog = { error: () => {} };
const mockClient = { reply: () => when.resolve() };
const mockLog = {error: () => {}};
const mockClient = {reply: () => when.resolve()};
const cmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(mockClient);
beforeEach(() => {
@@ -56,14 +56,14 @@ describe(CMD, function () {
mockClient.fs.rename.restore();
sandbox.stub(mockClient.fs, 'rename').rejects(new Error('test'));
return cmdFn({ log: mockLog, command: { arg: 'new' } })
return cmdFn({log: mockLog, command: {arg: 'new'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(550);
});
});
it('new // successful', () => {
return cmdFn({ command: { arg: 'new' } })
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']);

View File

@@ -5,8 +5,8 @@ const sinon = require('sinon');
const CMD = 'CHMOD';
describe(CMD, function () {
let sandbox;
const mockLog = { error: () => {} };
const mockClient = { reply: () => when.resolve() };
const mockLog = {error: () => {}};
const mockClient = {reply: () => when.resolve()};
const cmdFn = require(`../../../../src/commands/registration/site/${CMD.toLowerCase()}`).bind(mockClient);
beforeEach(() => {
@@ -49,7 +49,7 @@ describe(CMD, function () {
mockClient.fs.chmod.restore();
sandbox.stub(mockClient.fs, 'chmod').rejects(new Error('test'));
cmdFn({ log: mockLog, command: { arg: '777 test' } })
cmdFn({log: mockLog, command: {arg: '777 test'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(500);
done();
@@ -58,7 +58,7 @@ describe(CMD, function () {
});
it('777 test // successful', done => {
cmdFn({ log: mockLog, command: { arg: '777 test' } })
cmdFn({log: mockLog, command: {arg: '777 test'}})
.then(() => {
expect(mockClient.fs.chmod.args[0]).to.eql(['test', 511]);
expect(mockClient.reply.args[0][0]).to.equal(200);

View File

@@ -0,0 +1,52 @@
const when = require('when');
const {expect} = require('chai');
const sinon = require('sinon');
const bunyan = require('bunyan');
const siteRegistry = require('../../../../src/commands/registration/site/registry');
const FtpCommands = require('../../../../src/commands');
const CMD = 'SITE';
describe(CMD, function () {
let sandbox;
const log = bunyan.createLogger({name: 'site-test'});
const mockClient = {
reply: () => when.resolve(),
commands: new FtpCommands()
};
const cmdFn = require(`../../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(mockClient);
beforeEach(() => {
sandbox = sinon.sandbox.create();
sandbox.stub(mockClient, 'reply').resolves();
});
afterEach(() => {
sandbox.restore();
});
it('// unsuccessful', () => {
return cmdFn({log})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(502);
});
});
it('// unsuccessful', () => {
return cmdFn({log, command: {arg: 'BAD'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(502);
});
});
it('// successful', () => {
sandbox.stub(siteRegistry.CHMOD, 'handler').resolves();
return cmdFn({log, command: {arg: 'CHMOD test'}})
.then(() => {
const {command} = siteRegistry.CHMOD.handler.args[0][0];
expect(command.directive).to.equal('CHMOD');
expect(command.arg).to.equal('test');
});
});
});

View File

@@ -5,8 +5,8 @@ const sinon = require('sinon');
const CMD = 'SIZE';
describe(CMD, function () {
let sandbox;
const mockLog = { error: () => {} };
const mockClient = { reply: () => when.resolve() };
const mockLog = {error: () => {}};
const mockClient = {reply: () => when.resolve()};
const cmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(mockClient);
beforeEach(() => {
@@ -43,14 +43,14 @@ describe(CMD, function () {
it('// unsuccessful | file get fails', () => {
sandbox.stub(mockClient.fs, 'get').rejects(new Error('test'));
return cmdFn({ log: mockLog, command: { arg: 'test' } })
return cmdFn({log: mockLog, command: {arg: 'test'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(550);
});
});
it('// successful', () => {
return cmdFn({ command: { arg: 'test' } })
return cmdFn({command: {arg: 'test'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(213);
});

View File

@@ -5,8 +5,8 @@ const sinon = require('sinon');
const CMD = 'STAT';
describe(CMD, function () {
let sandbox;
const mockLog = { error: () => {} };
const mockClient = { reply: () => when.resolve() };
const mockLog = {error: () => {}};
const mockClient = {reply: () => when.resolve()};
const cmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(mockClient);
beforeEach(() => {
@@ -33,7 +33,7 @@ describe(CMD, function () {
it('// unsuccessful | no file system', () => {
delete mockClient.fs;
return cmdFn({ command: { arg: 'test' } })
return cmdFn({command: {arg: 'test'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(550);
});
@@ -42,7 +42,7 @@ describe(CMD, function () {
it('// unsuccessful | file system does not have functions', () => {
mockClient.fs = {};
return cmdFn({ command: { arg: 'test' } })
return cmdFn({command: {arg: 'test'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(402);
});
@@ -51,7 +51,7 @@ describe(CMD, function () {
it('// unsuccessful | file get fails', () => {
sandbox.stub(mockClient.fs, 'get').rejects(new Error('test'));
return cmdFn({ log: mockLog, command: { arg: 'test' } })
return cmdFn({log: mockLog, command: {arg: 'test'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(450);
});
@@ -77,7 +77,7 @@ describe(CMD, function () {
isDirectory: () => false
});
return cmdFn({ command: { arg: 'test' } })
return cmdFn({command: {arg: 'test'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(212);
});
@@ -122,7 +122,7 @@ describe(CMD, function () {
isDirectory: () => true
});
return cmdFn({ command: { arg: 'test' } })
return cmdFn({command: {arg: 'test'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(213);
});

View File

@@ -56,7 +56,7 @@ describe(CMD, function () {
return when.reject(new when.TimeoutError());
});
return cmdFn({log, command: {arg: 'test.txt'} })
return cmdFn({log, command: {arg: 'test.txt'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(425);
});
@@ -67,7 +67,7 @@ describe(CMD, function () {
return when.reject(new Error('test'));
});
return cmdFn({log, command: {arg: 'test.txt'} })
return cmdFn({log, command: {arg: 'test.txt'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(550);
});

View File

@@ -52,7 +52,7 @@ describe(CMD, function () {
mockClient.fs.get.restore();
sandbox.stub(mockClient.fs, 'get').rejects({});
return cmdFn({ command: { arg: 'good' } })
return cmdFn({command: {arg: 'good'}})
.then(() => {
const call = stor.handler.call.args[0][1];
expect(call).to.have.property('command');
@@ -63,7 +63,7 @@ describe(CMD, function () {
});
it('// successful | generates unique name', () => {
return cmdFn({ command: { arg: 'bad' } })
return cmdFn({command: {arg: 'bad'}})
.then(() => {
const call = stor.handler.call.args[0][1];
expect(call).to.have.property('command');

View File

@@ -20,14 +20,14 @@ describe(CMD, function () {
});
it('// successful', () => {
return cmdFn({command: { arg: 'F' } })
return cmdFn({command: {arg: 'F'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(200);
});
});
it('// unsuccessful', () => {
return cmdFn({command: { arg: 'X' } })
return cmdFn({command: {arg: 'X'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(504);
});

View File

@@ -21,7 +21,7 @@ describe(CMD, function () {
});
it('A // successful', () => {
return cmdFn({ command: { arg: 'A' } })
return cmdFn({command: {arg: 'A'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(200);
expect(mockClient.transferType).to.equal('ascii');
@@ -29,7 +29,7 @@ describe(CMD, function () {
});
it('I // successful', () => {
return cmdFn({ command: { arg: 'I' } })
return cmdFn({command: {arg: 'I'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(200);
expect(mockClient.transferType).to.equal('binary');
@@ -37,7 +37,7 @@ describe(CMD, function () {
});
it('L // successful', () => {
return cmdFn({ command: { arg: 'L' } })
return cmdFn({command: {arg: 'L'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(200);
expect(mockClient.transferType).to.equal('binary');
@@ -45,7 +45,7 @@ describe(CMD, function () {
});
it('X // successful', () => {
return cmdFn({ command: { arg: 'X' } })
return cmdFn({command: {arg: 'X'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(501);
expect(mockClient.transferType).to.equal(null);

View File

@@ -10,7 +10,7 @@ describe(CMD, function () {
};
const mockClient = {
reply: () => when.resolve(),
server: { options: {} },
server: {options: {}},
login: () => when.resolve()
};
const cmdFn = require(`../../../src/commands/registration/${CMD.toLowerCase()}`).handler.bind(mockClient);
@@ -29,7 +29,7 @@ describe(CMD, function () {
});
it('test // successful | prompt for password', () => {
return cmdFn({ command: { arg: 'test' } })
return cmdFn({command: {arg: 'test'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(331);
});
@@ -38,7 +38,7 @@ describe(CMD, function () {
it('test // successful | anonymous login', () => {
mockClient.server.options = {anonymous: true};
return 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);
@@ -46,7 +46,7 @@ describe(CMD, function () {
});
it('test // unsuccessful | no username provided', () => {
return cmdFn({ command: { } })
return cmdFn({command: { }})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(501);
expect(mockClient.login.callCount).to.equal(0);
@@ -56,7 +56,7 @@ describe(CMD, function () {
it('test // unsuccessful | already set username', () => {
mockClient.username = 'test';
return 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);
@@ -66,7 +66,7 @@ describe(CMD, function () {
it('test // successful | regular login if anonymous is true', () => {
mockClient.server.options = {anonymous: true};
return 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);
@@ -76,7 +76,7 @@ describe(CMD, function () {
it('test // successful | anonymous login with set username', () => {
mockClient.server.options = {anonymous: 'sillyrabbit'};
return 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);
@@ -88,7 +88,7 @@ describe(CMD, function () {
mockClient.login.restore();
sandbox.stub(mockClient, 'login').rejects(new Error('test'));
return cmdFn({ log: mockLog, command: { arg: 'anonymous' } })
return cmdFn({log: mockLog, command: {arg: 'anonymous'}})
.then(() => {
expect(mockClient.reply.args[0][0]).to.equal(530);
expect(mockClient.login.callCount).to.equal(1);
@@ -98,7 +98,7 @@ describe(CMD, function () {
it('test // successful | does not login if already authenticated', () => {
mockClient.authenticated = true;
return 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(0);

View File

@@ -66,7 +66,7 @@ describe('Connector - Active //', function () {
it('upgrades to a secure connection', function () {
mockConnection.secure = true;
mockConnection.server = { _tls: {} };
mockConnection.server = {_tls: {}};
return active.setupConnection('127.0.0.1', PORT)
.then(() => {

View File

@@ -16,7 +16,7 @@ describe('Connector - Passive //', function () {
encoding: 'utf8',
log: bunyan.createLogger({name: 'passive-test'}),
commandSocket: {},
server: { options: {} }
server: {options: {}}
};
let sandbox;

View File

@@ -1,5 +0,0 @@
{
"mute":false,
"level":"fatal",
"reporter":"spec"
}

View File

@@ -19,7 +19,7 @@ const server = new FtpServer('ftp://127.0.0.1:8880', {
});
server.on('login', ({username, password}, resolve, reject) => {
if (username === 'test' && password === 'test' || username === 'anonymous') {
resolve({ root: require('os').homedir() });
resolve({root: require('os').homedir()});
} else reject('Bad username or password');
});
server.listen();