Skip to content

Commit

Permalink
Create a POST /users handler
Browse files Browse the repository at this point in the history
  • Loading branch information
claudealdric committed Sep 16, 2024
1 parent c22bc58 commit b98aa8b
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 0 deletions.
17 changes: 17 additions & 0 deletions api/post_user_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package api

import (
"encoding/json"
"net/http"

"github.com/claudealdric/go-todolist-restful-api-server/models"
)

func (s *Server) HandlePostUser(w http.ResponseWriter, r *http.Request) {
w.Header().Set("content-type", jsonContentType)
var dto models.CreateUserDTO
json.NewDecoder(r.Body).Decode(&dto)
user, _ := s.store.CreateUser(dto)
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(user)
}
85 changes: 85 additions & 0 deletions api/post_user_handler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package api

import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"

"github.com/claudealdric/go-todolist-restful-api-server/models"
"github.com/claudealdric/go-todolist-restful-api-server/testutils"
"github.com/claudealdric/go-todolist-restful-api-server/testutils/assert"
)

func TestHandlePostUser(t *testing.T) {
t.Run("creates and returns the user with a 201 Status Created", func(t *testing.T) {
data := testutils.NewMockStore(false)
server := NewServer(data)

dto := models.CreateUserDTO{
Name: "Claude Aldric",
Email: "[email protected]",
Password: "password",
}
jsonData, err := json.Marshal(dto)
assert.HasNoError(t, err)
request := httptest.NewRequest(
http.MethodPost,
"/users",
bytes.NewBuffer(jsonData),
)
response := httptest.NewRecorder()
server.Handler.ServeHTTP(response, request)
newUser := models.NewUser(1, dto.Name, dto.Email, dto.Password)

assert.ContentType(
t,
testutils.GetContentTypeFromResponse(response),
jsonContentType,
)
assert.Status(t, response.Code, http.StatusCreated)
assert.Calls(t, data.CreateUserCalls, 1)
assert.Equals(
t,
testutils.GetUserFromResponse(t, response.Body),
*newUser,
)
})

// t.Run("responds with a 400 Bad Request given an invalid body", func(t *testing.T) {
// data := testutils.NewMockStore(false)
// server := NewServer(data)
//
// invalidJson := `{`
// request := httptest.NewRequest(
// http.MethodPost,
// "/users",
// bytes.NewBuffer([]byte(invalidJson)),
// )
// response := httptest.NewRecorder()
// server.Handler.ServeHTTP(response, request)
//
// assert.Status(t, response.Code, http.StatusBadRequest)
// assert.Calls(t, data.CreateUserCalls, 0)
// })
//
// t.Run("responds with a 500 error when the store user creation fails", func(t *testing.T) {
// data := testutils.NewMockStore(true)
// server := NewServer(data)
//
// newUser := models.NewUser(2, "Exercise")
// jsonData, err := json.Marshal(newUser)
// assert.HasNoError(t, err)
// request := httptest.NewRequest(
// http.MethodPost,
// "/users",
// bytes.NewBuffer(jsonData),
// )
// response := httptest.NewRecorder()
// server.Handler.ServeHTTP(response, request)
//
// assert.Status(t, response.Code, http.StatusInternalServerError)
// assert.Calls(t, data.CreateUserCalls, 1)
// })
}
1 change: 1 addition & 0 deletions api/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ func NewRouter(s *Server) *http.ServeMux {
mux.HandleFunc(get("/tasks/{id}"), s.HandleGetTaskById)
mux.HandleFunc("PATCH /tasks/{id}", s.HandlePatchTask)
mux.HandleFunc("POST /tasks", s.HandlePostTask)
mux.HandleFunc("POST /users", s.HandlePostUser)
mux.HandleFunc("DELETE /tasks/{id}", s.HandleDeleteTask)
return mux
}
Expand Down
5 changes: 5 additions & 0 deletions models/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ type User struct {
Password string `json:"password"`
}

func NewUser(id int, name string, email string, password string) *User {
user := User{Id: id, Name: name, Email: email, Password: password}
return &user
}

type CreateUserDTO struct {
Name string `json:"name"`
Email string `json:"email"`
Expand Down
15 changes: 15 additions & 0 deletions testutils/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,18 @@ func GetTasksFromResponse(t *testing.T, body io.Reader) (tasks []models.Task) {

return tasks
}

func GetUserFromResponse(t *testing.T, body io.Reader) (user models.User) {
t.Helper()
err := json.NewDecoder(body).Decode(&user)

if err != nil {
t.Fatalf(
"unable to parse response from server %q into User: %v",
body,
err,
)
}

return user
}

0 comments on commit b98aa8b

Please sign in to comment.