diff --git a/api/handler.go b/api/handler.go index 95c6260..eb7e213 100644 --- a/api/handler.go +++ b/api/handler.go @@ -44,6 +44,7 @@ func Handler() *mux.Router { m.Get(router.ObservationType).Handler(handler(serveObservationType)) m.Get(router.CreateObservationType).Handler(handler(serveCreateObservationType)) m.Get(router.ObservationTypes).Handler(handler(serveObservationTypeList)) + m.Get(router.UpdateObservationType).Handler(handler(serveUpdateObservationType)) return m } diff --git a/api/observation_types.go b/api/observation_types.go index 3242cb3..cbf28c9 100644 --- a/api/observation_types.go +++ b/api/observation_types.go @@ -57,3 +57,22 @@ func serveObservationTypeList(w http.ResponseWriter, r *http.Request) error { return writeJSON(w, observation_types) } + +func serveUpdateObservationType(w http.ResponseWriter, r *http.Request) error { + id, _ := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0) + var observation_type models.ObservationType + err := json.NewDecoder(r.Body).Decode(&observation_type) + if err != nil { + return err + } + + updated, err := store.ObservationTypes.Update(id, &observation_type) + if err != nil { + return err + } + if updated { + w.WriteHeader(http.StatusOK) + } + + return writeJSON(w, observation_type) +} diff --git a/api/observation_types_test.go b/api/observation_types_test.go index ee00d7f..4469695 100644 --- a/api/observation_types_test.go +++ b/api/observation_types_test.go @@ -94,3 +94,33 @@ func TestObservationType_List(t *testing.T) { t.Errorf("got observation_types %+v but wanted observation_types %+v", observation_types, want) } } + +func TestObservationType_Update(t *testing.T) { + setup() + + want := newObservationType() + + calledPut := false + store.ObservationTypes.(*models.MockObservationTypesService).Update_ = func(id int64, observation_type *models.ObservationType) (bool, error) { + if id != want.Id { + t.Errorf("wanted request for observation_type %d but got %d", want.Id, id) + } + if !normalizeDeepEqual(want, observation_type) { + t.Errorf("wanted request for observation_type %d but got %d", want, observation_type) + } + calledPut = true + return true, nil + } + + success, err := apiClient.ObservationTypes.Update(want.Id, want) + if err != nil { + t.Fatal(err) + } + + if !calledPut { + t.Error("!calledPut") + } + if !success { + t.Error("!success") + } +} diff --git a/datastore/observation_types.go b/datastore/observation_types.go index bff1da8..1bebeec 100644 --- a/datastore/observation_types.go +++ b/datastore/observation_types.go @@ -46,3 +46,26 @@ func (s *observationTypesStore) List(opt *models.ObservationTypeListOptions) ([] } return observation_types, nil } + +func (s *observationTypesStore) Update(id int64, observation_type *models.ObservationType) (bool, error) { + _, err := s.Get(id) + if err != nil { + return false, err + } + + if id != observation_type.Id { + return false, models.ErrObservationTypeNotFound + } + + observation_type.UpdatedAt = time.Now() + changed, err := s.dbh.Update(observation_type) + if err != nil { + return false, err + } + + if changed == 0 { + return false, ErrNoRowsUpdated + } + + return true, nil +} diff --git a/datastore/observation_types_test.go b/datastore/observation_types_test.go index addd956..86b66c0 100644 --- a/datastore/observation_types_test.go +++ b/datastore/observation_types_test.go @@ -85,3 +85,23 @@ func TestObservationTypesStore_List_db(t *testing.T) { t.Errorf("got observation_types %+v, want %+v", observation_types, want) } } + +func TestObservationTypesStore_Update_db(t *testing.T) { + tx, _ := DB.Begin() + defer tx.Rollback() + + observation_type := insertObservationType(t, tx) + + d := NewDatastore(tx) + + // Tweak it + observation_type.ObservationTypeName = "Updated Obs Type" + updated, err := d.ObservationTypes.Update(observation_type.Id, observation_type) + if err != nil { + t.Fatal(err) + } + + if !updated { + t.Error("!updated") + } +} diff --git a/models/observation_types.go b/models/observation_types.go index 7ae69ab..a785a3a 100644 --- a/models/observation_types.go +++ b/models/observation_types.go @@ -34,6 +34,9 @@ type ObservationTypesService interface { // Create an observation type record Create(observation_type *ObservationType) (bool, error) + + // Update an existing observation type + Update(id int64, observation_type *ObservationType) (updated bool, err error) } var ( @@ -109,10 +112,32 @@ func (s *observationTypesService) List(opt *ObservationTypeListOptions) ([]*Obse return observation_types, nil } +func (s *observationTypesService) Update(id int64, observation_type *ObservationType) (bool, error) { + strId := strconv.FormatInt(id, 10) + + url, err := s.client.url(router.UpdateObservationType, map[string]string{"Id": strId}, nil) + if err != nil { + return false, err + } + + req, err := s.client.NewRequest("PUT", url.String(), observation_type) + if err != nil { + return false, err + } + + resp, err := s.client.Do(req, &observation_type) + if err != nil { + return false, err + } + + return resp.StatusCode == http.StatusOK, nil +} + type MockObservationTypesService struct { Get_ func(id int64) (*ObservationType, error) List_ func(opt *ObservationTypeListOptions) ([]*ObservationType, error) Create_ func(observation_type *ObservationType) (bool, error) + Update_ func(id int64, observation_type *ObservationType) (bool, error) } var _ ObservationTypesService = &MockObservationTypesService{} @@ -137,3 +162,10 @@ func (s *MockObservationTypesService) List(opt *ObservationTypeListOptions) ([]* } return s.List_(opt) } + +func (s *MockObservationTypesService) Update(id int64, observation_type *ObservationType) (bool, error) { + if s.Update_ == nil { + return false, nil + } + return s.Update_(id, observation_type) +} diff --git a/models/observation_types_test.go b/models/observation_types_test.go index 81ffb48..cf53cfb 100644 --- a/models/observation_types_test.go +++ b/models/observation_types_test.go @@ -112,3 +112,34 @@ func TestObservationTypeService_List(t *testing.T) { t.Errorf("ObservationTypes.List return %+v, want %+v", observation_types, want) } } + +func TestObservationTypeService_Update(t *testing.T) { + setup() + defer teardown() + + want := newObservationType() + + var called bool + mux.HandleFunc(urlPath(t, router.UpdateObservationType, map[string]string{"Id": "1"}), func(w http.ResponseWriter, r *http.Request) { + called = true + testMethod(t, r, "PUT") + testBody(t, r, `{"id":1,"observation_type_name":"Test Obs Type Updated","created_at":"0001-01-01T00:00:00Z","updated_at":"0001-01-01T00:00:00Z","deleted_at":{"Time":"0001-01-01T00:00:00Z","Valid":false}}`+"\n") + w.WriteHeader(http.StatusOK) + writeJSON(w, want) + }) + + observation_type := newObservationType() + observation_type.ObservationTypeName = "Test Obs Type Updated" + updated, err := client.ObservationTypes.Update(observation_type.Id, observation_type) + if err != nil { + t.Errorf("ObservationTypes.Update returned error: %v", err) + } + + if !updated { + t.Error("!updated") + } + + if !called { + t.Fatal("!called") + } +} diff --git a/router/api.go b/router/api.go index bf0cabd..a1bbf34 100644 --- a/router/api.go +++ b/router/api.go @@ -35,6 +35,7 @@ func API() *mux.Router { m.Path("/observation_types").Methods("GET").Name(ObservationTypes) m.Path("/observation_types").Methods("POST").Name(CreateObservationType) m.Path("/observation_types/{Id:.+}").Methods("GET").Name(ObservationType) + m.Path("/observation_types/{Id:.+}").Methods("PUT").Name(UpdateObservationType) return m } diff --git a/router/routes.go b/router/routes.go index 332f374..ca63317 100644 --- a/router/routes.go +++ b/router/routes.go @@ -26,4 +26,5 @@ const ( ObservationType = "observation_type:get" CreateObservationType = "observation_type:create" ObservationTypes = "observation_type:list" + UpdateObservationType = "observation_type:update" )