Cleaning up null values in json
This commit is contained in:
		
							parent
							
								
									bc6e585b8d
								
							
						
					
					
						commit
						8dc07e3cc8
					
				
					 21 changed files with 222 additions and 92 deletions
				
			
		|  | @ -1,6 +1,7 @@ | ||||||
| package api | package api | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"database/sql" | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
| 	"github.com/thermokarst/bactdb/models" | 	"github.com/thermokarst/bactdb/models" | ||||||
|  | @ -8,6 +9,11 @@ import ( | ||||||
| 
 | 
 | ||||||
| func newMeasurement() *models.Measurement { | func newMeasurement() *models.Measurement { | ||||||
| 	measurement := models.NewMeasurement() | 	measurement := models.NewMeasurement() | ||||||
|  | 	measurement.Id = 1 | ||||||
|  | 	measurement.StrainId = 2 | ||||||
|  | 	measurement.ObservationId = 3 | ||||||
|  | 	measurement.TextMeasurementTypeId = models.NullInt64{sql.NullInt64{Int64: 4, Valid: false}} | ||||||
|  | 	measurement.UnitTypeId = models.NullInt64{sql.NullInt64{Int64: 5, Valid: true}} | ||||||
| 	return measurement | 	return measurement | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ import ( | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/lib/pq" | 	"github.com/lib/pq" | ||||||
|  | 	"github.com/thermokarst/bactdb/models" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func normalizeTime(t ...interface{}) { | func normalizeTime(t ...interface{}) { | ||||||
|  | @ -15,9 +16,9 @@ func normalizeTime(t ...interface{}) { | ||||||
| 		case *time.Time: | 		case *time.Time: | ||||||
| 			x, _ := v.(*time.Time) | 			x, _ := v.(*time.Time) | ||||||
| 			*x = x.In(time.UTC) | 			*x = x.In(time.UTC) | ||||||
| 		case *pq.NullTime: | 		case *models.NullTime: | ||||||
| 			x, _ := v.(*pq.NullTime) | 			x, _ := v.(*models.NullTime) | ||||||
| 			*x = pq.NullTime{Time: x.Time.In(time.UTC), Valid: x.Valid} | 			*x = models.NullTime{pq.NullTime{Time: x.Time.In(time.UTC), Valid: x.Valid}} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -30,8 +30,8 @@ func newMeasurement(t *testing.T, tx *modl.Transaction) *models.Measurement { | ||||||
| 	return &models.Measurement{ | 	return &models.Measurement{ | ||||||
| 		StrainId:      strain.Id, | 		StrainId:      strain.Id, | ||||||
| 		ObservationId: observation.Id, | 		ObservationId: observation.Id, | ||||||
| 		NumValue:      sql.NullFloat64{Float64: 1.23, Valid: true}, | 		NumValue:      models.NullFloat64{sql.NullFloat64{Float64: 1.23, Valid: true}}, | ||||||
| 		UnitTypeId:    sql.NullInt64{Int64: unit_type.Id, Valid: true}, | 		UnitTypeId:    models.NullInt64{sql.NullInt64{Int64: unit_type.Id, Valid: true}}, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -108,7 +108,7 @@ func TestMeasurementsStore_Update_db(t *testing.T) { | ||||||
| 	d := NewDatastore(tx) | 	d := NewDatastore(tx) | ||||||
| 
 | 
 | ||||||
| 	// Tweak it | 	// Tweak it | ||||||
| 	measurement.NumValue = sql.NullFloat64{Float64: 4.56, Valid: true} | 	measurement.NumValue = models.NullFloat64{sql.NullFloat64{Float64: 4.56, Valid: true}} | ||||||
| 	updated, err := d.Measurements.Update(measurement.Id, measurement) | 	updated, err := d.Measurements.Update(measurement.Id, measurement) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
|  |  | ||||||
|  | @ -99,9 +99,9 @@ func normalizeTime(t ...interface{}) { | ||||||
| 		case *time.Time: | 		case *time.Time: | ||||||
| 			x, _ := v.(*time.Time) | 			x, _ := v.(*time.Time) | ||||||
| 			*x = x.In(time.UTC) | 			*x = x.In(time.UTC) | ||||||
| 		case *pq.NullTime: | 		case *NullTime: | ||||||
| 			x, _ := v.(*pq.NullTime) | 			x, _ := v.(*NullTime) | ||||||
| 			*x = pq.NullTime{Time: x.Time.In(time.UTC), Valid: x.Valid} | 			*x = NullTime{pq.NullTime{Time: x.Time.In(time.UTC), Valid: x.Valid}} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -6,17 +6,16 @@ import ( | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/lib/pq" |  | ||||||
| 	"github.com/thermokarst/bactdb/router" | 	"github.com/thermokarst/bactdb/router" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // A Genus is a high-level classifier in bactdb. | // A Genus is a high-level classifier in bactdb. | ||||||
| type Genus struct { | type Genus struct { | ||||||
| 	Id        int64       `json:"id,omitempty"` | 	Id        int64     `json:"id,omitempty"` | ||||||
| 	GenusName string      `db:"genus_name" json:"genusName"` | 	GenusName string    `db:"genus_name" json:"genusName"` | ||||||
| 	CreatedAt time.Time   `db:"created_at" json:"createdAt"` | 	CreatedAt time.Time `db:"created_at" json:"createdAt"` | ||||||
| 	UpdatedAt time.Time   `db:"updated_at" json:"updatedAt"` | 	UpdatedAt time.Time `db:"updated_at" json:"updatedAt"` | ||||||
| 	DeletedAt pq.NullTime `db:"deleted_at" json:"deletedAt"` | 	DeletedAt NullTime  `db:"deleted_at" json:"deletedAt"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func NewGenus() *Genus { | func NewGenus() *Genus { | ||||||
|  |  | ||||||
|  | @ -54,7 +54,7 @@ func TestGeneraService_Create(t *testing.T) { | ||||||
| 	mux.HandleFunc(urlPath(t, router.CreateGenus, nil), func(w http.ResponseWriter, r *http.Request) { | 	mux.HandleFunc(urlPath(t, router.CreateGenus, nil), func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		called = true | 		called = true | ||||||
| 		testMethod(t, r, "POST") | 		testMethod(t, r, "POST") | ||||||
| 		testBody(t, r, `{"id":1,"genusName":"Test Genus","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":{"Time":"0001-01-01T00:00:00Z","Valid":false}}`+"\n") | 		testBody(t, r, `{"id":1,"genusName":"Test Genus","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":null}`+"\n") | ||||||
| 
 | 
 | ||||||
| 		w.WriteHeader(http.StatusCreated) | 		w.WriteHeader(http.StatusCreated) | ||||||
| 		writeJSON(w, want) | 		writeJSON(w, want) | ||||||
|  | @ -124,7 +124,7 @@ func TestGeneraService_Update(t *testing.T) { | ||||||
| 	mux.HandleFunc(urlPath(t, router.UpdateGenus, map[string]string{"Id": "1"}), func(w http.ResponseWriter, r *http.Request) { | 	mux.HandleFunc(urlPath(t, router.UpdateGenus, map[string]string{"Id": "1"}), func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		called = true | 		called = true | ||||||
| 		testMethod(t, r, "PUT") | 		testMethod(t, r, "PUT") | ||||||
| 		testBody(t, r, `{"id":1,"genusName":"Test Genus Updated","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":{"Time":"0001-01-01T00:00:00Z","Valid":false}}`+"\n") | 		testBody(t, r, `{"id":1,"genusName":"Test Genus Updated","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":null}`+"\n") | ||||||
| 
 | 
 | ||||||
| 		w.WriteHeader(http.StatusOK) | 		w.WriteHeader(http.StatusOK) | ||||||
| 		writeJSON(w, want) | 		writeJSON(w, want) | ||||||
|  |  | ||||||
|  | @ -15,23 +15,23 @@ import ( | ||||||
| // has a constraint that will allow one or the other for a particular | // has a constraint that will allow one or the other for a particular | ||||||
| // combination of strain & observation, but not both. | // combination of strain & observation, but not both. | ||||||
| type Measurement struct { | type Measurement struct { | ||||||
| 	Id                    int64           `json:"id,omitempty"` | 	Id                    int64       `json:"id,omitempty"` | ||||||
| 	StrainId              int64           `db:"strain_id" json:"strainId"` | 	StrainId              int64       `db:"strain_id" json:"strainId"` | ||||||
| 	ObservationId         int64           `db:"observation_id" json:"observationId"` | 	ObservationId         int64       `db:"observation_id" json:"observationId"` | ||||||
| 	TextMeasurementTypeId sql.NullInt64   `db:"text_measurement_type_id" json:"textMeasurementTypeId"` | 	TextMeasurementTypeId NullInt64   `db:"text_measurement_type_id" json:"textMeasurementTypeId"` | ||||||
| 	TxtValue              sql.NullString  `db:"txt_value" json:"txtValue"` | 	TxtValue              NullString  `db:"txt_value" json:"txtValue"` | ||||||
| 	NumValue              sql.NullFloat64 `db:"num_value" json:"numValue"` | 	NumValue              NullFloat64 `db:"num_value" json:"numValue"` | ||||||
| 	ConfidenceInterval    sql.NullFloat64 `db:"confidence_interval" json:"confidenceInterval"` | 	ConfidenceInterval    NullFloat64 `db:"confidence_interval" json:"confidenceInterval"` | ||||||
| 	UnitTypeId            sql.NullInt64   `db:"unit_type_id" json:"unitTypeId"` | 	UnitTypeId            NullInt64   `db:"unit_type_id" json:"unitTypeId"` | ||||||
| 	Notes                 sql.NullString  `db:"notes" json:"notes"` | 	Notes                 NullString  `db:"notes" json:"notes"` | ||||||
| 	TestMethodId          sql.NullInt64   `db:"test_method_id" json:"testMethodId"` | 	TestMethodId          NullInt64   `db:"test_method_id" json:"testMethodId"` | ||||||
| 	CreatedAt             time.Time       `db:"created_at" json:"createdAt"` | 	CreatedAt             time.Time   `db:"created_at" json:"createdAt"` | ||||||
| 	UpdatedAt             time.Time       `db:"updated_at" json:"updatedAt"` | 	UpdatedAt             time.Time   `db:"updated_at" json:"updatedAt"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func NewMeasurement() *Measurement { | func NewMeasurement() *Measurement { | ||||||
| 	return &Measurement{ | 	return &Measurement{ | ||||||
| 		NumValue: sql.NullFloat64{Float64: 1.23, Valid: true}, | 		NumValue: NullFloat64{sql.NullFloat64{Float64: 1.23, Valid: true}}, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ func newMeasurement() *Measurement { | ||||||
| 	measurement.Id = 1 | 	measurement.Id = 1 | ||||||
| 	measurement.StrainId = 1 | 	measurement.StrainId = 1 | ||||||
| 	measurement.ObservationId = 1 | 	measurement.ObservationId = 1 | ||||||
| 	measurement.UnitTypeId = sql.NullInt64{Int64: 1, Valid: true} | 	measurement.UnitTypeId = NullInt64{sql.NullInt64{Int64: 1, Valid: true}} | ||||||
| 	return measurement | 	return measurement | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -58,7 +58,7 @@ func TestMeasurementService_Create(t *testing.T) { | ||||||
| 	mux.HandleFunc(urlPath(t, router.CreateMeasurement, nil), func(w http.ResponseWriter, r *http.Request) { | 	mux.HandleFunc(urlPath(t, router.CreateMeasurement, nil), func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		called = true | 		called = true | ||||||
| 		testMethod(t, r, "POST") | 		testMethod(t, r, "POST") | ||||||
| 		testBody(t, r, `{"id":1,"strainId":1,"observationId":1,"textMeasurementTypeId":{"Int64":0,"Valid":false},"txtValue":{"String":"","Valid":false},"numValue":{"Float64":1.23,"Valid":true},"confidenceInterval":{"Float64":0,"Valid":false},"unitTypeId":{"Int64":1,"Valid":true},"notes":{"String":"","Valid":false},"testMethodId":{"Int64":0,"Valid":false},"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z"}`+"\n") | 		testBody(t, r, `{"id":1,"strainId":1,"observationId":1,"textMeasurementTypeId":null,"txtValue":null,"numValue":1.23,"confidenceInterval":null,"unitTypeId":1,"notes":null,"testMethodId":null,"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z"}`+"\n") | ||||||
| 
 | 
 | ||||||
| 		w.WriteHeader(http.StatusCreated) | 		w.WriteHeader(http.StatusCreated) | ||||||
| 		writeJSON(w, want) | 		writeJSON(w, want) | ||||||
|  | @ -127,13 +127,13 @@ func TestMeasurementService_Update(t *testing.T) { | ||||||
| 	mux.HandleFunc(urlPath(t, router.UpdateMeasurement, map[string]string{"Id": "1"}), func(w http.ResponseWriter, r *http.Request) { | 	mux.HandleFunc(urlPath(t, router.UpdateMeasurement, map[string]string{"Id": "1"}), func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		called = true | 		called = true | ||||||
| 		testMethod(t, r, "PUT") | 		testMethod(t, r, "PUT") | ||||||
| 		testBody(t, r, `{"id":1,"strainId":1,"observationId":1,"textMeasurementTypeId":{"Int64":0,"Valid":false},"txtValue":{"String":"","Valid":false},"numValue":{"Float64":4.56,"Valid":true},"confidenceInterval":{"Float64":0,"Valid":false},"unitTypeId":{"Int64":1,"Valid":true},"notes":{"String":"","Valid":false},"testMethodId":{"Int64":0,"Valid":false},"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z"}`+"\n") | 		testBody(t, r, `{"id":1,"strainId":1,"observationId":1,"textMeasurementTypeId":null,"txtValue":null,"numValue":4.56,"confidenceInterval":null,"unitTypeId":1,"notes":null,"testMethodId":null,"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z"}`+"\n") | ||||||
| 		w.WriteHeader(http.StatusOK) | 		w.WriteHeader(http.StatusOK) | ||||||
| 		writeJSON(w, want) | 		writeJSON(w, want) | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	measurement := newMeasurement() | 	measurement := newMeasurement() | ||||||
| 	measurement.NumValue = sql.NullFloat64{Float64: 4.56, Valid: true} | 	measurement.NumValue = NullFloat64{sql.NullFloat64{Float64: 4.56, Valid: true}} | ||||||
| 	updated, err := client.Measurements.Update(measurement.Id, measurement) | 	updated, err := client.Measurements.Update(measurement.Id, measurement) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Errorf("Measurements.Update returned error: %v", err) | 		t.Errorf("Measurements.Update returned error: %v", err) | ||||||
|  |  | ||||||
|  | @ -6,17 +6,16 @@ import ( | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/lib/pq" |  | ||||||
| 	"github.com/thermokarst/bactdb/router" | 	"github.com/thermokarst/bactdb/router" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // An Observation Type is a lookup type | // An Observation Type is a lookup type | ||||||
| type ObservationType struct { | type ObservationType struct { | ||||||
| 	Id                  int64       `json:"id,omitempty"` | 	Id                  int64     `json:"id,omitempty"` | ||||||
| 	ObservationTypeName string      `db:"observation_type_name" json:"observationTypeName"` | 	ObservationTypeName string    `db:"observation_type_name" json:"observationTypeName"` | ||||||
| 	CreatedAt           time.Time   `db:"created_at" json:"createdAt"` | 	CreatedAt           time.Time `db:"created_at" json:"createdAt"` | ||||||
| 	UpdatedAt           time.Time   `db:"updated_at" json:"updatedAt"` | 	UpdatedAt           time.Time `db:"updated_at" json:"updatedAt"` | ||||||
| 	DeletedAt           pq.NullTime `db:"deleted_at" json:"deletedAt"` | 	DeletedAt           NullTime  `db:"deleted_at" json:"deletedAt"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func NewObservationType() *ObservationType { | func NewObservationType() *ObservationType { | ||||||
|  |  | ||||||
|  | @ -54,7 +54,7 @@ func TestObservationTypeService_Create(t *testing.T) { | ||||||
| 	mux.HandleFunc(urlPath(t, router.CreateObservationType, nil), func(w http.ResponseWriter, r *http.Request) { | 	mux.HandleFunc(urlPath(t, router.CreateObservationType, nil), func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		called = true | 		called = true | ||||||
| 		testMethod(t, r, "POST") | 		testMethod(t, r, "POST") | ||||||
| 		testBody(t, r, `{"id":1,"observationTypeName":"Test Obs Type","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":{"Time":"0001-01-01T00:00:00Z","Valid":false}}`+"\n") | 		testBody(t, r, `{"id":1,"observationTypeName":"Test Obs Type","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":null}`+"\n") | ||||||
| 
 | 
 | ||||||
| 		w.WriteHeader(http.StatusCreated) | 		w.WriteHeader(http.StatusCreated) | ||||||
| 		writeJSON(w, want) | 		writeJSON(w, want) | ||||||
|  | @ -123,7 +123,7 @@ func TestObservationTypeService_Update(t *testing.T) { | ||||||
| 	mux.HandleFunc(urlPath(t, router.UpdateObservationType, map[string]string{"Id": "1"}), func(w http.ResponseWriter, r *http.Request) { | 	mux.HandleFunc(urlPath(t, router.UpdateObservationType, map[string]string{"Id": "1"}), func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		called = true | 		called = true | ||||||
| 		testMethod(t, r, "PUT") | 		testMethod(t, r, "PUT") | ||||||
| 		testBody(t, r, `{"id":1,"observationTypeName":"Test Obs Type Updated","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":{"Time":"0001-01-01T00:00:00Z","Valid":false}}`+"\n") | 		testBody(t, r, `{"id":1,"observationTypeName":"Test Obs Type Updated","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":null}`+"\n") | ||||||
| 		w.WriteHeader(http.StatusOK) | 		w.WriteHeader(http.StatusOK) | ||||||
| 		writeJSON(w, want) | 		writeJSON(w, want) | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
|  | @ -6,18 +6,17 @@ import ( | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/lib/pq" |  | ||||||
| 	"github.com/thermokarst/bactdb/router" | 	"github.com/thermokarst/bactdb/router" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // An Observation is a lookup type | // An Observation is a lookup type | ||||||
| type Observation struct { | type Observation struct { | ||||||
| 	Id                int64       `json:"id,omitempty"` | 	Id                int64     `json:"id,omitempty"` | ||||||
| 	ObservationName   string      `db:"observation_name" json:"observationName"` | 	ObservationName   string    `db:"observation_name" json:"observationName"` | ||||||
| 	ObservationTypeId int64       `db:"observation_type_id" json:"observationTypeId"` | 	ObservationTypeId int64     `db:"observation_type_id" json:"observationTypeId"` | ||||||
| 	CreatedAt         time.Time   `db:"created_at" json:"createdAt"` | 	CreatedAt         time.Time `db:"created_at" json:"createdAt"` | ||||||
| 	UpdatedAt         time.Time   `db:"updated_at" json:"updatedAt"` | 	UpdatedAt         time.Time `db:"updated_at" json:"updatedAt"` | ||||||
| 	DeletedAt         pq.NullTime `db:"deleted_at" json:"deletedAt"` | 	DeletedAt         NullTime  `db:"deleted_at" json:"deletedAt"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func NewObservation() *Observation { | func NewObservation() *Observation { | ||||||
|  |  | ||||||
|  | @ -54,7 +54,7 @@ func TestObservationService_Create(t *testing.T) { | ||||||
| 	mux.HandleFunc(urlPath(t, router.CreateObservation, nil), func(w http.ResponseWriter, r *http.Request) { | 	mux.HandleFunc(urlPath(t, router.CreateObservation, nil), func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		called = true | 		called = true | ||||||
| 		testMethod(t, r, "POST") | 		testMethod(t, r, "POST") | ||||||
| 		testBody(t, r, `{"id":1,"observationName":"Test Observation","observationTypeId":0,"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":{"Time":"0001-01-01T00:00:00Z","Valid":false}}`+"\n") | 		testBody(t, r, `{"id":1,"observationName":"Test Observation","observationTypeId":0,"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":null}`+"\n") | ||||||
| 
 | 
 | ||||||
| 		w.WriteHeader(http.StatusCreated) | 		w.WriteHeader(http.StatusCreated) | ||||||
| 		writeJSON(w, want) | 		writeJSON(w, want) | ||||||
|  | @ -123,7 +123,7 @@ func TestObservationService_Update(t *testing.T) { | ||||||
| 	mux.HandleFunc(urlPath(t, router.UpdateObservation, map[string]string{"Id": "1"}), func(w http.ResponseWriter, r *http.Request) { | 	mux.HandleFunc(urlPath(t, router.UpdateObservation, map[string]string{"Id": "1"}), func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		called = true | 		called = true | ||||||
| 		testMethod(t, r, "PUT") | 		testMethod(t, r, "PUT") | ||||||
| 		testBody(t, r, `{"id":1,"observationName":"Test Obs Updated","observationTypeId":0,"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":{"Time":"0001-01-01T00:00:00Z","Valid":false}}`+"\n") | 		testBody(t, r, `{"id":1,"observationName":"Test Obs Updated","observationTypeId":0,"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":null}`+"\n") | ||||||
| 		w.WriteHeader(http.StatusOK) | 		w.WriteHeader(http.StatusOK) | ||||||
| 		writeJSON(w, want) | 		writeJSON(w, want) | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
|  | @ -6,18 +6,17 @@ import ( | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/lib/pq" |  | ||||||
| 	"github.com/thermokarst/bactdb/router" | 	"github.com/thermokarst/bactdb/router" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // A Species is a high-level classifier in bactdb. | // A Species is a high-level classifier in bactdb. | ||||||
| type Species struct { | type Species struct { | ||||||
| 	Id          int64       `json:"id,omitempty"` | 	Id          int64     `json:"id,omitempty"` | ||||||
| 	GenusId     int64       `db:"genus_id" json:"genusId"` | 	GenusId     int64     `db:"genus_id" json:"genusId"` | ||||||
| 	SpeciesName string      `db:"species_name" json:"speciesName"` | 	SpeciesName string    `db:"species_name" json:"speciesName"` | ||||||
| 	CreatedAt   time.Time   `db:"created_at" json:"createdAt"` | 	CreatedAt   time.Time `db:"created_at" json:"createdAt"` | ||||||
| 	UpdatedAt   time.Time   `db:"updated_at" json:"updatedAt"` | 	UpdatedAt   time.Time `db:"updated_at" json:"updatedAt"` | ||||||
| 	DeletedAt   pq.NullTime `db:"deleted_at" json:"deletedAt"` | 	DeletedAt   NullTime  `db:"deleted_at" json:"deletedAt"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func NewSpecies() *Species { | func NewSpecies() *Species { | ||||||
|  |  | ||||||
|  | @ -55,7 +55,7 @@ func TestSpeciesService_Create(t *testing.T) { | ||||||
| 	mux.HandleFunc(urlPath(t, router.CreateSpecies, nil), func(w http.ResponseWriter, r *http.Request) { | 	mux.HandleFunc(urlPath(t, router.CreateSpecies, nil), func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		called = true | 		called = true | ||||||
| 		testMethod(t, r, "POST") | 		testMethod(t, r, "POST") | ||||||
| 		testBody(t, r, `{"id":1,"genusId":1,"speciesName":"Test Species","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":{"Time":"0001-01-01T00:00:00Z","Valid":false}}`+"\n") | 		testBody(t, r, `{"id":1,"genusId":1,"speciesName":"Test Species","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":null}`+"\n") | ||||||
| 
 | 
 | ||||||
| 		w.WriteHeader(http.StatusCreated) | 		w.WriteHeader(http.StatusCreated) | ||||||
| 		writeJSON(w, want) | 		writeJSON(w, want) | ||||||
|  | @ -124,7 +124,7 @@ func TestSpeciesService_Update(t *testing.T) { | ||||||
| 	mux.HandleFunc(urlPath(t, router.UpdateSpecies, map[string]string{"Id": "1"}), func(w http.ResponseWriter, r *http.Request) { | 	mux.HandleFunc(urlPath(t, router.UpdateSpecies, map[string]string{"Id": "1"}), func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		called = true | 		called = true | ||||||
| 		testMethod(t, r, "PUT") | 		testMethod(t, r, "PUT") | ||||||
| 		testBody(t, r, `{"id":1,"genusId":1,"speciesName":"Test Species Updated","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":{"Time":"0001-01-01T00:00:00Z","Valid":false}}`+"\n") | 		testBody(t, r, `{"id":1,"genusId":1,"speciesName":"Test Species Updated","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":null}`+"\n") | ||||||
| 
 | 
 | ||||||
| 		w.WriteHeader(http.StatusOK) | 		w.WriteHeader(http.StatusOK) | ||||||
| 		writeJSON(w, want) | 		writeJSON(w, want) | ||||||
|  |  | ||||||
|  | @ -1,29 +1,27 @@ | ||||||
| package models | package models | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"database/sql" |  | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/lib/pq" |  | ||||||
| 	"github.com/thermokarst/bactdb/router" | 	"github.com/thermokarst/bactdb/router" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // A Strain is a subclass of species | // A Strain is a subclass of species | ||||||
| type Strain struct { | type Strain struct { | ||||||
| 	Id             int64          `json:"id,omitempty"` | 	Id             int64      `json:"id,omitempty"` | ||||||
| 	SpeciesId      int64          `db:"species_id" json:"speciesId"` | 	SpeciesId      int64      `db:"species_id" json:"speciesId"` | ||||||
| 	StrainName     string         `db:"strain_name" json:"strainName"` | 	StrainName     string     `db:"strain_name" json:"strainName"` | ||||||
| 	StrainType     string         `db:"strain_type" json:"strainType"` | 	StrainType     string     `db:"strain_type" json:"strainType"` | ||||||
| 	Etymology      string         `db:"etymology" json:"etymology"` | 	Etymology      string     `db:"etymology" json:"etymology"` | ||||||
| 	AccessionBanks string         `db:"accession_banks" json:"accessionBanks"` | 	AccessionBanks string     `db:"accession_banks" json:"accessionBanks"` | ||||||
| 	GenbankEmblDdb string         `db:"genbank_embl_ddb" json:"genbankEmblDdb"` | 	GenbankEmblDdb string     `db:"genbank_embl_ddb" json:"genbankEmblDdb"` | ||||||
| 	IsolatedFrom   sql.NullString `db:"isolated_from" json:"isolatedFrom"` | 	IsolatedFrom   NullString `db:"isolated_from" json:"isolatedFrom"` | ||||||
| 	CreatedAt      time.Time      `db:"created_at" json:"createdAt"` | 	CreatedAt      time.Time  `db:"created_at" json:"createdAt"` | ||||||
| 	UpdatedAt      time.Time      `db:"updated_at" json:"updatedAt"` | 	UpdatedAt      time.Time  `db:"updated_at" json:"updatedAt"` | ||||||
| 	DeletedAt      pq.NullTime    `db:"deleted_at" json:"deletedAt"` | 	DeletedAt      NullTime   `db:"deleted_at" json:"deletedAt"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func NewStrain() *Strain { | func NewStrain() *Strain { | ||||||
|  |  | ||||||
|  | @ -55,7 +55,7 @@ func TestStrainService_Create(t *testing.T) { | ||||||
| 	mux.HandleFunc(urlPath(t, router.CreateStrain, nil), func(w http.ResponseWriter, r *http.Request) { | 	mux.HandleFunc(urlPath(t, router.CreateStrain, nil), func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		called = true | 		called = true | ||||||
| 		testMethod(t, r, "POST") | 		testMethod(t, r, "POST") | ||||||
| 		testBody(t, r, `{"id":1,"speciesId":1,"strainName":"Test Strain","strainType":"Test Type","etymology":"Test Etymology","accessionBanks":"Test Accession","genbankEmblDdb":"Test Genbank","isolatedFrom":{"String":"","Valid":false},"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":{"Time":"0001-01-01T00:00:00Z","Valid":false}}`+"\n") | 		testBody(t, r, `{"id":1,"speciesId":1,"strainName":"Test Strain","strainType":"Test Type","etymology":"Test Etymology","accessionBanks":"Test Accession","genbankEmblDdb":"Test Genbank","isolatedFrom":null,"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":null}`+"\n") | ||||||
| 
 | 
 | ||||||
| 		w.WriteHeader(http.StatusCreated) | 		w.WriteHeader(http.StatusCreated) | ||||||
| 		writeJSON(w, want) | 		writeJSON(w, want) | ||||||
|  | @ -124,7 +124,7 @@ func TestStrainService_Update(t *testing.T) { | ||||||
| 	mux.HandleFunc(urlPath(t, router.UpdateStrain, map[string]string{"Id": "1"}), func(w http.ResponseWriter, r *http.Request) { | 	mux.HandleFunc(urlPath(t, router.UpdateStrain, map[string]string{"Id": "1"}), func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		called = true | 		called = true | ||||||
| 		testMethod(t, r, "PUT") | 		testMethod(t, r, "PUT") | ||||||
| 		testBody(t, r, `{"id":1,"speciesId":1,"strainName":"Test Strain Updated","strainType":"Test Type Updated","etymology":"Test Etymology Updated","accessionBanks":"Test Accession Updated","genbankEmblDdb":"Test Genbank Updated","isolatedFrom":{"String":"","Valid":false},"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":{"Time":"0001-01-01T00:00:00Z","Valid":false}}`+"\n") | 		testBody(t, r, `{"id":1,"speciesId":1,"strainName":"Test Strain Updated","strainType":"Test Type Updated","etymology":"Test Etymology Updated","accessionBanks":"Test Accession Updated","genbankEmblDdb":"Test Genbank Updated","isolatedFrom":null,"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":null}`+"\n") | ||||||
| 		w.WriteHeader(http.StatusOK) | 		w.WriteHeader(http.StatusOK) | ||||||
| 		writeJSON(w, want) | 		writeJSON(w, want) | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
|  | @ -6,17 +6,16 @@ import ( | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/lib/pq" |  | ||||||
| 	"github.com/thermokarst/bactdb/router" | 	"github.com/thermokarst/bactdb/router" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // A TextMeasurementType is a lookup type | // A TextMeasurementType is a lookup type | ||||||
| type TextMeasurementType struct { | type TextMeasurementType struct { | ||||||
| 	Id                  int64       `json:"id,omitempty"` | 	Id                  int64     `json:"id,omitempty"` | ||||||
| 	TextMeasurementName string      `db:"text_measurement_name" json:"textMeasurementName"` | 	TextMeasurementName string    `db:"text_measurement_name" json:"textMeasurementName"` | ||||||
| 	CreatedAt           time.Time   `db:"created_at" json:"createdAt"` | 	CreatedAt           time.Time `db:"created_at" json:"createdAt"` | ||||||
| 	UpdatedAt           time.Time   `db:"updated_at" json:"updatedAt"` | 	UpdatedAt           time.Time `db:"updated_at" json:"updatedAt"` | ||||||
| 	DeletedAt           pq.NullTime `db:"deleted_at" json:"deletedAt"` | 	DeletedAt           NullTime  `db:"deleted_at" json:"deletedAt"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func NewTextMeasurementType() *TextMeasurementType { | func NewTextMeasurementType() *TextMeasurementType { | ||||||
|  |  | ||||||
|  | @ -54,7 +54,7 @@ func TestTextMeasurementTypeService_Create(t *testing.T) { | ||||||
| 	mux.HandleFunc(urlPath(t, router.CreateTextMeasurementType, nil), func(w http.ResponseWriter, r *http.Request) { | 	mux.HandleFunc(urlPath(t, router.CreateTextMeasurementType, nil), func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		called = true | 		called = true | ||||||
| 		testMethod(t, r, "POST") | 		testMethod(t, r, "POST") | ||||||
| 		testBody(t, r, `{"id":1,"textMeasurementName":"Test Text Measurement Type","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":{"Time":"0001-01-01T00:00:00Z","Valid":false}}`+"\n") | 		testBody(t, r, `{"id":1,"textMeasurementName":"Test Text Measurement Type","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":null}`+"\n") | ||||||
| 
 | 
 | ||||||
| 		w.WriteHeader(http.StatusCreated) | 		w.WriteHeader(http.StatusCreated) | ||||||
| 		writeJSON(w, want) | 		writeJSON(w, want) | ||||||
|  | @ -123,7 +123,7 @@ func TestTextMeasurementTypeService_Update(t *testing.T) { | ||||||
| 	mux.HandleFunc(urlPath(t, router.UpdateTextMeasurementType, map[string]string{"Id": "1"}), func(w http.ResponseWriter, r *http.Request) { | 	mux.HandleFunc(urlPath(t, router.UpdateTextMeasurementType, map[string]string{"Id": "1"}), func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		called = true | 		called = true | ||||||
| 		testMethod(t, r, "PUT") | 		testMethod(t, r, "PUT") | ||||||
| 		testBody(t, r, `{"id":1,"textMeasurementName":"Test Text Measurement Type Updated","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":{"Time":"0001-01-01T00:00:00Z","Valid":false}}`+"\n") | 		testBody(t, r, `{"id":1,"textMeasurementName":"Test Text Measurement Type Updated","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":null}`+"\n") | ||||||
| 		w.WriteHeader(http.StatusOK) | 		w.WriteHeader(http.StatusOK) | ||||||
| 		writeJSON(w, want) | 		writeJSON(w, want) | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
							
								
								
									
										131
									
								
								models/types.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								models/types.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,131 @@ | ||||||
|  | package models | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"database/sql" | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/lib/pq" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type NullString struct { | ||||||
|  | 	sql.NullString | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (s *NullString) MarshalJSON() ([]byte, error) { | ||||||
|  | 	if !s.Valid { | ||||||
|  | 		return []byte("null"), nil | ||||||
|  | 	} | ||||||
|  | 	return json.Marshal(s.String) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (s *NullString) UnmarshalJSON(b []byte) error { | ||||||
|  | 	if bytes.Equal(b, []byte("null")) { | ||||||
|  | 		s.String = "" | ||||||
|  | 		s.Valid = false | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	var x interface{} | ||||||
|  | 	var err error | ||||||
|  | 	json.Unmarshal(b, &x) | ||||||
|  | 	switch x.(type) { | ||||||
|  | 	case float64: | ||||||
|  | 		err = json.Unmarshal(b, &s.String) | ||||||
|  | 	case map[string]interface{}: | ||||||
|  | 		err = json.Unmarshal(b, &s.NullString) | ||||||
|  | 	} | ||||||
|  | 	s.Valid = true | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type NullInt64 struct { | ||||||
|  | 	sql.NullInt64 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (i *NullInt64) MarshalJSON() ([]byte, error) { | ||||||
|  | 	if !i.Valid { | ||||||
|  | 		return []byte("null"), nil | ||||||
|  | 	} | ||||||
|  | 	return json.Marshal(i.Int64) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (i *NullInt64) UnmarshalJSON(b []byte) error { | ||||||
|  | 	if bytes.Equal(b, []byte("null")) { | ||||||
|  | 		i.Int64 = 0 | ||||||
|  | 		i.Valid = false | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	var x interface{} | ||||||
|  | 	var err error | ||||||
|  | 	json.Unmarshal(b, &x) | ||||||
|  | 	switch x.(type) { | ||||||
|  | 	case float64: | ||||||
|  | 		err = json.Unmarshal(b, &i.Int64) | ||||||
|  | 	case map[string]interface{}: | ||||||
|  | 		err = json.Unmarshal(b, &i.NullInt64) | ||||||
|  | 	} | ||||||
|  | 	i.Valid = true | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type NullFloat64 struct { | ||||||
|  | 	sql.NullFloat64 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (f *NullFloat64) MarshalJSON() ([]byte, error) { | ||||||
|  | 	if !f.Valid { | ||||||
|  | 		return []byte("null"), nil | ||||||
|  | 	} | ||||||
|  | 	return json.Marshal(f.Float64) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (f *NullFloat64) UnmarshalJSON(b []byte) error { | ||||||
|  | 	if bytes.Equal(b, []byte("null")) { | ||||||
|  | 		f.Float64 = 0 | ||||||
|  | 		f.Valid = false | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	var x interface{} | ||||||
|  | 	var err error | ||||||
|  | 	json.Unmarshal(b, &x) | ||||||
|  | 	switch x.(type) { | ||||||
|  | 	case float64: | ||||||
|  | 		err = json.Unmarshal(b, &f.Float64) | ||||||
|  | 	case map[string]interface{}: | ||||||
|  | 		err = json.Unmarshal(b, &f.NullFloat64) | ||||||
|  | 	} | ||||||
|  | 	f.Valid = true | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type NullTime struct { | ||||||
|  | 	pq.NullTime | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (t *NullTime) MarshalJSON() ([]byte, error) { | ||||||
|  | 	if !t.Valid { | ||||||
|  | 		return []byte("null"), nil | ||||||
|  | 	} | ||||||
|  | 	return json.Marshal(t.Time) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (t *NullTime) UnmarshalJSON(b []byte) error { | ||||||
|  | 	if bytes.Equal(b, []byte("null")) { | ||||||
|  | 		var nt time.Time | ||||||
|  | 		t.Time = nt.In(time.UTC) | ||||||
|  | 		t.Valid = false | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	var x interface{} | ||||||
|  | 	var err error | ||||||
|  | 	json.Unmarshal(b, &x) | ||||||
|  | 	switch x.(type) { | ||||||
|  | 	case time.Time: | ||||||
|  | 		err = json.Unmarshal(b, &t.Time) | ||||||
|  | 	case map[string]interface{}: | ||||||
|  | 		err = json.Unmarshal(b, &t.NullTime) | ||||||
|  | 	} | ||||||
|  | 	t.Valid = true | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  | @ -6,18 +6,17 @@ import ( | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/lib/pq" |  | ||||||
| 	"github.com/thermokarst/bactdb/router" | 	"github.com/thermokarst/bactdb/router" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // A UnitType is a lookup type | // A UnitType is a lookup type | ||||||
| type UnitType struct { | type UnitType struct { | ||||||
| 	Id        int64       `json:"id,omitempty"` | 	Id        int64     `json:"id,omitempty"` | ||||||
| 	Name      string      `db:"name" json:"name"` | 	Name      string    `db:"name" json:"name"` | ||||||
| 	Symbol    string      `db:"symbol" json:"symbol"` | 	Symbol    string    `db:"symbol" json:"symbol"` | ||||||
| 	CreatedAt time.Time   `db:"created_at" json:"createdAt"` | 	CreatedAt time.Time `db:"created_at" json:"createdAt"` | ||||||
| 	UpdatedAt time.Time   `db:"updated_at" json:"updatedAt"` | 	UpdatedAt time.Time `db:"updated_at" json:"updatedAt"` | ||||||
| 	DeletedAt pq.NullTime `db:"deleted_at" json:"deletedAt"` | 	DeletedAt NullTime  `db:"deleted_at" json:"deletedAt"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func NewUnitType() *UnitType { | func NewUnitType() *UnitType { | ||||||
|  |  | ||||||
|  | @ -54,7 +54,7 @@ func TestUnitTypeService_Create(t *testing.T) { | ||||||
| 	mux.HandleFunc(urlPath(t, router.CreateUnitType, nil), func(w http.ResponseWriter, r *http.Request) { | 	mux.HandleFunc(urlPath(t, router.CreateUnitType, nil), func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		called = true | 		called = true | ||||||
| 		testMethod(t, r, "POST") | 		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") | 		testBody(t, r, `{"id":1,"name":"Test Unit Type","symbol":"x","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":null}`+"\n") | ||||||
| 
 | 
 | ||||||
| 		w.WriteHeader(http.StatusCreated) | 		w.WriteHeader(http.StatusCreated) | ||||||
| 		writeJSON(w, want) | 		writeJSON(w, want) | ||||||
|  | @ -123,7 +123,7 @@ func TestUnitTypeService_Update(t *testing.T) { | ||||||
| 	mux.HandleFunc(urlPath(t, router.UpdateUnitType, map[string]string{"Id": "1"}), func(w http.ResponseWriter, r *http.Request) { | 	mux.HandleFunc(urlPath(t, router.UpdateUnitType, map[string]string{"Id": "1"}), func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		called = true | 		called = true | ||||||
| 		testMethod(t, r, "PUT") | 		testMethod(t, r, "PUT") | ||||||
| 		testBody(t, r, `{"id":1,"name":"Test Unit Type Updated","symbol":"x","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":{"Time":"0001-01-01T00:00:00Z","Valid":false}}`+"\n") | 		testBody(t, r, `{"id":1,"name":"Test Unit Type Updated","symbol":"x","createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z","deletedAt":null}`+"\n") | ||||||
| 		w.WriteHeader(http.StatusOK) | 		w.WriteHeader(http.StatusOK) | ||||||
| 		writeJSON(w, want) | 		writeJSON(w, want) | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 Matthew Dillon
						Matthew Dillon