Skip to content

Commit

Permalink
wip: v2
Browse files Browse the repository at this point in the history
  • Loading branch information
joostdebruijn committed Dec 29, 2023
1 parent 40e8394 commit 573ddd8
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 117 deletions.
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
# node-postcode-nl

[![npm version](https://badge.fury.io/js/postcode-nl.svg)](https://badge.fury.io/js/postcode-nl) [![Build Status](https://travis-ci.org/joostdebruijn/node-postcode-nl.svg?branch=master)](https://travis-ci.org/joostdebruijn/node-postcode-nl) [![Coverage Status](https://coveralls.io/repos/github/joostdebruijn/node-postcode-nl/badge.svg?branch=master)](https://coveralls.io/github/joostdebruijn/node-postcode-nl?branch=master) [![dependencies Status](https://david-dm.org/joostdebruijn/node-postcode-nl/status.svg)](https://david-dm.org/joostdebruijn/node-postcode-nl) [![Known Vulnerabilities](https://snyk.io/test/github/joostdebruijn/node-postcode-nl/badge.svg)](https://snyk.io/test/github/joostdebruijn/node-postcode-nl)

Node module to obtain Dutch postcodes via [postcodeapi.nu](https://www.postcodeapi.nu). The module is able to perform requests to the v2 API, does some basic validation before the call is performed, handles errors from the API and returns the results as a json for further processing within your own application. To use this module, requesting an API-key at postcodeapi.nu is required.

## Using the module
Expand Down
70 changes: 28 additions & 42 deletions lib/requestApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,54 +21,40 @@ const helpers = require('./helpers.js')
* @returns {Function} callback
*/
async function get (options, callback) {
// Preparing options for request
const requestOptions = {
url: options.url,
headers: options.headers,
json: true,
qs: options.qs || {}
const url = new URL(options.url)

if (options.qs) {
for (const [key, value] of Object.entries(options.qs)) {
url.searchParams.set(key, value)
}
}

/**
* This is the callback invoked by the request module, it follows it's parameters
* @callback requestCallback
* @private
* @since 1.1.0
* @param {Error} error - Error object from request
* @param {Object} response - Response object from request
* @param {Object} body - Body object from request
* @returns {Function} callback
*/
function requestCallback (error, response, body) {
if (!error) {
// If requested, prepare rateLimit statistics from response
let rateLimit
if (options.returnRateLimit === true) {
rateLimit = {
limit: response.headers['x-ratelimit-limit'],
remaining: response.headers['x-ratelimit-remaining']
}
}
if (!options.headers) {
options.headers = {}
}

options.headers.Accept = 'application/json'

switch (response.statusCode) {
// Response received without errors
case 200:
return callback(null, body, rateLimit)
// No response received
case 404:
return callback(null, null)
// In other cases, there is some kind of an error or unexpected return
default:
helpers.handleOtherResponses(response, body, callback)
const res = await fetch(options.url, {
headers: options.headers
})

if (res.ok) {
// If requested, prepare rateLimit statistics from response
let rateLimit
if (options.returnRateLimit === true) {
rateLimit = {
limit: res.headers['x-ratelimit-limit'],
remaining: res.headers['x-ratelimit-remaining']
}
} else {
// There was an error with the request-module
return callback(new Error(error), null)
}
}

// Executing API-request
request.get(requestOptions, requestCallback)
const body = await res.json()

return callback(null, body, rateLimit)
} else {
return callback(new Error(`Something went wrong executing the request, statuscode: ${res.status}`), null)
}
}

exports.get = get
75 changes: 47 additions & 28 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@
},
"homepage": "https://github.com/joostdebruijn/node-postcode-nl#readme",
"devDependencies": {
"chai": "^5.0.0",
"chai": "^4.2.0",
"minami": "^1.2.3",
"mocha": "^10.2.0",
"nyc": "^15.1.0",
"sinon": "^17.0.1",
"sinon-chai": "^3.3.0",
"standard": "^17.1.0"
},
"engines": {
Expand Down
62 changes: 19 additions & 43 deletions test/global.requestApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,21 @@
const sinon = require('sinon')
const chai = require('chai')
const sinonChai = require('sinon-chai')
const request = require('request')
const requestApi = require('../lib/requestApi.js')
const expect = chai.expect

function fakeResponse (status = 200) {
const mockResponse = new window.Response(JSON.stringify({}), {
status,
headers: {
'Content-type': 'application/json'
}
});

return Promise.resolve(mockResponse);
}


before(() => {
chai.use(sinonChai)
})
Expand Down Expand Up @@ -34,9 +45,8 @@ describe('global/requestApi()', () => {
json: true,
qs: {}
}
const requestStub = sandbox.stub(request, 'get').callsFake((options, callback) => {
callback(null, { statusCode: 200 }, 'test')
})
const requestStub = sandbox.stub(window, 'fetch')
requestStub.onCall(0).returns(fakeResponse())

return requestApi.get(options, (error, body, rateLimit) => {
expect(error).to.eql(null)
Expand All @@ -62,50 +72,16 @@ describe('global/requestApi()', () => {
remaining: response.headers['x-ratelimit-remaining']
}

sandbox.stub(request, 'get').callsFake((options, callback) => {
callback(null, response, null)
})
const requestStub = sandbox.stub(window, 'fetch')
requestStub.onCall(0).returns(fakeResponse())

return requestApi.get(options, (error, body, rateLimit) => {
expect(rateLimit).to.eql(rateLimitReturn)
})
})
it('should return null if a 404 was responded by the API', () => {
// Setting up the test data
const response = {
statusCode: 404
}

sandbox.stub(request, 'get').callsFake((options, callback) => {
callback(null, response, null)
})

return requestApi.get({}, (error, body, rateLimit) => {
expect(error).to.eql(null)
expect(body).to.eql(null)
expect(rateLimit).to.eql(undefined)
})
})
it('should return a error when the statusCode is not 200 or 404', () => {
// Setting up the test data
const response = {
statusCode: 403
}

sandbox.stub(request, 'get').callsFake((options, callback) => {
callback(null, response, null)
})

return requestApi.get({}, (error, body, rateLimit) => {
expect(error).to.instanceof(Error)
expect(body).to.eql(null)
expect(rateLimit).to.eql(undefined)
})
})
it('should be able to handle errors from the request module and pass them through', () => {
sandbox.stub(request, 'get').callsFake((options, callback) => {
callback(new Error(''), null, null)
})
it('should return a error when the statusCode is not ok', () => {
const requestStub = sandbox.stub(window, 'fetch')
requestStub.onCall(0).returns(fakeResponse(403))

return requestApi.get({}, (error, body, rateLimit) => {
expect(error).to.instanceof(Error)
Expand Down

0 comments on commit 573ddd8

Please sign in to comment.