Skip to content

Commit a926b20

Browse files
authored
Merge pull request #216 from fingerprintjs/feat/remove-visitorId-comparison-inter-1473
2 parents 83f816d + 8545f20 commit a926b20

File tree

1 file changed

+79
-95
lines changed

1 file changed

+79
-95
lines changed
Lines changed: 79 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,117 +1,101 @@
1-
import { FingerprintJsServerApiClient, Region, RequestError } from '@fingerprintjs/fingerprintjs-pro-server-api'
1+
import { FingerprintJsServerApiClient, Region, RequestError, TooManyRequestsError } from '@fingerprintjs/fingerprintjs-pro-server-api'
22
import { config } from 'dotenv'
33
config()
44

5-
const apiKey = process.env.API_KEY
6-
const envRegion = process.env.REGION
5+
const REGION_MAP = { eu: Region.EU, ap: Region.AP, us: Region.Global }
6+
const region = REGION_MAP[(process.env.REGION ?? 'us').toLowerCase()] ?? Region.Global
77

8-
if (!apiKey) {
9-
console.error('API key not defined')
10-
process.exit(1)
11-
}
8+
function createClient() {
9+
if (!process.env['API_KEY']) {
10+
throw new Error('Missing required API_KEY env variable!')
11+
}
1212

13-
let region = Region.Global
14-
if (envRegion === 'eu') {
15-
region = Region.EU
16-
} else if (envRegion === 'ap') {
17-
region = Region.AP
13+
return new FingerprintJsServerApiClient({ region, apiKey: process.env.API_KEY })
1814
}
1915

20-
const end = Date.now()
21-
const start = end - 90 * 24 * 60 * 60 * 1000
16+
async function getRecentEvents(client, start, end) {
17+
console.log('Retrieving recent 2 events...')
18+
const recent = await client.searchEvents({ limit: 2, start, end })
19+
if (!recent?.events?.length) {
20+
throw new Error('searchEvents returned no recent events')
21+
}
2222

23-
const client = new FingerprintJsServerApiClient({ region, apiKey })
24-
let visitorId, requestId
23+
const paginationKey = recent.pagination_key
24+
if (paginationKey) {
25+
console.log('Retrieving next page...')
26+
const page2 = await client.searchEvents({ limit: 2, start, end, pagination_key: paginationKey })
27+
if (!page2?.events?.length) {
28+
throw new Error('searchEvents page 2 returned no events')
29+
}
30+
}
2531

26-
// test search events
27-
try {
28-
const searchEventsResponse = await client.searchEvents({ limit: 2, start, end })
29-
if (searchEventsResponse.events.length === 0) {
30-
console.log('FingerprintJsServerApiClient.searchEvents: is empty')
31-
process.exit(1)
32+
return recent
33+
}
34+
35+
async function fetchEventAndVisitorDetails(client, firstEvent) {
36+
const identification = firstEvent?.products?.identification?.data
37+
const { visitorId, requestId } = identification
38+
if (!requestId || !visitorId) {
39+
throw new Error('Event missing requestId or visitorId')
3240
}
33-
const firstEvent = searchEventsResponse.events[0]
34-
visitorId = firstEvent.products.identification.data.visitorId
35-
requestId = firstEvent.products.identification.data.requestId
36-
37-
console.log(JSON.stringify(searchEventsResponse, null, 2))
38-
const searchEventsResponseSecondPage = await client.searchEvents({
39-
limit: 2,
40-
start,
41-
end,
42-
pagination_key: firstEvent.pagination_key,
43-
})
44-
if (searchEventsResponseSecondPage.events.length === 0) {
45-
console.log('Second page of FingerprintJsServerApiClient.searchEvents: is empty')
46-
process.exit(1)
41+
42+
console.log(`Retrieving event detail by requestId \`${requestId}\`...`)
43+
await client.getEvent(requestId)
44+
45+
console.log(`Retrieving visitor detail by visitorId \`${visitorId}\`...`)
46+
await client.getVisits(visitorId, { limit: 10 })
47+
}
48+
49+
async function validateOldestOrder(client, start, end) {
50+
console.log('Retrieving old 2 events...')
51+
const old = await client.searchEvents({ limit: 2, start, end, reverse: true })
52+
if (!old?.events || old.events.length < 2) {
53+
throw new Error('searchEvents returned less than 2 events')
4754
}
48-
} catch (error) {
49-
if (error instanceof RequestError) {
50-
console.log(`error ${error.statusCode}: `, error.message)
51-
// You can also access the raw response
52-
console.log(error.response.statusText)
53-
} else {
54-
console.log('unknown error: ', error)
55+
56+
const [a, b] = old.events
57+
const ts1 = a?.products?.identification?.data?.timestamp
58+
const ts2 = b?.products?.identification?.data?.timestamp
59+
if (typeof ts1 !== 'number' || typeof ts2 !== 'number') {
60+
throw new Error('Old events missing identification.data.timestamp')
5561
}
56-
process.exit(1)
57-
}
5862

59-
// Test getEvent
60-
try {
61-
const event = await client.getEvent(requestId)
62-
console.log(JSON.stringify(event, null, 2))
63-
} catch (error) {
64-
if (error instanceof RequestError) {
65-
console.log(`error ${error.statusCode}: `, error.message)
66-
// You can also access the raw response
67-
console.log(error.response.statusText)
68-
} else {
69-
console.log('unknown error: ', error)
63+
if (ts1 > ts2) {
64+
throw new Error(`Oldest event timestamp is bigger than second oldest event: ${ts1} > ${ts2}`)
7065
}
71-
process.exit(1)
7266
}
7367

74-
// Test getVisits
75-
try {
76-
const visitorHistory = await client.getVisits(visitorId, { limit: 10 })
77-
console.log(JSON.stringify(visitorHistory, null, 2))
78-
} catch (error) {
79-
if (error instanceof RequestError) {
80-
console.log(error.statusCode, error.message)
68+
async function main() {
69+
try {
70+
const client = createClient()
71+
const end = Date.now()
72+
const start = end - 90 * 24 * 60 * 60 * 1000
73+
74+
const recent = await getRecentEvents(client, start, end)
75+
const [firstEvent] = recent.events
76+
await fetchEventAndVisitorDetails(client, firstEvent)
77+
78+
await validateOldestOrder(client, start, end)
79+
80+
console.log('All tests passed')
81+
return 0
82+
} catch (error) {
8183
if (error instanceof TooManyRequestsError) {
82-
retryLater(error.retryAfter) // Needs to be implemented on your side
84+
console.error(`[TooManyRequestsError]: Rate limited. Retry after: ${error.retryAfter}s`)
85+
return 1
8386
}
84-
} else {
85-
console.error('unknown error: ', error)
86-
}
87-
process.exit(1)
88-
}
8987

90-
// Check that old events are still match expected format
91-
try {
92-
const searchEventsResponseOld = await client.searchEvents({ limit: 2, start, end, reverse: true })
93-
if (searchEventsResponseOld.events.length === 0) {
94-
console.log('FingerprintJsServerApiClient.searchEvents: is empty for old events')
95-
process.exit(1)
96-
}
97-
const oldEventIdentificationData = searchEventsResponseOld.events[0].products.identification.data
98-
const visitorIdOld = oldEventIdentificationData.visitorId
99-
const requestIdOld = oldEventIdentificationData.requestId
88+
if (error instanceof RequestError) {
89+
console.error(`[RequestError] ${error.statusCode}: ${error.message}`)
90+
if (error.response) {
91+
console.error(`[RequestError] ${error.response.statusText}`)
92+
}
93+
return 1
94+
}
10095

101-
if (visitorId === visitorIdOld || requestId === requestIdOld) {
102-
console.log('Old events are identical to new')
103-
process.exit(1)
96+
console.error(error?.stack ?? error)
97+
return 1
10498
}
105-
await client.getEvent(requestIdOld)
106-
await client.getVisits(visitorIdOld)
107-
console.log('Old events are good')
108-
} catch (error) {
109-
if (error instanceof RequestError) {
110-
console.log(`error ${error.statusCode}: `, error.message)
111-
// You can also access the raw response
112-
console.log(error.response.statusText)
113-
} else {
114-
console.log('unknown error: ', error)
115-
}
116-
process.exit(1)
11799
}
100+
101+
process.exitCode = await main()

0 commit comments

Comments
 (0)