Skip to content

Commit

Permalink
fix(start): Fix json() helper merging of headers, and set up unit tes…
Browse files Browse the repository at this point in the history
…ts for @tanstack/start (#2956)

* Simplify json implementation and fix headers handling

* set up tests for start package

* Fix ssr script test

* Add test for json helper

* name test script consistently

* add name and watch options to test config

* add test script

* don't override existing Content-Type header
  • Loading branch information
EskiMojo14 authored Dec 8, 2024
1 parent 58fd908 commit 85d9d79
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 20 deletions.
2 changes: 2 additions & 0 deletions packages/start/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
],
"scripts": {
"clean": "rimraf ./dist && rimraf ./coverage",
"test": "pnpm test:eslint && pnpm test:types && pnpm test:build && pnpm test:unit",
"test:unit": "vitest",
"test:eslint": "eslint ./src",
"test:types": "pnpm run \"/^test:types:ts[0-9]{2}$/\"",
"test:types:ts52": "node ../../node_modules/typescript52/lib/tsc.js",
Expand Down
20 changes: 7 additions & 13 deletions packages/start/src/client/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,15 @@ import type { JsonResponse } from './createServerFn'

export function json<TData>(
payload: TData,
opts?: {
status?: number
statusText?: string
headers?: HeadersInit
},
init?: ResponseInit,
): JsonResponse<TData> {
const status = opts?.status || 200
const statusText = opts?.statusText
const headers = new Headers(init?.headers)

if (!headers.has('Content-Type'))
headers.set('Content-Type', 'application/json')

return new Response(JSON.stringify(payload), {
status,
statusText,
headers: {
'Content-Type': 'application/json',
...opts?.headers,
},
...init,
headers,
})
}
6 changes: 1 addition & 5 deletions packages/start/src/client/tests/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,7 @@ describe('ssr scripts', () => {
const { container } = render(<RouterProvider router={router} />)

expect(container.innerHTML).toEqual(
`<script id="__TSR_DEHYDRATED__">
__TSR_DEHYDRATED__ = {
data: '{}'
}
</script><script src="script.js"></script><script src="script2.js"></script><script src="script3.js"></script>`,
`<script src="script.js"></script><script src="script2.js"></script><script src="script3.js"></script>`,
)
})
})
Expand Down
37 changes: 37 additions & 0 deletions packages/start/src/client/tests/json.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { describe, expect, it } from 'vitest'
import { json } from '../json'

describe('json', () => {
it('sets the content type to application/json and stringifies the data', async () => {
const data = { foo: 'bar' }
const response = json(data)

expect(response.headers.get('Content-Type')).toBe('application/json')

const responseClone = response.clone()
await expect(responseClone.text()).resolves.toEqual(JSON.stringify(data))

await expect(response.json()).resolves.toEqual(data)
})
it("doesn't override the content type if it's already set", () => {
const response = json(null, { headers: { 'Content-Type': 'text/plain' } })

expect(response.headers.get('Content-Type')).toBe('text/plain')
})
it('reflects passed status and statusText', () => {
const response = json(null, { status: 404, statusText: 'Not Found' })

expect(response.status).toBe(404)
expect(response.statusText).toBe('Not Found')
})
it.each<[string, HeadersInit]>([
['plain object', { 'X-TYPE': 'example' }],
['array', [['X-TYPE', 'example']]],
['Headers', new Headers({ 'X-TYPE': 'example' })],
])('merges headers from %s', (_, headers) => {
const response = json(null, { headers })

expect(response.headers.get('X-TYPE')).toBe('example')
expect(response.headers.get('Content-Type')).toBe('application/json')
})
})
10 changes: 8 additions & 2 deletions packages/start/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { defineConfig, mergeConfig } from 'vitest/config'
import { tanstackViteConfig } from '@tanstack/config/vite'
import react from '@vitejs/plugin-react'
import type { UserConfig } from 'vitest/config'
import packageJson from './package.json'
import type { ViteUserConfig } from 'vitest/config'

const config = defineConfig({
plugins: [react()] as UserConfig['plugins'],
plugins: [react()] as ViteUserConfig['plugins'],
test: {
name: packageJson.name,
watch: false,
environment: 'jsdom',
},
})

export default mergeConfig(
Expand Down

0 comments on commit 85d9d79

Please sign in to comment.