Skip to content

Commit

Permalink
fix(fromOpenApi): remove extra whitespace from content type (#62)
Browse files Browse the repository at this point in the history
Co-authored-by: Kiskae <[email protected]>
Co-authored-by: Artem Zakharchenko <[email protected]>
  • Loading branch information
3 people committed Aug 30, 2024
1 parent adaa00f commit 02157b5
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 9 deletions.
48 changes: 48 additions & 0 deletions src/open-api/utils/open-api-utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { getAcceptedContentTypes } from './open-api-utils.js'

it('returns a single content type as-is', () => {
expect(
getAcceptedContentTypes(new Headers([['accept', 'text/html']])),
).toEqual(['text/html'])
})

it('ignores whitespace separating multiple content types', () => {
expect(
getAcceptedContentTypes(
new Headers([['accept', 'text/html, application/xhtml+xml, */*']]),
),
).toEqual(['text/html', 'application/xhtml+xml', '*/*'])
})

it('removes an empty content type', () => {
expect(getAcceptedContentTypes(new Headers([['accept', ', ,']]))).toEqual([])

expect(
getAcceptedContentTypes(new Headers([['accept', 'text/html, , */*']])),
).toEqual(['text/html', '*/*'])
})

describe.skip('complex "accept" headers', () => {
it('supports weight reordering', () => {
expect(
getAcceptedContentTypes(
new Headers([
[
'accept',
'text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c',
],
]),
),
).toEqual(['text/html', 'text/x-c', 'text/x-dvi', 'text/plain'])
})

it('supports specificity reordering', () => {
expect(
getAcceptedContentTypes(
new Headers([
['accept', 'text/*, text/plain, text/plain;format=flowed, */*'],
]),
),
).toEqual(['text/plain;format=flowed', 'text/plain', 'text/*', '*/*'])
})
})
18 changes: 10 additions & 8 deletions src/open-api/utils/open-api-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,7 @@ export function toHeaders(
}

// See what "Content-Type" the request accepts.
const accept = request.headers.get('accept') || ''
const acceptedContentTypes = accept
.split(',')
.filter((item) => item.length !== 0)
const acceptedContentTypes = getAcceptedContentTypes(request.headers)

const responseContentTypes = Object.keys(content)

Expand Down Expand Up @@ -164,10 +161,7 @@ export function toBody(
}

// See what "Content-Type" the request accepts.
const accept = request.headers.get('accept') || ''
const acceptedContentTypes = accept
.split(',')
.filter((item) => item.length !== 0)
const acceptedContentTypes = getAcceptedContentTypes(request.headers)

let mediaTypeObject: OpenAPIV3.MediaTypeObject | undefined
const responseContentTypes = Object.keys(content)
Expand Down Expand Up @@ -263,6 +257,14 @@ export function toBody(
return null
}

export function getAcceptedContentTypes(headers: Headers): string[] {
const accept = headers.get('accept') || ''
return accept
.split(',')
.map((item) => item.trim())
.filter((item) => item.length !== 0)
}

function contentTypeToRegExp(contentType: string): RegExp {
return new RegExp(contentType.replace(/\/+/g, '\\/').replace(/\*/g, '.+?'))
}
19 changes: 19 additions & 0 deletions test/oas/oas-json-schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,4 +272,23 @@ it('respects the "Accept" request header', async () => {
},
}),
)

// Skip content-types if the schema does not contain
// a matching response.
await expect(
await withHandlers(handlers, () => {
return fetch('http://localhost/user', {
headers: {
Accept: 'text/html, application/json',
},
})
}),
).toEqualResponse(
new Response(JSON.stringify({ id: 'user-1' }), {
status: 200,
headers: {
'Content-Type': 'application/json',
},
}),
)
})
6 changes: 5 additions & 1 deletion vitest.workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ export default defineWorkspace([
{
test: {
name: 'node',
include: ['!**/*.browser.test.ts', 'test/**/*.test.ts'],
include: [
'!**/*.browser.test.ts',
'test/**/*.test.ts',
'src/**/*.test.ts',
],
globals: true,
setupFiles: ['./vitest.setup.ts'],
environment: 'node',
Expand Down

0 comments on commit 02157b5

Please sign in to comment.