diff --git a/context.go b/context.go index 38f175e..6bb02af 100644 --- a/context.go +++ b/context.go @@ -66,6 +66,17 @@ func (c *Context) View(items ...any) error { if name != "" { v, ok = c.app.viewers[name] + if ok { + mime := v.MimeType() + ok = false + for _, accept := range c.Accept() { + if mime == accept { + ok = true + break + } + } + } + } else { for _, accept := range c.Accept() { v, ok = c.routing.Viewers[accept] diff --git a/group_test.go b/group_test.go index 91e3f1a..debbcb1 100644 --- a/group_test.go +++ b/group_test.go @@ -1,88 +1,142 @@ package htmx import ( + "io" "net/http" - "os" + "net/http/httptest" "testing" + "testing/fstest" + + "github.com/stretchr/testify/require" ) func TestGroup(t *testing.T) { - app := New(WithMux(http.NewServeMux()), - WithFsys(os.DirFS("."))) - app.Get("/hello", func(c *Context) error { - //c.View(map[string]string{"name": "World"}) + fsys := &fstest.MapFS{ + "pages/admin/index.html": &fstest.MapFile{Data: []byte(`{{.}}`)}, + } - return nil - }) + mux := http.NewServeMux() + srv := httptest.NewServer(mux) + defer srv.Close() + + app := New(WithMux(mux), WithFsys(fsys)) + + app.Start() + defer app.Close() admin := app.Group("/admin") - admin.Use(func(next HandleFunc) HandleFunc { - return func(c *Context) error { - if c.routing.Options.String(NavigationAccess) != "admin:*" { - c.WriteStatus(http.StatusForbidden) - return ErrCancelled - } + admin.Get("/", func(c *Context) error { + return c.View("GET", "admin/index") + }) - return next(c) - } + admin.Post("/", func(c *Context) error { + return c.View("POST", "admin/index") + }) + admin.Put("/", func(c *Context) error { + return c.View("PUT", "admin/index") }) - admin.Get("/", func(c *Context) error { - return c.View(nil) + admin.Delete("/", func(c *Context) error { + return c.View("DELETE", "admin/index") + }) - }, WithNavigation("admin", "fa fa-home", "admin:*")) + req, err := http.NewRequest("GET", srv.URL+"/admin/", nil) + req.Header.Set("Accept", "text/html") + require.NoError(t, err) + resp, err := client.Do(req) + require.NoError(t, err) - admin.Post("/form", func(c *Context) error { - data, err := BindJSON[TestData](c.Request()) + buf, err := io.ReadAll(resp.Body) + require.NoError(t, err) + resp.Body.Close() - if err != nil { - c.WriteStatus(http.StatusBadRequest) - return ErrCancelled - } + require.Equal(t, `GET`, string(buf)) - if !data.Validate(c.AcceptLanguage()...) { - c.WriteStatus(http.StatusBadRequest) - return c.View(data) - } + req, err = http.NewRequest("GET", srv.URL+"/admin/", nil) + req.Header.Set("Accept", "application/json") + require.NoError(t, err) + resp, err = client.Do(req) + require.NoError(t, err) - return c.View(data) - }) + buf, err = io.ReadAll(resp.Body) + require.NoError(t, err) + resp.Body.Close() - admin.Get("/search", func(c *Context) error { - data, err := BindQuery[TestData](c.Request()) + require.Equal(t, "\"GET\"\n", string(buf)) - if err != nil { - c.WriteStatus(http.StatusBadRequest) - return ErrCancelled - } + req, err = http.NewRequest("POST", srv.URL+"/admin/", nil) + req.Header.Set("Accept", "text/html") + require.NoError(t, err) + resp, err = client.Do(req) + require.NoError(t, err) - if !data.Validate(c.AcceptLanguage()...) { - c.WriteStatus(http.StatusBadRequest) - return c.View(data) - } + buf, err = io.ReadAll(resp.Body) + require.NoError(t, err) + resp.Body.Close() - return c.View(data) - }) + require.Equal(t, `POST`, string(buf)) - admin.Post("/form", func(c *Context) error { - data, err := BindForm[TestData](c.Request()) + req, err = http.NewRequest("POST", srv.URL+"/admin/", nil) + req.Header.Set("Accept", "application/json") + require.NoError(t, err) + resp, err = client.Do(req) + require.NoError(t, err) - if err != nil { - c.WriteStatus(http.StatusBadRequest) - return ErrCancelled - } + buf, err = io.ReadAll(resp.Body) + require.NoError(t, err) + resp.Body.Close() - if !data.Validate(c.AcceptLanguage()...) { - c.WriteStatus(http.StatusBadRequest) - return c.View(data) - } + require.Equal(t, "\"POST\"\n", string(buf)) - return c.View(data) - }) -} + req, err = http.NewRequest("PUT", srv.URL+"/admin/", nil) + req.Header.Set("Accept", "text/html") + require.NoError(t, err) + resp, err = client.Do(req) + require.NoError(t, err) + + buf, err = io.ReadAll(resp.Body) + require.NoError(t, err) + resp.Body.Close() + + require.Equal(t, `PUT`, string(buf)) + + req, err = http.NewRequest("PUT", srv.URL+"/admin/", nil) + req.Header.Set("Accept", "application/json") + require.NoError(t, err) + resp, err = client.Do(req) + require.NoError(t, err) + + buf, err = io.ReadAll(resp.Body) + require.NoError(t, err) + resp.Body.Close() + + require.Equal(t, "\"PUT\"\n", string(buf)) + + req, err = http.NewRequest("DELETE", srv.URL+"/admin/", nil) + req.Header.Set("Accept", "text/html") + require.NoError(t, err) + resp, err = client.Do(req) + require.NoError(t, err) + + buf, err = io.ReadAll(resp.Body) + require.NoError(t, err) + resp.Body.Close() + + require.Equal(t, `DELETE`, string(buf)) + + req, err = http.NewRequest("DELETE", srv.URL+"/admin/", nil) + req.Header.Set("Accept", "application/json") + require.NoError(t, err) + resp, err = client.Do(req) + require.NoError(t, err) + + buf, err = io.ReadAll(resp.Body) + require.NoError(t, err) + resp.Body.Close() + + require.Equal(t, "\"DELETE\"\n", string(buf)) -type TestData struct { }