From 62fc40cd4b61a2b6c14df6d91426d86857976e80 Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Fri, 31 Oct 2014 11:59:23 -0400 Subject: [PATCH] Implement Server module --- lib/config.coffee | 4 ++ lib/server/server.coffee | 35 +++++++++++ lib/server/server.spec.coffee | 113 ++++++++++++++++++++++++++++++++++ package.json | 7 ++- 4 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 lib/config.coffee create mode 100644 lib/server/server.coffee create mode 100644 lib/server/server.spec.coffee diff --git a/lib/config.coffee b/lib/config.coffee new file mode 100644 index 00000000..bfe35e8f --- /dev/null +++ b/lib/config.coffee @@ -0,0 +1,4 @@ +module.exports = + + # TODO: Should be configurable + baseUrl: 'https://alpha.resin.io' diff --git a/lib/server/server.coffee b/lib/server/server.coffee new file mode 100644 index 00000000..fda055e0 --- /dev/null +++ b/lib/server/server.coffee @@ -0,0 +1,35 @@ +request = require('request') +urljoin = require('url-join') +config = require('../config') + +exports.request = (method = 'GET', uri, json, callback) -> + method = method.toUpperCase() + uri = urljoin(config.baseUrl, uri) + + request { + uri + method + json + }, (error, response, body) -> + try + response.body = JSON.parse(response.body) + + return callback?.call(null, error, response, body) + +exports.get = (uri, callback) -> + return exports.request('GET', uri, null, callback) + +exports.head = (uri, callback) -> + return exports.request('HEAD', uri, null, callback) + +exports.delete = (uri, callback) -> + return exports.request('DELETE', uri, null, callback) + +exports.post = (uri, json, callback) -> + return exports.request('POST', uri, json, callback) + +exports.put = (uri, json, callback) -> + return exports.request('PUT', uri, json, callback) + +exports.patch = (uri, json, callback) -> + return exports.request('PATCH', uri, json, callback) diff --git a/lib/server/server.spec.coffee b/lib/server/server.spec.coffee new file mode 100644 index 00000000..4c71fe07 --- /dev/null +++ b/lib/server/server.spec.coffee @@ -0,0 +1,113 @@ +expect = require('chai').expect +nock = require('nock') +server = require('./server') +config = require('../config') + +TEST_URI = config.baseUrl + +URI = + ok: '/ok' + nojson: '/nojson' + +RESPONSE = + nojson: 'NO JSON RESPONSE' + +STATUS = + ok: 'ok' + +METHODS = [ + 'GET' + 'HEAD' + 'POST' + 'PUT' + 'DELETE' + 'PATCH' +] + +describe 'Server', -> + + beforeEach -> + nock(TEST_URI).get('/nojson').reply(200, RESPONSE.nojson) + + for method in METHODS + lowercaseMethod = method.toLowerCase() + nock(TEST_URI)[lowercaseMethod]('/ok').reply(200, status: STATUS.ok) + + describe '#request()', -> + + it 'should make a real HTTP request', (done) -> + server.request 'GET', URI.ok, null, (error, response) -> + return done(error) if error? + expect(response.body.status).to.equal(STATUS.ok) + expect(response.statusCode).to.equal(200) + done() + + it 'should make a GET request if method is omitted', (done) -> + server.request undefined, URI.ok, null, (error, response) -> + return done(error) if error? + expect(response.request.method).to.equal('GET') + done() + + checkRequestType = (type) -> + return (done) -> + server.request type, URI.ok, null, (error, response) -> + return done(error) if error? + expect(response.request.method).to.equal(type) + done() + + for method in METHODS + it("should make a #{method} request if method is #{method}", checkRequestType(method)) + + it 'should get a raw response of response is not JSON', (done) -> + server.request 'GET', URI.nojson, null, (error, response) -> + return done(error) if error? + expect(response.body).to.equal(RESPONSE.nojson) + done() + + it 'should be able to send data in the body', (done) -> + body = { hello: 'world' } + + server.request 'POST', URI.ok, body, (error, response) -> + return done(error) if error? + expect(response.request.body.toString()).to.equal(JSON.stringify(body)) + done() + + it 'should throw an error if method is unknown', (done) -> + server.request 'FOO', URI.ok, null, (error, response) -> + expect(error).to.exist + expect(error).to.be.an.instanceof(Error) + done() + + checkRequestTypeWithoutBody = (type) -> + return (done) -> + lowercaseType = type.toLowerCase() + server[lowercaseType] URI.ok, (error, response) -> + return done(error) if error? + expect(response.request.method).to.equal(type) + done() + + describe '#get()', -> + it('should be a facade to request()', checkRequestTypeWithoutBody('GET')) + + describe '#head()', -> + it('should be a facade to request()', checkRequestTypeWithoutBody('HEAD')) + + describe '#delete()', -> + it('should be a facade to request()', checkRequestTypeWithoutBody('DELETE')) + + checkRequestTypeWithBody = (type, body) -> + return (done) -> + lowercaseType = type.toLowerCase() + server[lowercaseType] URI.ok, body, (error, response) -> + return done(error) if error? + expect(response.request.method).to.equal(type) + done() + + describe '#post()', -> + it('should be a facade to request()', checkRequestTypeWithBody('POST', { hello: 'world' })) + + describe '#put()', -> + it('should be a facade to request()', checkRequestTypeWithBody('PUT', { hello: 'world' })) + + describe '#patch()', -> + it('should be a facade to request()', checkRequestTypeWithBody('PATCH', { hello: 'world' })) diff --git a/package.json b/package.json index 3fae2cba..5f3970d6 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,11 @@ "gulp": "~3.8.9", "coffee-script": "~1.8.0", "mocha-notifier-reporter": "~0.1.0", - "gulp-coffeelint": "~0.4.0" + "gulp-coffeelint": "~0.4.0", + "nock": "~0.48.2" + }, + "dependencies": { + "request": "~2.47.0", + "url-join": "0.0.1" } }