GeoIpLookupTest.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  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('WAT')).to.equal(false)
  48. expect(this.GeoIpLookup.isValidCurrencyParam('NON')).to.equal(false)
  49. expect(this.GeoIpLookup.isValidCurrencyParam('LOL')).to.equal(false)
  50. })
  51. })
  52. describe('getDetails', function () {
  53. beforeEach(function () {
  54. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  55. })
  56. describe('callback', function () {
  57. it('should request the details using the ip', function (done) {
  58. this.GeoIpLookup.getDetails(this.ipAddress, err => {
  59. assert.equal(err, null)
  60. this.request.get
  61. .calledWith({
  62. url: this.settings.apis.geoIpLookup.url + '/' + this.ipAddress,
  63. timeout: 1000,
  64. json: true,
  65. })
  66. .should.equal(true)
  67. done()
  68. })
  69. })
  70. it('should return the ip details', function (done) {
  71. this.GeoIpLookup.getDetails(this.ipAddress, (err, returnedDetails) => {
  72. assert.equal(err, null)
  73. assert.deepEqual(returnedDetails, this.stubbedResponse)
  74. done()
  75. })
  76. })
  77. it('should take the first ip in the string', function (done) {
  78. this.GeoIpLookup.getDetails(
  79. ` ${this.ipAddress} 123.123.123.123 234.234.234.234`,
  80. err => {
  81. assert.equal(err, null)
  82. this.request.get
  83. .calledWith({
  84. url: this.settings.apis.geoIpLookup.url + '/' + this.ipAddress,
  85. timeout: 1000,
  86. json: true,
  87. })
  88. .should.equal(true)
  89. done()
  90. }
  91. )
  92. })
  93. })
  94. describe('async', function () {
  95. it('should request the details using the ip', async function () {
  96. await this.GeoIpLookup.promises.getDetails(this.ipAddress)
  97. this.request.get
  98. .calledWith({
  99. url: this.settings.apis.geoIpLookup.url + '/' + this.ipAddress,
  100. timeout: 1000,
  101. json: true,
  102. })
  103. .should.equal(true)
  104. })
  105. it('should return the ip details', async function () {
  106. const returnedDetails = await this.GeoIpLookup.promises.getDetails(
  107. this.ipAddress
  108. )
  109. assert.deepEqual(returnedDetails, this.stubbedResponse)
  110. })
  111. it('should take the first ip in the string', async function () {
  112. await this.GeoIpLookup.promises.getDetails(
  113. ` ${this.ipAddress} 123.123.123.123 234.234.234.234`
  114. )
  115. this.request.get
  116. .calledWith({
  117. url: this.settings.apis.geoIpLookup.url + '/' + this.ipAddress,
  118. timeout: 1000,
  119. json: true,
  120. })
  121. .should.equal(true)
  122. })
  123. })
  124. })
  125. describe('getCurrencyCode', function () {
  126. describe('callback', function () {
  127. it('should return GBP for GB country', function (done) {
  128. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  129. this.GeoIpLookup.getCurrencyCode(
  130. this.ipAddress,
  131. (err, currencyCode) => {
  132. assert.equal(err, null)
  133. currencyCode.should.equal('GBP')
  134. done()
  135. }
  136. )
  137. })
  138. it('should return GBP for gb country', function (done) {
  139. this.stubbedResponse.country_code = 'gb'
  140. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  141. this.GeoIpLookup.getCurrencyCode(
  142. this.ipAddress,
  143. (err, currencyCode) => {
  144. assert.equal(err, null)
  145. currencyCode.should.equal('GBP')
  146. done()
  147. }
  148. )
  149. })
  150. it('should return USD for US', function (done) {
  151. this.stubbedResponse.country_code = 'US'
  152. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  153. this.GeoIpLookup.getCurrencyCode(
  154. this.ipAddress,
  155. (err, currencyCode) => {
  156. assert.equal(err, null)
  157. currencyCode.should.equal('USD')
  158. done()
  159. }
  160. )
  161. })
  162. it('should return EUR for DE', function (done) {
  163. this.stubbedResponse.country_code = 'DE'
  164. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  165. this.GeoIpLookup.getCurrencyCode(
  166. this.ipAddress,
  167. (err, currencyCode) => {
  168. assert.equal(err, null)
  169. currencyCode.should.equal('EUR')
  170. done()
  171. }
  172. )
  173. })
  174. it('should default to USD if there is an error', function (done) {
  175. this.request.get.callsArgWith(1, null, null, { error: true })
  176. this.GeoIpLookup.getCurrencyCode(
  177. this.ipAddress,
  178. (err, currencyCode) => {
  179. assert.equal(err, null)
  180. currencyCode.should.equal('USD')
  181. done()
  182. }
  183. )
  184. })
  185. it('should default to USD if there are no details', function (done) {
  186. this.request.get.callsArgWith(1, null, null, {})
  187. this.GeoIpLookup.getCurrencyCode(
  188. this.ipAddress,
  189. (err, currencyCode) => {
  190. assert.equal(err, null)
  191. currencyCode.should.equal('USD')
  192. done()
  193. }
  194. )
  195. })
  196. it('should default to USD if there is no match for their country', function (done) {
  197. this.stubbedResponse.country_code = 'Non existant'
  198. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  199. this.GeoIpLookup.getCurrencyCode(
  200. this.ipAddress,
  201. (err, currencyCode) => {
  202. assert.equal(err, null)
  203. currencyCode.should.equal('USD')
  204. done()
  205. }
  206. )
  207. })
  208. })
  209. describe('async', function () {
  210. it('should return GBP for GB country', async function () {
  211. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  212. const {
  213. currencyCode,
  214. countryCode,
  215. } = await this.GeoIpLookup.promises.getCurrencyCode(this.ipAddress)
  216. currencyCode.should.equal('GBP')
  217. countryCode.should.equal('GB')
  218. })
  219. it('should return GBP for gb country', async function () {
  220. this.stubbedResponse.country_code = 'gb'
  221. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  222. const {
  223. currencyCode,
  224. countryCode,
  225. } = await this.GeoIpLookup.promises.getCurrencyCode(this.ipAddress)
  226. currencyCode.should.equal('GBP')
  227. countryCode.should.equal('GB')
  228. })
  229. it('should return USD for US', async function () {
  230. this.stubbedResponse.country_code = 'US'
  231. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  232. const {
  233. currencyCode,
  234. countryCode,
  235. } = await this.GeoIpLookup.promises.getCurrencyCode(this.ipAddress)
  236. currencyCode.should.equal('USD')
  237. countryCode.should.equal('US')
  238. })
  239. it('should return EUR for DE', async function () {
  240. this.stubbedResponse.country_code = 'DE'
  241. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  242. const {
  243. currencyCode,
  244. countryCode,
  245. } = await this.GeoIpLookup.promises.getCurrencyCode(this.ipAddress)
  246. currencyCode.should.equal('EUR')
  247. countryCode.should.equal('DE')
  248. })
  249. it('should default to USD if there is an error', async function () {
  250. this.request.get.callsArgWith(1, null, null, { error: true })
  251. const {
  252. currencyCode,
  253. countryCode,
  254. } = await this.GeoIpLookup.promises.getCurrencyCode(this.ipAddress)
  255. currencyCode.should.equal('USD')
  256. expect(countryCode).to.be.undefined
  257. })
  258. it('should default to USD if there are no details', async function () {
  259. this.request.get.callsArgWith(1, null, null, {})
  260. const {
  261. currencyCode,
  262. countryCode,
  263. } = await this.GeoIpLookup.promises.getCurrencyCode(this.ipAddress)
  264. currencyCode.should.equal('USD')
  265. expect(countryCode).to.be.undefined
  266. })
  267. it('should default to USD if there is no match for their country', async function () {
  268. this.stubbedResponse.country_code = 'Non existant'
  269. this.request.get.callsArgWith(1, null, null, this.stubbedResponse)
  270. const {
  271. currencyCode,
  272. countryCode,
  273. } = await this.GeoIpLookup.promises.getCurrencyCode(this.ipAddress)
  274. currencyCode.should.equal('USD')
  275. countryCode.should.equal('NON EXISTANT')
  276. })
  277. })
  278. })
  279. })