it ("should create links when values for key are falsy (ex: 0)", function (done) { var module = new CRUDCollection({ list : function(req, res, cb){ cb(null, [{"id": 0, value: "zero"}], {key : "id"}); } }); var req = { app : { autoLink : true }, uri : urlgrey('http://localhost:8080/'), headers: {} }; var res = { setHeader: function () {}, end: function (body) { body.toString().should.equal('{"_items":[{"id":0,"value":"zero","_links":{"self":{"href":"http://localhost:8080/0"}}}]}') console.log(body); done(); } }; hyperjson()(req, res, function () {}); module.handler.GET(req, res); });
it ("creates object by key", function (done) { var module = new CRUDCollection({ list : function(req, res, cb){ cb(null, [{"id": "0", value: "zero"}, {"id": "1", value: "one"}, {"id": "2", value: "two"}], {key : "id", listAsKeyedObject: true}); } }); var req = { app : { autoLink : true }, uri : urlgrey('http://localhost:8080/'), headers: {} }; var res = { setHeader: function () {}, end: function (body) { body.toString().should.equal('{"_items":{"0":{"id":"0","value":"zero","_links":{"self":{"href":"http://localhost:8080/0"}}},"1":{"id":"1","value":"one","_links":{"self":{"href":"http://localhost:8080/1"}}},"2":{"id":"2","value":"two","_links":{"self":{"href":"http://localhost:8080/2"}}}}}') console.log(body); done(); } }; hyperjson()(req, res, function () {}); module.handler.GET(req, res); });
it ("does not output an update link if there's no update()", function(done){ var module = new CRUDCollection({ list : function(req, res, cb){ cb([]); }, fetch : function(req, res, cb){ cb(null, {"some":"obj"}); }, updateSchema : { name : "somename" } }); var req = { uri : urlgrey('http://self.com/coll/1234'), fetched : {"some":"obj"} }; var res = { object : function(obj){ obj.should.eql({'some':'obj'}); return { send : function(thing){ done(); }, link : function(rel, href, opts){ console.log(arguments); should.fail("there should be no additional calls to link() because there's not update() method."); } }; } }; module.wildcard.GET(req, res); });
var sendToCodecovV2 = function(codecov_endpoint, query, body, on_success, on_failure){ // Direct to Codecov request.post( { url : urlgrey(codecov_endpoint + '/upload/v2').query(query).toString(), body : body, headers : { 'Content-Type': 'text/plain', 'Accept': 'text/plain' } }, function(err, response, body){ if (err || response.statusCode !== 200) { console.log(' ' + (err || response.body)); return on_failure(response.statusCode, response.body); } else { console.log(' Success!'); console.log(' View report at: ' + response.body); return on_success(response.body); } } ); };
it ("calls options.destroy() and its callback if specified", function(done){ var headWritten = false; var module = new CRUDCollection({ list : function(req, res, cb){ cb([]); }, destroy : function(req, res, id, cb){ id.should.equal('1234'); return cb(); } }); var res = { writeHead : function(code){ headWritten = true; code.should.equal(204); }, end : function(){ headWritten.should.equal(true); done(); } }; var req = { uri : urlgrey('http://self.com/coll/1234'), onBody : function(cb){ cb(null, '{"age":37}'); } }; module.wildcard.DELETE(req, res); });
it ("creates self links in all items based on a given key", function(done){ var module = new CRUDCollection({ list : function(req, res, cb){ cb(null, { sometest : {"here" : "goes"}}, {key : 'here'}); } }); var req = { app : { autoLink : true }, uri : urlgrey('http://localhost:8080/') }; var res = { collection : function(items){ items.should.eql({ sometest: { here: 'goes' } }); return { linkEach : function(rel, strategy){ rel.should.equal('self'); strategy({here : 'goes'}, 'somename').toString() .should.equal('http://localhost:8080/goes'); return { send : function(){ done(); } }; } }; } }; module.handler.GET(req, res); });
function(done){ var module = new CRUDCollection({ list : function(req, res, cb){ cb(null, [{"an" : "item"}]); }, create : function(req, res, obj){ }, schema : { troof : true} }); var req = { app : { autoLink : true }, uri : urlgrey('http://self.com/coll?asdf=asdf') }; var res = { collection : function(){ return { linkEach : function(rel, cb){ return { link : function(rel, href, opts){ rel.should.equal('create'); href.toString().should.equal('http://self.com/coll'); opts.should.eql({method : 'POST', schema : { troof : true}}); return { send : function(){ done(); } }; } }; } }; } }; module.handler.GET(req, res); });
it ("calls options.create() and its callback if specified", function(done){ var module = new CRUDCollection({ list : function(req, res, cb){ cb([]); }, create : function(req, res, obj, cb){ obj.should.eql({age:37}); return cb(); } }); var req = { uri : urlgrey('http://self/1234'), onJson : function(schema, cb){ //TODO: verify schema cb(null, {"age":37}); } }; var res = { status : { created : function(url){ url.toString().should.equal('http://self/1234'); done(); } } }; module.handler.POST(req, res); });
var addDefaultLinks = function(req, res, json, options) { var current, parent; if (json instanceof HyperJson) { current = json.toObject(); } else { current = json; } if (!current._links || !current._links.parent) { try { var host = 'localhost'; if (!!req.headers.host){ host = req.headers.host; } var base = options.protocol + '://' + (req.headers.host || 'localhost'); parent = urlgrey(base) .hostname(req.headers.host || 'localhost') .path(req.url) .parent() .toString(); json.link("parent", parent); } catch (ex) { if (ex.message !== "The current path has no parent path") { throw ex; } } } return current; };
it ("outputs a representation of a resource when fetch is defined", function(done){ var module = new CRUDCollection({ list : function(req, res, cb){ cb([]); }, fetch : function(req, res, cb){ cb(null, {"some":"obj"}); } }); var req = { uri : urlgrey('http://self.com/coll/1234'), fetched : {"some":"obj"} }; var res = { object : function(obj){ obj.should.eql({'some':'obj'}); return { send : function(thing){ done(); } }; } }; module.wildcard.GET(req, res); });
it ("outputs without an update link if update() is not defined", function(done){ var module = new CRUDCollection({ list : function(req, res, cb){ cb([]); }, fetch : function(req, res, cb){ cb(null, {"some":"obj"}); }, updateSchema : { name : "somename" } }); var req = { uri : urlgrey('http://self/1234'), fetched : {"some":"obj"} }; var res = { object : function(obj){ obj.should.eql({'some':'obj'}); return { send : function(thing){ done(); }, link : function(rel, href, opts){ should.fail("no link should be added!"); } }; } }; module.wildcard.GET(req, res); });
it ("calls options.destroy()", function(done){ var module = new CRUDCollection({ list : function(req, res, cb){ cb([]); }, destroy : function(req, res, id, cb){ id.should.equal('1234'); done(); } }); var req = { uri : urlgrey('http://self.com/coll/1234') }; var res = {}; module.wildcard.DELETE(req, res); });
it ("calls options.update()", function(done){ var module = new CRUDCollection({ list : function(req, res, cb){ cb([]); }, update : function(req, res, id, obj){ id.should.equal('1234'); obj.should.eql({age:37}); done(); } }); var req = { uri : urlgrey('http://self.com/coll/1234'), onJson : function(schema, cb){ // TODO: verify schema cb(null, {"age":37}); } }; var res = {}; module.wildcard.fetchOnPUT.should.equal(true); module.wildcard.PUT(req, res); });
var sendToCodecov = function(str, cb){ var withTestTokenUrl = 'https://codecov.io/upload/v1?token=473c8c5b-10ee-4d83-86c6-bfd72a185a27&commit=743b04806ea677403aa2ff26c6bdeb85005de658&branch=master'; var configuration = getConfiguration(); console.log("configuration: ", configuration); var query = { commit : configuration.commitId, travis_job_id : configuration.buildId, build : configuration.build, branch : configuration.branch }; if (!!configuration.pullRequest){ query.pull_request = configuration.pullRequest; } var url = urlgrey('https://codecov.io/upload/v1').query(query).toString(); var headers = { 'content-type' : 'text/lcov' }; var body = str; var options = { url : url, headers : headers, body : body }; request.post(options, function(err, response, body){ if (err){ return cb(err); } if (response.statusCode !== 200){ var error = new Error("non-success response"); error.detail = { statusCode : response.statusCode, body : body, headers : response.headers }; return cb(error); } return cb(); }); };
var sendToCodecovV3 = function(codecov_endpoint, query, body, on_success, on_failure){ // Direct to S3 request.post( { url : urlgrey(codecov_endpoint + '/upload/v3').query(query).toString(), body : '', headers : { 'Content-Type': 'text/plain', 'Accept': 'text/plain' } }, function(err, response, result){ if (err) { sendToCodecovV2(codecov_endpoint, query, body, on_success, on_failure); } else { var codecov_report_url = result.split('\n')[0]; request.put( { url : result.split('\n')[1], body : body, headers : { 'Content-Type': 'plain/text', 'x-amz-acl': 'public-read' } }, function(err, response, result){ if (err) { sendToCodecovV2(codecov_endpoint, query, body, on_success, on_failure); } else { console.log(' Success!'); console.log(' View report at: ' + codecov_report_url); on_success(codecov_report_url); } } ); } } ); };
it ("outputs with an update link if update() is defined", function(done){ var createdUpdateLink = false; var module = new CRUDCollection({ list : function(req, res, cb){ cb([]); }, fetch : function(req, res, cb){ cb(null, {"some":"obj"}); }, update : function(){}, updateSchema : { name : "somename" } }); var req = { app : { autoLink : true }, fetched : {"some":"obj"}, uri : urlgrey('http://self/1234') }; var res = { object : function(obj){ obj.should.eql({'some':'obj'}); return { send : function(thing){ createdUpdateLink.should.equal(true); done(); }, link : function(rel, href, opts){ createdUpdateLink = true; rel.should.equal("update"); href.toString().should.equal("http://self/1234"); opts.should.eql({method : 'PUT', schema : { name : "somename"}}); } }; } }; module.wildcard.GET(req, res); });
it ("calls options.upsert() with its callback if it exists", function(done){ var headerSet = false; var headWritten = false; var schema = { "name" : "name" }; var module = new CRUDCollection({ schema : schema, list : function(req, res, cb){ cb([]); }, upsert : function(req, res, id, obj, cb){ obj.should.eql({age:37}); cb(); } }); var req = { uri : urlgrey('http://self.com/coll/1234'), onJson : function(schema, cb){ schema.should.eql(schema); cb(null, {"age":37}); } }; var res = { setHeader : function(name, value){ headerSet = true; name.should.equal('Location'); value.toString().should.equal('http://self.com/coll/1234'); }, writeHead : function(code){ headWritten = true; code.should.equal(303); }, end : function(){ headerSet.should.equal(true); headWritten.should.equal(true); done(); } }; module.wildcard.PUT(req, res); });
it ("calls options.upsert() if it exists", function(done){ var schema = { "name" : "name" }; var module = new CRUDCollection({ schema : schema, list : function(req, res, cb){ cb([]); }, upsert : function(req, res, id, obj){ obj.should.eql({age:37}); done(); } }); var req = { uri : urlgrey('http://self.com/coll/1234'), onJson : function(schema, cb){ schema.should.eql(schema); cb(null, {"age":37}); } }; var res = {}; module.wildcard.fetchOnPUT.should.equal(false); module.wildcard.PUT(req, res); });
var Verity = function(uri, _method){ if (!(this instanceof Verity)) { return new Verity(uri, _method); } this.uri = urlgrey(uri || 'http://localhost:80'); this._method = _method || 'GET'; this._body = ''; this.cookieJar = request.jar(); this.client = request.defaults({ timeout:3000, jar: this.cookieJar }); this.headers = {}; this.cookies = {}; this.shouldLog = true; this.expectedBody = null; this.jsonModeOn = false; this._expectedHeaders = {}; this._expectedCookies = {}; this._expectations = {}; this._unnamedExpectationCount = 0; };
it ("calls options.update() and its callback if specified", function(done){ var headerSet = false; var headWritten = false; var module = new CRUDCollection({ list : function(req, res, cb){ cb([]); }, update : function(req, res, id, obj, cb){ id.should.equal('1234'); obj.should.eql({age:37}); return cb(); } }); var req = { uri : urlgrey('http://self.com/coll/1234'), onJson : function(schema, cb){ //TODO verify schema cb(null, {"age":37}); } }; var res = { setHeader : function(name, value){ headerSet = true; name.should.equal('Location'); value.toString().should.equal('http://self.com/coll/1234'); }, writeHead : function(code){ headWritten = true; code.should.equal(303); }, end : function(){ headerSet.should.equal(true); headWritten.should.equal(true); done(); } }; module.wildcard.PUT(req, res); });
var ContextFake = function(method, url, headers, body, expectations){ var fake = this; var parsedUrl = nodeUrl.parse(url); var protocol = 'http'; if (parsedUrl.protocol){ this.protocol = parsedUrl.protocol.slice(0, -1); // remove trailing ':' } var hostname = parsedUrl.hostname || 'localhost'; var port = parsedUrl.port || 80; this.router = { }; this.done = function(){}; var endHandler = function(){}; var dataHandler = function(){}; this.req = { app : {}, headers : headers, method : method, url : url, uri : urlgrey(url), resume : function(){}, on : function(eventName, cb){ if (eventName === 'data'){ dataHandler = cb; } if (eventName === 'end'){ endHandler = cb; } }, write : function(data){ dataHandler(data); }, end : function(data){ endHandler(data); } }; this.actual = {}; this.actual.body = ''; this.actual.headers = {}; this.res = { writeHead : function(statusCode, reasonPhrase, headers){ fake.res.statusCode = statusCode; fake.actual.statusCode = statusCode; fake.actual.headers = _.extend(fake.actual.headers, headers); }, setHeader : function(name, value){ fake.actual.headers[name] = value; }, statusCode : 200, write : function(data, encoding){ fake.actual.body += data; }, end : function(data, encoding){ fake.actual.statusCode = fake.res.statusCode; if (data){ fake.actual.body += data; } fake.validate(); if (fake.done){ fake.done(fake.actual); } } }; var that = this; HyperjsonConnect({'protocol' : this.protocol})(this.req, this.res, function(){ that.res.status = (new StatusManager()).createResponder(that.req, that.res); that.res.status.on('error', function(data){ /* do nothing */}); that.res.status.emit = function(){}; // swallow events //TODO can validate() be hidden? it's only called from res.end() right? // does it ever need to be called explicitly? that.validate = function(){ if (expectations.statusCode){ assert.equal(that.res.statusCode, expectations.statusCode, "response statusCode should have been " + expectations.statusCode + " but was " + that.res.statusCode ); } if (expectations.body){ assert.equal(that.actual.body, expectations.body, "response body should have been: \n " + expectations.body + "\n\n ...but was: \n" + that.actual.body + "\n\n" ); } }; }); };