diff --git a/api/handler.go b/api/handler.go index 2275bcd..479bc27 100644 --- a/api/handler.go +++ b/api/handler.go @@ -61,6 +61,7 @@ func Handler() *mux.Router { m.Get(router.UnitType).Handler(handler(serveUnitType)) m.Get(router.CreateUnitType).Handler(handler(serveCreateUnitType)) + m.Get(router.UnitTypes).Handler(handler(serveUnitTypeList)) return m } diff --git a/api/unit_types.go b/api/unit_types.go index 65c2e5e..34d6bb6 100644 --- a/api/unit_types.go +++ b/api/unit_types.go @@ -40,3 +40,20 @@ func serveCreateUnitType(w http.ResponseWriter, r *http.Request) error { return writeJSON(w, unit_type) } + +func serveUnitTypeList(w http.ResponseWriter, r *http.Request) error { + var opt models.UnitTypeListOptions + if err := schemaDecoder.Decode(&opt, r.URL.Query()); err != nil { + return err + } + + unit_types, err := store.UnitTypes.List(&opt) + if err != nil { + return err + } + if unit_types == nil { + unit_types = []*models.UnitType{} + } + + return writeJSON(w, unit_types) +} diff --git a/api/unit_types_test.go b/api/unit_types_test.go index a762b79..385732f 100644 --- a/api/unit_types_test.go +++ b/api/unit_types_test.go @@ -65,3 +65,32 @@ func TestUnitType_Create(t *testing.T) { t.Error("!success") } } + +func TestUnitType_List(t *testing.T) { + setup() + + want := []*models.UnitType{newUnitType()} + wantOpt := &models.UnitTypeListOptions{ListOptions: models.ListOptions{Page: 1, PerPage: 10}} + + calledList := false + store.UnitTypes.(*models.MockUnitTypesService).List_ = func(opt *models.UnitTypeListOptions) ([]*models.UnitType, error) { + if !normalizeDeepEqual(wantOpt, opt) { + t.Errorf("wanted options %d but got %d", wantOpt, opt) + } + calledList = true + return want, nil + } + + unit_types, err := apiClient.UnitTypes.List(wantOpt) + if err != nil { + t.Fatal(err) + } + + if !calledList { + t.Error("!calledList") + } + + if !normalizeDeepEqual(&want, &unit_types) { + t.Errorf("got unit_types %+v but wanted unit_types %+v", unit_types, want) + } +} diff --git a/datastore/unit_types.go b/datastore/unit_types.go index a6c1ada..621ba60 100644 --- a/datastore/unit_types.go +++ b/datastore/unit_types.go @@ -34,3 +34,15 @@ func (s *unitTypesStore) Create(unit_type *models.UnitType) (bool, error) { } return true, nil } + +func (s *unitTypesStore) List(opt *models.UnitTypeListOptions) ([]*models.UnitType, error) { + if opt == nil { + opt = &models.UnitTypeListOptions{} + } + var unit_types []*models.UnitType + err := s.dbh.Select(&unit_types, `SELECT * FROM unit_types LIMIT $1 OFFSET $2;`, opt.PerPageOrDefault(), opt.Offset()) + if err != nil { + return nil, err + } + return unit_types, nil +} diff --git a/datastore/unit_types_test.go b/datastore/unit_types_test.go index ea39d4e..7133a17 100644 --- a/datastore/unit_types_test.go +++ b/datastore/unit_types_test.go @@ -62,3 +62,26 @@ func TestUnitTypesStore_Create_db(t *testing.T) { t.Error("want nonzero unit_type.Id after submitting") } } + +func TestUnitTypesStore_List_db(t *testing.T) { + tx, _ := DB.Begin() + defer tx.Rollback() + + want_unit_type := insertUnitType(t, tx) + want := []*models.UnitType{want_unit_type} + + d := NewDatastore(tx) + + unit_types, err := d.UnitTypes.List(&models.UnitTypeListOptions{ListOptions: models.ListOptions{Page: 1, PerPage: 10}}) + if err != nil { + t.Fatal(err) + } + + for i := range want { + normalizeTime(&want[i].CreatedAt, &want[i].UpdatedAt, &want[i].DeletedAt) + normalizeTime(&unit_types[i].CreatedAt, &unit_types[i].UpdatedAt, &unit_types[i].DeletedAt) + } + if !reflect.DeepEqual(unit_types, want) { + t.Errorf("got unit_types %+v, want %+v", unit_types, want) + } +} diff --git a/models/unit_types.go b/models/unit_types.go index b587f6e..30ca352 100644 --- a/models/unit_types.go +++ b/models/unit_types.go @@ -31,6 +31,9 @@ type UnitTypesService interface { // Get a unit type Get(id int64) (*UnitType, error) + // List all unit types + List(opt *UnitTypeListOptions) ([]*UnitType, error) + // Create a unit type Create(unit_type *UnitType) (bool, error) } @@ -84,8 +87,33 @@ func (s *unitTypesService) Create(unit_type *UnitType) (bool, error) { return resp.StatusCode == http.StatusCreated, nil } +type UnitTypeListOptions struct { + ListOptions +} + +func (s *unitTypesService) List(opt *UnitTypeListOptions) ([]*UnitType, error) { + url, err := s.client.url(router.UnitTypes, nil, opt) + if err != nil { + return nil, err + } + + req, err := s.client.NewRequest("GET", url.String(), nil) + if err != nil { + return nil, err + } + + var unit_types []*UnitType + _, err = s.client.Do(req, &unit_types) + if err != nil { + return nil, err + } + + return unit_types, nil +} + type MockUnitTypesService struct { Get_ func(id int64) (*UnitType, error) + List_ func(opt *UnitTypeListOptions) ([]*UnitType, error) Create_ func(unit_type *UnitType) (bool, error) } @@ -104,3 +132,10 @@ func (s *MockUnitTypesService) Create(unit_type *UnitType) (bool, error) { } return s.Create_(unit_type) } + +func (s *MockUnitTypesService) List(opt *UnitTypeListOptions) ([]*UnitType, error) { + if s.List_ == nil { + return nil, nil + } + return s.List_(opt) +} diff --git a/models/unit_types_test.go b/models/unit_types_test.go index af674a7..1bcd154 100644 --- a/models/unit_types_test.go +++ b/models/unit_types_test.go @@ -79,3 +79,36 @@ func TestUnitTypeService_Create(t *testing.T) { t.Errorf("UnitTypes.Create returned %+v, want %+v", unit_type, want) } } + +func TestUnitTypeService_List(t *testing.T) { + setup() + defer teardown() + + want := []*UnitType{newUnitType()} + + var called bool + mux.HandleFunc(urlPath(t, router.UnitTypes, nil), func(w http.ResponseWriter, r *http.Request) { + called = true + testMethod(t, r, "GET") + testFormValues(t, r, values{}) + + writeJSON(w, want) + }) + + unit_types, err := client.UnitTypes.List(nil) + if err != nil { + t.Errorf("UnitTypes.List returned error: %v", err) + } + + if !called { + t.Fatal("!called") + } + + for _, u := range want { + normalizeTime(&u.CreatedAt, &u.UpdatedAt, &u.DeletedAt) + } + + if !reflect.DeepEqual(unit_types, want) { + t.Errorf("UnitTypes.List return %+v, want %+v", unit_types, want) + } +} diff --git a/router/api.go b/router/api.go index 11b8bfd..78a4e41 100644 --- a/router/api.go +++ b/router/api.go @@ -53,6 +53,7 @@ func API() *mux.Router { m.Path("/text_measurement_types/{Id:.+}").Methods("DELETE").Name(DeleteTextMeasurementType) // UnitTypes + m.Path("/unit_types/").Methods("GET").Name(UnitTypes) m.Path("/unit_types/").Methods("POST").Name(CreateUnitType) m.Path("/unit_types/{Id:.+}").Methods("GET").Name(UnitType) diff --git a/router/routes.go b/router/routes.go index ffb436d..031d42c 100644 --- a/router/routes.go +++ b/router/routes.go @@ -43,4 +43,5 @@ const ( UnitType = "unit_type:get" CreateUnitType = "unit_type:create" + UnitTypes = "unit_type:list" )