Skip to content

Commit 12a9887

Browse files
Merge pull request #766 from vsaraikin/fix/multi-value-enum-validation
Validate each token of multi-value enum fields
2 parents 9c93db9 + b69abec commit 12a9887

2 files changed

Lines changed: 54 additions & 3 deletions

File tree

validation.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
package quickfix
1717

1818
import (
19+
"bytes"
20+
1921
"github.com/quickfixgo/quickfix/datadictionary"
2022
)
2123

@@ -385,10 +387,21 @@ func validateField(d *datadictionary.DataDictionary,
385387
return nil
386388
}
387389

388-
allowedValues := d.FieldTypeByTag[int(field.tag)].Enums
390+
allowedValues := fieldType.Enums
389391
if len(allowedValues) != 0 {
390-
if _, validValue := allowedValues[string(field.value)]; !validValue {
391-
return ValueIsIncorrect(field.tag)
392+
switch fieldType.Type {
393+
case "MULTIPLESTRINGVALUE", "MULTIPLEVALUESTRING", "MULTIPLECHARVALUE":
394+
// These fields carry a space-delimited set of enum tokens, each of
395+
// which must be individually valid (e.g. ExecInst "1 5" = two enums).
396+
for _, component := range bytes.Split(field.value, []byte{' '}) {
397+
if _, validValue := allowedValues[string(component)]; !validValue {
398+
return ValueIsIncorrect(field.tag)
399+
}
400+
}
401+
default:
402+
if _, validValue := allowedValues[string(field.value)]; !validValue {
403+
return ValueIsIncorrect(field.tag)
404+
}
392405
}
393406
}
394407

validation_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ func TestValidate(t *testing.T) {
8686
tcCheckUserDefinedFieldsDisabled(),
8787
tcCheckUserDefinedFieldsDisabledFixT(),
8888
tcMultipleRepeatingGroupFields(),
89+
tcMultiValueEnumValid(),
90+
tcMultiValueEnumInvalidComponent(),
8991
}
9092

9193
msg := NewMessage()
@@ -662,6 +664,42 @@ func tcValueIsIncorrectFixT() validateTest {
662664
}
663665
}
664666

667+
func tcMultiValueEnumValid() validateTest {
668+
dict, _ := datadictionary.Parse("spec/FIX43.xml")
669+
validator := NewValidator(defaultValidatorSettings, dict, nil)
670+
671+
// ExecInst (tag 18) is a MULTIPLEVALUESTRING: a space-delimited set of
672+
// individually-valid enum tokens (e.g. "Y M") must be accepted.
673+
builder := createFIX43NewOrderSingle()
674+
builder.Body.SetField(Tag(18), FIXString("Y M"))
675+
msgBytes := builder.build()
676+
677+
return validateTest{
678+
TestName: "Multi-value enum valid",
679+
Validator: validator,
680+
MessageBytes: msgBytes,
681+
DoNotExpectReject: true,
682+
}
683+
}
684+
685+
func tcMultiValueEnumInvalidComponent() validateTest {
686+
dict, _ := datadictionary.Parse("spec/FIX43.xml")
687+
validator := NewValidator(defaultValidatorSettings, dict, nil)
688+
689+
tag := Tag(18)
690+
builder := createFIX43NewOrderSingle()
691+
builder.Body.SetField(tag, FIXString("Y ZZ")) // ZZ is not a valid ExecInst enum
692+
msgBytes := builder.build()
693+
694+
return validateTest{
695+
TestName: "Multi-value enum invalid component",
696+
Validator: validator,
697+
MessageBytes: msgBytes,
698+
ExpectedRejectReason: rejectReasonValueIsIncorrect,
699+
ExpectedRefTagID: &tag,
700+
}
701+
}
702+
665703
func tcIncorrectDataFormatForValue() validateTest {
666704
dict, _ := datadictionary.Parse("spec/FIX40.xml")
667705
validator := NewValidator(defaultValidatorSettings, dict, nil)

0 commit comments

Comments
 (0)