package apis import ( "bytes" "io" "net/http" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // NewMockRequest creates a new mock request. func NewMockRequest(t *testing.T, method string, body io.ReadCloser) *http.Request { req, err := http.NewRequest(method, "/vm/xxx?name=alice", body) require.NoError(t, err) return req } // TestDecodeReq tests the decodeReq function. func TestDecodeReq(t *testing.T) { // Define a test struct type TestStruct struct { Field string `json:"field"` EnvID string `json:"env_id" in:"path=env_id" validate:"required"` Name string `json:"name" in:"query=name"` } // Test case 1: GET request with no body t.Run("GET request with no body", func(t *testing.T) { req := NewMockRequest(t, http.MethodGet, nil) result, err := decodeReq[TestStruct](req) assert.NoError(t, err) assert.Equal(t, "alice", result.Name) }) // Test case 2: POST request with valid JSON body t.Run("POST request with valid JSON body", func(t *testing.T) { jsonBody := `{"field": "value", "env_id": "test", "name": "alice1"}` body := io.NopCloser(bytes.NewBufferString(jsonBody)) req := NewMockRequest(t, http.MethodPost, body) result, err := decodeReq[TestStruct](req) assert.NoError(t, err) assert.Equal(t, "value", result.Field) assert.Equal(t, "test", result.EnvID) assert.Equal(t, "alice1", result.Name) }) // Test case 3: POST request with invalid JSON body t.Run("POST request with invalid JSON body", func(t *testing.T) { jsonBody := `{"field": "value"` // Invalid JSON body := io.NopCloser(bytes.NewBufferString(jsonBody)) req := NewMockRequest(t, http.MethodPost, body) result, err := decodeReq[TestStruct](req) assert.Error(t, err) assert.Nil(t, result) }) // Test case 4: Invalid request header t.Run("invalid request header", func(t *testing.T) { jsonBody := `{"field": "value", "env_id": "test", "name": "alice1"}` body := io.NopCloser(bytes.NewBufferString(jsonBody)) req := NewMockRequest(t, http.MethodPost, body) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") result, err := decodeReq[TestStruct](req) assert.Error(t, err) assert.Nil(t, result) }) // Test case 5: EmptyReq type check t.Run("EmptyReq type check", func(t *testing.T) { req := NewMockRequest(t, http.MethodPost, nil) result, err := decodeReq[EmptyReq](req) assert.NoError(t, err) assert.NotNil(t, result) }) // Test case 5: EmptyReq type check t.Run("HttpRequest type check", func(t *testing.T) { req := &http.Request{ Method: http.MethodPost, } result, err := decodeReq[http.Request](req) assert.NoError(t, err) assert.Equal(t, req.Method, result.Method) }) } func BenchmarkDecodeReq(b *testing.B) { r := &http.Request{ Method: http.MethodPost, } for i := 0; i < b.N; i++ { result, err := decodeReq[http.Request](r) if err != nil { b.Error(err) } if result.Method != http.MethodPost { b.Error("invalid result") } } }