[coverme] Add finish todo handler.

This commit is contained in:
Arseny Balobanov 2022-03-24 18:48:48 +03:00
parent b0739ad918
commit 8868dac428
4 changed files with 70 additions and 9 deletions

View file

@ -85,3 +85,19 @@ Content-Length: 53
[{"id":0,"title":"A","content":"a","finished":false}]
```
Завершить todo:
```
✗ curl -i -X POST localhost:6029/todo/0/finish
HTTP/1.1 200 OK
Date: Thu, 24 Mar 2022 15:40:49 GMT
Content-Length: 0
✗ curl -i -X GET localhost:6029/todo
HTTP/1.1 200 OK
Content-Type: application/json
Date: Thu, 24 Mar 2022 15:41:04 GMT
Content-Length: 52
[{"id":0,"title":"A","content":"a","finished":true}]%
```

View file

@ -9,7 +9,6 @@ import (
"net/http"
"os"
"strconv"
"strings"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
@ -34,10 +33,11 @@ func (app *App) Start(port int) {
func (app *App) initRoutes() {
app.router = mux.NewRouter()
app.router.HandleFunc("/", app.status).Methods("Get")
app.router.HandleFunc("/todo", app.list).Methods("Get")
app.router.HandleFunc("/todo/{id:[0-9]+}", app.getTodo).Methods("Get")
app.router.HandleFunc("/todo/create", app.addTodo).Methods("Post")
app.router.HandleFunc("/", app.status).Methods("GET")
app.router.HandleFunc("/todo", app.list).Methods("GET")
app.router.HandleFunc("/todo/{id:[0-9]+}", app.getTodo).Methods("GET")
app.router.HandleFunc("/todo/{id:[0-9]+}/finish", app.finishTodo).Methods("POST")
app.router.HandleFunc("/todo/create", app.addTodo).Methods("POST")
}
func (app *App) run(addr string) {
@ -80,7 +80,7 @@ func (app *App) addTodo(w http.ResponseWriter, r *http.Request) {
}
func (app *App) getTodo(w http.ResponseWriter, r *http.Request) {
id, err := strconv.Atoi(strings.TrimPrefix(r.URL.Path, "/todo/"))
id, err := strconv.Atoi(mux.Vars(r)["id"])
if err != nil {
utils.BadRequest(w, "ID must be an int")
return
@ -95,6 +95,21 @@ func (app *App) getTodo(w http.ResponseWriter, r *http.Request) {
_ = utils.RespondJSON(w, http.StatusOK, todo)
}
func (app *App) finishTodo(w http.ResponseWriter, r *http.Request) {
id, err := strconv.Atoi(mux.Vars(r)["id"])
if err != nil {
utils.BadRequest(w, "ID must be an int")
return
}
if err := app.db.FinishTodo(models.ID(id)); err != nil {
utils.ServerError(w)
return
}
w.WriteHeader(http.StatusOK)
}
func (app *App) status(w http.ResponseWriter, r *http.Request) {
_ = utils.RespondJSON(w, http.StatusOK, "API is up and working!")
}

View file

@ -69,3 +69,19 @@ func (c *Client) List() ([]*models.Todo, error) {
err = json.NewDecoder(resp.Body).Decode(&todos)
return todos, err
}
func (c *Client) Finish(id models.ID) error {
u := fmt.Sprintf("%s/todo/%d/finish", c.addr, id)
resp, err := http.Post(u, "application/json", nil)
if err != nil {
return err
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status code %d", resp.StatusCode)
}
return err
}

View file

@ -12,6 +12,7 @@ type Storage interface {
AddTodo(string, string) (*Todo, error)
GetTodo(ID) (*Todo, error)
GetAll() ([]*Todo, error)
FinishTodo(ID) error
}
type InMemoryStorage struct {
@ -69,3 +70,16 @@ func (s *InMemoryStorage) GetAll() ([]*Todo, error) {
return out, nil
}
func (s *InMemoryStorage) FinishTodo(id ID) error {
s.mu.Lock()
defer s.mu.Unlock()
todo, ok := s.todos[id]
if !ok {
return fmt.Errorf("todo %d not found", id)
}
todo.MarkFinished()
return nil
}