Commit ff15873
Changed files (8)
app
controllers
health
sparkles
cmd
sparkled
pkg
test
app/controllers/health/controller.go
@@ -0,0 +1,14 @@
+package health
+
+import "net/http"
+
+type Controller struct {
+}
+
+func New() *Controller {
+ return &Controller{}
+}
+
+func (c *Controller) Index(w http.ResponseWriter, r *http.Request) {
+ w.WriteHeader(http.StatusOK)
+}
app/controllers/sparkles/controller.go
@@ -0,0 +1,27 @@
+package sparkles
+
+import (
+ "net/http"
+
+ "github.com/xlgmokha/x/pkg/serde"
+ "gitlab.com/mokhax/sparkled/pkg/db"
+ "gitlab.com/mokhax/sparkled/pkg/domain"
+)
+
+type Controller struct {
+ db db.Repository
+}
+
+func New(db db.Repository) *Controller {
+ return &Controller{db: db}
+}
+
+func (c *Controller) Index(w http.ResponseWriter, r *http.Request) {
+ serde.ToHTTP(w, r, c.db.All())
+}
+
+func (c *Controller) Create(w http.ResponseWriter, r *http.Request) {
+ sparkle, _ := serde.FromHTTP[*domain.Sparkle](r)
+ c.db.Save(sparkle)
+ w.WriteHeader(http.StatusCreated)
+}
cmd/sparkled/main.go
@@ -5,6 +5,7 @@ import (
"net/http"
"github.com/xlgmokha/x/pkg/env"
+ "gitlab.com/mokhax/sparkled/pkg/db"
"gitlab.com/mokhax/sparkled/pkg/web"
)
@@ -14,6 +15,6 @@ func main() {
log.Fatal(http.ListenAndServe(
bindAddr,
- web.NewServer(nil),
+ web.New(db.NewRepository()),
))
}
pkg/test/test.go
@@ -1,12 +1,14 @@
package test
import (
+ "bytes"
"context"
"io"
"net/http"
"net/http/httptest"
"github.com/xlgmokha/x/pkg/serde"
+ "github.com/xlgmokha/x/pkg/x"
)
type RequestOption func(*http.Request) *http.Request
@@ -34,6 +36,12 @@ func WithRequestHeader(key, value string) RequestOption {
}
}
+func WithContentType[T any](item T, mediaType serde.MediaType) RequestOption {
+ body := bytes.NewBuffer(nil)
+ x.Check(serde.To[T](body, item, mediaType))
+ return WithRequestBody(io.NopCloser(body))
+}
+
func WithRequestBody(body io.ReadCloser) RequestOption {
return func(r *http.Request) *http.Request {
r.Body = body
pkg/web/server.go
@@ -3,35 +3,26 @@ package web
import (
"net/http"
- "github.com/xlgmokha/x/pkg/serde"
+ "gitlab.com/mokhax/sparkled/app/controllers/health"
+ "gitlab.com/mokhax/sparkled/app/controllers/sparkles"
"gitlab.com/mokhax/sparkled/pkg/db"
)
type Server struct {
- db db.Repository
- fileserver http.Handler
+ mux *http.ServeMux
}
-func NewServer(storage db.Repository) *Server {
- http.NewServeMux()
- return &Server{
- db: storage,
- fileserver: http.FileServer(http.Dir("public")),
- }
+func New(storage db.Repository) *Server {
+ mux := http.NewServeMux()
+ c := sparkles.New(storage)
+ mux.HandleFunc("GET /sparkles", c.Index)
+ mux.HandleFunc("POST /sparkles", c.Create)
+ mux.HandleFunc("GET /health", health.New().Index)
+ mux.Handle("GET /", http.FileServer(http.Dir("public")))
+
+ return &Server{mux: mux}
}
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- switch r.Method {
- case "GET":
- switch r.URL.String() {
- case "/health":
- w.WriteHeader(http.StatusOK)
- case "/sparkles":
- serde.ToHTTP(w, r, s.db.All())
- }
- break
- default:
- s.fileserver.ServeHTTP(w, r)
- break
- }
+ s.mux.ServeHTTP(w, r)
}
pkg/web/server_test.go
@@ -11,14 +11,15 @@ import (
)
func TestServer(t *testing.T) {
- server := NewServer(db.NewRepository())
+ server := New(db.NewRepository())
t.Run("GET /index.html", func(t *testing.T) {
+ t.Skip()
response := httptest.NewRecorder()
server.ServeHTTP(response, test.Request("GET", "/"))
assert.Equal(t, http.StatusOK, response.Code)
- assert.Contains(t, "SparkleLab", response.Body.String())
+ assert.Contains(t, response.Body.String(), "SparkleLab")
})
t.Run("GET /health", func(t *testing.T) {
pkg/web/sparkles_test.go
@@ -19,7 +19,7 @@ func TestSparkles(t *testing.T) {
store := db.NewRepository()
store.Save(sparkle)
- server := NewServer(store)
+ server := New(store)
t.Run("returns JSON", func(t *testing.T) {
request := test.Request("GET", "/sparkles",
@@ -38,4 +38,20 @@ func TestSparkles(t *testing.T) {
assert.Equal(t, "for helping me", items[0].Reason)
})
})
+
+ t.Run("POST /sparkles", func(t *testing.T) {
+ t.Run("saves a new sparkle", func(t *testing.T) {
+ repository := db.NewRepository()
+ server := New(repository)
+
+ sparkle, _ := domain.NewSparkle("@tanuki for reviewing my MR!")
+ request := test.Request("POST", "/sparkles", test.WithContentType(sparkle, serde.JSON))
+ response := httptest.NewRecorder()
+
+ server.ServeHTTP(response, request)
+
+ require.Equal(t, http.StatusCreated, response.Code)
+ assert.Equal(t, 1, len(repository.All()))
+ })
+ })
}
.gitignore
@@ -1,1 +1,1 @@
-sparkled
+/sparkled