1+ import keyBy from 'lodash/keyBy' ;
12import IPData from './ipdata' ;
23
4+ const TEST_IP = '1.1.1.1' ;
5+ const DEFAULT_IP_KEY = 'DEFAULT_IP' ;
6+
37describe ( 'constructor()' , ( ) => {
48 it ( 'should throw an error if an apiKey is not provided' , ( ) => {
59 // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
610 // @ts -ignore
7- expect ( ( ) => new IPData ( ) ) . toThrowError ( 'An API key is required.' ) ;
11+ expect ( ( ) => new IPData ( ) ) . toThrow ( 'An API key is required.' ) ;
812 } ) ;
913
1014 it ( 'should set the apiKey' , ( ) => {
1115 const ipdata = new IPData ( process . env . IPDATA_API_KEY ) ;
1216 expect ( ipdata . apiKey ) . toEqual ( process . env . IPDATA_API_KEY ) ;
1317 } ) ;
18+
19+ it ( 'should configure the cache by default' , ( ) => {
20+ const ipdata = new IPData ( process . env . IPDATA_API_KEY ) ;
21+ expect ( ipdata . cache . max ) . toEqual ( 4096 ) ;
22+ expect ( ipdata . cache . maxAge ) . toEqual ( 1000 * 60 * 60 * 24 ) ;
23+ } ) ;
24+
25+ it ( 'should configure the cache' , ( ) => {
26+ const max = 1 ;
27+ const maxAge = 1000 ;
28+ const ipdata = new IPData ( process . env . IPDATA_API_KEY , { max, maxAge } ) ;
29+ expect ( ipdata . cache . max ) . toEqual ( max ) ;
30+ expect ( ipdata . cache . maxAge ) . toEqual ( maxAge ) ;
31+ } ) ;
1432} ) ;
1533
1634describe ( 'lookup()' , ( ) => {
1735 const ipdata = new IPData ( process . env . IPDATA_API_KEY ) ;
18- const IP = '1.1.1.1' ;
1936
2037 afterEach ( ( ) => {
2138 return ipdata . cache . reset ( ) ;
2239 } ) ;
2340
24- it ( 'should throw an error if the ip address is invalid' , async ( ) => {
25- const badIP = '1.1.11' ;
26- await expect ( ipdata . lookup ( badIP ) ) . rejects . toThrowError ( `${ badIP } is an invalid IP address.` ) ;
27- } ) ;
41+ describe ( 'default IP address' , ( ) => {
42+ it ( 'should return information' , async ( ) => {
43+ const info = await ipdata . lookup ( ) ;
44+ expect ( info ) . toHaveProperty ( 'ip' ) ;
45+ expect ( info ) . toHaveProperty ( 'status' ) ;
46+ } ) ;
2847
29- it ( 'should return default information when no ip address is provided' , async ( ) => {
30- const info = await ipdata . lookup ( ) ;
31- expect ( info ) . toHaveProperty ( 'ip' ) ;
32- expect ( info ) . toHaveProperty ( 'status' ) ;
33- } ) ;
48+ it ( 'should return information when null is provided' , async ( ) => {
49+ const info = await ipdata . lookup ( null ) ;
50+ expect ( info ) . toHaveProperty ( 'ip' ) ;
51+ expect ( info ) . toHaveProperty ( 'status' ) ;
52+ } ) ;
3453
35- it ( 'should return default information when null is provided' , async ( ) => {
36- const info = await ipdata . lookup ( null ) ;
37- expect ( info ) . toHaveProperty ( 'ip' ) ;
38- expect ( info ) . toHaveProperty ( 'status' ) ;
39- } ) ;
54+ it ( 'should return information when undefined is provided' , async ( ) => {
55+ const info = await ipdata . lookup ( undefined ) ;
56+ expect ( info ) . toHaveProperty ( 'ip' ) ;
57+ expect ( info ) . toHaveProperty ( 'status' ) ;
58+ } ) ;
4059
41- it ( 'should return default information when undefined is provided' , async ( ) => {
42- const info = await ipdata . lookup ( undefined ) ;
43- expect ( info ) . toHaveProperty ( 'ip' ) ;
44- expect ( info ) . toHaveProperty ( 'status' ) ;
45- } ) ;
60+ it ( 'should cache the information' , async ( ) => {
61+ await ipdata . lookup ( ) ;
62+ const info = ipdata . cache . get ( DEFAULT_IP_KEY ) ;
63+ expect ( info ) . toHaveProperty ( 'ip' ) ;
64+ expect ( info ) . toHaveProperty ( 'status' ) ;
65+ } ) ;
4666
47- it ( 'should cache the ip address info for the default ip address' , async ( ) => {
48- await ipdata . lookup ( ) ;
49- const info = ipdata . cache . get ( 'DEFAULT_IP' ) ;
50- expect ( info ) . toHaveProperty ( 'ip' ) ;
51- expect ( info ) . toHaveProperty ( 'status' ) ;
67+ it ( 'should not cache the information' , async ( ) => {
68+ const customIPData = new IPData ( process . env . IPDATA_API_KEY , { maxAge : - 1 } ) ;
69+ await customIPData . lookup ( ) ;
70+ const info = ipdata . cache . get ( DEFAULT_IP_KEY ) ;
71+ expect ( info ) . toBeUndefined ( ) ;
72+ } ) ;
5273 } ) ;
5374
54- it ( 'should accept an ip address', async ( ) => {
55- const info = await ipdata . lookup ( IP ) ;
56- expect ( info ) . toHaveProperty ( 'ip' , IP ) ;
57- expect ( info ) . toHaveProperty ( 'status' ) ;
58- } ) ;
75+ describe ( 'custom IP address', ( ) => {
76+ it ( 'should throw an error if the ip address is invalid' , async ( ) => {
77+ const badIP = '1.1.11' ;
78+ await expect ( ipdata . lookup ( badIP ) ) . rejects . toThrow ( ` ${ badIP } is an invalid IP address.` ) ;
79+ } ) ;
5980
60- it ( 'should cache the ip address info' , async ( ) => {
61- await ipdata . lookup ( IP ) ;
62- const info = ipdata . cache . get ( IP ) ;
63- expect ( info ) . toHaveProperty ( 'ip' , IP ) ;
64- expect ( info ) . toHaveProperty ( 'status' ) ;
81+ it ( 'should return information' , async ( ) => {
82+ const info = await ipdata . lookup ( TEST_IP ) ;
83+ expect ( info ) . toHaveProperty ( 'ip' , TEST_IP ) ;
84+ expect ( info ) . toHaveProperty ( 'status' ) ;
85+ } ) ;
86+
87+ it ( 'should cache the information' , async ( ) => {
88+ await ipdata . lookup ( TEST_IP ) ;
89+ const info = ipdata . cache . get ( TEST_IP ) ;
90+ expect ( info ) . toHaveProperty ( 'ip' , TEST_IP ) ;
91+ expect ( info ) . toHaveProperty ( 'status' ) ;
92+ } ) ;
93+
94+ it ( 'should not cache the information' , async ( ) => {
95+ const customIPData = new IPData ( process . env . IPDATA_API_KEY , { maxAge : - 1 } ) ;
96+ await customIPData . lookup ( TEST_IP ) ;
97+ const info = ipdata . cache . get ( TEST_IP ) ;
98+ expect ( info ) . toBeUndefined ( ) ;
99+ } ) ;
65100 } ) ;
66101
67102 it ( 'should throw an error if a selectField and fields is provided' , async ( ) => {
68- await expect ( ipdata . lookup ( null , 'field' , [ 'field' ] ) ) . rejects . toThrowError (
103+ await expect ( ipdata . lookup ( null , 'field' , [ 'field' ] ) ) . rejects . toThrow (
69104 'The selectField and fields parameters cannot be used at the same time.' ,
70105 ) ;
71106 } ) ;
72107
73108 describe ( 'selectField' , ( ) => {
74109 it ( 'should throw an error for an invlaid field ' , async ( ) => {
75110 const field = 'field' ;
76- await expect ( ipdata . lookup ( null , field ) ) . rejects . toThrowError ( `${ field } is not a valid field.` ) ;
111+ await expect ( ipdata . lookup ( null , field ) ) . rejects . toThrow ( `${ field } is not a valid field.` ) ;
77112 } ) ;
78113
79114 it ( 'should return a response with only the field' , async ( ) => {
@@ -88,15 +123,15 @@ describe('lookup()', () => {
88123 it ( 'should throw an error for an invlaid field ' , async ( ) => {
89124 const field = 'field' ;
90125 const fields = [ field ] ;
91- await expect ( ipdata . lookup ( null , null , fields ) ) . rejects . toThrowError ( `${ field } is not a valid field.` ) ;
126+ await expect ( ipdata . lookup ( null , null , fields ) ) . rejects . toThrow ( `${ field } is not a valid field.` ) ;
92127 } ) ;
93128
94129 it ( 'should return a response with only the field' , async ( ) => {
95130 const field1 = 'ip' ;
96131 const field2 = 'is_eu' ;
97132 const fields = [ field1 , field2 ] ;
98- const info = await ipdata . lookup ( IP , null , fields ) ;
99- expect ( info ) . toHaveProperty ( field1 , IP ) ;
133+ const info = await ipdata . lookup ( TEST_IP , null , fields ) ;
134+ expect ( info ) . toHaveProperty ( field1 , TEST_IP ) ;
100135 expect ( info ) . toHaveProperty ( field2 , false ) ;
101136 expect ( info ) . toHaveProperty ( 'status' ) ;
102137 } ) ;
@@ -105,7 +140,7 @@ describe('lookup()', () => {
105140
106141describe ( 'bulkLookup()' , ( ) => {
107142 const ipdata = new IPData ( process . env . IPDATA_API_KEY ) ;
108- const IP1 = '1.1.1.1' ;
143+ const IP1 = TEST_IP ;
109144 const IP2 = '8.8.8.8' ;
110145
111146 afterEach ( ( ) => {
@@ -114,43 +149,67 @@ describe('bulkLookup()', () => {
114149
115150 it ( 'should throw an error if less than 2 ip addresses are provided' , async ( ) => {
116151 const ips = [ IP1 ] ;
117- await expect ( ipdata . bulkLookup ( ips ) ) . rejects . toThrowError (
118- 'Bulk Lookup requires more than 1 IP Address in the payload.' ,
119- ) ;
152+ await expect ( ipdata . bulkLookup ( ips ) ) . rejects . toThrow ( 'Bulk Lookup requires more than 1 IP Address in the payload.' ) ;
120153 } ) ;
121154
122155 it ( 'should throw an error if an ip address is invalid' , async ( ) => {
123156 const badIP = '1.1.11' ;
124157 const ips = [ badIP , IP2 ] ;
125- await expect ( ipdata . bulkLookup ( ips ) ) . rejects . toThrowError ( `${ badIP } is an invalid IP address.` ) ;
158+ await expect ( ipdata . bulkLookup ( ips ) ) . rejects . toThrow ( `${ badIP } is an invalid IP address.` ) ;
126159 } ) ;
127160
128161 it ( 'should return info for the ip addresses' , async ( ) => {
129- const info = await ipdata . bulkLookup ( [ IP1 , IP2 ] ) ;
130- expect ( info ) . toHaveProperty ( 'responses' ) ;
131- expect ( info ) . toHaveProperty ( 'status' ) ;
132- expect ( info . responses [ 0 ] ) . toHaveProperty ( 'ip' , IP1 ) ;
133- expect ( info . responses [ 1 ] ) . toHaveProperty ( 'ip' , IP2 ) ;
162+ const result = await ipdata . bulkLookup ( [ IP1 , IP2 ] ) ;
163+ const info = keyBy ( result , ipInfo => ipInfo . ip ) ;
164+ expect ( info [ IP1 ] ) . toHaveProperty ( 'ip' , IP1 ) ;
165+ expect ( info [ IP1 ] ) . toHaveProperty ( 'status' ) ;
166+ expect ( info [ IP2 ] ) . toHaveProperty ( 'ip' , IP2 ) ;
167+ expect ( info [ IP2 ] ) . toHaveProperty ( 'status' ) ;
168+ } ) ;
169+
170+ it ( 'should cache the info' , async ( ) => {
171+ await ipdata . bulkLookup ( [ IP1 , IP2 ] ) ;
172+ const ip1Info = ipdata . cache . get ( IP1 ) ;
173+ const ip2Info = ipdata . cache . get ( IP2 ) ;
174+ expect ( ip1Info ) . toHaveProperty ( 'ip' , IP1 ) ;
175+ expect ( ip1Info ) . toHaveProperty ( 'status' ) ;
176+ expect ( ip2Info ) . toHaveProperty ( 'ip' , IP2 ) ;
177+ expect ( ip2Info ) . toHaveProperty ( 'status' ) ;
178+ } ) ;
179+
180+ it ( 'should use existing cached ips and merge ones that do not exist' , async ( ) => {
181+ const IP3 = '1.0.0.1' ;
182+ await ipdata . lookup ( IP1 ) ;
183+ expect ( ipdata . cache . get ( IP1 ) ) . not . toBeUndefined ( ) ;
184+ const result = await ipdata . bulkLookup ( [ IP1 , IP2 , IP3 ] ) ;
185+ const info = keyBy ( result , ipInfo => ipInfo . ip ) ;
186+ expect ( info [ IP1 ] ) . toHaveProperty ( 'ip' , IP1 ) ;
187+ expect ( info [ IP1 ] ) . toHaveProperty ( 'status' ) ;
188+ expect ( info [ IP2 ] ) . toHaveProperty ( 'ip' , IP2 ) ;
189+ expect ( info [ IP2 ] ) . toHaveProperty ( 'status' ) ;
190+ expect ( info [ IP3 ] ) . toHaveProperty ( 'ip' , IP3 ) ;
191+ expect ( info [ IP3 ] ) . toHaveProperty ( 'status' ) ;
134192 } ) ;
135193
136194 describe ( 'fields' , ( ) => {
137195 it ( 'should throw an error for an invlaid field ' , async ( ) => {
138196 const field = 'field' ;
139197 const fields = [ field ] ;
140- await expect ( ipdata . bulkLookup ( [ IP1 , IP2 ] , fields ) ) . rejects . toThrowError ( `${ field } is not a valid field.` ) ;
198+ await expect ( ipdata . bulkLookup ( [ IP1 , IP2 ] , fields ) ) . rejects . toThrow ( `${ field } is not a valid field.` ) ;
141199 } ) ;
142200
143201 it ( 'should return a response with only the field' , async ( ) => {
144202 const field1 = 'ip' ;
145203 const field2 = 'is_eu' ;
146204 const fields = [ field1 , field2 ] ;
147- const info = await ipdata . bulkLookup ( [ IP1 , IP2 ] , fields ) ;
148- expect ( info ) . toHaveProperty ( 'responses' ) ;
149- expect ( info ) . toHaveProperty ( 'status' ) ;
150- expect ( info . responses [ 0 ] ) . toHaveProperty ( field1 , IP1 ) ;
151- expect ( info . responses [ 0 ] ) . toHaveProperty ( field2 , false ) ;
152- expect ( info . responses [ 1 ] ) . toHaveProperty ( field1 , IP2 ) ;
153- expect ( info . responses [ 1 ] ) . toHaveProperty ( field2 , false ) ;
205+ const result = await ipdata . bulkLookup ( [ IP1 , IP2 ] , fields ) ;
206+ const info = keyBy ( result , ipInfo => ipInfo . ip ) ;
207+ expect ( info [ IP1 ] ) . toHaveProperty ( field1 , IP1 ) ;
208+ expect ( info [ IP1 ] ) . toHaveProperty ( field2 , false ) ;
209+ expect ( info [ IP1 ] ) . toHaveProperty ( 'status' ) ;
210+ expect ( info [ IP2 ] ) . toHaveProperty ( field1 , IP2 ) ;
211+ expect ( info [ IP2 ] ) . toHaveProperty ( field2 , false ) ;
212+ expect ( info [ IP2 ] ) . toHaveProperty ( 'status' ) ;
154213 } ) ;
155214 } ) ;
156215} ) ;
0 commit comments