Skip to content

Commit

Permalink
Merge pull request #197 from fingerprintjs/rc
Browse files Browse the repository at this point in the history
Release v1.2.4-rc.1
  • Loading branch information
ilfa authored Dec 13, 2023
2 parents dbb73fb + cfe8bfe commit 3c3e8b4
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 69 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/create-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ jobs:
name: Create PR
uses: fingerprintjs/dx-team-toolkit/.github/workflows/create-pr.yml@v1
with:
target_branch: ${{ github.event.release.prerelease && 'main' || 'test' }}
target_branch: ${{ github.event.release.prerelease && 'main' || 'rc' }}
tag_name: ${{ github.event.release.tag_name }}
prerelease: ${{ github.event.release.prerelease }}
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:
branches:
- main
- test
- rc

jobs:
build-and-release:
Expand Down
2 changes: 1 addition & 1 deletion .releaserc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"branches": [
"main",
{
"name": "test",
"name": "rc",
"prerelease": true
}
],
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## [1.2.4-rc.1](https://github.com/fingerprintjs/fingerprint-pro-azure-integration/compare/v1.2.3...v1.2.4-rc.1) (2023-12-13)


### Bug Fixes

* improve endpoint creation ([dd84407](https://github.com/fingerprintjs/fingerprint-pro-azure-integration/commit/dd84407f10cb4a010c3cfc73b02ae41e95d086e5))

## [1.2.3](https://github.com/fingerprintjs/fingerprint-pro-azure-integration/compare/v1.2.2...v1.2.3) (2023-12-01)


Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fingerprintjs/fingerprint-pro-azure-integration",
"version": "1.2.3",
"version": "1.2.4-rc.1",
"license": "MIT",
"sideEffects": false,
"private": true,
Expand Down
14 changes: 14 additions & 0 deletions proxy/handlers/agent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,20 @@ describe('Agent Endpoint', () => {
)
})

test('invalid apiKey, version and loaderVersion', async () => {
const req = mockRequestGet('https://fp.domain.com', 'fpjs/agent', {
apiKey: 'foo.bar/baz',
version: 'foo.bar1/baz',
loaderVersion: 'foo.bar2/baz',
})

await proxy(mockContext(req), req)

const [url] = requestSpy.mock.calls[0]

expect(url.origin).toEqual(`https://${origin}`)
})

test('Browser cache set to an hour when original value is higher', async () => {
const req = mockRequestGet('https://fp.domain.com', 'fpjs/agent', {
apiKey: 'ujKG34hUYKLJKJ1F',
Expand Down
216 changes: 153 additions & 63 deletions proxy/handlers/ingress.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,49 @@ import { Socket } from 'net'
import { CustomerVariableType } from '../../shared/customer-variables/types'
import { EventEmitter } from 'events'
import { mockContext, mockRequestGet, mockRequestPost } from '../../shared/test/azure'
import { Region } from '../utils/region'

describe('Result Endpoint', function () {
let requestSpy: jest.MockInstance<ClientRequest, any>
const origin: string = 'https://__ingress_api__'
const mockSuccessfulResponse = ({
checkRequestUrl,
responseHeaders = {},
}: {
checkRequestUrl: (url: URL) => void
responseHeaders?: Record<string, string>
}) => {
requestSpy.mockImplementationOnce((...args: any[]): any => {
const [url, , callback] = args

checkRequestUrl(url)

const response = new EventEmitter()
const request = new EventEmitter()

Object.assign(response, {
headers: responseHeaders,
})

Object.assign(request, {
end: jest.fn(),
write: jest.fn(),
})

callback(response)

setTimeout(() => {
response.emit('data', Buffer.from('data', 'utf-8'))
response.emit('end')
}, 10)

return request
})
}

const getOrigin = (region?: string) => (region ? `https://${region}.__ingress_api__` : 'https://__ingress_api__')
const defaultOrigin: string = getOrigin()
const search: string = '?ii=fingerprint-pro-azure%2F__azure_function_version__%2Fingress'
const getSearchWithRegion = (region: string) => `?region=${region}&${search.replace('?', '')}`

beforeAll(() => {
jest.spyOn(ingress, 'handleIngress')
Expand All @@ -29,7 +67,7 @@ describe('Result Endpoint', function () {
const req = mockRequestGet('https://fp.domain.com', 'fpjs/resultId')
requestSpy.mockImplementationOnce((...args) => {
const [url, options] = args
expect(url.toString()).toBe(`${origin}/${search}`)
expect(url.toString()).toBe(`${defaultOrigin}/${search}`)
options.agent = new Agent()
return Reflect.construct(ClientRequest, args)
})
Expand All @@ -46,13 +84,14 @@ describe('Result Endpoint', function () {
[CustomerVariableType.PreSharedSecret]: 'secret',
})

const req = mockRequestGet('https://fp.domain.com', 'fpjs/resultId')
requestSpy.mockImplementationOnce((...args) => {
const [url, options] = args
expect(url.toString()).toBe(`${origin}/${search}`)
options.agent = new Agent()
return Reflect.construct(ClientRequest, args)
mockSuccessfulResponse({
checkRequestUrl: (url) => {
expect(url.toString()).toBe(`${defaultOrigin}/${search}`)
},
})

const req = mockRequestGet('https://fp.domain.com', 'fpjs/resultId')

await proxy(mockContext(req), req)

const [, options] = requestSpy.mock.calls[0]
Expand All @@ -62,12 +101,13 @@ describe('Result Endpoint', function () {

test('Cookies should include only _iidt', async () => {
const req = mockRequestGet('https://fp.domain.com', 'fpjs/resultId')
requestSpy.mockImplementationOnce((...args) => {
const [url, options] = args
expect(url.toString()).toBe(`${origin}/${search}`)
options.agent = new Agent()
return Reflect.construct(ClientRequest, args)

mockSuccessfulResponse({
checkRequestUrl: (url) => {
expect(url.toString()).toBe(`${defaultOrigin}/${search}`)
},
})

await proxy(mockContext(req), req)

const [, options] = requestSpy.mock.calls[0]
Expand Down Expand Up @@ -156,36 +196,16 @@ describe('Result Endpoint', function () {
'transfer-encoding': 'chunked',
}

const resBody = 'data'
requestSpy.mockImplementationOnce((...args: any[]): any => {
const [url, , callback] = args
expect(url.toString()).toBe(`${origin}/${search}`)

const response = new EventEmitter()
const request = new EventEmitter()

Object.assign(request, {
end: jest.fn(),
write: jest.fn(),
})

Object.assign(response, {
headers: resHeaders,
})

callback(response)

setTimeout(() => {
response.emit('data', Buffer.from(resBody, 'utf-8'))
response.emit('end')
}, 10)

return request
mockSuccessfulResponse({
checkRequestUrl: (url) => {
expect(url.toString()).toBe(`${defaultOrigin}/${search}`)
},
responseHeaders: resHeaders,
})
const ctx = mockContext(req)
await proxy(ctx, req)

expect(ctx.res?.body.toString()).toBe(resBody)
expect(ctx.res?.body.toString()).toBe('data')
expect(ctx.res?.headers).toEqual({
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'Retry-After',
Expand Down Expand Up @@ -257,17 +277,17 @@ describe('Result Endpoint', function () {

test('HTTP GET without suffix', async () => {
const req = mockRequestGet('https://fp.domain.com', 'fpjs/resultId')
requestSpy.mockImplementationOnce((...args) => {
const [url, options] = args
expect(url.toString()).toBe(`${origin}/${search}`)
options.agent = new Agent()
return Reflect.construct(ClientRequest, args)
mockSuccessfulResponse({
checkRequestUrl: (url) => {
expect(url.toString()).toBe(`${defaultOrigin}/${search}`)
},
})

await proxy(mockContext(req), req)
expect(ingress.handleIngress).toHaveBeenCalledTimes(1)
expect(https.request).toHaveBeenCalledWith(
expect.objectContaining({
origin,
origin: defaultOrigin,
pathname: '/',
search,
}),
Expand All @@ -279,17 +299,16 @@ describe('Result Endpoint', function () {

test('HTTP GET with suffix', async () => {
const req = mockRequestGet('https://fp.domain.com', 'fpjs/resultId/with/suffix')
requestSpy.mockImplementationOnce((...args) => {
const [url, options] = args
expect(url.toString()).toBe(`${origin}/with/suffix${search}`)
options.agent = new Agent()
return Reflect.construct(ClientRequest, args)
mockSuccessfulResponse({
checkRequestUrl: (url) => {
expect(url.toString()).toBe(`${defaultOrigin}/with/suffix${search}`)
},
})
await proxy(mockContext(req), req)
expect(ingress.handleIngress).toHaveBeenCalledTimes(1)
expect(https.request).toHaveBeenCalledWith(
expect.objectContaining({
origin,
origin: defaultOrigin,
pathname: '/with/suffix',
search,
}),
Expand All @@ -308,17 +327,16 @@ describe('Result Endpoint', function () {

test('HTTP POST without suffix', async () => {
const req = mockRequestPost('https://fp.domain.com', 'fpjs/resultId')
requestSpy.mockImplementationOnce((...args) => {
const [url, options] = args
expect(url.toString()).toBe(`${origin}/${search}`)
options.agent = new Agent()
return Reflect.construct(ClientRequest, args)
mockSuccessfulResponse({
checkRequestUrl: (url) => {
expect(url.toString()).toBe(`${defaultOrigin}/${search}`)
},
})
await proxy(mockContext(req), req)
expect(ingress.handleIngress).toHaveBeenCalledTimes(1)
expect(https.request).toHaveBeenCalledWith(
expect.objectContaining({
origin,
origin: defaultOrigin,
pathname: '/',
search,
}),
Expand All @@ -330,17 +348,16 @@ describe('Result Endpoint', function () {

test('HTTP POST with suffix', async () => {
const req = mockRequestPost('https://fp.domain.com', 'fpjs/resultId/with/suffix')
requestSpy.mockImplementationOnce((...args) => {
const [url, options] = args
expect(url.toString()).toBe(`${origin}/with/suffix${search}`)
options.agent = new Agent()
return Reflect.construct(ClientRequest, args)
mockSuccessfulResponse({
checkRequestUrl: (url) => {
expect(url.toString()).toBe(`${defaultOrigin}/with/suffix${search}`)
},
})
await proxy(mockContext(req), req)
expect(ingress.handleIngress).toHaveBeenCalledTimes(1)
expect(https.request).toHaveBeenCalledWith(
expect.objectContaining({
origin,
origin: defaultOrigin,
pathname: '/with/suffix',
search,
}),
Expand All @@ -356,6 +373,79 @@ describe('Result Endpoint', function () {
expect(ingress.handleIngress).toHaveBeenCalledTimes(0)
expect(https.request).toHaveBeenCalledTimes(0)
})

test('Suffix with a dot', async () => {
const req = mockRequestGet('https://fp.domain.com', 'fpjs/resultId/.suffix')

mockSuccessfulResponse({
checkRequestUrl: (url) => {
expect(url.toString()).toEqual(`${defaultOrigin}/.suffix${search}`)
},
})

const ctx = mockContext(req)

await proxy(ctx, req)
})

Object.values(Region).forEach((region) => {
test(`Suffix with a dot for region ${region}`, async () => {
const req = mockRequestGet('https://fp.domain.com', 'fpjs/resultId/.suffix', {
region,
})

mockSuccessfulResponse({
checkRequestUrl: (url) => {
const expectedQuery = getSearchWithRegion(region)

if (region === Region.us) {
expect(url.toString()).toEqual(`${defaultOrigin}/.suffix${expectedQuery}`)
} else {
expect(url.toString()).toEqual(`${getOrigin(region)}/.suffix${expectedQuery}`)
}
},
})

const ctx = mockContext(req)

await proxy(ctx, req)
})
})

test('Suffix with a dot for invalid region', async () => {
const req = mockRequestGet('https://fp.domain.com', 'fpjs/resultId/.suffix', {
region: 'invalid',
})

mockSuccessfulResponse({
checkRequestUrl: (url) => {
expect(url.toString()).toEqual(`${defaultOrigin}/.suffix${getSearchWithRegion('invalid')}`)
},
})

const ctx = mockContext(req)

await proxy(ctx, req)
})

test.each(['invalid', 'usa', 'EU', 'US', 'AP', '.invalid'])(
'Should set default (US) region when invalid region is provided in query parameter: %s',
async (region) => {
const req = mockRequestGet('https://fp.domain.com', 'fpjs/resultId', {
region,
})

mockSuccessfulResponse({
checkRequestUrl: (url) => {
expect(url.toString()).toBe(`${defaultOrigin}/${getSearchWithRegion(region)}`)
},
})

const ctx = mockContext(req)

await proxy(ctx, req)
},
)
})

describe('Browser caching endpoint', () => {
Expand Down
Loading

0 comments on commit 3c3e8b4

Please sign in to comment.