Create a unit type
This commit is contained in:
		
							parent
							
								
									c2bfc8b93b
								
							
						
					
					
						commit
						b7caffa373
					
				
					 9 changed files with 155 additions and 4 deletions
				
			
		|  | @ -60,6 +60,7 @@ func Handler() *mux.Router { | |||
| 	m.Get(router.DeleteTextMeasurementType).Handler(handler(serveDeleteTextMeasurementType)) | ||||
| 
 | ||||
| 	m.Get(router.UnitType).Handler(handler(serveUnitType)) | ||||
| 	m.Get(router.CreateUnitType).Handler(handler(serveCreateUnitType)) | ||||
| 
 | ||||
| 	return m | ||||
| } | ||||
|  |  | |||
|  | @ -1,10 +1,12 @@ | |||
| package api | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"net/http" | ||||
| 	"strconv" | ||||
| 
 | ||||
| 	"github.com/gorilla/mux" | ||||
| 	"github.com/thermokarst/bactdb/models" | ||||
| ) | ||||
| 
 | ||||
| func serveUnitType(w http.ResponseWriter, r *http.Request) error { | ||||
|  | @ -20,3 +22,21 @@ func serveUnitType(w http.ResponseWriter, r *http.Request) error { | |||
| 
 | ||||
| 	return writeJSON(w, unit_type) | ||||
| } | ||||
| 
 | ||||
| func serveCreateUnitType(w http.ResponseWriter, r *http.Request) error { | ||||
| 	var unit_type models.UnitType | ||||
| 	err := json.NewDecoder(r.Body).Decode(&unit_type) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	created, err := store.UnitTypes.Create(&unit_type) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if created { | ||||
| 		w.WriteHeader(http.StatusCreated) | ||||
| 	} | ||||
| 
 | ||||
| 	return writeJSON(w, unit_type) | ||||
| } | ||||
|  |  | |||
|  | @ -38,3 +38,30 @@ func TestUnitType_Get(t *testing.T) { | |||
| 		t.Errorf("got %+v but wanted %+v", got, want) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestUnitType_Create(t *testing.T) { | ||||
| 	setup() | ||||
| 
 | ||||
| 	want := newUnitType() | ||||
| 
 | ||||
| 	calledPost := false | ||||
| 	store.UnitTypes.(*models.MockUnitTypesService).Create_ = func(unit_type *models.UnitType) (bool, error) { | ||||
| 		if !normalizeDeepEqual(want, unit_type) { | ||||
| 			t.Errorf("wanted request for unit_type %d but got %d", want, unit_type) | ||||
| 		} | ||||
| 		calledPost = true | ||||
| 		return true, nil | ||||
| 	} | ||||
| 
 | ||||
| 	success, err := apiClient.UnitTypes.Create(want) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	if !calledPost { | ||||
| 		t.Error("!calledPost") | ||||
| 	} | ||||
| 	if !success { | ||||
| 		t.Error("!success") | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,10 @@ | |||
| package datastore | ||||
| 
 | ||||
| import "github.com/thermokarst/bactdb/models" | ||||
| import ( | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/thermokarst/bactdb/models" | ||||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	DB.AddTableWithName(models.UnitType{}, "unit_types").SetKeys(true, "Id") | ||||
|  | @ -20,3 +24,13 @@ func (s *unitTypesStore) Get(id int64) (*models.UnitType, error) { | |||
| 	} | ||||
| 	return unit_type[0], nil | ||||
| } | ||||
| 
 | ||||
| func (s *unitTypesStore) Create(unit_type *models.UnitType) (bool, error) { | ||||
| 	currentTime := time.Now() | ||||
| 	unit_type.CreatedAt = currentTime | ||||
| 	unit_type.UpdatedAt = currentTime | ||||
| 	if err := s.dbh.Insert(unit_type); err != nil { | ||||
| 		return false, err | ||||
| 	} | ||||
| 	return true, nil | ||||
| } | ||||
|  |  | |||
|  | @ -42,3 +42,23 @@ func TestUnitTypesStore_Get_db(t *testing.T) { | |||
| 		t.Errorf("got unit_type %+v, want %+v", unit_type, want) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestUnitTypesStore_Create_db(t *testing.T) { | ||||
| 	tx, _ := DB.Begin() | ||||
| 	defer tx.Rollback() | ||||
| 
 | ||||
| 	unit_type := newUnitType(t, tx) | ||||
| 
 | ||||
| 	d := NewDatastore(tx) | ||||
| 
 | ||||
| 	created, err := d.UnitTypes.Create(unit_type) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if !created { | ||||
| 		t.Error("!created") | ||||
| 	} | ||||
| 	if unit_type.Id == 0 { | ||||
| 		t.Error("want nonzero unit_type.Id after submitting") | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ package models | |||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"net/http" | ||||
| 	"strconv" | ||||
| 	"time" | ||||
| 
 | ||||
|  | @ -11,7 +12,7 @@ import ( | |||
| 
 | ||||
| // A UnitType is a lookup type | ||||
| type UnitType struct { | ||||
| 	Id        int64       `json:id,omitempty"` | ||||
| 	Id        int64       `json:"id,omitempty"` | ||||
| 	Name      string      `db:"name" json:"name"` | ||||
| 	Symbol    string      `db:"symbol" json:"symbol"` | ||||
| 	CreatedAt time.Time   `db:"created_at" json:"createdAt"` | ||||
|  | @ -29,6 +30,9 @@ func NewUnitType() *UnitType { | |||
| type UnitTypesService interface { | ||||
| 	// Get a unit type | ||||
| 	Get(id int64) (*UnitType, error) | ||||
| 
 | ||||
| 	// Create a unit type | ||||
| 	Create(unit_type *UnitType) (bool, error) | ||||
| } | ||||
| 
 | ||||
| var ( | ||||
|  | @ -61,8 +65,28 @@ func (s *unitTypesService) Get(id int64) (*UnitType, error) { | |||
| 	return unit_type, nil | ||||
| } | ||||
| 
 | ||||
| func (s *unitTypesService) Create(unit_type *UnitType) (bool, error) { | ||||
| 	url, err := s.client.url(router.CreateUnitType, nil, nil) | ||||
| 	if err != nil { | ||||
| 		return false, err | ||||
| 	} | ||||
| 
 | ||||
| 	req, err := s.client.NewRequest("POST", url.String(), unit_type) | ||||
| 	if err != nil { | ||||
| 		return false, err | ||||
| 	} | ||||
| 
 | ||||
| 	resp, err := s.client.Do(req, &unit_type) | ||||
| 	if err != nil { | ||||
| 		return false, err | ||||
| 	} | ||||
| 
 | ||||
| 	return resp.StatusCode == http.StatusCreated, nil | ||||
| } | ||||
| 
 | ||||
| type MockUnitTypesService struct { | ||||
| 	Get_ func(id int64) (*UnitType, error) | ||||
| 	Get_    func(id int64) (*UnitType, error) | ||||
| 	Create_ func(unit_type *UnitType) (bool, error) | ||||
| } | ||||
| 
 | ||||
| var _ UnitTypesService = &MockUnitTypesService{} | ||||
|  | @ -73,3 +97,10 @@ func (s *MockUnitTypesService) Get(id int64) (*UnitType, error) { | |||
| 	} | ||||
| 	return s.Get_(id) | ||||
| } | ||||
| 
 | ||||
| func (s *MockUnitTypesService) Create(unit_type *UnitType) (bool, error) { | ||||
| 	if s.Create_ == nil { | ||||
| 		return false, nil | ||||
| 	} | ||||
| 	return s.Create_(unit_type) | ||||
| } | ||||
|  |  | |||
|  | @ -43,3 +43,39 @@ func TestUnitTypeService_Get(t *testing.T) { | |||
| 		t.Errorf("UnitTypes.Get return %+v, want %+v", unit_type, want) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestUnitTypeService_Create(t *testing.T) { | ||||
| 	setup() | ||||
| 	defer teardown() | ||||
| 
 | ||||
| 	want := newUnitType() | ||||
| 
 | ||||
| 	var called bool | ||||
| 	mux.HandleFunc(urlPath(t, router.CreateUnitType, nil), func(w http.ResponseWriter, r *http.Request) { | ||||
| 		called = true | ||||
| 		testMethod(t, r, "POST") | ||||
| 		testBody(t, r, `{"id":1,"name":"Test Unit Type","symbol":"x","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":{"Time":"0001-01-01T00:00:00Z","Valid":false}}`+"\n") | ||||
| 
 | ||||
| 		w.WriteHeader(http.StatusCreated) | ||||
| 		writeJSON(w, want) | ||||
| 	}) | ||||
| 
 | ||||
| 	unit_type := newUnitType() | ||||
| 	created, err := client.UnitTypes.Create(unit_type) | ||||
| 	if err != nil { | ||||
| 		t.Errorf("UnitTypes.Create returned error: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	if !created { | ||||
| 		t.Error("!created") | ||||
| 	} | ||||
| 
 | ||||
| 	if !called { | ||||
| 		t.Fatal("!called") | ||||
| 	} | ||||
| 
 | ||||
| 	normalizeTime(&want.CreatedAt, &want.UpdatedAt, &want.DeletedAt) | ||||
| 	if !reflect.DeepEqual(unit_type, want) { | ||||
| 		t.Errorf("UnitTypes.Create returned %+v, want %+v", unit_type, want) | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -53,6 +53,7 @@ func API() *mux.Router { | |||
| 	m.Path("/text_measurement_types/{Id:.+}").Methods("DELETE").Name(DeleteTextMeasurementType) | ||||
| 
 | ||||
| 	// UnitTypes | ||||
| 	m.Path("/unit_types/").Methods("POST").Name(CreateUnitType) | ||||
| 	m.Path("/unit_types/{Id:.+}").Methods("GET").Name(UnitType) | ||||
| 
 | ||||
| 	return m | ||||
|  |  | |||
|  | @ -41,5 +41,6 @@ const ( | |||
| 	UpdateTextMeasurementType = "text_measurement_type:update" | ||||
| 	DeleteTextMeasurementType = "text_measurement_type:delete" | ||||
| 
 | ||||
| 	UnitType = "unit_type:get" | ||||
| 	UnitType       = "unit_type:get" | ||||
| 	CreateUnitType = "unit_type:create" | ||||
| ) | ||||
|  |  | |||
		Reference in a new issue
	
	 Matthew Dillon
						Matthew Dillon