From ae159aed38e8bbd0f14625d06299fb15516a57ff Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 2 Nov 2023 08:30:58 +1300 Subject: [PATCH 1/5] wip --- data/types/settings/pump/bolus.go | 35 +++++++++++++++++++++++++++++++ data/types/settings/pump/pump.go | 8 +++++++ 2 files changed, 43 insertions(+) diff --git a/data/types/settings/pump/bolus.go b/data/types/settings/pump/bolus.go index 344d7f0a0..40dda069c 100644 --- a/data/types/settings/pump/bolus.go +++ b/data/types/settings/pump/bolus.go @@ -1,8 +1,11 @@ package pump import ( + "strconv" + "github.com/tidepool-org/platform/data" "github.com/tidepool-org/platform/structure" + structureValidator "github.com/tidepool-org/platform/structure/validator" ) type Bolus struct { @@ -53,3 +56,35 @@ func (b *Bolus) Normalize(normalizer data.Normalizer) { b.Extended.Normalize(normalizer.WithReference("extended")) } } + +type Boluses []*Bolus + +func ParseBoluses(parser structure.ArrayParser) *Boluses { + if !parser.Exists() { + return nil + } + datum := NewBoluses() + parser.Parse(datum) + return datum +} + +func NewBoluses() *Boluses { + return &Boluses{} +} + +func (b *Boluses) Parse(parser structure.ArrayParser) { + for _, reference := range parser.References() { + *b = append(*b, ParseBolus(parser.WithReferenceObjectParser(reference))) + } +} + +func (b *Boluses) Validate(validator structure.Validator) { + + for index, datum := range *b { + if datumValidator := validator.WithReference(strconv.Itoa(index)); datum != nil { + datum.Validate(datumValidator) + } else { + datumValidator.ReportError(structureValidator.ErrorValueNotExists()) + } + } +} diff --git a/data/types/settings/pump/pump.go b/data/types/settings/pump/pump.go index eb61abdfb..621f34576 100644 --- a/data/types/settings/pump/pump.go +++ b/data/types/settings/pump/pump.go @@ -42,6 +42,7 @@ type Pump struct { BloodGlucoseTargetSchedule *BloodGlucoseTargetStartArray `json:"bgTarget,omitempty" bson:"bgTarget,omitempty"` // TODO: Move into BolusCalculator struct; rename bloodGlucoseTarget BloodGlucoseTargetSchedules *BloodGlucoseTargetStartArrayMap `json:"bgTargets,omitempty" bson:"bgTargets,omitempty"` // TODO: Move into BolusCalculator struct; rename bloodGlucoseTargets Bolus *Bolus `json:"bolus,omitempty" bson:"bolus,omitempty"` + Boluses *Boluses `json:"boluses,omitempty" bson:"boluses,omitempty"` CarbohydrateRatioSchedule *CarbohydrateRatioStartArray `json:"carbRatio,omitempty" bson:"carbRatio,omitempty"` // TODO: Move into BolusCalculator struct; rename carbohydrateRatio CarbohydrateRatioSchedules *CarbohydrateRatioStartArrayMap `json:"carbRatios,omitempty" bson:"carbRatios,omitempty"` // TODO: Move into BolusCalculator struct; rename carbohydrateRatios Display *Display `json:"display,omitempty" bson:"display,omitempty"` @@ -85,6 +86,7 @@ func (p *Pump) Parse(parser structure.ObjectParser) { p.BloodGlucoseTargetSchedule = ParseBloodGlucoseTargetStartArray(parser.WithReferenceArrayParser("bgTarget")) p.BloodGlucoseTargetSchedules = ParseBloodGlucoseTargetStartArrayMap(parser.WithReferenceObjectParser("bgTargets")) p.Bolus = ParseBolus(parser.WithReferenceObjectParser("bolus")) + p.Boluses = ParseBoluses(parser.WithReferenceArrayParser("boluses")) p.CarbohydrateRatioSchedule = ParseCarbohydrateRatioStartArray(parser.WithReferenceArrayParser("carbRatio")) p.CarbohydrateRatioSchedules = ParseCarbohydrateRatioStartArrayMap(parser.WithReferenceObjectParser("carbRatios")) p.Display = ParseDisplay(parser.WithReferenceObjectParser("display")) @@ -149,7 +151,13 @@ func (p *Pump) Validate(validator structure.Validator) { } if p.Bolus != nil { p.Bolus.Validate(validator.WithReference("bolus")) + if p.Boluses != nil { + validator.WithReference("boluses").ReportError(structureValidator.ErrorValueExists()) + } + } else if p.Boluses != nil { + p.Boluses.Validate(validator.WithReference("boluses")) } + if p.CarbohydrateRatioSchedule != nil { p.CarbohydrateRatioSchedule.Validate(validator.WithReference("carbRatio")) if p.CarbohydrateRatioSchedules != nil { From 2deb1319c070e401f0258fcab75ad0d545706c22 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 2 Nov 2023 18:13:22 +1300 Subject: [PATCH 2/5] include boluses to pump settings --- data/types/settings/pump/bolus.go | 54 +++++++++--- data/types/settings/pump/bolus_test.go | 109 ++++++++++++++++++++++++- data/types/settings/pump/pump.go | 7 +- data/types/settings/pump/pump_test.go | 2 +- data/types/settings/pump/test/bolus.go | 30 ++++++- data/types/settings/pump/test/pump.go | 2 +- 6 files changed, 183 insertions(+), 21 deletions(-) diff --git a/data/types/settings/pump/bolus.go b/data/types/settings/pump/bolus.go index 40dda069c..aa8201394 100644 --- a/data/types/settings/pump/bolus.go +++ b/data/types/settings/pump/bolus.go @@ -1,7 +1,7 @@ package pump import ( - "strconv" + "sort" "github.com/tidepool-org/platform/data" "github.com/tidepool-org/platform/structure" @@ -57,34 +57,62 @@ func (b *Bolus) Normalize(normalizer data.Normalizer) { } } -type Boluses []*Bolus +type BolusMap map[string]*Bolus -func ParseBoluses(parser structure.ArrayParser) *Boluses { +func ParseBolusMap(parser structure.ObjectParser) *BolusMap { if !parser.Exists() { return nil } - datum := NewBoluses() + datum := NewBolusMap() parser.Parse(datum) return datum } -func NewBoluses() *Boluses { - return &Boluses{} +func NewBolusMap() *BolusMap { + return &BolusMap{} } -func (b *Boluses) Parse(parser structure.ArrayParser) { +func (b *BolusMap) Parse(parser structure.ObjectParser) { for _, reference := range parser.References() { - *b = append(*b, ParseBolus(parser.WithReferenceObjectParser(reference))) + b.Set(reference, ParseBolus(parser.WithReferenceObjectParser(reference))) } } -func (b *Boluses) Validate(validator structure.Validator) { +func (b *BolusMap) Normalize(normalizer data.Normalizer) { + for _, name := range b.sortedNames() { + if datum := b.Get(name); datum != nil { + datum.Normalize(normalizer.WithReference(name)) + } + } +} - for index, datum := range *b { - if datumValidator := validator.WithReference(strconv.Itoa(index)); datum != nil { - datum.Validate(datumValidator) +func (b *BolusMap) Validate(validator structure.Validator) { + for _, name := range b.sortedNames() { + datumArrayValidator := validator.WithReference(name) + if datumArray := b.Get(name); datumArray != nil { + datumArray.Validate(datumArrayValidator) } else { - datumValidator.ReportError(structureValidator.ErrorValueNotExists()) + datumArrayValidator.ReportError(structureValidator.ErrorValueNotExists()) } } } + +func (b *BolusMap) Get(name string) *Bolus { + if datumArray, exists := (*b)[name]; exists { + return datumArray + } + return nil +} + +func (b *BolusMap) Set(name string, datum *Bolus) { + (*b)[name] = datum +} + +func (b *BolusMap) sortedNames() []string { + names := []string{} + for name := range *b { + names = append(names, name) + } + sort.Strings(names) + return names +} diff --git a/data/types/settings/pump/bolus_test.go b/data/types/settings/pump/bolus_test.go index bcfe12659..4f9c7d75a 100644 --- a/data/types/settings/pump/bolus_test.go +++ b/data/types/settings/pump/bolus_test.go @@ -34,7 +34,7 @@ var _ = Describe("Bolus", func() { Context("Validate", func() { DescribeTable("validates the datum", func(mutator func(datum *pump.Bolus), expectedErrors ...error) { - datum := pumpTest.NewBolus() + datum := pumpTest.NewRandomBolus() mutator(datum) dataTypesTest.ValidateWithExpectedOrigins(datum, structure.Origins(), expectedErrors...) }, @@ -76,7 +76,7 @@ var _ = Describe("Bolus", func() { DescribeTable("normalizes the datum", func(mutator func(datum *pump.Bolus)) { for _, origin := range structure.Origins() { - datum := pumpTest.NewBolus() + datum := pumpTest.NewRandomBolus() mutator(datum) expectedDatum := pumpTest.CloneBolus(datum) normalizer := dataNormalizer.New() @@ -99,4 +99,109 @@ var _ = Describe("Bolus", func() { ) }) }) + + Context("Boluses", func() { + + Context("Validate", func() { + DescribeTable("validates the datum", + func(mutator func(datum *pump.BolusMap), expectedErrors ...error) { + datum := pump.NewBolusMap() + mutator(datum) + dataTypesTest.ValidateWithExpectedOrigins(datum, structure.Origins(), expectedErrors...) + }, + Entry("succeeds", + func(datum *pump.BolusMap) {}, + ), + Entry("empty", + func(datum *pump.BolusMap) { + *datum = *pump.NewBolusMap() + }, + ), + + Entry("single invalid", + func(datum *pump.BolusMap) { + invalid := pumpTest.NewRandomBolus() + invalid.AmountMaximum.Units = nil + datum.Set("one", invalid) + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/one/amountMaximum/units"), + ), + Entry("single valid", + func(datum *pump.BolusMap) { + datum.Set("one", pumpTest.NewRandomBolus()) + }, + ), + Entry("multiple valid", + func(datum *pump.BolusMap) { + datum.Set("one", pumpTest.NewRandomBolus()) + datum.Set("two", pumpTest.NewRandomBolus()) + datum.Set("three", pumpTest.NewRandomBolus()) + }, + ), + Entry("multiple errors", + func(datum *pump.BolusMap) { + invalid := pumpTest.NewRandomBolus() + invalid.AmountMaximum.Units = nil + + invalidThree := pumpTest.NewRandomBolus() + invalidThree.AmountMaximum.Value = nil + + datum.Set("one", invalid) + datum.Set("two", pumpTest.NewRandomBolus()) + datum.Set("three", invalidThree) + }, + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/one/amountMaximum/units"), + errorsTest.WithPointerSource(structureValidator.ErrorValueNotExists(), "/three/amountMaximum/value"), + ), + ) + }) + Context("Normalize", func() { + DescribeTable("normalizes the datum", + func(mutator func(datum *pump.BolusMap), expectator func(datum *pump.BolusMap, expectedDatum *pump.BolusMap)) { + for _, origin := range structure.Origins() { + datum := pumpTest.NewRandomBolusMap(1, 4) + mutator(datum) + expectedDatum := pumpTest.CloneBolusMap(datum) + normalizer := dataNormalizer.New() + Expect(normalizer).ToNot(BeNil()) + datum.Normalize(normalizer.WithOrigin(origin)) + Expect(normalizer.Error()).To(BeNil()) + Expect(normalizer.Data()).To(BeEmpty()) + if expectator != nil { + expectator(datum, expectedDatum) + } + Expect(datum).To(Equal(expectedDatum)) + } + }, + Entry("does not modify the datum", + func(datum *pump.BolusMap) {}, + nil, + ), + Entry("does not modify the datum; amountMaximum missing", + func(datum *pump.BolusMap) { + for name := range *datum { + (*(*datum)[name]).AmountMaximum = nil + } + }, + nil, + ), + Entry("does not modify the datum; calculator missing", + func(datum *pump.BolusMap) { + for name := range *datum { + (*(*datum)[name]).Calculator = nil + } + }, + nil, + ), + Entry("does not modify the datum; extended missing", + func(datum *pump.BolusMap) { + for name := range *datum { + (*(*datum)[name]).Extended = nil + } + }, + nil, + ), + ) + }) + }) }) diff --git a/data/types/settings/pump/pump.go b/data/types/settings/pump/pump.go index 621f34576..5f3ca91e2 100644 --- a/data/types/settings/pump/pump.go +++ b/data/types/settings/pump/pump.go @@ -42,7 +42,7 @@ type Pump struct { BloodGlucoseTargetSchedule *BloodGlucoseTargetStartArray `json:"bgTarget,omitempty" bson:"bgTarget,omitempty"` // TODO: Move into BolusCalculator struct; rename bloodGlucoseTarget BloodGlucoseTargetSchedules *BloodGlucoseTargetStartArrayMap `json:"bgTargets,omitempty" bson:"bgTargets,omitempty"` // TODO: Move into BolusCalculator struct; rename bloodGlucoseTargets Bolus *Bolus `json:"bolus,omitempty" bson:"bolus,omitempty"` - Boluses *Boluses `json:"boluses,omitempty" bson:"boluses,omitempty"` + Boluses *BolusMap `json:"boluses,omitempty" bson:"boluses,omitempty"` CarbohydrateRatioSchedule *CarbohydrateRatioStartArray `json:"carbRatio,omitempty" bson:"carbRatio,omitempty"` // TODO: Move into BolusCalculator struct; rename carbohydrateRatio CarbohydrateRatioSchedules *CarbohydrateRatioStartArrayMap `json:"carbRatios,omitempty" bson:"carbRatios,omitempty"` // TODO: Move into BolusCalculator struct; rename carbohydrateRatios Display *Display `json:"display,omitempty" bson:"display,omitempty"` @@ -86,7 +86,7 @@ func (p *Pump) Parse(parser structure.ObjectParser) { p.BloodGlucoseTargetSchedule = ParseBloodGlucoseTargetStartArray(parser.WithReferenceArrayParser("bgTarget")) p.BloodGlucoseTargetSchedules = ParseBloodGlucoseTargetStartArrayMap(parser.WithReferenceObjectParser("bgTargets")) p.Bolus = ParseBolus(parser.WithReferenceObjectParser("bolus")) - p.Boluses = ParseBoluses(parser.WithReferenceArrayParser("boluses")) + p.Boluses = ParseBolusMap(parser.WithReferenceObjectParser("boluses")) p.CarbohydrateRatioSchedule = ParseCarbohydrateRatioStartArray(parser.WithReferenceArrayParser("carbRatio")) p.CarbohydrateRatioSchedules = ParseCarbohydrateRatioStartArrayMap(parser.WithReferenceObjectParser("carbRatios")) p.Display = ParseDisplay(parser.WithReferenceObjectParser("display")) @@ -240,6 +240,9 @@ func (p *Pump) Normalize(normalizer data.Normalizer) { if p.Bolus != nil { p.Bolus.Normalize(normalizer.WithReference("bolus")) } + if p.Boluses != nil { + p.Boluses.Normalize(normalizer.WithReference("boluses")) + } if p.CarbohydrateRatioSchedule != nil { p.CarbohydrateRatioSchedule.Normalize(normalizer.WithReference("carbRatio")) } diff --git a/data/types/settings/pump/pump_test.go b/data/types/settings/pump/pump_test.go index 631dd2671..af4b6d231 100644 --- a/data/types/settings/pump/pump_test.go +++ b/data/types/settings/pump/pump_test.go @@ -288,7 +288,7 @@ var _ = Describe("Pump", func() { ), Entry("bolus valid", pointer.FromString("mmol/L"), - func(datum *pump.Pump, unitsBloodGlucose *string) { datum.Bolus = pumpTest.NewBolus() }, + func(datum *pump.Pump, unitsBloodGlucose *string) { datum.Bolus = pumpTest.NewRandomBolus() }, ), Entry("carbohydrate ratio schedule and carbohydrate ratio schedules missing", pointer.FromString("mmol/L"), diff --git a/data/types/settings/pump/test/bolus.go b/data/types/settings/pump/test/bolus.go index 105d990b9..6bade153a 100644 --- a/data/types/settings/pump/test/bolus.go +++ b/data/types/settings/pump/test/bolus.go @@ -1,8 +1,11 @@ package test -import "github.com/tidepool-org/platform/data/types/settings/pump" +import ( + "github.com/tidepool-org/platform/data/types/settings/pump" + "github.com/tidepool-org/platform/test" +) -func NewBolus() *pump.Bolus { +func NewRandomBolus() *pump.Bolus { datum := pump.NewBolus() datum.AmountMaximum = NewBolusAmountMaximum() datum.Extended = NewBolusExtended() @@ -18,3 +21,26 @@ func CloneBolus(datum *pump.Bolus) *pump.Bolus { clone.Extended = CloneBolusExtended(datum.Extended) return clone } + +func RandomBolusName() string { + return test.RandomStringFromRange(1, 20) +} + +func NewRandomBolusMap(minimumLength int, maximumLength int) *pump.BolusMap { + datum := pump.NewBolusMap() + for count := test.RandomIntFromRange(minimumLength, maximumLength); count > 0; count-- { + datum.Set(RandomBolusName(), NewRandomBolus()) + } + return datum +} + +func CloneBolusMap(datum *pump.BolusMap) *pump.BolusMap { + if datum == nil { + return nil + } + clone := pump.NewBolusMap() + for k, v := range *datum { + (*clone)[k] = CloneBolus(v) + } + return clone +} diff --git a/data/types/settings/pump/test/pump.go b/data/types/settings/pump/test/pump.go index 39992eae9..604286551 100644 --- a/data/types/settings/pump/test/pump.go +++ b/data/types/settings/pump/test/pump.go @@ -48,7 +48,7 @@ func NewPump(unitsBloodGlucose *string) *pump.Pump { datum.BloodGlucoseTargetPreprandial = dataBloodGlucoseTest.RandomTarget(unitsBloodGlucose) datum.BloodGlucoseTargetSchedules = pump.NewBloodGlucoseTargetStartArrayMap() datum.BloodGlucoseTargetSchedules.Set(scheduleName, RandomBloodGlucoseTargetStartArray(unitsBloodGlucose)) - datum.Bolus = NewBolus() + datum.Bolus = NewRandomBolus() datum.CarbohydrateRatioSchedules = pump.NewCarbohydrateRatioStartArrayMap() datum.CarbohydrateRatioSchedules.Set(scheduleName, NewCarbohydrateRatioStartArray()) datum.Display = NewDisplay() From fb3b9f7c458771301812cefb043f9b1ae682fd7f Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 7 Nov 2023 18:43:58 +1300 Subject: [PATCH 3/5] just boluses --- data/types/settings/pump/bolus.go | 8 ++++---- data/types/settings/pump/pump.go | 13 ++----------- data/types/settings/pump/pump_test.go | 22 ++++++++++++---------- data/types/settings/pump/test/bolus.go | 8 +++++--- data/types/settings/pump/test/pump.go | 4 ++-- 5 files changed, 25 insertions(+), 30 deletions(-) diff --git a/data/types/settings/pump/bolus.go b/data/types/settings/pump/bolus.go index aa8201394..629d5964f 100644 --- a/data/types/settings/pump/bolus.go +++ b/data/types/settings/pump/bolus.go @@ -88,11 +88,11 @@ func (b *BolusMap) Normalize(normalizer data.Normalizer) { func (b *BolusMap) Validate(validator structure.Validator) { for _, name := range b.sortedNames() { - datumArrayValidator := validator.WithReference(name) - if datumArray := b.Get(name); datumArray != nil { - datumArray.Validate(datumArrayValidator) + datumValidator := validator.WithReference(name) + if datum := b.Get(name); datum != nil { + datum.Validate(datumValidator) } else { - datumArrayValidator.ReportError(structureValidator.ErrorValueNotExists()) + datumValidator.ReportError(structureValidator.ErrorValueNotExists()) } } } diff --git a/data/types/settings/pump/pump.go b/data/types/settings/pump/pump.go index 5f3ca91e2..bbd65d2be 100644 --- a/data/types/settings/pump/pump.go +++ b/data/types/settings/pump/pump.go @@ -41,7 +41,6 @@ type Pump struct { BloodGlucoseTargetPreprandial *dataBloodGlucose.Target `json:"bgTargetPreprandial,omitempty" bson:"bgTargetPreprandial,omitempty"` BloodGlucoseTargetSchedule *BloodGlucoseTargetStartArray `json:"bgTarget,omitempty" bson:"bgTarget,omitempty"` // TODO: Move into BolusCalculator struct; rename bloodGlucoseTarget BloodGlucoseTargetSchedules *BloodGlucoseTargetStartArrayMap `json:"bgTargets,omitempty" bson:"bgTargets,omitempty"` // TODO: Move into BolusCalculator struct; rename bloodGlucoseTargets - Bolus *Bolus `json:"bolus,omitempty" bson:"bolus,omitempty"` Boluses *BolusMap `json:"boluses,omitempty" bson:"boluses,omitempty"` CarbohydrateRatioSchedule *CarbohydrateRatioStartArray `json:"carbRatio,omitempty" bson:"carbRatio,omitempty"` // TODO: Move into BolusCalculator struct; rename carbohydrateRatio CarbohydrateRatioSchedules *CarbohydrateRatioStartArrayMap `json:"carbRatios,omitempty" bson:"carbRatios,omitempty"` // TODO: Move into BolusCalculator struct; rename carbohydrateRatios @@ -85,7 +84,6 @@ func (p *Pump) Parse(parser structure.ObjectParser) { p.BloodGlucoseTargetPreprandial = dataBloodGlucose.ParseTarget(parser.WithReferenceObjectParser("bgTargetPreprandial")) p.BloodGlucoseTargetSchedule = ParseBloodGlucoseTargetStartArray(parser.WithReferenceArrayParser("bgTarget")) p.BloodGlucoseTargetSchedules = ParseBloodGlucoseTargetStartArrayMap(parser.WithReferenceObjectParser("bgTargets")) - p.Bolus = ParseBolus(parser.WithReferenceObjectParser("bolus")) p.Boluses = ParseBolusMap(parser.WithReferenceObjectParser("boluses")) p.CarbohydrateRatioSchedule = ParseCarbohydrateRatioStartArray(parser.WithReferenceArrayParser("carbRatio")) p.CarbohydrateRatioSchedules = ParseCarbohydrateRatioStartArrayMap(parser.WithReferenceObjectParser("carbRatios")) @@ -149,12 +147,8 @@ func (p *Pump) Validate(validator structure.Validator) { } else if p.BloodGlucoseTargetSchedules != nil { p.BloodGlucoseTargetSchedules.Validate(validator.WithReference("bgTargets"), unitsBloodGlucose) } - if p.Bolus != nil { - p.Bolus.Validate(validator.WithReference("bolus")) - if p.Boluses != nil { - validator.WithReference("boluses").ReportError(structureValidator.ErrorValueExists()) - } - } else if p.Boluses != nil { + + if p.Boluses != nil { p.Boluses.Validate(validator.WithReference("boluses")) } @@ -237,9 +231,6 @@ func (p *Pump) Normalize(normalizer data.Normalizer) { if p.BloodGlucoseTargetSchedules != nil { p.BloodGlucoseTargetSchedules.Normalize(normalizer.WithReference("bgTargets"), unitsBloodGlucose) } - if p.Bolus != nil { - p.Bolus.Normalize(normalizer.WithReference("bolus")) - } if p.Boluses != nil { p.Boluses.Normalize(normalizer.WithReference("boluses")) } diff --git a/data/types/settings/pump/pump_test.go b/data/types/settings/pump/pump_test.go index 17d3bec84..863e6ed85 100644 --- a/data/types/settings/pump/pump_test.go +++ b/data/types/settings/pump/pump_test.go @@ -1,6 +1,7 @@ package pump_test import ( + "fmt" "sort" . "github.com/onsi/ginkgo/v2" @@ -42,7 +43,7 @@ var _ = Describe("Pump", func() { Expect(datum.BloodGlucoseTargetPreprandial).To(BeNil()) Expect(datum.BloodGlucoseTargetSchedule).To(BeNil()) Expect(datum.BloodGlucoseTargetSchedules).To(BeNil()) - Expect(datum.Bolus).To(BeNil()) + Expect(datum.Boluses).To(BeNil()) Expect(datum.CarbohydrateRatioSchedule).To(BeNil()) Expect(datum.CarbohydrateRatioSchedules).To(BeNil()) Expect(datum.Display).To(BeNil()) @@ -276,18 +277,21 @@ var _ = Describe("Pump", func() { datum.BloodGlucoseTargetSchedules.Set("one", pumpTest.RandomBloodGlucoseTargetStartArray(unitsBloodGlucose)) }, ), - Entry("bolus missing", + Entry("boluses missing", pointer.FromString("mmol/L"), - func(datum *pump.Pump, unitsBloodGlucose *string) { datum.Bolus = nil }, + func(datum *pump.Pump, unitsBloodGlucose *string) { datum.Boluses = nil }, ), - Entry("bolus invalid", + Entry("boluses invalid", pointer.FromString("mmol/L"), - func(datum *pump.Pump, unitsBloodGlucose *string) { datum.Bolus.Extended.Enabled = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/bolus/extended/enabled", pumpTest.NewMeta()), + func(datum *pump.Pump, unitsBloodGlucose *string) { + datum.Boluses = pumpTest.NewRandomBolusMap(2, 2) + (*datum.Boluses)[pumpTest.BolusName(1)].Extended.Enabled = nil + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), fmt.Sprintf("/boluses/%s/extended/enabled", pumpTest.BolusName(1)), pumpTest.NewMeta()), ), - Entry("bolus valid", + Entry("boluses valid", pointer.FromString("mmol/L"), - func(datum *pump.Pump, unitsBloodGlucose *string) { datum.Bolus = pumpTest.NewRandomBolus() }, + func(datum *pump.Pump, unitsBloodGlucose *string) { datum.Boluses = pumpTest.NewRandomBolusMap(1, 5) }, ), Entry("carbohydrate ratio schedule and carbohydrate ratio schedules missing", pointer.FromString("mmol/L"), @@ -673,7 +677,6 @@ var _ = Describe("Pump", func() { datum.BloodGlucoseTargetPhysicalActivity = dataBloodGlucose.NewTarget() datum.BloodGlucoseTargetPreprandial = dataBloodGlucose.NewTarget() datum.BloodGlucoseTargetSchedules = nil - datum.Bolus.Extended.Enabled = nil invalidCarbohydrateRatioSchedule := pumpTest.NewCarbohydrateRatioStartArray() (*invalidCarbohydrateRatioSchedule)[0].Start = nil datum.CarbohydrateRatioSchedule = invalidCarbohydrateRatioSchedule @@ -704,7 +707,6 @@ var _ = Describe("Pump", func() { errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/bgTargetPhysicalActivity/target", &dataTypes.Meta{Type: "invalidType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/bgTargetPreprandial/target", &dataTypes.Meta{Type: "invalidType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/bgTarget/0/start", &dataTypes.Meta{Type: "invalidType"}), - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/bolus/extended/enabled", &dataTypes.Meta{Type: "invalidType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/carbRatio/0/start", &dataTypes.Meta{Type: "invalidType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/display/bloodGlucose/units", &dataTypes.Meta{Type: "invalidType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueEmpty(), "/firmwareVersion", &dataTypes.Meta{Type: "invalidType"}), diff --git a/data/types/settings/pump/test/bolus.go b/data/types/settings/pump/test/bolus.go index 6bade153a..526cdfd4d 100644 --- a/data/types/settings/pump/test/bolus.go +++ b/data/types/settings/pump/test/bolus.go @@ -1,6 +1,8 @@ package test import ( + "fmt" + "github.com/tidepool-org/platform/data/types/settings/pump" "github.com/tidepool-org/platform/test" ) @@ -22,14 +24,14 @@ func CloneBolus(datum *pump.Bolus) *pump.Bolus { return clone } -func RandomBolusName() string { - return test.RandomStringFromRange(1, 20) +func BolusName(index int) string { + return fmt.Sprintf("bolus-%d", index) } func NewRandomBolusMap(minimumLength int, maximumLength int) *pump.BolusMap { datum := pump.NewBolusMap() for count := test.RandomIntFromRange(minimumLength, maximumLength); count > 0; count-- { - datum.Set(RandomBolusName(), NewRandomBolus()) + datum.Set(BolusName(count), NewRandomBolus()) } return datum } diff --git a/data/types/settings/pump/test/pump.go b/data/types/settings/pump/test/pump.go index 604286551..903628b52 100644 --- a/data/types/settings/pump/test/pump.go +++ b/data/types/settings/pump/test/pump.go @@ -48,7 +48,7 @@ func NewPump(unitsBloodGlucose *string) *pump.Pump { datum.BloodGlucoseTargetPreprandial = dataBloodGlucoseTest.RandomTarget(unitsBloodGlucose) datum.BloodGlucoseTargetSchedules = pump.NewBloodGlucoseTargetStartArrayMap() datum.BloodGlucoseTargetSchedules.Set(scheduleName, RandomBloodGlucoseTargetStartArray(unitsBloodGlucose)) - datum.Bolus = NewRandomBolus() + datum.Boluses = NewRandomBolusMap(2, 4) datum.CarbohydrateRatioSchedules = pump.NewCarbohydrateRatioStartArrayMap() datum.CarbohydrateRatioSchedules.Set(scheduleName, NewCarbohydrateRatioStartArray()) datum.Display = NewDisplay() @@ -85,7 +85,7 @@ func ClonePump(datum *pump.Pump) *pump.Pump { clone.BloodGlucoseTargetPreprandial = dataBloodGlucoseTest.CloneTarget(datum.BloodGlucoseTargetPreprandial) clone.BloodGlucoseTargetSchedule = CloneBloodGlucoseTargetStartArray(datum.BloodGlucoseTargetSchedule) clone.BloodGlucoseTargetSchedules = CloneBloodGlucoseTargetStartArrayMap(datum.BloodGlucoseTargetSchedules) - clone.Bolus = CloneBolus(datum.Bolus) + clone.Boluses = CloneBolusMap(datum.Boluses) clone.CarbohydrateRatioSchedule = CloneCarbohydrateRatioStartArray(datum.CarbohydrateRatioSchedule) clone.CarbohydrateRatioSchedules = CloneCarbohydrateRatioStartArrayMap(datum.CarbohydrateRatioSchedules) clone.Display = CloneDisplay(datum.Display) From e04413f24f9ff8f4ef1149273548669fa31fd3b7 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 8 Nov 2023 12:20:06 +1300 Subject: [PATCH 4/5] both bolus and boluses for consistency --- data/types/settings/pump/pump.go | 12 +++++++- data/types/settings/pump/pump_test.go | 38 +++++++++++++++++++++++--- data/types/settings/pump/test/bolus.go | 2 ++ data/types/settings/pump/test/pump.go | 1 + 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/data/types/settings/pump/pump.go b/data/types/settings/pump/pump.go index bbd65d2be..f5e1396fa 100644 --- a/data/types/settings/pump/pump.go +++ b/data/types/settings/pump/pump.go @@ -41,6 +41,7 @@ type Pump struct { BloodGlucoseTargetPreprandial *dataBloodGlucose.Target `json:"bgTargetPreprandial,omitempty" bson:"bgTargetPreprandial,omitempty"` BloodGlucoseTargetSchedule *BloodGlucoseTargetStartArray `json:"bgTarget,omitempty" bson:"bgTarget,omitempty"` // TODO: Move into BolusCalculator struct; rename bloodGlucoseTarget BloodGlucoseTargetSchedules *BloodGlucoseTargetStartArrayMap `json:"bgTargets,omitempty" bson:"bgTargets,omitempty"` // TODO: Move into BolusCalculator struct; rename bloodGlucoseTargets + Bolus *Bolus `json:"bolus,omitempty" bson:"bolus,omitempty"` Boluses *BolusMap `json:"boluses,omitempty" bson:"boluses,omitempty"` CarbohydrateRatioSchedule *CarbohydrateRatioStartArray `json:"carbRatio,omitempty" bson:"carbRatio,omitempty"` // TODO: Move into BolusCalculator struct; rename carbohydrateRatio CarbohydrateRatioSchedules *CarbohydrateRatioStartArrayMap `json:"carbRatios,omitempty" bson:"carbRatios,omitempty"` // TODO: Move into BolusCalculator struct; rename carbohydrateRatios @@ -84,6 +85,7 @@ func (p *Pump) Parse(parser structure.ObjectParser) { p.BloodGlucoseTargetPreprandial = dataBloodGlucose.ParseTarget(parser.WithReferenceObjectParser("bgTargetPreprandial")) p.BloodGlucoseTargetSchedule = ParseBloodGlucoseTargetStartArray(parser.WithReferenceArrayParser("bgTarget")) p.BloodGlucoseTargetSchedules = ParseBloodGlucoseTargetStartArrayMap(parser.WithReferenceObjectParser("bgTargets")) + p.Bolus = ParseBolus(parser.WithReferenceObjectParser("bolus")) p.Boluses = ParseBolusMap(parser.WithReferenceObjectParser("boluses")) p.CarbohydrateRatioSchedule = ParseCarbohydrateRatioStartArray(parser.WithReferenceArrayParser("carbRatio")) p.CarbohydrateRatioSchedules = ParseCarbohydrateRatioStartArrayMap(parser.WithReferenceObjectParser("carbRatios")) @@ -148,7 +150,12 @@ func (p *Pump) Validate(validator structure.Validator) { p.BloodGlucoseTargetSchedules.Validate(validator.WithReference("bgTargets"), unitsBloodGlucose) } - if p.Boluses != nil { + if p.Bolus != nil { + p.Bolus.Validate(validator.WithReference("bolus")) + if p.Boluses != nil { + validator.WithReference("boluses").ReportError(structureValidator.ErrorValueExists()) + } + } else if p.Boluses != nil { p.Boluses.Validate(validator.WithReference("boluses")) } @@ -231,6 +238,9 @@ func (p *Pump) Normalize(normalizer data.Normalizer) { if p.BloodGlucoseTargetSchedules != nil { p.BloodGlucoseTargetSchedules.Normalize(normalizer.WithReference("bgTargets"), unitsBloodGlucose) } + if p.Bolus != nil { + p.Bolus.Normalize(normalizer.WithReference("bolus")) + } if p.Boluses != nil { p.Boluses.Normalize(normalizer.WithReference("boluses")) } diff --git a/data/types/settings/pump/pump_test.go b/data/types/settings/pump/pump_test.go index 863e6ed85..b96a6363f 100644 --- a/data/types/settings/pump/pump_test.go +++ b/data/types/settings/pump/pump_test.go @@ -43,6 +43,7 @@ var _ = Describe("Pump", func() { Expect(datum.BloodGlucoseTargetPreprandial).To(BeNil()) Expect(datum.BloodGlucoseTargetSchedule).To(BeNil()) Expect(datum.BloodGlucoseTargetSchedules).To(BeNil()) + Expect(datum.Bolus).To(BeNil()) Expect(datum.Boluses).To(BeNil()) Expect(datum.CarbohydrateRatioSchedule).To(BeNil()) Expect(datum.CarbohydrateRatioSchedules).To(BeNil()) @@ -277,6 +278,28 @@ var _ = Describe("Pump", func() { datum.BloodGlucoseTargetSchedules.Set("one", pumpTest.RandomBloodGlucoseTargetStartArray(unitsBloodGlucose)) }, ), + Entry("bolus missing", + pointer.FromString("mmol/L"), + func(datum *pump.Pump, unitsBloodGlucose *string) { + datum.Bolus = nil + }, + ), + Entry("bolus invalid", + pointer.FromString("mmol/L"), + func(datum *pump.Pump, unitsBloodGlucose *string) { + datum.Boluses = nil + datum.Bolus = pumpTest.NewRandomBolus() + datum.Bolus.Calculator.Enabled = nil + }, + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/bolus/calculator/enabled", pumpTest.NewMeta()), + ), + Entry("bolus valid", + pointer.FromString("mmol/L"), + func(datum *pump.Pump, unitsBloodGlucose *string) { + datum.Boluses = nil + datum.Bolus = pumpTest.NewRandomBolus() + }, + ), Entry("boluses missing", pointer.FromString("mmol/L"), func(datum *pump.Pump, unitsBloodGlucose *string) { datum.Boluses = nil }, @@ -284,14 +307,22 @@ var _ = Describe("Pump", func() { Entry("boluses invalid", pointer.FromString("mmol/L"), func(datum *pump.Pump, unitsBloodGlucose *string) { + datum.Bolus = nil datum.Boluses = pumpTest.NewRandomBolusMap(2, 2) - (*datum.Boluses)[pumpTest.BolusName(1)].Extended.Enabled = nil + (*datum.Boluses)[pumpTest.BolusName(1)].AmountMaximum.Units = nil + (*datum.Boluses)[pumpTest.BolusName(2)].Extended.Enabled = nil + (*datum.Boluses)[pumpTest.BolusName(1)].Calculator.Enabled = nil }, - errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), fmt.Sprintf("/boluses/%s/extended/enabled", pumpTest.BolusName(1)), pumpTest.NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), fmt.Sprintf("/boluses/%s/amountMaximum/units", pumpTest.BolusName(1)), pumpTest.NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), fmt.Sprintf("/boluses/%s/calculator/enabled", pumpTest.BolusName(1)), pumpTest.NewMeta()), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), fmt.Sprintf("/boluses/%s/extended/enabled", pumpTest.BolusName(2)), pumpTest.NewMeta()), ), Entry("boluses valid", pointer.FromString("mmol/L"), - func(datum *pump.Pump, unitsBloodGlucose *string) { datum.Boluses = pumpTest.NewRandomBolusMap(1, 5) }, + func(datum *pump.Pump, unitsBloodGlucose *string) { + datum.Bolus = nil + datum.Boluses = pumpTest.NewRandomBolusMap(1, 5) + }, ), Entry("carbohydrate ratio schedule and carbohydrate ratio schedules missing", pointer.FromString("mmol/L"), @@ -676,7 +707,6 @@ var _ = Describe("Pump", func() { datum.BloodGlucoseTargetSchedules = nil datum.BloodGlucoseTargetPhysicalActivity = dataBloodGlucose.NewTarget() datum.BloodGlucoseTargetPreprandial = dataBloodGlucose.NewTarget() - datum.BloodGlucoseTargetSchedules = nil invalidCarbohydrateRatioSchedule := pumpTest.NewCarbohydrateRatioStartArray() (*invalidCarbohydrateRatioSchedule)[0].Start = nil datum.CarbohydrateRatioSchedule = invalidCarbohydrateRatioSchedule diff --git a/data/types/settings/pump/test/bolus.go b/data/types/settings/pump/test/bolus.go index 526cdfd4d..2a24e39dd 100644 --- a/data/types/settings/pump/test/bolus.go +++ b/data/types/settings/pump/test/bolus.go @@ -11,6 +11,7 @@ func NewRandomBolus() *pump.Bolus { datum := pump.NewBolus() datum.AmountMaximum = NewBolusAmountMaximum() datum.Extended = NewBolusExtended() + datum.Calculator = NewBolusCalculator() return datum } @@ -21,6 +22,7 @@ func CloneBolus(datum *pump.Bolus) *pump.Bolus { clone := pump.NewBolus() clone.AmountMaximum = CloneBolusAmountMaximum(datum.AmountMaximum) clone.Extended = CloneBolusExtended(datum.Extended) + clone.Calculator = CloneBolusCalculator(datum.Calculator) return clone } diff --git a/data/types/settings/pump/test/pump.go b/data/types/settings/pump/test/pump.go index 903628b52..1f5314544 100644 --- a/data/types/settings/pump/test/pump.go +++ b/data/types/settings/pump/test/pump.go @@ -85,6 +85,7 @@ func ClonePump(datum *pump.Pump) *pump.Pump { clone.BloodGlucoseTargetPreprandial = dataBloodGlucoseTest.CloneTarget(datum.BloodGlucoseTargetPreprandial) clone.BloodGlucoseTargetSchedule = CloneBloodGlucoseTargetStartArray(datum.BloodGlucoseTargetSchedule) clone.BloodGlucoseTargetSchedules = CloneBloodGlucoseTargetStartArrayMap(datum.BloodGlucoseTargetSchedules) + clone.Bolus = CloneBolus(datum.Bolus) clone.Boluses = CloneBolusMap(datum.Boluses) clone.CarbohydrateRatioSchedule = CloneCarbohydrateRatioStartArray(datum.CarbohydrateRatioSchedule) clone.CarbohydrateRatioSchedules = CloneCarbohydrateRatioStartArrayMap(datum.CarbohydrateRatioSchedules) From d9ebea0c7cad78e0532129c7f03d217a767d8d85 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 8 Nov 2023 16:00:25 +1300 Subject: [PATCH 5/5] add bolus for validation test errors --- data/types/settings/pump/pump_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/data/types/settings/pump/pump_test.go b/data/types/settings/pump/pump_test.go index b96a6363f..077a2b031 100644 --- a/data/types/settings/pump/pump_test.go +++ b/data/types/settings/pump/pump_test.go @@ -707,6 +707,9 @@ var _ = Describe("Pump", func() { datum.BloodGlucoseTargetSchedules = nil datum.BloodGlucoseTargetPhysicalActivity = dataBloodGlucose.NewTarget() datum.BloodGlucoseTargetPreprandial = dataBloodGlucose.NewTarget() + datum.Boluses = nil + datum.Bolus = pumpTest.NewRandomBolus() + datum.Bolus.Extended.Enabled = nil invalidCarbohydrateRatioSchedule := pumpTest.NewCarbohydrateRatioStartArray() (*invalidCarbohydrateRatioSchedule)[0].Start = nil datum.CarbohydrateRatioSchedule = invalidCarbohydrateRatioSchedule @@ -737,6 +740,7 @@ var _ = Describe("Pump", func() { errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/bgTargetPhysicalActivity/target", &dataTypes.Meta{Type: "invalidType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/bgTargetPreprandial/target", &dataTypes.Meta{Type: "invalidType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/bgTarget/0/start", &dataTypes.Meta{Type: "invalidType"}), + errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/bolus/extended/enabled", &dataTypes.Meta{Type: "invalidType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/carbRatio/0/start", &dataTypes.Meta{Type: "invalidType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueNotExists(), "/display/bloodGlucose/units", &dataTypes.Meta{Type: "invalidType"}), errorsTest.WithPointerSourceAndMeta(structureValidator.ErrorValueEmpty(), "/firmwareVersion", &dataTypes.Meta{Type: "invalidType"}),