Skip to content

Commit e3e3820

Browse files
committed
Improve types and add happy path test
1 parent 1c46058 commit e3e3820

2 files changed

Lines changed: 53 additions & 24 deletions

File tree

packages/app/backend-http-client/src/client/httpClient.spec.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,50 @@ describe('httpClient', () => {
639639
}
640640
]`)
641641
})
642+
643+
it('validates response structure with provided schema, passes validation', async () => {
644+
const schema = z.object({
645+
category: z.string(),
646+
description: z.string(),
647+
id: z.number(),
648+
image: z.string(),
649+
price: z.number(),
650+
rating: z.object({
651+
count: z.number(),
652+
rate: z.number(),
653+
}),
654+
title: z.string(),
655+
})
656+
657+
const apiContract = buildPayloadRoute({
658+
successResponseBodySchema: schema,
659+
requestPathParamsSchema: z.undefined(),
660+
method: 'post',
661+
requestBodySchema: z.undefined(),
662+
pathResolver: () => '/products/1',
663+
})
664+
665+
client
666+
.intercept({
667+
path: '/products/1',
668+
method: 'POST',
669+
})
670+
.reply(200, mockProduct1, { headers: JSON_HEADERS })
671+
672+
const result = await sendByPayloadRoute(
673+
client,
674+
apiContract,
675+
{},
676+
{
677+
validateResponse: true,
678+
throwOnError: true,
679+
requestLabel: 'dummy',
680+
reqContext,
681+
},
682+
)
683+
684+
expect(result.result.body).toEqual(mockProduct1)
685+
})
642686
})
643687

644688
describe('POST', () => {

packages/app/backend-http-client/src/client/httpClient.ts

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ export function sendByPayloadRoute<
358358
RequestHeaderSchema extends z.Schema | undefined = undefined,
359359
IsNonJSONResponseExpected extends boolean = false,
360360
IsEmptyResponseExpected extends boolean = false,
361+
DoThrowOnError extends boolean = DEFAULT_THROW_ON_ERROR,
361362
>(
362363
client: Client,
363364
routeDefinition: PayloadRouteDefinition<
@@ -377,10 +378,16 @@ export function sendByPayloadRoute<
377378
InferSchemaInput<RequestHeaderSchema>
378379
>,
379380
options: Omit<
380-
RequestOptions<InferSchemaOutput<ResponseBodySchema>, IsEmptyResponseExpected, boolean>,
381+
RequestOptions<InferSchemaOutput<ResponseBodySchema>, IsEmptyResponseExpected, DoThrowOnError>,
381382
'body' | 'headers' | 'query' | 'isEmptyResponseExpected' | 'responseSchema'
382383
>,
383-
) {
384+
): Promise<
385+
RequestResultDefinitiveEither<
386+
InferSchemaOutput<ResponseBodySchema>,
387+
IsEmptyResponseExpected,
388+
DoThrowOnError
389+
>
390+
> {
384391
return sendResourceChange(
385392
client,
386393
// @ts-expect-error TS loses exact string type during uppercasing
@@ -399,28 +406,6 @@ export function sendByPayloadRoute<
399406
...options,
400407
},
401408
)
402-
403-
/**
404-
* {
405-
* // @ts-expect-error magic type inferring happening
406-
* body: params.body,
407-
* isEmptyResponseExpected: routeDefinition.isEmptyResponseExpected,
408-
* isNonJSONResponseExpected: routeDefinition.isNonJSONResponseExpected,
409-
* // biome-ignore lint/suspicious/noExplicitAny: FixMe try to find a solution
410-
* requestBodySchema: routeDefinition.requestBodySchema as any,
411-
* // biome-ignore lint/suspicious/noExplicitAny: FixMe try to find a solution
412-
* responseBodySchema: routeDefinition.successResponseBodySchema as any,
413-
* // @ts-expect-error magic type inferring happening
414-
* queryParams: params.queryParams,
415-
* queryParamsSchema: routeDefinition.requestQuerySchema,
416-
* // @ts-expect-error magic type inferring happening
417-
* path: routeDefinition.pathResolver(params.pathParams),
418-
* // @ts-expect-error FixMe
419-
* headers: params.headers,
420-
* // @ts-expect-error magic type inferring happening
421-
* headersSchema: params.headersSchema,
422-
* }
423-
*/
424409
}
425410

426411
export const httpClient = {

0 commit comments

Comments
 (0)