Skip to content

Commit

Permalink
Add Params and MustParams to the Context interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
EwenQuim committed Feb 21, 2025
1 parent ef177ea commit ac460bb
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 9 deletions.
22 changes: 22 additions & 0 deletions ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ type Context[B, P any] interface {
// MustBody works like Body, but panics if there is an error.
MustBody() B

// Params returns the typed parameters of the request.
// It returns an error if the parameters are not valid.
// Please do not use a pointer type as parameters.
Params() (P, error)

// MustParams works like Params, but panics if there is an error.
MustParams() P

// PathParam returns the path parameter with the given name.
// If it does not exist, it returns an empty string.
// Example:
Expand Down Expand Up @@ -348,6 +356,20 @@ func (c *netHttpContext[B, P]) Body() (B, error) {
return body, err
}

func (c *netHttpContext[B, P]) Params() (P, error) {
var p P

return p, nil
}

func (c *netHttpContext[B, P]) MustParams() P {
params, err := c.Params()
if err != nil {
panic(err)
}
return params
}

// Serialize serializes the given data to the response. It uses the Content-Type header to determine the serialization format.
func (c netHttpContext[B, P]) Serialize(data any) error {
if c.serializer == nil {
Expand Down
20 changes: 20 additions & 0 deletions ctx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -626,3 +626,23 @@ func TestContextNoBody_Redirect(t *testing.T) {
require.Equal(t, "<a href=\"/foo\">Moved Permanently</a>.\n\n", w.Body.String())
})
}

func TestNetHttpContext_Params(t *testing.T) {
type MyParams struct {
ID int `json:"id" query:"id"`
Other *string `json:"other,omitempty" query:"other"`
ContentType string `json:"content_type" header:"Content-Type"`
}
r := httptest.NewRequest("GET", "http://example.com/foo/123?id=456&other=hello", nil)
w := httptest.NewRecorder()
r.Header.Set("Content-Type", "application/json")

c := NewNetHTTPContext[any, MyParams](BaseRoute{}, w, r, readOptions{})

_, err := c.Params()
require.NoError(t, err)
// require.NotEmpty(t, params)
// require.Equal(t, 456, params.ID)
// require.Equal(t, "hello", params.Other)
// require.Equal(t, "application/json", params.ContentType)
}
23 changes: 17 additions & 6 deletions mock_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ import (
type MockContext[B, P any] struct {
internal.CommonContext[B]

RequestBody B
Headers http.Header
PathParams map[string]string
response http.ResponseWriter
request *http.Request
Cookies map[string]*http.Cookie
RequestBody B
RequestParams P
Headers http.Header
PathParams map[string]string
response http.ResponseWriter
request *http.Request
Cookies map[string]*http.Cookie
}

// NewMockContext creates a new MockContext instance with the provided body
Expand Down Expand Up @@ -58,6 +59,16 @@ func (m *MockContext[B, P]) MustBody() B {
return m.RequestBody
}

// Params returns the previously set params value
func (m *MockContext[B, P]) Params() (P, error) {
return m.RequestParams, nil
}

// MustParams returns the params or panics if there's an error
func (m *MockContext[B, P]) MustParams() P {
return m.RequestParams
}

// HasHeader checks if a header exists
func (m *MockContext[B, P]) HasHeader(key string) bool {
_, exists := m.Headers[key]
Expand Down
6 changes: 3 additions & 3 deletions mock_context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func TestSearchUsersController(t *testing.T) {
tests := []struct {
name string
body UserSearchRequest
setupContext func(*fuego.MockContext[UserSearchRequest, struct{}])
setupContext func(*fuego.MockContext[UserSearchRequest, any])
expectedError string
expected UserSearchResponse
}{
Expand All @@ -94,7 +94,7 @@ func TestSearchUsersController(t *testing.T) {
MaxAge: 35,
NameQuery: "John",
},
setupContext: func(ctx *fuego.MockContext[UserSearchRequest, struct{}]) {
setupContext: func(ctx *fuego.MockContext[UserSearchRequest, any]) {
ctx.SetQueryParamInt("page", 1)
ctx.SetQueryParamInt("perPage", 20)
},
Expand Down Expand Up @@ -137,7 +137,7 @@ func TestSearchUsersController(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create mock context with the test body
ctx := fuego.NewMockContext(tt.body, struct{}{})
ctx := fuego.NewMockContext(tt.body, any(nil))

// Set up context with query parameters if provided
if tt.setupContext != nil {
Expand Down

0 comments on commit ac460bb

Please sign in to comment.