Files
supabase/apps/docs/app/api/graphql/route.test.ts
Charis aba0095bd7 feat(content api): add error endpoint (#35941)
* feat(content api): add error endpoint

Add an endpoint to return the details of a Supabase error, given the
error code and service.

Schema additions:

```graphql
type RootQueryType {
  "...previous root queries"

  """Get the details of an error code returned from a Supabase service"""
  error(code: String!, service: Service!): Error
}

"""An error returned by a Supabase service"""
type Error {
  """
  The unique code identifying the error. The code is stable, and can be used for string matching during error handling.
  """
  code: String!

  """The Supabase service that returns this error."""
  service: Service!

  """The HTTP status code returned with this error."""
  httpStatusCode: Int

  """
  A human-readable message describing the error. The message is not stable, and should not be used for string matching during error handling. Use the code instead.
  """
  message: String
}

enum Service {
  AUTH
  REALTIME
  STORAGE
}
```

* test(content api): add tests for top-level query `error`
2025-05-29 15:39:47 -04:00

93 lines
2.6 KiB
TypeScript

import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
import { POST } from './route'
describe('/api/graphql basic error statuses', () => {
beforeAll(() => {
vi.spyOn(console, 'error').mockImplementation(() => {})
})
afterAll(() => {
vi.restoreAllMocks()
})
beforeEach(() => {
vi.clearAllMocks()
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: Request body 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: Request body 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()
})
})