Convert test files to Typescript

Change-type: patch
Signed-off-by: Lucian <lucian.buzzo@gmail.com>
This commit is contained in:
Lucian 2019-08-07 12:31:03 +01:00
parent 9c49890399
commit 13610ef814
11 changed files with 406 additions and 503 deletions

View File

@ -2,7 +2,6 @@ path = require('path')
gulp = require('gulp') gulp = require('gulp')
coffee = require('gulp-coffee') coffee = require('gulp-coffee')
inlinesource = require('gulp-inline-source') inlinesource = require('gulp-inline-source')
mocha = require('gulp-mocha')
shell = require('gulp-shell') shell = require('gulp-shell')
packageJSON = require('./package.json') packageJSON = require('./package.json')
@ -25,12 +24,6 @@ gulp.task 'coffee', ->
.pipe(coffee(bare: true, header: true)) .pipe(coffee(bare: true, header: true))
.pipe(gulp.dest(OPTIONS.directories.build)) .pipe(gulp.dest(OPTIONS.directories.build))
gulp.task 'test', ->
gulp.src(OPTIONS.files.tests, read: false)
.pipe(mocha({
reporter: 'spec'
}))
gulp.task 'build', gulp.series [ gulp.task 'build', gulp.series [
'coffee', 'coffee',
'pages' 'pages'

217
npm-shrinkwrap.json generated
View File

@ -376,6 +376,21 @@
"resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz",
"integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w=="
}, },
"@types/chai": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz",
"integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==",
"dev": true
},
"@types/chai-as-promised": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.1.tgz",
"integrity": "sha512-dberBxQW/XWv6BMj0su1lV9/C9AUx5Hqu2pisuS6S4YK/Qt6vurcj/BmcbEsobIWWCQzhesNY8k73kIxx4X7Mg==",
"dev": true,
"requires": {
"@types/chai": "*"
}
},
"@types/chokidar": { "@types/chokidar": {
"version": "1.7.5", "version": "1.7.5",
"resolved": "https://registry.npmjs.org/@types/chokidar/-/chokidar-1.7.5.tgz", "resolved": "https://registry.npmjs.org/@types/chokidar/-/chokidar-1.7.5.tgz",
@ -415,6 +430,12 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"@types/ejs": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/@types/ejs/-/ejs-2.6.3.tgz",
"integrity": "sha512-/F+qQ0Fr0Dr1YvHjX+FCvbba4sQ27RdCPDqmP/si0e1v1GOkbQ3VRBvZPSQM7NoQ3iz3SyiJVscCP2f0vKuIhQ==",
"dev": true
},
"@types/event-stream": { "@types/event-stream": {
"version": "3.3.34", "version": "3.3.34",
"resolved": "https://registry.npmjs.org/@types/event-stream/-/event-stream-3.3.34.tgz", "resolved": "https://registry.npmjs.org/@types/event-stream/-/event-stream-3.3.34.tgz",
@ -530,6 +551,12 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"@types/mocha": {
"version": "5.2.7",
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz",
"integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==",
"dev": true
},
"@types/mz": { "@types/mz": {
"version": "0.0.32", "version": "0.0.32",
"resolved": "https://registry.npmjs.org/@types/mz/-/mz-0.0.32.tgz", "resolved": "https://registry.npmjs.org/@types/mz/-/mz-0.0.32.tgz",
@ -599,6 +626,12 @@
} }
} }
}, },
"@types/rewire": {
"version": "2.5.28",
"resolved": "https://registry.npmjs.org/@types/rewire/-/rewire-2.5.28.tgz",
"integrity": "sha512-uD0j/AQOa5le7afuK+u+woi8jNKF1vf3DN0H7LCJhft/lNNibUr7VcAesdgtWfEKveZol3ZG1CJqwx2Bhrnl8w==",
"dev": true
},
"@types/rimraf": { "@types/rimraf": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.2.tgz", "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.2.tgz",
@ -620,6 +653,12 @@
"integrity": "sha512-7kUdtJtUylvyISJbe9FMcvMTjRdP0EvNDO1WbT0lT22k/IPBiPRTpmWaKu5HTWLCGLQRWVHrzVHZktTDvvR23g==", "integrity": "sha512-7kUdtJtUylvyISJbe9FMcvMTjRdP0EvNDO1WbT0lT22k/IPBiPRTpmWaKu5HTWLCGLQRWVHrzVHZktTDvvR23g==",
"dev": true "dev": true
}, },
"@types/sinon": {
"version": "7.0.13",
"resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.13.tgz",
"integrity": "sha512-d7c/C/+H/knZ3L8/cxhicHUiTDxdgap0b/aNJfsmLwFu/iOP17mdgbQsbHA3SJmrzsjD0l3UEE5SN4xxuz5ung==",
"dev": true
},
"@types/stream-to-promise": { "@types/stream-to-promise": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/@types/stream-to-promise/-/stream-to-promise-2.2.0.tgz", "resolved": "https://registry.npmjs.org/@types/stream-to-promise/-/stream-to-promise-2.2.0.tgz",
@ -6226,12 +6265,6 @@
"lodash": "^4.17.2" "lodash": "^4.17.2"
} }
}, },
"growl": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz",
"integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=",
"dev": true
},
"gulp": { "gulp": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz",
@ -6296,127 +6329,6 @@
"through2": "~2.0.0" "through2": "~2.0.0"
} }
}, },
"gulp-mocha": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/gulp-mocha/-/gulp-mocha-2.2.0.tgz",
"integrity": "sha1-HOXrpLlLQMdDav7DxJgsjuqJQZI=",
"dev": true,
"requires": {
"gulp-util": "^3.0.0",
"mocha": "^2.0.1",
"plur": "^2.1.0",
"resolve-from": "^1.0.0",
"temp": "^0.8.3",
"through": "^2.3.4"
},
"dependencies": {
"commander": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz",
"integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=",
"dev": true
},
"debug": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
"integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
"dev": true,
"requires": {
"ms": "0.7.1"
}
},
"diff": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz",
"integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=",
"dev": true
},
"escape-string-regexp": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz",
"integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=",
"dev": true
},
"glob": {
"version": "3.2.11",
"resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz",
"integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=",
"dev": true,
"requires": {
"inherits": "2",
"minimatch": "0.3"
}
},
"lru-cache": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
"integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=",
"dev": true
},
"minimatch": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz",
"integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=",
"dev": true,
"requires": {
"lru-cache": "2",
"sigmund": "~1.0.0"
}
},
"mocha": {
"version": "2.5.3",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz",
"integrity": "sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg=",
"dev": true,
"requires": {
"commander": "2.3.0",
"debug": "2.2.0",
"diff": "1.4.0",
"escape-string-regexp": "1.0.2",
"glob": "3.2.11",
"growl": "1.9.2",
"jade": "0.26.3",
"mkdirp": "0.5.1",
"supports-color": "1.2.0",
"to-iso-string": "0.0.2"
}
},
"ms": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
"integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=",
"dev": true
},
"resolve-from": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
"integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
"dev": true
},
"rimraf": {
"version": "2.2.8",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
"integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
"dev": true
},
"supports-color": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz",
"integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=",
"dev": true
},
"temp": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz",
"integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=",
"dev": true,
"requires": {
"os-tmpdir": "^1.0.0",
"rimraf": "~2.2.6"
}
}
}
},
"gulp-shell": { "gulp-shell": {
"version": "0.5.2", "version": "0.5.2",
"resolved": "https://registry.npmjs.org/gulp-shell/-/gulp-shell-0.5.2.tgz", "resolved": "https://registry.npmjs.org/gulp-shell/-/gulp-shell-0.5.2.tgz",
@ -7288,12 +7200,6 @@
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
"integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
}, },
"irregular-plurals": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.4.0.tgz",
"integrity": "sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y=",
"dev": true
},
"is-absolute": { "is-absolute": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
@ -7662,30 +7568,6 @@
"is-object": "^1.0.1" "is-object": "^1.0.1"
} }
}, },
"jade": {
"version": "0.26.3",
"resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz",
"integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=",
"dev": true,
"requires": {
"commander": "0.6.1",
"mkdirp": "0.3.0"
},
"dependencies": {
"commander": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz",
"integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=",
"dev": true
},
"mkdirp": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz",
"integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=",
"dev": true
}
}
},
"js-tokens": { "js-tokens": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
@ -13483,15 +13365,6 @@
"xmldom": "0.1.x" "xmldom": "0.1.x"
} }
}, },
"plur": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz",
"integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=",
"dev": true,
"requires": {
"irregular-plurals": "^1.0.0"
}
},
"posix-character-classes": { "posix-character-classes": {
"version": "0.1.1", "version": "0.1.1",
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
@ -15665,12 +15538,6 @@
"resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
"integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww=="
}, },
"sigmund": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
"integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
"dev": true
},
"signal-exit": { "signal-exit": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
@ -16661,12 +16528,6 @@
"integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
"dev": true "dev": true
}, },
"to-iso-string": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz",
"integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=",
"dev": true
},
"to-object-path": { "to-object-path": {
"version": "0.3.0", "version": "0.3.0",
"resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",

View File

@ -46,8 +46,8 @@
"package": "npm run build:fast && npm run build:standalone && npm run build:installer", "package": "npm run build:fast && npm run build:standalone && npm run build:installer",
"release": "ts-node --type-check -P automation/tsconfig.json automation/run.ts release", "release": "ts-node --type-check -P automation/tsconfig.json automation/run.ts release",
"pretest": "npm run build", "pretest": "npm run build",
"test": "gulp test", "test": "mocha -r ts-node/register tests/**/*.spec.ts",
"test:fast": "npm run build:fast && gulp test", "test:fast": "npm run build:fast && npm run test",
"ci": "npm run test && catch-uncommitted", "ci": "npm run test && catch-uncommitted",
"watch": "gulp watch", "watch": "gulp watch",
"prettify": "prettier --write \"{lib,tests,automation,typings}/**/*.ts\" --config ./node_modules/resin-lint/config/.prettierrc", "prettify": "prettier --write \"{lib,tests,automation,typings}/**/*.ts\" --config ./node_modules/resin-lint/config/.prettierrc",
@ -82,22 +82,28 @@
"@oclif/parser": "^3.7.3", "@oclif/parser": "^3.7.3",
"@types/archiver": "2.1.2", "@types/archiver": "2.1.2",
"@types/bluebird": "3.5.21", "@types/bluebird": "3.5.21",
"@types/chai": "^4.1.7",
"@types/chai-as-promised": "^7.1.1",
"@types/chokidar": "^1.7.5", "@types/chokidar": "^1.7.5",
"@types/common-tags": "1.4.0", "@types/common-tags": "1.4.0",
"@types/dockerode": "2.5.6", "@types/dockerode": "2.5.6",
"@types/ejs": "^2.6.3",
"@types/fs-extra": "7.0.0", "@types/fs-extra": "7.0.0",
"@types/is-root": "1.0.0", "@types/is-root": "1.0.0",
"@types/lodash": "4.14.112", "@types/lodash": "4.14.112",
"@types/mixpanel": "2.14.0", "@types/mixpanel": "2.14.0",
"@types/mkdirp": "0.5.2", "@types/mkdirp": "0.5.2",
"@types/mocha": "^5.2.7",
"@types/mz": "0.0.32", "@types/mz": "0.0.32",
"@types/net-keepalive": "^0.4.0", "@types/net-keepalive": "^0.4.0",
"@types/node": "10.14.5", "@types/node": "10.14.5",
"@types/prettyjson": "0.0.28", "@types/prettyjson": "0.0.28",
"@types/raven": "2.5.1", "@types/raven": "2.5.1",
"@types/request": "2.48.1", "@types/request": "2.48.1",
"@types/rewire": "^2.5.28",
"@types/rimraf": "^2.0.2", "@types/rimraf": "^2.0.2",
"@types/shell-escape": "^0.2.0", "@types/shell-escape": "^0.2.0",
"@types/sinon": "^7.0.13",
"@types/stream-to-promise": "2.2.0", "@types/stream-to-promise": "2.2.0",
"@types/tar-stream": "1.6.0", "@types/tar-stream": "1.6.0",
"@types/through2": "2.0.33", "@types/through2": "2.0.33",
@ -110,7 +116,6 @@
"gulp": "^4.0.1", "gulp": "^4.0.1",
"gulp-coffee": "^2.2.0", "gulp-coffee": "^2.2.0",
"gulp-inline-source": "^2.1.0", "gulp-inline-source": "^2.1.0",
"gulp-mocha": "^2.0.0",
"gulp-shell": "^0.5.2", "gulp-shell": "^0.5.2",
"mocha": "^6.2.0", "mocha": "^6.2.0",
"pkg": "^4.4.0", "pkg": "^4.4.0",

View File

@ -1,164 +0,0 @@
const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
const request = require('request');
const sinon = require('sinon');
const Promise = require('bluebird');
const path = require('path');
const fs = require('fs');
const ejs = require('ejs');
const server = require('../../build/auth/server');
const utils = require('../../build/auth/utils');
const tokens = require('./tokens.json');
chai.use(chaiAsPromised);
let options = {
port: 3000,
path: '/auth'
};
let getPage = function(name) {
let pagePath = path.join(__dirname, '..', '..', 'build', 'auth', 'pages', `${name}.ejs`);
let tpl = fs.readFileSync(pagePath, {encoding: 'utf8'});
let compiledTpl = ejs.compile(tpl);
return server.getContext(name)
.then(context => compiledTpl(context));
};
describe('Server:', function() {
it('should get 404 if posting to an unknown path', function(done) {
let promise = server.awaitForToken(options);
chai.expect(promise).to.be.rejectedWith('Unknown path or verb');
return request.post(`http://localhost:${options.port}/foobarbaz`, {
form: {
token: tokens.johndoe.token
}
}
, function(error, response, body) {
chai.expect(error).to.not.exist;
chai.expect(response.statusCode).to.equal(404);
chai.expect(body).to.equal('Not found');
return done();
});
});
it('should get 404 if not using the correct verb', function(done) {
let promise = server.awaitForToken(options);
chai.expect(promise).to.be.rejectedWith('Unknown path or verb');
return request.get(`http://localhost:${options.port}${options.path}`, {
form: {
token: tokens.johndoe.token
}
}
, function(error, response, body) {
chai.expect(error).to.not.exist;
chai.expect(response.statusCode).to.equal(404);
chai.expect(body).to.equal('Not found');
return done();
});
});
describe('given the token authenticates with the server', function() {
beforeEach(function() {
this.loginIfTokenValidStub = sinon.stub(utils, 'loginIfTokenValid');
return this.loginIfTokenValidStub.returns(Promise.resolve(true));
});
afterEach(function() {
return this.loginIfTokenValidStub.restore();
});
return it('should eventually be the token', function(done) {
let promise = server.awaitForToken(options);
chai.expect(promise).to.eventually.equal(tokens.johndoe.token);
return request.post(`http://localhost:${options.port}${options.path}`, {
form: {
token: tokens.johndoe.token
}
}
, function(error, response, body) {
chai.expect(error).to.not.exist;
chai.expect(response.statusCode).to.equal(200);
return getPage('success').then(function(expectedBody) {
chai.expect(body).to.equal(expectedBody);
return done();
});
});
});
});
return describe('given the token does not authenticate with the server', function() {
beforeEach(function() {
this.loginIfTokenValidStub = sinon.stub(utils, 'loginIfTokenValid');
return this.loginIfTokenValidStub.returns(Promise.resolve(false));
});
afterEach(function() {
return this.loginIfTokenValidStub.restore();
});
it('should be rejected', function(done) {
let promise = server.awaitForToken(options);
chai.expect(promise).to.be.rejectedWith('Invalid token');
return request.post(`http://localhost:${options.port}${options.path}`, {
form: {
token: tokens.johndoe.token
}
}
, function(error, response, body) {
chai.expect(error).to.not.exist;
chai.expect(response.statusCode).to.equal(401);
return getPage('error').then(function(expectedBody) {
chai.expect(body).to.equal(expectedBody);
return done();
});
});
});
it('should be rejected if no token', function(done) {
let promise = server.awaitForToken(options);
chai.expect(promise).to.be.rejectedWith('No token');
return request.post(`http://localhost:${options.port}${options.path}`, {
form: {
token: ''
}
}
, function(error, response, body) {
chai.expect(error).to.not.exist;
chai.expect(response.statusCode).to.equal(401);
return getPage('error').then(function(expectedBody) {
chai.expect(body).to.equal(expectedBody);
return done();
});
});
});
return it('should be rejected if token is malformed', function(done) {
let promise = server.awaitForToken(options);
chai.expect(promise).to.be.rejectedWith('Invalid token');
return request.post(`http://localhost:${options.port}${options.path}`, {
form: {
token: 'asdf'
}
}
, function(error, response, body) {
chai.expect(error).to.not.exist;
chai.expect(response.statusCode).to.equal(401);
return getPage('error').then(function(expectedBody) {
chai.expect(body).to.equal(expectedBody);
return done();
});
});
});
});
});

193
tests/auth/server.spec.ts Normal file
View File

@ -0,0 +1,193 @@
import * as Promise from 'bluebird';
import * as chai from 'chai';
import chaiAsPromised = require('chai-as-promised');
import * as ejs from 'ejs';
import * as fs from 'fs';
import * as path from 'path';
import * as request from 'request';
import * as sinon from 'sinon';
// TODO: Convert server code to Typescript so it can have a declaration file
// @ts-ignore
import * as server from '../../build/auth/server';
// TODO: Convert utils code to Typescript so it can have a declaration file
// @ts-ignore
import * as utils from '../../build/auth/utils';
import tokens from './tokens';
chai.use(chaiAsPromised);
const { expect } = chai;
const options = {
port: 3000,
path: '/auth',
};
const getPage = function(name: string): Promise<string> {
const pagePath = path.join(
__dirname,
'..',
'..',
'build',
'auth',
'pages',
`${name}.ejs`,
);
const tpl = fs.readFileSync(pagePath, { encoding: 'utf8' });
const compiledTpl = ejs.compile(tpl);
return server.getContext(name).then((context: any) => compiledTpl(context));
};
describe('Server:', function() {
it('should get 404 if posting to an unknown path', function(done) {
const promise = server.awaitForToken(options);
expect(promise).to.be.rejectedWith('Unknown path or verb');
return request.post(
`http://localhost:${options.port}/foobarbaz`,
{
form: {
token: tokens.johndoe.token,
},
},
function(error, response, body) {
expect(error).to.not.exist;
expect(response.statusCode).to.equal(404);
expect(body).to.equal('Not found');
return done();
},
);
});
it('should get 404 if not using the correct verb', function(done) {
const promise = server.awaitForToken(options);
expect(promise).to.be.rejectedWith('Unknown path or verb');
return request.get(
`http://localhost:${options.port}${options.path}`,
{
form: {
token: tokens.johndoe.token,
},
},
function(error, response, body) {
expect(error).to.not.exist;
expect(response.statusCode).to.equal(404);
expect(body).to.equal('Not found');
return done();
},
);
});
describe('given the token authenticates with the server', function() {
beforeEach(function() {
this.loginIfTokenValidStub = sinon.stub(utils, 'loginIfTokenValid');
return this.loginIfTokenValidStub.returns(Promise.resolve(true));
});
afterEach(function() {
return this.loginIfTokenValidStub.restore();
});
return it('should eventually be the token', function(done) {
const promise = server.awaitForToken(options);
expect(promise).to.eventually.equal(tokens.johndoe.token);
return request.post(
`http://localhost:${options.port}${options.path}`,
{
form: {
token: tokens.johndoe.token,
},
},
function(error, response, body) {
expect(error).to.not.exist;
expect(response.statusCode).to.equal(200);
return getPage('success').then(function(expectedBody) {
expect(body).to.equal(expectedBody);
return done();
});
},
);
});
});
return describe('given the token does not authenticate with the server', function() {
beforeEach(function() {
this.loginIfTokenValidStub = sinon.stub(utils, 'loginIfTokenValid');
return this.loginIfTokenValidStub.returns(Promise.resolve(false));
});
afterEach(function() {
return this.loginIfTokenValidStub.restore();
});
it('should be rejected', function(done) {
const promise = server.awaitForToken(options);
expect(promise).to.be.rejectedWith('Invalid token');
return request.post(
`http://localhost:${options.port}${options.path}`,
{
form: {
token: tokens.johndoe.token,
},
},
function(error, response, body) {
expect(error).to.not.exist;
expect(response.statusCode).to.equal(401);
return getPage('error').then(function(expectedBody) {
expect(body).to.equal(expectedBody);
return done();
});
},
);
});
it('should be rejected if no token', function(done) {
const promise = server.awaitForToken(options);
expect(promise).to.be.rejectedWith('No token');
return request.post(
`http://localhost:${options.port}${options.path}`,
{
form: {
token: '',
},
},
function(error, response, body) {
expect(error).to.not.exist;
expect(response.statusCode).to.equal(401);
return getPage('error').then(function(expectedBody) {
expect(body).to.equal(expectedBody);
return done();
});
},
);
});
return it('should be rejected if token is malformed', function(done) {
const promise = server.awaitForToken(options);
expect(promise).to.be.rejectedWith('Invalid token');
return request.post(
`http://localhost:${options.port}${options.path}`,
{
form: {
token: 'asdf',
},
},
function(error, response, body) {
expect(error).to.not.exist;
expect(response.statusCode).to.equal(401);
return getPage('error').then(function(expectedBody) {
expect(body).to.equal(expectedBody);
return done();
});
},
);
});
});
});

View File

@ -1,18 +0,0 @@
{
"johndoe": {
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImpvaG5kb2UxIiwiZW1haWwiOiJqb2huZG9lQGpvaG5kb2UuY29tIiwiZ2l0bGFiX2lkIjoxMzI1LCJzb2NpYWxfc2VydmljZV9hY2NvdW50IjpudWxsLCJoYXNQYXNzd29yZFNldCI6dHJ1ZSwibmVlZHNQYXNzd29yZFJlc2V0IjpmYWxzZSwicHVibGljX2tleSI6ZmFsc2UsImZlYXR1cmVzIjpbXSwiaWQiOjEzNDQsImludGVyY29tVXNlckhhc2giOiJlMDM3NzhkZDI5ZTE1NzQ0NWYyNzJhY2M5MjExNzBjZjI4MTBiNjJmNTAyNjQ1MjY1Y2MzNDlkNmRlZGEzNTI0IiwicGVybWlzc2lvbnMiOltdLCJpYXQiOjE0MjY3ODMzMTJ9.v5bmh9HwyUZu8zhh1rA79mTL-1jzDOO8eUr_lVaBwhg",
"data": {
"email": "johndoe@johndoe.com",
"username": "johndoe1",
"id": 1344
}
},
"janedoe": {
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MTUyLCJ1c2VybmFtZSI6ImphbmVkb2UiLCJlbWFpbCI6ImphbmVkb2VAYXNkZi5jb20iLCJzb2NpYWxfc2VydmljZV9hY2NvdW50IjpudWxsLCJoYXNfZGlzYWJsZWRfbmV3c2xldHRlciI6dHJ1ZSwiaGFzUGFzc3dvcmRTZXQiOnRydWUsIm5lZWRzUGFzc3dvcmRSZXNldCI6ZmFsc2UsInB1YmxpY19rZXkiOmZhbHNlLCJmZWF0dXJlcyI6W10sImludGVyY29tVXNlckhhc2giOiIwYjRmOWViNDRiMzcxZjBlMzI4ZWY1ZmUwM2FkN2ViMmY1ZjcyZGQ0MThlZjIzMTQ5ZDUyODcwOTY1NThjZTAzIiwicGVybWlzc2lvbnMiOltdLCJpYXQiOjE0MzUzMjAyNjN9.jVzUFu58vzdJFctR8ulyjGL0Em1kjIZSbSxX2SeU03Y",
"data": {
"email": "janedoe@asdf.com",
"username": "janedoe",
"id": 152
}
}
}

20
tests/auth/tokens.ts Normal file
View File

@ -0,0 +1,20 @@
export default {
johndoe: {
token:
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImpvaG5kb2UxIiwiZW1haWwiOiJqb2huZG9lQGpvaG5kb2UuY29tIiwiZ2l0bGFiX2lkIjoxMzI1LCJzb2NpYWxfc2VydmljZV9hY2NvdW50IjpudWxsLCJoYXNQYXNzd29yZFNldCI6dHJ1ZSwibmVlZHNQYXNzd29yZFJlc2V0IjpmYWxzZSwicHVibGljX2tleSI6ZmFsc2UsImZlYXR1cmVzIjpbXSwiaWQiOjEzNDQsImludGVyY29tVXNlckhhc2giOiJlMDM3NzhkZDI5ZTE1NzQ0NWYyNzJhY2M5MjExNzBjZjI4MTBiNjJmNTAyNjQ1MjY1Y2MzNDlkNmRlZGEzNTI0IiwicGVybWlzc2lvbnMiOltdLCJpYXQiOjE0MjY3ODMzMTJ9.v5bmh9HwyUZu8zhh1rA79mTL-1jzDOO8eUr_lVaBwhg',
data: {
email: 'johndoe@johndoe.com',
username: 'johndoe1',
id: 1344,
},
},
janedoe: {
token:
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MTUyLCJ1c2VybmFtZSI6ImphbmVkb2UiLCJlbWFpbCI6ImphbmVkb2VAYXNkZi5jb20iLCJzb2NpYWxfc2VydmljZV9hY2NvdW50IjpudWxsLCJoYXNfZGlzYWJsZWRfbmV3c2xldHRlciI6dHJ1ZSwiaGFzUGFzc3dvcmRTZXQiOnRydWUsIm5lZWRzUGFzc3dvcmRSZXNldCI6ZmFsc2UsInB1YmxpY19rZXkiOmZhbHNlLCJmZWF0dXJlcyI6W10sImludGVyY29tVXNlckhhc2giOiIwYjRmOWViNDRiMzcxZjBlMzI4ZWY1ZmUwM2FkN2ViMmY1ZjcyZGQ0MThlZjIzMTQ5ZDUyODcwOTY1NThjZTAzIiwicGVybWlzc2lvbnMiOltdLCJpYXQiOjE0MzUzMjAyNjN9.jVzUFu58vzdJFctR8ulyjGL0Em1kjIZSbSxX2SeU03Y',
data: {
email: 'janedoe@asdf.com',
username: 'janedoe',
id: 152,
},
},
};

View File

@ -1,77 +1,72 @@
const chai = require('chai'); import * as Promise from 'bluebird';
const sinon = require('sinon'); import * as chai from 'chai';
const url = require('url'); import rewire = require('rewire');
const Promise = require('bluebird'); import * as sinon from 'sinon';
import * as url from 'url';
import tokens from './tokens';
const tokens = require('./tokens.json'); const utils = rewire('../../build/auth/utils');
const balena = utils.__get__('balena');
const rewire = require('rewire');
let utils = rewire('../../build/auth/utils');
let balena = utils.__get__('balena');
describe('Utils:', function() { describe('Utils:', function() {
describe('.getDashboardLoginURL()', function() { describe('.getDashboardLoginURL()', function() {
it('should eventually be a valid url', () => it('should eventually be a valid url', () =>
utils.getDashboardLoginURL('https://127.0.0.1:3000/callback').then(loginUrl => utils
chai.expect(() => url.parse(loginUrl)).to.not.throw(Error) .getDashboardLoginURL('https://127.0.0.1:3000/callback')
) .then((loginUrl: string) =>
); chai.expect(() => url.parse(loginUrl)).to.not.throw(Error),
));
it('should eventually contain an https protocol', () => it('should eventually contain an https protocol', () =>
Promise.props({ Promise.props({
dashboardUrl: balena.settings.get('dashboardUrl'), dashboardUrl: balena.settings.get('dashboardUrl'),
loginUrl: utils.getDashboardLoginURL('https://127.0.0.1:3000/callback')}).then(function({ dashboardUrl, loginUrl }) { loginUrl: utils.getDashboardLoginURL('https://127.0.0.1:3000/callback'),
let { protocol } = url.parse(loginUrl); }).then(function({ dashboardUrl, loginUrl }) {
const { protocol } = url.parse(loginUrl);
return chai.expect(protocol).to.equal(url.parse(dashboardUrl).protocol); return chai.expect(protocol).to.equal(url.parse(dashboardUrl).protocol);
}) }));
);
it('should correctly escape a callback url without a path', () => it('should correctly escape a callback url without a path', () =>
Promise.props({ Promise.props({
dashboardUrl: balena.settings.get('dashboardUrl'), dashboardUrl: balena.settings.get('dashboardUrl'),
loginUrl: utils.getDashboardLoginURL('http://127.0.0.1:3000')}).then(function({ dashboardUrl, loginUrl }) { loginUrl: utils.getDashboardLoginURL('http://127.0.0.1:3000'),
let expectedUrl = `${dashboardUrl}/login/cli/http%253A%252F%252F127.0.0.1%253A3000`; }).then(function({ dashboardUrl, loginUrl }) {
const expectedUrl = `${dashboardUrl}/login/cli/http%253A%252F%252F127.0.0.1%253A3000`;
return chai.expect(loginUrl).to.equal(expectedUrl); return chai.expect(loginUrl).to.equal(expectedUrl);
}) }));
);
return it('should correctly escape a callback url with a path', () => return it('should correctly escape a callback url with a path', () =>
Promise.props({ Promise.props({
dashboardUrl: balena.settings.get('dashboardUrl'), dashboardUrl: balena.settings.get('dashboardUrl'),
loginUrl: utils.getDashboardLoginURL('http://127.0.0.1:3000/callback')}).then(function({ dashboardUrl, loginUrl }) { loginUrl: utils.getDashboardLoginURL('http://127.0.0.1:3000/callback'),
let expectedUrl = `${dashboardUrl}/login/cli/http%253A%252F%252F127.0.0.1%253A3000%252Fcallback`; }).then(function({ dashboardUrl, loginUrl }) {
const expectedUrl = `${dashboardUrl}/login/cli/http%253A%252F%252F127.0.0.1%253A3000%252Fcallback`;
return chai.expect(loginUrl).to.equal(expectedUrl); return chai.expect(loginUrl).to.equal(expectedUrl);
}) }));
);
}); });
return describe('.loginIfTokenValid()', function() { return describe('.loginIfTokenValid()', function() {
it('should eventually be false if token is undefined', function() { it('should eventually be false if token is undefined', function() {
let promise = utils.loginIfTokenValid(undefined); const promise = utils.loginIfTokenValid(undefined);
return chai.expect(promise).to.eventually.be.false; return chai.expect(promise).to.eventually.be.false;
}); });
it('should eventually be false if token is null', function() { it('should eventually be false if token is null', function() {
let promise = utils.loginIfTokenValid(null); const promise = utils.loginIfTokenValid(null);
return chai.expect(promise).to.eventually.be.false; return chai.expect(promise).to.eventually.be.false;
}); });
it('should eventually be false if token is an empty string', function() { it('should eventually be false if token is an empty string', function() {
let promise = utils.loginIfTokenValid(''); const promise = utils.loginIfTokenValid('');
return chai.expect(promise).to.eventually.be.false; return chai.expect(promise).to.eventually.be.false;
}); });
it('should eventually be false if token is a string containing only spaces', function() { it('should eventually be false if token is a string containing only spaces', function() {
let promise = utils.loginIfTokenValid(' '); const promise = utils.loginIfTokenValid(' ');
return chai.expect(promise).to.eventually.be.false; return chai.expect(promise).to.eventually.be.false;
}); });
describe('given the token does not authenticate with the server', function() { describe('given the token does not authenticate with the server', function() {
beforeEach(function() { beforeEach(function() {
this.balenaAuthIsLoggedInStub = sinon.stub(balena.auth, 'isLoggedIn'); this.balenaAuthIsLoggedInStub = sinon.stub(balena.auth, 'isLoggedIn');
return this.balenaAuthIsLoggedInStub.returns(Promise.resolve(false)); return this.balenaAuthIsLoggedInStub.returns(Promise.resolve(false));
@ -82,33 +77,40 @@ describe('Utils:', function() {
}); });
it('should eventually be false', function() { it('should eventually be false', function() {
let promise = utils.loginIfTokenValid(tokens.johndoe.token); const promise = utils.loginIfTokenValid(tokens.johndoe.token);
return chai.expect(promise).to.eventually.be.false; return chai.expect(promise).to.eventually.be.false;
}); });
describe('given there was a token already', function() { describe('given there was a token already', function() {
beforeEach(() => balena.auth.loginWithToken(tokens.janedoe.token)); beforeEach(() => balena.auth.loginWithToken(tokens.janedoe.token));
return it('should preserve the old token', () => return it('should preserve the old token', () =>
balena.auth.getToken().then(function(originalToken) { balena.auth
chai.expect(originalToken).to.equal(tokens.janedoe.token); .getToken()
return utils.loginIfTokenValid(tokens.johndoe.token);}).then(balena.auth.getToken).then(currentToken => chai.expect(currentToken).to.equal(tokens.janedoe.token)) .then(function(originalToken: string) {
); chai.expect(originalToken).to.equal(tokens.janedoe.token);
return utils.loginIfTokenValid(tokens.johndoe.token);
})
.then(balena.auth.getToken)
.then((currentToken: string) =>
chai.expect(currentToken).to.equal(tokens.janedoe.token),
));
}); });
return describe('given there was no token', function() { return describe('given there was no token', function() {
beforeEach(() => balena.auth.logout()); beforeEach(() => balena.auth.logout());
return it('should stay without a token', () => return it('should stay without a token', () =>
utils.loginIfTokenValid(tokens.johndoe.token).then(() => balena.auth.isLoggedIn()).then(isLoggedIn => chai.expect(isLoggedIn).to.equal(false)) utils
); .loginIfTokenValid(tokens.johndoe.token)
.then(() => balena.auth.isLoggedIn())
.then((isLoggedIn: boolean) =>
chai.expect(isLoggedIn).to.equal(false),
));
}); });
}); });
return describe('given the token does authenticate with the server', function() { return describe('given the token does authenticate with the server', function() {
beforeEach(function() { beforeEach(function() {
this.balenaAuthIsLoggedInStub = sinon.stub(balena.auth, 'isLoggedIn'); this.balenaAuthIsLoggedInStub = sinon.stub(balena.auth, 'isLoggedIn');
return this.balenaAuthIsLoggedInStub.returns(Promise.resolve(true)); return this.balenaAuthIsLoggedInStub.returns(Promise.resolve(true));
@ -119,7 +121,7 @@ describe('Utils:', function() {
}); });
return it('should eventually be true', function() { return it('should eventually be true', function() {
let promise = utils.loginIfTokenValid(tokens.johndoe.token); const promise = utils.loginIfTokenValid(tokens.johndoe.token);
return chai.expect(promise).to.eventually.be.true; return chai.expect(promise).to.eventually.be.true;
}); });
}); });

View File

@ -1,88 +0,0 @@
const chai = require('chai');
const _ = require('lodash');
const path = require('path');
let { expect } = chai;
const { FileIgnorer, IgnoreFileType } = require('../../build/utils/ignore');
describe('File ignorer', function() {
it('should detect ignore files', function() {
let f = new FileIgnorer(`.${path.sep}`);
expect(f.getIgnoreFileType('.gitignore')).to.equal(IgnoreFileType.GitIgnore);
expect(f.getIgnoreFileType('.dockerignore')).to.equal(IgnoreFileType.DockerIgnore);
expect(f.getIgnoreFileType('./.gitignore')).to.equal(IgnoreFileType.GitIgnore);
expect(f.getIgnoreFileType('./.dockerignore')).to.equal(IgnoreFileType.DockerIgnore);
// gitignore files can appear in subdirectories, but dockerignore files cannot
expect(f.getIgnoreFileType('./subdir/.gitignore')).to.equal(IgnoreFileType.GitIgnore);
expect(f.getIgnoreFileType('./subdir/.dockerignore')).to.equal(null);
expect(f.getIgnoreFileType('./subdir/subdir2/.gitignore')).to.equal(IgnoreFileType.GitIgnore);
expect(f.getIgnoreFileType('file')).to.equal(null);
return expect(f.getIgnoreFileType('./file')).to.equal(null);
});
it('should filter files from the root directory', function() {
let ignore = new FileIgnorer(`.${path.sep}`);
ignore.gitIgnoreEntries = [
{ pattern: '*.ignore', filePath: '.gitignore' }
];
ignore.dockerIgnoreEntries = [
{ pattern: '*.ignore2', filePath: '.dockerignore' }
];
let files = [
'a',
'a/b',
'a/b/c',
'file.ignore',
'file2.ignore',
'file.ignore2',
'file2.ignore'
];
return expect(_.filter(files, ignore.filter.bind(ignore))).to.deep.equal([
'a',
'a/b',
'a/b/c'
]);
});
return it('should filter files from subdirectories', function() {
let ignore = new FileIgnorer(`.${path.sep}`);
ignore.gitIgnoreEntries = [
{ pattern: '*.ignore', filePath: 'lib/.gitignore' }
];
let files = [
'test.ignore',
'root.ignore',
'lib/normal-file',
'lib/should.ignore',
'lib/thistoo.ignore'
];
expect(_.filter(files, ignore.filter.bind(ignore))).to.deep.equal([
'test.ignore',
'root.ignore',
'lib/normal-file'
]);
ignore.gitIgnoreEntries = [
{ pattern: '*.ignore', filePath: './lib/.gitignore' }
];
files = [
'test.ignore',
'root.ignore',
'lib/normal-file',
'lib/should.ignore',
'lib/thistoo.ignore'
];
return expect(_.filter(files, ignore.filter.bind(ignore))).to.deep.equal([
'test.ignore',
'root.ignore',
'lib/normal-file'
]);
});
});

View File

@ -0,0 +1,98 @@
import { expect } from 'chai';
import * as _ from 'lodash';
import * as path from 'path';
import { FileIgnorer, IgnoreFileType } from '../../build/utils/ignore';
// Note that brack notation is used intentionally when accessing private members
// of the FileIgnorer class to prevent a Typescript compilation error (this
// behaviour is by design: see
// https://github.com/microsoft/TypeScript/issues/19335 )
describe('File ignorer', function() {
it('should detect ignore files', function() {
const f = new FileIgnorer(`.${path.sep}`);
expect(f.getIgnoreFileType('.gitignore')).to.equal(
IgnoreFileType.GitIgnore,
);
expect(f.getIgnoreFileType('.dockerignore')).to.equal(
IgnoreFileType.DockerIgnore,
);
expect(f.getIgnoreFileType('./.gitignore')).to.equal(
IgnoreFileType.GitIgnore,
);
expect(f.getIgnoreFileType('./.dockerignore')).to.equal(
IgnoreFileType.DockerIgnore,
);
// gitignore files can appear in subdirectories, but dockerignore files cannot
expect(f.getIgnoreFileType('./subdir/.gitignore')).to.equal(
IgnoreFileType.GitIgnore,
);
expect(f.getIgnoreFileType('./subdir/.dockerignore')).to.equal(null);
expect(f.getIgnoreFileType('./subdir/subdir2/.gitignore')).to.equal(
IgnoreFileType.GitIgnore,
);
expect(f.getIgnoreFileType('file')).to.equal(null);
return expect(f.getIgnoreFileType('./file')).to.equal(null);
});
it('should filter files from the root directory', function() {
const ignore = new FileIgnorer(`.${path.sep}`);
ignore['gitIgnoreEntries'] = [
{ pattern: '*.ignore', filePath: '.gitignore' },
];
ignore['dockerIgnoreEntries'] = [
{ pattern: '*.ignore2', filePath: '.dockerignore' },
];
const files = [
'a',
'a/b',
'a/b/c',
'file.ignore',
'file2.ignore',
'file.ignore2',
'file2.ignore',
];
return expect(_.filter(files, ignore.filter.bind(ignore))).to.deep.equal([
'a',
'a/b',
'a/b/c',
]);
});
return it('should filter files from subdirectories', function() {
const ignore = new FileIgnorer(`.${path.sep}`);
ignore['gitIgnoreEntries'] = [
{ pattern: '*.ignore', filePath: 'lib/.gitignore' },
];
let files = [
'test.ignore',
'root.ignore',
'lib/normal-file',
'lib/should.ignore',
'lib/thistoo.ignore',
];
expect(_.filter(files, ignore.filter.bind(ignore))).to.deep.equal([
'test.ignore',
'root.ignore',
'lib/normal-file',
]);
ignore['gitIgnoreEntries'] = [
{ pattern: '*.ignore', filePath: './lib/.gitignore' },
];
files = [
'test.ignore',
'root.ignore',
'lib/normal-file',
'lib/should.ignore',
'lib/thistoo.ignore',
];
return expect(_.filter(files, ignore.filter.bind(ignore))).to.deep.equal([
'test.ignore',
'root.ignore',
'lib/normal-file',
]);
});
});

View File

@ -1,5 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"declaration": true,
"module": "commonjs", "module": "commonjs",
"target": "es2017", "target": "es2017",
"outDir": "build", "outDir": "build",