Lab.experiment('html with default options', function () { Lab.before(function (done) { var options = { main: __dirname + '/../fixtures/app/app.js', jsFileName: 'app', cssFileName: 'app', stylesheets: [ __dirname + '/../fixtures/stylesheets/style.css' ] }; moonboots = new Moonboots(options); moonboots.on('ready', done); }); Lab.test('htmlContext', function (done) { var context = moonboots.htmlContext(); Lab.expect(context).to.have.keys('jsFileName', 'cssFileName'); Lab.expect(context.jsFileName).to.equal(EXPECTED_JS_MIN_HASH); Lab.expect(context.cssFileName).to.equal(EXPECTED_CSS_MIN_HASH); done(); }); Lab.test('htmlSource', function (done) { var source = moonboots.htmlSource(); Lab.expect(source).to.equal('<!DOCTYPE html>\n<link href=\"/' + EXPECTED_CSS_MIN_HASH + '\" rel=\"stylesheet\" type=\"text/css\">\n<script src=\"/' + EXPECTED_JS_MIN_HASH + '\"></script>'); done(); }); });
Lab.experiment('Errors', function () { Lab.test('No files', function (done) { lessitizer({ outputDir: buildDir() }, function (err) { Lab.expect(err instanceof Error).to.equal(true); done(); }); }); Lab.test('Null files', function (done) { lessitizer({ outputDir: buildDir(), files: null }, function (err) { Lab.expect(err instanceof Error).to.equal(true); done(); }); }); Lab.test('No callback throws', function (done) { function noOutputDir() { lessitizer({ files: ['app-combined'].map(filePath) }); } Lab.expect(noOutputDir).to.throw(Error); done(); }); });
Lab.experiment('Init', function () { Lab.test('Builds an array', function (done) { lessitizer({ files: ['app-combined'].map(filePath), outputDir: buildDir() }, function (err, files) { Lab.expect(err).to.equal(null); Lab.expect(Array.isArray(files)).to.equal(true); Lab.expect(files.length).to.equal(1); Lab.expect(typeof files[0]).to.equal('string'); Lab.expect(files[0].length > 1).to.equal(true); done(); }); }); Lab.test('Builds a file string', function (done) { lessitizer({ files: filePath('app-combined'), outputDir: buildDir() }, function (err, files) { Lab.expect(err).to.equal(null); Lab.expect(Array.isArray(files)).to.equal(true); Lab.expect(files.length).to.equal(1); Lab.expect(typeof files[0]).to.equal('string'); Lab.expect(files[0].length > 1).to.equal(true); done(); }); }); });
Lab.experiment('Dont write to file', function () { Lab.test('No outputDir', function (done) { lessitizer({ files: ['app-combined'].map(filePath) }, function (err, css) { Lab.expect(err).to.equal(null); Lab.expect(Array.isArray(css)).to.equal(true); Lab.expect(css.length).to.equal(1); Lab.expect(typeof css[0]).to.equal('string'); Lab.expect(css[0].indexOf('body {')).to.equal(0); done(); }); }); Lab.test('multiple files', function (done) { lessitizer({ files: ['app-combined', 'app-combined2'].map(filePath) }, function (err, css) { Lab.expect(err).to.equal(null); Lab.expect(Array.isArray(css)).to.equal(true); Lab.expect(css.length).to.equal(2); Lab.expect(typeof css[0]).to.equal('string'); Lab.expect(typeof css[1]).to.equal('string'); Lab.expect(css[0] === css[1]).to.equal(true); done(); }); }); });
Lab.experiment('CSS errors', function () { Lab.test('Dev mode', function (done) { var _buildDir = buildDir(); lessitizer({ files: ['app-err'].map(filePath), outputDir: _buildDir, developmentMode: true }, function (err, files) { Lab.expect(Array.isArray(files)).to.equal(true); Lab.expect(files.length).to.equal(1); Lab.expect(typeof files[0]).to.equal('string'); Lab.expect(files[0].length > 1).to.equal(true); var writtenFile = fs.readFileSync(_buildDir + '/app-err.css', 'utf8'); Lab.expect(writtenFile.indexOf('body:before { content:')).to.not.equal(-1); done(); }); }); Lab.test('Prod mode', function (done) { var _buildDir = buildDir(); lessitizer({ files: ['app-err'].map(filePath), outputDir: _buildDir }, function (err, files) { Lab.expect(err instanceof Error).to.equal(true); Lab.expect(err.message.indexOf('ParseError')).to.equal(0); Lab.expect(files[0]).to.equal(undefined); done(); }); }); });
Lab.experiment('Output dir errors', function () { Lab.test('Bad output dir', function (done) { lessitizer({ files: ['app-combined'].map(filePath), outputDir: '/this/does/not/exist/', developmentMode: true }, function (err, files) { Lab.expect(err instanceof Error).to.equal(true); Lab.expect(err.message.indexOf('ENOENT')).to.equal(0); Lab.expect(files[0]).to.equal(undefined); done(); }); }); Lab.test('Good output dir', function (done) { lessitizer({ files: ['app-err'].map(filePath), outputDir: buildDir(), developmentMode: true }, function (err, files) { Lab.expect(err).to.equal(null); Lab.expect(Array.isArray(files)).to.equal(true); Lab.expect(files.length).to.equal(1); Lab.expect(typeof files[0]).to.equal('string'); Lab.expect(files[0].length > 1).to.equal(true); done(); }); }); });
Lab.experiment('GET /room/messages', function() { Lab.test('should set correct headers', function(done) { var options = { method: 'GET', url: '/room/messages' }; app.room.channel.end(); // End the messages stream app.server.inject(options, function(response) { Lab.expect(response.headers.connection).to.equal('keep-alive'); Lab.expect(response.headers['cache-control']).to.equal('no-cache'); done(); }); }); Lab.test('should propagate messages from the main channel', function(done) { var options = { method: 'GET', url: '/room/messages' }; app.room.channel.write('Hey, QChatters'); app.room.channel.end(); // End the messages stream app.server.inject(options, function(response) { Lab.expect(response.payload).to.equal('Hey, QChatters'); done(); }); }); });
Lab.experiment('Files get written to build directory', function () { var tmpHash = crypto.randomBytes(16).toString('hex'); var buildDir = path.join(os.tmpdir(), tmpHash); Lab.before(function (done) { fs.mkdir(buildDir, function () { var options = { main: __dirname + '/../fixtures/app/app.js', jsFileName: 'app', cssFileName: 'app', buildDirectory: buildDir, stylesheets: [ __dirname + '/../fixtures/stylesheets/style.css' ], libraries: [ __dirname + '/../fixtures/libraries/iife-no-semicolon.js', __dirname + '/../fixtures/libraries/lib.js' ] }; moonboots = new Moonboots(options); moonboots.on('ready', done); }); }); Lab.after(function (done) { async.series([ function (next) { fs.unlink(path.join(buildDir, 'app.3adb4850.min.js'), next); }, function (next) { fs.unlink(path.join(buildDir, 'app.38ea6c96.min.css'), next); }, function (next) { fs.rmdir(buildDir, next); } ], function (err) { if (err) {throw err; } done(); }); }); Lab.test('js file was written', function (done) { var jsFileName = moonboots.jsFileName(); var filePath = path.join(buildDir, jsFileName); Lab.expect(jsFileName).to.equal('app.3adb4850.min.js'); fs.readFile(filePath, 'utf8', function (err) { Lab.expect(err).to.not.be.ok; // Test that iife-no-semicolon.js doesn't introduce a parsing bug // via a (function () {…})\n(function () {…}) sequence Lab.expect(function () { require(filePath); }).to.not.throw(); done(); }); }); Lab.test('css file was written', function (done) { var cssFileName = moonboots.cssFileName(); Lab.expect(cssFileName).to.equal('app.38ea6c96.min.css'); fs.readFile(path.join(buildDir, cssFileName), 'utf8', function (err) { Lab.expect(err).to.not.be.ok; done(); }); }); });
Lab.experiment("Item", function () { Lab.test("does something", function (done) { var item = new Item(); Lab.expect(item.doSomething("bob")).to.equal("bob"); done(); }); Lab.test("has a name", function (done) { var item = new Item(); Lab.expect(item.name).to.exist; done(); }); });
Lab.experiment('CLI', function () { Lab.test('Exits with 0', function (done) { var r = sh.run('node index.js sample/config.js --quiet'); Lab.expect(r).to.equal(0); done(); }); Lab.test('Exits with non 0', function (done) { var r = sh.run('node index.js sample/cong.js 2>/dev/null'); Lab.expect(r).to.not.equal(0); done(); }); });
Lab.experiment('transforms with transform option', function () { var transformRan = 0; Lab.before(function (done) { var options = { main: __dirname + '/../fixtures/app/app.js', jsFileName: 'app', browserify: { transform: [ function () { var through = require('through'); transformRan++; return through( function write() {}, function _end() { this.queue(null); } ); } ] } }; moonboots = new Moonboots(options); moonboots.on('ready', done); }); Lab.test('ran', function (done) { Lab.expect(transformRan).to.equal(1); done(); }); });
Lab.experiment("Orders:", function () { Lab.test("post endpoint recieves Order", function (done) { var assertions = { logStatus: "success" }; var options = { method: "POST", url: "/api/orders", credentials: creds, payload: { farmer: "test 1", farmerInitials: "t1", notes: "Nothing to report", price: [0.5, 1], quantity: [2, 1], unit: ["oz", "oz"], transportation: "true", productName: ["oregano", "tomillo"], } }; server.inject(options, function (response) { //console.error(response); var result = response.result; Lab.expect(response.statusCode).to.equal(200); Lab.expect(result).to.be.instanceof(Object); Lab.expect(result.logStatus).to.equal(assertions.logStatus); done(); }); }); });
Lab.experiment('Hash is the same', function () { function setup(done) { var options = { main: __dirname + '/../fixtures/app/appImports.js', jsFileName: 'app', minify: false }; var moonboots = new Moonboots(options); moonboots.on('ready', function () { done(moonboots); }); } Lab.test('50 times', function (done) { async.timesSeries(50, function (index, next) { setup(function (moonboots) { var filename = moonboots.jsFileName(); moonboots.jsSource(function (err, js) { next(null, [filename, js]); }); }); }, function (err, results) { var filenames = results.map(function (r) { return r[0]; }); var js = results.map(function (r) { return r[1]; }); Lab.expect(arrEqual(filenames)).to.equal(true); Lab.expect(arrEqual(js)).to.equal(true); done(); }); }); });
Lab.experiment('UserVoice', function () { var mockUserVoice, preamble; Lab.beforeEach(function (done) { mockUserVoice = []; preamble = require('../services/libs/uservoice-preamble'); sinon.stub(preamble, 'init').returns(mockUserVoice); done(); }); Lab.afterEach(function (done) { preamble.init.restore(); done(); }); Lab.test('It should identify users', function (done) { require('../services/uservoice').configure({ key: '1234' }); tracking.identify('123', { name: 'Phil Roberts', email: '*****@*****.**', other: 'junk' }); Lab.expect(mockUserVoice[0]).to.deep.equal(['identify', { id: '123', name: 'Phil Roberts', email: '*****@*****.**' }]); done(); }); });
Lab.experiment('CLI', function () { Lab.test('Exits with 0', function (done) { var test = spawn('node', ['index.js', 'sample/config.js', '--quiet']); test.on('close', function (code) { Lab.expect(code).to.equal(0); done(); }); }); Lab.test('Exits with non 0', function (done) { var test = spawn('node', ['index.js', 'sample/cong.js', '2>/dev/null']); test.on('close', function (code) { Lab.expect(code).to.not.equal(0); done(); }); }); });
Lab.experiment('labels parameter', function () { Lab.before(function (done) { async.parallel({ pack: function (next) { pack = new Hapi.Pack(); //TODO clean up once https://github.com/spumko/hapi/pull/1425 is merged server3001 = pack.server(3001, {labels: ['foo']}); server3002 = pack.server(3002, {labels: ['bar']}); //server3001 = new Hapi.Server('localhost', 3001, {labels: ['foo']}); //server3002 = new Hapi.Server('localhost', 3002, {labels: ['bar']}); //pack._server(server3001); //pack._server(server3002); pack.require({'..': options }, next); }, getSource: function (next) { appSource = moonboots.htmlSource(); next(); } }, function (err) { if (err) { process.stderr.write('Unable to setUp tests', err, '\n'); process.exit(1); } done(); }); }); Lab.test('server with matching label', function (done) { server3001.inject({ method: 'GET', url: '/app' }, function _getApp(res) { Lab.expect(res.statusCode, 'response code').to.equal(200); Lab.expect(res.payload, 'response body').to.equal(appSource, 'application source'); done(); }); }); Lab.test('server without matching label', function (done) { server3002.inject({ method: 'GET', url: '/app' }, function _getApp(res) { Lab.expect(res.statusCode, 'response code').to.equal(404); done(); }); }); });
Lab.experiment("Path", function() { var options = {}, server, delay = 0 Lab.before(function (done) { server = new Server.getServer() options.headers = headers // Wait 1 second setTimeout(function () { done() }, 1000) }) Lab.beforeEach(function (done) { options = {} options.headers = headers done() }) // Lab.test("Authentication Error", function (done) { // options = fixtures.load('path/methodForbidden') // server.inject(options, function(response) { // Lab.expect(response.statusCode).to.equal(401) // setTimeout(done, delay) // }) // }) Lab.test("notFound error", function (done) { options = fixtures.load('path/notFound', options) server.inject(options, function(response) { Lab.expect(response.statusCode).to.equal(404) setTimeout(done, delay) }) }) // Lab.test("methodForbidden error", function (done) { // options = fixtures.load('path/methodForbidden', options) // server.inject(options, function(response) { // console.log(response) // Lab.expect(response.statusCode).to.equal(400) // setTimeout(done, delay) // }) // }) })
Lab.experiment('create tests', function () { Lab.test('try to create without express app', function (done) { try { restfs(); } catch (err) { if (err) { return done(); } return (err); } }); Lab.test('test invalid setModifyOut', function (done) { try { server.setModifyOut("fake"); } catch (err) { done(); } }); });
Lab.experiment('GET /{view_name}', function() { Lab.test("retrieves index", function(done) { var options = { method: "GET", url: "/" }; server.inject(options, function(response) { var result = response.result; Lab.expect(response.statusCode).to.equal(200); assert(/html>/.test(result)); assert(/html/.test(response.headers["content-type"])); done(); }); }); Lab.test("retrieves about view", function(done) { var options = { method: "GET", url: "/about" }; server.inject(options, function(response) { Lab.expect(response.statusCode).to.equal(200); assert(/html/.test(response.headers["content-type"])); done(); }); }); Lab.test("Not found error when view does not exist.", function(done) { var options = { method: "GET", url: "/non_view_name" }; server.inject(options, function(response) { var result = response.result; assert.equal(response.statusCode, 404); assert.equal(result.error, 'Not Found'); done(); }); }); });
Lab.experiment('basic delete tests', function () { Lab.beforeEach(function (done) { cleanBase(done); }); Lab.test('delete file', function (done) { var filepath = baseFolder+'/test_file.txt'; createFile(filepath, function(err) { if (err) { return done(err); } rmFile(filepath, done); }); }); Lab.test('delete file that does not exist', function (done) { rmFile(baseFolder+'/fake.txt', function(err){ if(err) { if(err.code === 'ENOENT') { return done(); } return done(err); } return done(new Error('file should not exist')); }); }); Lab.test('try to delete folder', function (done) { rmFile(baseFolder, function(err){ if(err) { if(err.code === 'EPERM' || err.code === 'EISDIR') { return done(); } return done(err); } return done(new Error('folder should not be removed')); }); }); });
Lab.experiment('Root page', function() { Lab.test('should render successfully', function(done) { var options = { method: 'GET', url: '/' }; app.server.inject(options, function(response) { Lab.expect(response.statusCode).to.equal(200); done(); }); }); });
Lab.experiment('Development mode', function () { Lab.test('Development mode sets cache to 0', function (done) { var moonboots = new Moonboots({ moonboots: { main: __dirname + '../sample/app/app.js', developmentMode: true }, server: express() }); Lab.expect(moonboots.options.cachePeriod).to.equal(0); done(); }); });
Lab.experiment('js with .js already added', function () { Lab.before(function (done) { var options = { main: __dirname + '/../fixtures/app/app.js', jsFileName: 'app.js' }; moonboots = new Moonboots(options); moonboots.on('ready', done); }); Lab.test('filename', function (done) { Lab.expect(moonboots.jsFileName(), 'js filename').to.equal(EXPECTED_JS_MIN_HASH); done(); }); });
Lab.experiment("Authentication Required to View Photo", function() { // tests Lab.test("Deny view of photo if unauthenticated /photo/{id*} ", function(done) { var options = { method: "GET", url: "/photo/8795" }; // server.inject lets you similate an http request server.inject(options, function(response) { Lab.expect(response.statusCode).to.equal(401); // Expect http response status code to be 200 ("Ok") Lab.expect(response.result.message).to.equal("Please log-in to see that"); // (Don't hard-code error messages) done(); }); }); });
Lab.experiment('GET /room/users', function() { Lab.test('should return all users connected to the room', function(done) { var options = { method: 'GET', url: '/room/users' }; app.room.users = ['Hipster', 'Fellow']; app.server.inject(options, function(response) { Lab.expect(response.result.users.length).to.equal(2); Lab.expect(response.result.users[0]).to.equal('Hipster'); Lab.expect(response.result.users[1]).to.equal('Fellow'); done(); }); }); });
Lab.experiment('image builder without versions', function () { Lab.before(function (done) { // set up ImageBuilder this.ib = new ImageBuilder({ dockerHost: 'http://localhost', dockerPort: 4243, context: context, aws: { accessKeyId: 'AN-AWS-ACCESS-KEY', secretAccessKey: 'AN-AWS-SECRET-ACCESS-KEY' } }); // mocks for amazon requests // nock.recorder.rec(); nock('https://bucket.s3.amazonaws.com:443') .get('/path/to/some/source/Dockerfile?response-content-type=application%2Fjson') .reply(200, "FROM runnable/node\n\nWORKDIR /root\nRUN git clone https://github.com/heroku/node-js-sample\n\nWORKDIR /root/node-js-sample\nRUN npm install\nENTRYPOINT [\"node\"]\nCMD [\"web.js\"]"); nock('https://bucket.s3.amazonaws.com:443') .get('/?prefix=path%2Fto%2Fsome%2Fsource%2F') .reply(200, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>bucket</Name><Prefix>path/to/some/source/</Prefix><Marker></Marker><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated><Contents></Contents></ListBucketResult>"); nock('https://bucket.s3.amazonaws.com:443') .get('/source/1/?response-content-type=application%2Fjson') .reply(200, ""); // mocks for docker requests nock('http://localhost:4243') .filteringRequestBody(function (path) { return '*'; }) .post('/build?t=owner%2Fweb-server', '*') .reply(200, '{"stream": "Successfully built 0123456789001"}'); done(); }); Lab.after(function (done) { delete this.ib; done(); }); Lab.test('returns docker image ids built from latest', function (done) { this.ib.run(function (err, results) { if (err) { done(err); } else { Lab.expect(Object.keys(results)).to.have.length(1); Lab.expect(results['owner/web-server']).to.equal('0123456789001'); done(); } }); }); });
Lab.experiment('modulesDir', function () { Lab.before(function (done) { var options = { main: __dirname + '/../fixtures/app/app.js', jsFileName: 'app', modulesDir: __dirname + '/../fixtures/modules' }; moonboots = new Moonboots(options); moonboots.on('ready', done); }); Lab.test('module foo is in source', function (done) { moonboots.jsSource(function (err, js) { Lab.expect(js, 'js source').to.contain('"foo"'); done(); }); }); });
Lab.experiment('image builder with versions', function () { Lab.before(function (done) { // set up ImageBuilder this.ib = new ImageBuilder({ dockerHost: 'http://localhost', dockerPort: 4243, context: context, aws: { accessKeyId: 'AN-AWS-ACCESS-KEY', secretAccessKey: 'AN-AWS-SECRET-ACCESS-KEY' } }); // mocks for amazon requests nock('https://bucket.s3.amazonaws.com:443') .get('/path/to/some/source/Dockerfile?versionId=1234&response-content-type=application%2Fjson') .reply(200, "FROM runnable/node\n\nWORKDIR /root\nRUN git clone https://github.com/heroku/node-js-sample\n\nWORKDIR /root/node-js-sample\nRUN npm install\nENTRYPOINT [\"node\"]\nCMD [\"web.js\"]"); nock('https://bucket.s3.amazonaws.com:443') .get('/path/to/some/source/?versionId=5678&response-content-type=application%2Fjson') .reply(200, ""); // mocks for docker requests nock('http://localhost:4243') .filteringRequestBody(function (path) { return '*'; }) .post('/build?t=owner%2Fweb-server', '*') .reply(200, '{"stream": "Successfully built 0123456789001"}'); done(); }); Lab.after(function (done) { delete this.ib; done(); }); Lab.test('returns docker image ids built from latest', function (done) { this.ib.run(function (err, results) { if (err) { done(err); } else { Lab.expect(Object.keys(results)).to.have.length(1); Lab.expect(results['owner/web-server']).to.equal('0123456789001'); done(); } }); }); });
Lab.experiment('Warns for overwriting props', function () { Lab.test('less.outputDir and filename', function (done) { lessitizer({ files: ['app-combined'].map(filePath), outputDir: buildDir(), less: { outputDir: 'here', filename: 'thisfilename' } }, function (err, files) { Lab.expect(err).to.equal(null); Lab.expect(Array.isArray(files)).to.equal(true); Lab.expect(files.length).to.equal(1); Lab.expect(typeof files[0]).to.equal('string'); Lab.expect(files[0].length > 1).to.equal(true); done(); }); }); });
Lab.experiment('sync beforeBuildJS', function () { var beforeRan = false; Lab.before(function (done) { var options = { main: __dirname + '/../fixtures/app/app.js', jsFileName: 'app', minify: false, beforeBuildJS: function () { beforeRan = true; } }; moonboots = new Moonboots(options); moonboots.on('ready', done); }); Lab.test('ran', function (done) { Lab.expect(beforeRan).to.equal(true); done(); }); });