gin/problem_test.go
Miguel Quintero 7b9d081d7c feat(render): add RFC 9457 problem details JSON response support
Add first-class support for RFC 9457 "Problem Details for HTTP APIs"
error responses in JSON format:

- gin.Problem type with the standard members (type, title, status,
  detail, instance) and extension members serialized at the top level
- render.ProblemJSON renderer setting Content-Type to
  "application/problem+json; charset=utf-8"
- Context.ProblemJSON and Context.AbortWithProblemJSON helpers; when
  given a gin.Problem, a zero Status defaults to the response code and
  an empty Title defaults to http.StatusText

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 16:10:11 -04:00

62 lines
1.6 KiB
Go

// Copyright 2026 Gin Core Team. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package gin
import (
"testing"
"github.com/gin-gonic/gin/codec/json"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestProblemMarshalJSON(t *testing.T) {
p := Problem{
Type: "https://example.com/probs/out-of-credit",
Title: "You do not have enough credit.",
Status: 403,
Detail: "Your current balance is 30, but that costs 50.",
Instance: "/account/12345/msgs/abc",
}
jsonBytes, err := json.API.Marshal(p)
require.NoError(t, err)
assert.JSONEq(t, `{
"type": "https://example.com/probs/out-of-credit",
"title": "You do not have enough credit.",
"status": 403,
"detail": "Your current balance is 30, but that costs 50.",
"instance": "/account/12345/msgs/abc"
}`, string(jsonBytes))
}
func TestProblemMarshalJSONOmitsEmptyMembers(t *testing.T) {
jsonBytes, err := json.API.Marshal(Problem{Status: 404})
require.NoError(t, err)
assert.JSONEq(t, `{"status":404}`, string(jsonBytes))
}
func TestProblemMarshalJSONExtensions(t *testing.T) {
p := Problem{
Status: 403,
Detail: "Your current balance is 30, but that costs 50.",
Extensions: map[string]any{
"balance": 30,
"status": "extension members must not override standard members",
},
}
jsonBytes, err := json.API.Marshal(p)
require.NoError(t, err)
assert.JSONEq(t, `{
"status": 403,
"detail": "Your current balance is 30, but that costs 50.",
"balance": 30
}`, string(jsonBytes))
}