Skip to content

Commit

Permalink
Merge pull request #195 from kafkajs/set-user-agent-header
Browse files Browse the repository at this point in the history
Send user-agent header with API requests
  • Loading branch information
Nevon authored Mar 16, 2022
2 parents 67c4285 + 036ceba commit 68c9fd5
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 2 deletions.
23 changes: 23 additions & 0 deletions src/api/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import API from '.'
import { mockClient, install, uninstall } from 'mappersmith/test'

const client = API({ clientId: 'test-client', host: 'http://example.com' })
const mock = mockClient<typeof client>(client)
.resource('Schema')
.method('find')
.with({ id: 'abc' })
.response({})
.assertObject()

describe('API Client', () => {
beforeEach(() => install())

afterEach(() => uninstall())

it('should include a user agent header', async () => {
const response = await client.Schema.find({ id: 'abc' })

expect(mock.callsCount()).toBe(1)
expect(response.request().header('User-Agent')).not.toBeUndefined()
})
})
7 changes: 5 additions & 2 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import BasicAuthMiddleware from 'mappersmith/middleware/basic-auth'
import { DEFAULT_API_CLIENT_ID } from '../constants'
import errorMiddleware from './middleware/errorMiddleware'
import confluentEncoder from './middleware/confluentEncoderMiddleware'
import userAgentMiddleware from './middleware/userAgent'

const DEFAULT_RETRY = {
maxRetryTimeInSecs: 5,
Expand Down Expand Up @@ -43,17 +44,19 @@ export type SchemaRegistryAPIClient = Client<{

export default ({
auth,
clientId,
clientId: userClientId,
host,
retry = {},
agent,
}: SchemaRegistryAPIClientArgs): SchemaRegistryAPIClient => {
const clientId = userClientId || DEFAULT_API_CLIENT_ID
// FIXME: ResourcesType typings is not exposed by mappersmith
const manifest: Options<any> = {
clientId: clientId || DEFAULT_API_CLIENT_ID,
clientId,
ignoreGlobalMiddleware: true,
host,
middleware: [
userAgentMiddleware,
confluentEncoder,
RetryMiddleware(Object.assign(DEFAULT_RETRY, retry)),
errorMiddleware,
Expand Down
53 changes: 53 additions & 0 deletions src/api/middleware/userAgent.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Request } from 'mappersmith'

import UserAgentMiddleware from './userAgent'

const middlewareParams = (clientId?: string) => ({
resourceName: 'resourceNameMock',
resourceMethod: 'resourceMethodMock',
context: { context: 'contextMock' },
clientId,
})

describe('UserAgentMiddleware', () => {
let next, request

beforeEach(() => {
request = ({
enhance: jest.fn(),
} as unknown) as jest.Mocked<Request>
next = jest.fn().mockResolvedValue(request)
})

describe('When the user has provided a clientId', () => {
const params = middlewareParams('some-client-id')

it('should add the client id as a user agent comment', async () => {
const middleware = UserAgentMiddleware(params)

await middleware.prepareRequest(next, jest.fn())

expect(request.enhance).toHaveBeenCalledWith({
headers: {
'User-Agent': `@kafkajs/confluent-schema-registry (${params.clientId})`,
},
})
})
})

describe('When the user has not provided a clientId', () => {
const params = middlewareParams()

it('should not include a comment in the user agent', async () => {
const middleware = UserAgentMiddleware(params)

await middleware.prepareRequest(next, jest.fn())

expect(request.enhance).toHaveBeenCalledWith({
headers: {
'User-Agent': `@kafkajs/confluent-schema-registry`,
},
})
})
})
})
19 changes: 19 additions & 0 deletions src/api/middleware/userAgent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Middleware } from 'mappersmith'
import { DEFAULT_API_CLIENT_ID } from '../../constants'

const product = '@kafkajs/confluent-schema-registry'

const userAgentMiddleware: Middleware = ({ clientId }) => {
const comment = clientId !== DEFAULT_API_CLIENT_ID ? clientId : undefined
const userAgent = comment ? `${product} (${comment})` : product
const headers = {
'User-Agent': userAgent,
}
return {
prepareRequest: next => {
return next().then(req => req.enhance({ headers }))
},
}
}

export default userAgentMiddleware

0 comments on commit 68c9fd5

Please sign in to comment.