mirror of
https://github.com/supabase/supabase.git
synced 2026-09-22 13:37:53 +08:00
171 lines
4.9 KiB
TypeScript
171 lines
4.9 KiB
TypeScript
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
vi.mock('~/lib/logger', async () => {
|
|
const actual = await vi.importActual<typeof import('~/lib/logger')>('~/lib/logger')
|
|
return {
|
|
...actual,
|
|
sendToLogflare: vi.fn(),
|
|
}
|
|
})
|
|
|
|
import { GET, POST } from './route'
|
|
|
|
describe('/api/graphql POST basic error statuses', () => {
|
|
beforeAll(() => {
|
|
vi.spyOn(console, 'error').mockImplementation(() => {})
|
|
})
|
|
|
|
afterAll(() => {
|
|
vi.restoreAllMocks()
|
|
})
|
|
|
|
beforeEach(() => {
|
|
vi.spyOn(console, 'error').mockImplementation(() => {})
|
|
})
|
|
|
|
it('should return error if request body is not valid JSON', async () => {
|
|
const request = new Request('http://localhost/api/graphql', {
|
|
method: 'POST',
|
|
body: 'not json',
|
|
})
|
|
|
|
const response = await POST(request)
|
|
const json = await response.json()
|
|
expect(json.errors[0].message).toBe('Invalid request: Request body must be valid JSON')
|
|
})
|
|
|
|
it('should return error if request body is missing required fields', async () => {
|
|
const request = new Request('http://localhost/api/graphql', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ variables: {} }),
|
|
})
|
|
|
|
const response = await POST(request)
|
|
const json = await response.json()
|
|
expect(json.errors[0].message).toContain(
|
|
'Invalid request: GraphQL request payload must be valid GraphQL request object'
|
|
)
|
|
})
|
|
|
|
it('should return error if query is not a string', async () => {
|
|
const request = new Request('http://localhost/api/graphql', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ query: 123 }),
|
|
})
|
|
|
|
const response = await POST(request)
|
|
const json = await response.json()
|
|
expect(json.errors[0].message).toContain(
|
|
'Invalid request: GraphQL request payload must be valid GraphQL request object'
|
|
)
|
|
})
|
|
|
|
it('should return error for internal server errors', async () => {
|
|
const request = new Request('http://localhost/api/graphql', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ query: 'query { hello }' }),
|
|
})
|
|
|
|
vi.spyOn(request, 'json').mockImplementation(() => {
|
|
throw new Error('Unexpected error')
|
|
})
|
|
|
|
const response = await POST(request)
|
|
const json = await response.json()
|
|
expect(json.errors[0].message).toBe('Internal Server Error')
|
|
})
|
|
})
|
|
|
|
describe('/api/graphql schema snapshot', () => {
|
|
it('should match snapshot', async () => {
|
|
const schemaQuery = `
|
|
query {
|
|
schema
|
|
}
|
|
`
|
|
const request = new Request('http://localhost/api/graphql', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ query: schemaQuery }),
|
|
})
|
|
|
|
const response = await POST(request)
|
|
const json = await response.json()
|
|
expect(json.errors).toBeUndefined()
|
|
|
|
const {
|
|
data: { schema },
|
|
} = json
|
|
expect(schema).toMatchSnapshot()
|
|
})
|
|
})
|
|
|
|
describe('/api/graphql GET support', () => {
|
|
beforeAll(() => {
|
|
vi.spyOn(console, 'error').mockImplementation(() => {})
|
|
})
|
|
|
|
afterAll(() => {
|
|
vi.restoreAllMocks()
|
|
})
|
|
|
|
it('should return error if query parameter is missing', async () => {
|
|
const request = new Request('http://localhost/api/graphql', {
|
|
method: 'GET',
|
|
})
|
|
|
|
const response = await GET(request)
|
|
const json = await response.json()
|
|
expect(json.errors[0].message).toContain(
|
|
'Invalid request: GraphQL request payload must be valid GraphQL request object'
|
|
)
|
|
})
|
|
|
|
it('should return error if variables parameter is not valid JSON', async () => {
|
|
const url = new URL('http://localhost/api/graphql')
|
|
url.searchParams.set('query', '{ schema }')
|
|
url.searchParams.set('variables', '{not json}')
|
|
const request = new Request(url, {
|
|
method: 'GET',
|
|
})
|
|
|
|
const response = await GET(request)
|
|
const json = await response.json()
|
|
expect(json.errors[0].message).toBe(
|
|
'Invalid request: Variables query parameter must be valid JSON'
|
|
)
|
|
})
|
|
|
|
it('should not allow mutations on GET requests', async () => {
|
|
const url = new URL('http://localhost/api/graphql')
|
|
url.searchParams.set('query', 'mutation { __typename }')
|
|
const request = new Request(url, {
|
|
method: 'GET',
|
|
})
|
|
|
|
const response = await GET(request)
|
|
const json = await response.json()
|
|
expect(
|
|
json.errors.some((error: { message: string }) =>
|
|
error.message.includes('GET requests may only execute query operations')
|
|
)
|
|
).toBe(true)
|
|
})
|
|
|
|
it('should return schema via GET and set cache headers', async () => {
|
|
const schemaQuery = 'query { schema }'
|
|
const url = new URL('http://localhost/api/graphql')
|
|
url.searchParams.set('query', schemaQuery)
|
|
const request = new Request(url, {
|
|
method: 'GET',
|
|
})
|
|
|
|
const response = await GET(request)
|
|
const json = await response.json()
|
|
expect(json.errors).toBeUndefined()
|
|
|
|
const cacheControl = response.headers.get('Cache-Control')
|
|
expect(cacheControl).toBe('public, s-maxage=3600, stale-while-revalidate=300')
|
|
expect(json.data.schema).toBeDefined()
|
|
})
|
|
})
|