GeoIpLookupTest.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. const SandboxedModule = require('sandboxed-module')
  2. const assert = require('assert')
  3. const path = require('path')
  4. const sinon = require('sinon')
  5. const { expect } = require('chai')
  6. const modulePath = path.join(
  7. __dirname,
  8. '../../../../app/src/infrastructure/GeoIpLookup'
  9. )
  10. describe('GeoIpLookup', function () {
  11. beforeEach(function () {
  12. this.request = { get: sinon.stub() }
  13. this.settings = {
  14. apis: {
  15. geoIpLookup: {
  16. url: 'http://lookup.com',
  17. },
  18. },
  19. }
  20. this.GeoIpLookup = SandboxedModule.require(modulePath, {
  21. requires: {
  22. request: this.request,
  23. '@overleaf/settings': this.settings,
  24. },
  25. })
  26. this.ipAddress = '12.34.56.78'
  27. this.stubbedResponse = {
  28. ip: this.ipAddress,
  29. country_code: 'GB',
  30. country_name: 'United Kingdom',
  31. region_code: 'H9',
  32. region_name: 'London, City of',
  33. city: 'London',
  34. zipcode: 'SE16',
  35. latitude: 51.0,
  36. longitude: -0.0493,
  37. metro_code: '',
  38. area_code: '',
  39. }
  40. })
  41. describe('isValidCurrencyParam', function () {
  42. it('should reject invalid currency codes', function () {
  43. expect(this.GeoIpLookup.isValidCurrencyParam('GBP')).to.equal(true)
  44. expect(this.GeoIpLookup.isValidCurrencyParam('USD')).to.equal(true)
  45. expect(this.GeoIpLookup.isValidCurrencyParam('AUD')).to.equal(true)
  46. expect(this.GeoIpLookup.isValidCurrencyParam('EUR')).to.equal(true)
  47. expect(this.GeoIpLookup.isValidCurrencyParam('SGD')).to.equal(true)
  48. expect(this.GeoIpLookup.isValidCurrencyParam('WAT')).to.equal(false)
  49. expect(this.GeoIpLookup.isValidCurrencyParam('NON')).to.equal(false)
  50. expect(this.GeoIpLookup.isValidCurrencyParam('LOL')).to.equal(false)
  51. })
  52. })
  53. describe('getDetails', function () {
  54. beforeEach(function () {
  55. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  56. })
  57. describe('callback', function () {
  58. it('should request the details using the ip', function (done) {
  59. this.GeoIpLookup.getDetails(this.ipAddress, err => {
  60. assert.equal(err, null)
  61. this.request.get
  62. .calledWith({
  63. url: this.settings.apis.geoIpLookup.url + '/' + this.ipAddress,
  64. timeout: 1000,
  65. json: true,
  66. })
  67. .should.equal(true)
  68. done()
  69. })
  70. })
  71. it('should return the ip details', function (done) {
  72. this.GeoIpLookup.getDetails(this.ipAddress, (err, returnedDetails) => {
  73. assert.equal(err, null)
  74. assert.deepEqual(returnedDetails, this.stubbedResponse)
  75. done()
  76. })
  77. })
  78. it('should take the first ip in the string', function (done) {
  79. this.GeoIpLookup.getDetails(
  80. ` ${this.ipAddress} 123.123.123.123 234.234.234.234`,
  81. err => {
  82. assert.equal(err, null)
  83. this.request.get
  84. .calledWith({
  85. url: this.settings.apis.geoIpLookup.url + '/' + this.ipAddress,
  86. timeout: 1000,
  87. json: true,
  88. })
  89. .should.equal(true)
  90. done()
  91. }
  92. )
  93. })
  94. })
  95. describe('async', function () {
  96. it('should request the details using the ip', async function () {
  97. await this.GeoIpLookup.promises.getDetails(this.ipAddress)
  98. this.request.get
  99. .calledWith({
  100. url: this.settings.apis.geoIpLookup.url + '/' + this.ipAddress,
  101. timeout: 1000,
  102. json: true,
  103. })
  104. .should.equal(true)
  105. })
  106. it('should return the ip details', async function () {
  107. const returnedDetails = await this.GeoIpLookup.promises.getDetails(
  108. this.ipAddress
  109. )
  110. assert.deepEqual(returnedDetails, this.stubbedResponse)
  111. })
  112. it('should take the first ip in the string', async function () {
  113. await this.GeoIpLookup.promises.getDetails(
  114. ` ${this.ipAddress} 123.123.123.123 234.234.234.234`
  115. )
  116. this.request.get
  117. .calledWith({
  118. url: this.settings.apis.geoIpLookup.url + '/' + this.ipAddress,
  119. timeout: 1000,
  120. json: true,
  121. })
  122. .should.equal(true)
  123. })
  124. })
  125. })
  126. describe('getCurrencyCode', function () {
  127. describe('callback', function () {
  128. it('should return GBP for GB country', function (done) {
  129. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  130. this.GeoIpLookup.getCurrencyCode(
  131. this.ipAddress,
  132. (err, currencyCode) => {
  133. assert.equal(err, null)
  134. currencyCode.should.equal('GBP')
  135. done()
  136. }
  137. )
  138. })
  139. it('should return GBP for gb country', function (done) {
  140. this.stubbedResponse.country_code = 'gb'
  141. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  142. this.GeoIpLookup.getCurrencyCode(
  143. this.ipAddress,
  144. (err, currencyCode) => {
  145. assert.equal(err, null)
  146. currencyCode.should.equal('GBP')
  147. done()
  148. }
  149. )
  150. })
  151. it('should return USD for US', function (done) {
  152. this.stubbedResponse.country_code = 'US'
  153. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  154. this.GeoIpLookup.getCurrencyCode(
  155. this.ipAddress,
  156. (err, currencyCode) => {
  157. assert.equal(err, null)
  158. currencyCode.should.equal('USD')
  159. done()
  160. }
  161. )
  162. })
  163. it('should return EUR for DE', function (done) {
  164. this.stubbedResponse.country_code = 'DE'
  165. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  166. this.GeoIpLookup.getCurrencyCode(
  167. this.ipAddress,
  168. (err, currencyCode) => {
  169. assert.equal(err, null)
  170. currencyCode.should.equal('EUR')
  171. done()
  172. }
  173. )
  174. })
  175. it('should default to USD if there is an error', function (done) {
  176. this.request.get.callsArgWith(1, null, null, { error: true })
  177. this.GeoIpLookup.getCurrencyCode(
  178. this.ipAddress,
  179. (err, currencyCode) => {
  180. assert.equal(err, null)
  181. currencyCode.should.equal('USD')
  182. done()
  183. }
  184. )
  185. })
  186. it('should default to USD if there are no details', function (done) {
  187. this.request.get.callsArgWith(1, null, null, {})
  188. this.GeoIpLookup.getCurrencyCode(
  189. this.ipAddress,
  190. (err, currencyCode) => {
  191. assert.equal(err, null)
  192. currencyCode.should.equal('USD')
  193. done()
  194. }
  195. )
  196. })
  197. it('should default to USD if there is no match for their country', function (done) {
  198. this.stubbedResponse.country_code = 'Non existant'
  199. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  200. this.GeoIpLookup.getCurrencyCode(
  201. this.ipAddress,
  202. (err, currencyCode) => {
  203. assert.equal(err, null)
  204. currencyCode.should.equal('USD')
  205. done()
  206. }
  207. )
  208. })
  209. })
  210. describe('async', function () {
  211. it('should return GBP for GB country', async function () {
  212. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  213. const { currencyCode, countryCode } =
  214. await this.GeoIpLookup.promises.getCurrencyCode(this.ipAddress)
  215. currencyCode.should.equal('GBP')
  216. countryCode.should.equal('GB')
  217. })
  218. it('should return GBP for gb country', async function () {
  219. this.stubbedResponse.country_code = 'gb'
  220. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  221. const { currencyCode, countryCode } =
  222. await this.GeoIpLookup.promises.getCurrencyCode(this.ipAddress)
  223. currencyCode.should.equal('GBP')
  224. countryCode.should.equal('GB')
  225. })
  226. it('should return USD for US', async function () {
  227. this.stubbedResponse.country_code = 'US'
  228. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  229. const { currencyCode, countryCode } =
  230. await this.GeoIpLookup.promises.getCurrencyCode(this.ipAddress)
  231. currencyCode.should.equal('USD')
  232. countryCode.should.equal('US')
  233. })
  234. it('should return EUR for DE', async function () {
  235. this.stubbedResponse.country_code = 'DE'
  236. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  237. const { currencyCode, countryCode } =
  238. await this.GeoIpLookup.promises.getCurrencyCode(this.ipAddress)
  239. currencyCode.should.equal('EUR')
  240. countryCode.should.equal('DE')
  241. })
  242. it('should default to USD if there is an error', async function () {
  243. this.request.get.callsArgWith(1, null, null, { error: true })
  244. const { currencyCode, countryCode } =
  245. await this.GeoIpLookup.promises.getCurrencyCode(this.ipAddress)
  246. currencyCode.should.equal('USD')
  247. expect(countryCode).to.be.undefined
  248. })
  249. it('should default to USD if there are no details', async function () {
  250. this.request.get.callsArgWith(1, null, null, {})
  251. const { currencyCode, countryCode } =
  252. await this.GeoIpLookup.promises.getCurrencyCode(this.ipAddress)
  253. currencyCode.should.equal('USD')
  254. expect(countryCode).to.be.undefined
  255. })
  256. it('should default to USD if there is no match for their country', async function () {
  257. this.stubbedResponse.country_code = 'Non existant'
  258. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  259. const { currencyCode, countryCode } =
  260. await this.GeoIpLookup.promises.getCurrencyCode(this.ipAddress)
  261. currencyCode.should.equal('USD')
  262. countryCode.should.equal('NON EXISTANT')
  263. })
  264. })
  265. })
  266. })