Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(dandi/http-model): add
@RequestHeader
decorator to allow injec…
…ting individual request headers closes #56
- Loading branch information
1 parent
d0f5b8e
commit 3ed6434
Showing
3 changed files
with
87 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
packages/dandi/http-model/src/request-header.decorator.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { OpinionatedToken } from '@dandi/core' | ||
import { getInjectableParamMetadata, methodTarget, ParamMetadata } from '@dandi/core/internal/util' | ||
import { testHarness } from '@dandi/core/testing' | ||
import { | ||
createHttpRequestScope, | ||
HttpHeader, | ||
HttpRequest, | ||
HttpRequestHeadersAccessor, | ||
HttpRequestHeadersHashAccessor, | ||
MimeType, | ||
requestHeaderToken, | ||
} from '@dandi/http' | ||
|
||
import { expect } from 'chai' | ||
|
||
import { RequestHeader } from './request-header.decorator' | ||
|
||
describe('@RequestHeader', () => { | ||
class TestController { | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
public testHeader(@RequestHeader(HttpHeader.contentType) contentType: any): any {} | ||
} | ||
|
||
const harness = testHarness() | ||
|
||
let meta: ParamMetadata<any> | ||
|
||
beforeEach(() => { | ||
meta = getInjectableParamMetadata(methodTarget(TestController), 'testHeader', 0) | ||
}) | ||
afterEach(() => { | ||
meta = undefined | ||
}) | ||
|
||
it('sets a token for the specified header', async () => { | ||
expect(meta).to.exist | ||
expect(meta.token).to.exist | ||
expect(meta.token).to.be.instanceOf(OpinionatedToken) | ||
expect(meta.token).to.equal(requestHeaderToken(HttpHeader.contentType)) | ||
}) | ||
|
||
it('creates a provider to handle injecting the header value', async () => { | ||
|
||
harness.register(...meta.providers, { | ||
provide: HttpRequestHeadersAccessor, | ||
useValue: HttpRequestHeadersHashAccessor.fromRaw({ | ||
[HttpHeader.contentType]: MimeType.applicationJson, | ||
}), | ||
}) | ||
const injector = harness.createChild(createHttpRequestScope({} as HttpRequest)) | ||
|
||
expect(await injector.inject(requestHeaderToken(HttpHeader.contentType))).to.deep.equal({ contentType: MimeType.applicationJson }) | ||
|
||
}) | ||
|
||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { MethodTarget } from '@dandi/common' | ||
import { getInjectableParamMetadata, ParamMetadata } from '@dandi/core/internal/util' | ||
import { | ||
HttpRequestHeader, HttpRequestHeaders, | ||
requestHeaderProvider, | ||
requestHeaderToken, | ||
} from '@dandi/http' | ||
|
||
export interface RequestHeader<THeaderName extends HttpRequestHeader> extends ParamMetadata<HttpRequestHeaders[THeaderName]> { | ||
headerName: THeaderName | ||
} | ||
|
||
export function requestHeaderDecorator<THeaderName extends HttpRequestHeader>( | ||
header: RequestHeader<THeaderName>, | ||
target: MethodTarget<HttpRequestHeaders[THeaderName]>, | ||
propertyName: string, | ||
paramIndex: number, | ||
): void { | ||
const meta = getInjectableParamMetadata<HttpRequestHeaders[THeaderName], RequestHeader<THeaderName>>(target, propertyName, paramIndex) | ||
meta.token = requestHeaderToken<THeaderName>(header.headerName) | ||
meta.providers = [requestHeaderProvider(header.headerName)] | ||
} | ||
|
||
export function RequestHeader<THeaderName extends HttpRequestHeader, TTarget>(headerName: THeaderName): ParameterDecorator { | ||
return requestHeaderDecorator.bind(null, { headerName }) | ||
} |