chi icon indicating copy to clipboard operation
chi copied to clipboard

middleware.AllowContentType not running for subroutes

Open jtuchel opened this issue 2 years ago • 1 comments

Given this sample code

package main

import (
    "net/http"

    "github.com/go-chi/chi/v5"
    "github.com/go-chi/chi/v5/middleware"
)

func main() {
    http.ListenAndServe(":3000", GetRouter())
}

func GetRouter() *chi.Mux {
    apiRouter := chi.NewRouter()

    apiRouter.Route("/foo-group", func(fooGroupRouter chi.Router) {
        fooGroupRouter.Use(middleware.AllowContentType("application/json"))

        fooGroupRouter.Post("/sub-route", HandleRoute( /* Params */))
    })

    // other routes

    return apiRouter
}

func HandleRoute( /* Params */) http.HandlerFunc {
    return func(responseWriter http.ResponseWriter, request *http.Request) {
        responseWriter.WriteHeader(http.StatusCreated)

        responseWriter.Write([]byte("done"))
    }
}

When calling the API via

POST localhost:3000/foo-group/sub-route

I get a 201 with "done". But I want to ensure this endpoint only accepts the content type "application/json", otherwise send back a 415.

Unfortunately the middleware is not working yet. I also tried to test the behaviour with the testrunner

package main

import (
    "net/http"
    "net/http/httptest"
    "strconv"
    "testing"
)

func TestHandleRoute(suite *testing.T) {
    server := httptest.NewServer(HandleRoute())

    suite.Run("responds with status code "+strconv.Itoa(http.StatusUnsupportedMediaType)+" if content type is not application/json", func(testing *testing.T) {
        response, _ := http.Post(server.URL, "text/xml", nil)

        if response.StatusCode != http.StatusUnsupportedMediaType {
            testing.Errorf("Expected statuscode %d but got %d", http.StatusUnsupportedMediaType, response.StatusCode)
        }
    })
}

Unfortunately the test fails with the message

main_test.go:17: Expected statuscode 415 but got 201

so it seems the middleware didn't run.

Is my setup wrong or is it a bug?

jtuchel avatar Jan 25 '23 07:01 jtuchel

@jtuchel, your unit test setup is wrong. httptest is intended to test the handler rather than the HTTP server itself. So basically you just test the HandleRoute instead of the whole server logic.

You can use TestMain to serve your server or stub the chi router with the handler.

fahimbagar avatar Jan 26 '23 15:01 fahimbagar