| package server |
|
|
| import ( |
| "bytes" |
| "context" |
| "encoding/json" |
| "net/http" |
| "net/http/httptest" |
| "testing" |
|
|
| "github.com/go-chi/chi/v5" |
| "github.com/stretchr/testify/require" |
|
|
| "github.com/openmeterio/openmeter/pkg/framework/commonhttp" |
| "github.com/openmeterio/openmeter/pkg/framework/transport/httptransport" |
| "github.com/openmeterio/openmeter/pkg/models" |
| ) |
|
|
| const ErrCodeSomething models.ErrorCode = "something" |
|
|
| func TestIssueIfHTTPStatusKnownErrorResponses(t *testing.T) { |
| t.Run("Should map http.StatusBadRequest to errors", func(t *testing.T) { |
| testHandler := httptransport.NewHandler( |
| func(ctx context.Context, r *http.Request) (any, error) { |
| return nil, nil |
| }, |
| func(ctx context.Context, req any) (any, error) { |
| |
| return nil, models.NewValidationIssue(ErrCodeSomething, "something went wrong", commonhttp.WithHTTPStatusCodeAttribute(http.StatusBadRequest), models.WithAttribute("expectedKey", "expectedValue")) |
| }, |
| commonhttp.JSONResponseEncoderWithStatus[any](http.StatusOK), |
| ) |
|
|
| r := chi.NewRouter() |
| r.Handle("/", testHandler) |
|
|
| req := httptest.NewRequest(http.MethodGet, "/", bytes.NewReader(nil)) |
|
|
| |
| writer := httptest.NewRecorder() |
| r.ServeHTTP(writer, req) |
| res := writer.Result() |
|
|
| defer res.Body.Close() |
|
|
| |
| require.Equal(t, http.StatusBadRequest, res.StatusCode, writer.Body.String()) |
|
|
| |
| var body map[string]interface{} |
| err := json.Unmarshal(writer.Body.Bytes(), &body) |
| require.NoError(t, err) |
|
|
| |
| extensions, ok := body["extensions"].(map[string]interface{}) |
| require.True(t, ok) |
|
|
| issues, ok := extensions["validationErrors"].([]interface{}) |
| require.True(t, ok, "got body: %+v", body) |
| require.Len(t, issues, 1) |
|
|
| require.Equal(t, |
| map[string]interface{}{ |
| "code": "something", |
| |
| |
| "expectedKey": "expectedValue", |
| "message": "something went wrong", |
| "severity": "critical", |
| }, issues[0]) |
| }) |
|
|
| t.Run("Should map other statuses to errors", func(t *testing.T) { |
| testHandler := httptransport.NewHandler( |
| func(ctx context.Context, r *http.Request) (any, error) { |
| return nil, nil |
| }, |
| func(ctx context.Context, req any) (any, error) { |
| |
| return nil, models.NewValidationIssue(ErrCodeSomething, "something went wrong", commonhttp.WithHTTPStatusCodeAttribute(http.StatusConflict), models.WithAttribute("expectedKey", "expectedValue")) |
| }, |
| commonhttp.JSONResponseEncoderWithStatus[any](http.StatusOK), |
| ) |
|
|
| r := chi.NewRouter() |
| r.Handle("/", testHandler) |
|
|
| req := httptest.NewRequest(http.MethodGet, "/", bytes.NewReader(nil)) |
|
|
| |
| writer := httptest.NewRecorder() |
| r.ServeHTTP(writer, req) |
| res := writer.Result() |
|
|
| defer res.Body.Close() |
|
|
| |
| require.Equal(t, http.StatusConflict, res.StatusCode, writer.Body.String()) |
|
|
| |
| var body map[string]interface{} |
| err := json.Unmarshal(writer.Body.Bytes(), &body) |
| require.NoError(t, err) |
|
|
| |
| extensions, ok := body["extensions"].(map[string]interface{}) |
| require.True(t, ok) |
|
|
| _, ok = extensions["409"].([]interface{}) |
| require.False(t, ok) |
|
|
| issues, ok := extensions["validationErrors"].([]interface{}) |
| require.True(t, ok, "got body: %+v", body) |
| require.Len(t, issues, 1) |
|
|
| require.Equal(t, |
| map[string]interface{}{ |
| "code": "something", |
| |
| |
| "expectedKey": "expectedValue", |
| "message": "something went wrong", |
| "severity": "critical", |
| }, issues[0]) |
| }) |
| } |
|
|