Skip to content

Commit

Permalink
feat(geolocate): geolocate based on ip using IP service providers
Browse files Browse the repository at this point in the history
  • Loading branch information
Jun711 committed Feb 13, 2018
1 parent 9da22d1 commit c273320
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/geolocate/geolocate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
async function geolocateFreeGeoIp() {
const response = await fetch('https://freegeoip.net/json/');
const ipInfo = await response.json();
return ipInfo;
}

async function geolocateIPAPI() {
const response = await fetch('https://ipapi.co/country');
const countryCode = await response.text();
return countryCode;
}

export {
geolocateFreeGeoIp,
geolocateIPAPI,
};
27 changes: 27 additions & 0 deletions src/whereabout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { geolocateFreeGeoIp, geolocateIPAPI } from './geolocate/geolocate';

const whereabout = function (provider = 0) {
if (provider > 1) {
return Promise.reject(new Error('Service is not available'));
}
let response = null;
try {
if (provider === 0) {
response = geolocateIPAPI();
} else {
response = geolocateFreeGeoIp();
}
} catch (err) {
const nextProvider = provider + 1;
whereabout(nextProvider);
}

return response;
};

if (typeof window !== 'undefined'
&& typeof window.whereabout === 'undefined') {
window.whereabout = whereabout;
}

module.exports = whereabout;
76 changes: 76 additions & 0 deletions tests/geolocate.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* eslint-env node, mocha */
import { assert, expect } from 'chai';
import { geolocateFreeGeoIp, geolocateIPAPI } from '../src/geolocate/geolocate';

describe('geolocateFreeGeoIp', () => {
it('should return ipinfo json object', (done) => {
geolocateFreeGeoIp()
.then((response) => {
assert.isObject(response);
// console.log('response: ', response);
done();
})
.catch((err) => {
done(err);
});
});

it('should contain properties as specified in the document', (done) => {
const responseKeys = ['ip', 'country_code', 'country_name', 'region_code', 'region_name',
'city', 'zip_code', 'time_zone', 'latitude', 'longitude', 'metro_code'];
geolocateFreeGeoIp()
.then((response) => {
assert.containsAllKeys(response, responseKeys);
done();
})
.catch((err) => {
done(err);
});
});

it('should contain country code property', (done) => {
geolocateFreeGeoIp()
.then((response) => {
expect(response).to.have.property('country_code');
done();
})
.catch((err) => {
done(err);
});
});
});

describe('geolocateIPAPI', () => {
it('should return country code string', (done) => {
geolocateIPAPI()
.then((response) => {
assert.isString(response, 'IPAPI returns country code');
done();
})
.catch((err) => {
done(err);
});
});

it('should return country code string', (done) => {
geolocateIPAPI()
.then((response) => {
expect(response).to.be.a('string');
done();
})
.catch((err) => {
done(err);
});
});

it('should return country code string that has length 2', (done) => {
geolocateIPAPI()
.then((response) => {
expect(response).to.have.lengthOf(2);
done();
})
.catch((err) => {
done(err);
});
});
});
49 changes: 49 additions & 0 deletions tests/whereabout.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* eslint-env node, mocha */
import { assert, expect } from 'chai';
import whereabout from '../src/whereabout';

describe('whereabout', () => {
it('should call FreeGeoIp when no provider specified', (done) => {
whereabout()
.then((response) => {
assert.isString(response, 'IPAPI returns country code');
expect(response).to.be.a('string');
expect(response).to.have.lengthOf(2);
done();
})
.catch((err) => {
done(err);
});
});

it('should call IPAPI when provider 0 specified', async () => {
const response = await whereabout(0);
assert.isString(response, 'IPAPI returns country code');
expect(response).to.be.a('string');
expect(response).to.have.lengthOf(2);
});

it('should call FreeGeoIp when provider 1 specified', (done) => {
whereabout(1)
.then((response) => {
assert.isObject(response);
expect(response).to.have.property('country_code');
done();
})
.catch((err) => {
done(err);
});
});

it('should rejects as promised when provider 2 specified', (done) => {
whereabout(2)
.then(() => {
assert.fail(0, 1, 'Expected rejected promise');
done();
}, (error) => {
expect(error).to.be.an.instanceof(Error);
expect(error.message).to.equal('Service is not available')
done();
});
});
});

0 comments on commit c273320

Please sign in to comment.