Skip to content

Commit

Permalink
fix: provide all request headers (#370)
Browse files Browse the repository at this point in the history
  • Loading branch information
AuHau authored Jul 21, 2021
1 parent 6f227e1 commit 5b4c94b
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 5 deletions.
9 changes: 6 additions & 3 deletions src/utils/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ type HookCallback<V> = (value: V) => V | Promise<V>
function wrapRequest(request: AxiosRequestConfig): BeeRequest {
let headers = request.headers

// For request interceptor, axios returns wrapped headers split based on methods
// which needs to be joined. This is not case for response interceptor's config property which has headers already "flat".
// For request interceptor, axios returns also default headers in the object that needs to be joined based on HTTP method
// and the default headers removed
if (headers.common && headers.get && headers.delete && headers.post && headers.patch) {
headers = Object.assign({}, request.headers.common ?? {}, request.headers[request.method as HttpMethod] ?? {})
// Filters out the default headers properties
const { common: _1, get: _2, delete: _3, post: _4, patch: _5, head: _6, put: _7, ...rest } = headers

headers = Object.assign({}, request.headers.common ?? {}, request.headers[request.method as HttpMethod] ?? {}, rest)
}

return {
Expand Down
28 changes: 28 additions & 0 deletions test/unit/nock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const MOCK_SERVER_URL = 'http://localhost:12345/'

// Endpoints
const FEED_ENDPOINT = '/feeds'
const BZZ_ENDPOINT = '/bzz'
const BYTES_ENDPOINT = '/bytes'
const POSTAGE_ENDPOINT = '/stamps'
const CHEQUEBOOK_ENDPOINT = '/chequebook'
Expand All @@ -29,6 +30,33 @@ export function downloadDataMock(reference: Reference | string): nock.Intercepto
return nock(MOCK_SERVER_URL).get(`${BYTES_ENDPOINT}/${reference}`)
}

interface UploadOptions {
name?: string
tag?: number
pin?: boolean
encrypt?: boolean
collection?: boolean
indexDocument?: string
errorDocument?: string
}

function camelCaseToDashCase(str: string) {
return str.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`)
}

export function uploadFileMock(batchId: string, name?: string, options?: UploadOptions): nock.Interceptor {
// Prefixes the options with `swarm-` so the object can be used for required headers
const headers = Object.entries(options || {}).reduce<Record<string, string>>((prev, curr) => {
prev[`swarm-${camelCaseToDashCase(curr[0])}`] = curr[1]

return prev
}, {})

return nock(MOCK_SERVER_URL, { reqheaders: { 'swarm-postage-batch-id': batchId, ...headers } })
.post(`${BZZ_ENDPOINT}`)
.query({ name })
}

export function createPostageBatchMock(
amount: string,
depth: string,
Expand Down
65 changes: 63 additions & 2 deletions test/unit/utils/hooks.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { assertAllIsDone, downloadDataMock, fetchFeedUpdateMock, MOCK_SERVER_URL } from '../nock'
import { testChunkHash, testIdentity, testJsonHash } from '../../utils'
import { assertAllIsDone, downloadDataMock, fetchFeedUpdateMock, MOCK_SERVER_URL, uploadFileMock } from '../nock'
import { testBatchId, testChunkHash, testIdentity, testJsonHash } from '../../utils'
import { Bee, ReferenceResponse } from '../../../src'
import * as hooks from '../../../src/utils/hooks'

Expand Down Expand Up @@ -115,4 +115,65 @@ describe('hooks', () => {

assertAllIsDone()
})

it('should call with request with correct headers', async () => {
const bee = new Bee(MOCK_SERVER_URL)

uploadFileMock(testBatchId, 'nice.txt', { encrypt: true }).reply(200, {
reference: testJsonHash,
} as ReferenceResponse)

const requestSpy = jest.fn()
const responseSpy = jest.fn()
hooks.onRequest(requestSpy)
hooks.onResponse(responseSpy)

const reference = await bee.uploadFile(testBatchId, 'hello world', 'nice.txt', { encrypt: true })

expect(reference).toEqual(testJsonHash)

expect(requestSpy.mock.calls.length).toEqual(1)
expect(requestSpy.mock.calls[0].length).toEqual(1)
expect(requestSpy.mock.calls[0][0]).toEqual({
url: `${MOCK_SERVER_URL}bzz`,
method: 'post',
data: new Uint8Array([104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]),
params: { name: 'nice.txt' },
headers: {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/x-www-form-urlencoded',
'swarm-encrypt': 'true',
'swarm-postage-batch-id': testBatchId,
},
})

expect(responseSpy.mock.calls.length).toEqual(1)
expect(responseSpy.mock.calls[0].length).toEqual(1)
expect(responseSpy.mock.calls[0][0]).toEqual({
status: 200,
statusText: null,
headers: {
'content-type': 'application/json',
},
data: {
reference: testJsonHash,
},
request: {
url: `${MOCK_SERVER_URL}bzz`,
method: 'post',
data: new ArrayBuffer(0),
params: { name: 'nice.txt' },
headers: {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'axios/0.21.1',
'Content-Length': 11,
'swarm-encrypt': 'true',
'swarm-postage-batch-id': testBatchId,
},
},
})

assertAllIsDone()
})
})

0 comments on commit 5b4c94b

Please sign in to comment.