diff --git a/docs/static/openapi/envoy.json b/docs/static/openapi/envoy.json index 58dc153..070621b 100644 --- a/docs/static/openapi/envoy.json +++ b/docs/static/openapi/envoy.json @@ -11,16 +11,10 @@ "name": "MIT Licensed", "url": "https://github.com/trisacrypto/envoy/blob/main/LICENSE" }, - "version": "v{{ .Version }}" + "version": "v0.25.0" }, "openapi": "3.1.0", - "servers": [ - { - "url": "{{ .Origin }}", - "variables": {}, - "description": "{{ .Description }}" - } - ], + "servers": [], "tags": [ { "name": "Authentication", diff --git a/pkg/ivms101/enum.go b/pkg/ivms101/enum.go index 2fbe8db..8ad4f53 100644 --- a/pkg/ivms101/enum.go +++ b/pkg/ivms101/enum.go @@ -2,7 +2,6 @@ package ivms101 import ( "encoding/json" - "errors" "strings" ) @@ -83,17 +82,18 @@ func (n NaturalPersonNameTypeCode) MarshalJSON() ([]byte, error) { } // Must be a pointer receiver so that we can indirect back to the correct variable -func (n *NaturalPersonNameTypeCode) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return errors.New("could not parse NaturalPersonNameTypeCode from value") +func (n *NaturalPersonNameTypeCode) UnmarshalJSON(data []byte) (err error) { + var val interface{} + if err = json.Unmarshal(data, &val); err != nil { + return Wrap(ErrParseNaturalPersonNameTypeCode, err) } - s = naturalPersonTypeCodePrefix + strings.ToUpper(s) - code, ok := NaturalPersonNameTypeCode_value[s] - if !ok { - return errors.New("invalid NaturalPersonNameTypeCode alias") + + var code NaturalPersonNameTypeCode + if code, err = ParseNaturalPersonNameTypeCode(val); err != nil { + return err } - *n = NaturalPersonNameTypeCode(code) + + *n = code return nil } @@ -110,16 +110,17 @@ func (l LegalPersonNameTypeCode) MarshalJSON() ([]byte, error) { } // Must be a pointer receiver so that we can indirect back to the correct variable -func (l *LegalPersonNameTypeCode) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return errors.New("could not parse LegalPersonNameTypeCode from value") +func (l *LegalPersonNameTypeCode) UnmarshalJSON(data []byte) (err error) { + var val interface{} + if err = json.Unmarshal(data, &val); err != nil { + return Wrap(ErrParseLegalPersonNameTypeCode, err) } - s = legalPersonNameTypeCodePrefix + strings.ToUpper(s) - code, ok := LegalPersonNameTypeCode_value[s] - if !ok { - return errors.New("invalid LegalPersonNameTypeCode alias") + + var code LegalPersonNameTypeCode + if code, err = ParseLegalPersonNameTypeCode(val); err != nil { + return err } + *l = LegalPersonNameTypeCode(code) return nil } @@ -137,16 +138,17 @@ func (a AddressTypeCode) MarshalJSON() ([]byte, error) { } // Must be a pointer receiver so that we can indirect back to the correct variable -func (a *AddressTypeCode) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return errors.New("could not parse AddressTypeCode from value") +func (a *AddressTypeCode) UnmarshalJSON(data []byte) (err error) { + var val interface{} + if err = json.Unmarshal(data, &val); err != nil { + return Wrap(ErrParseAddressTypeCode, err) } - s = addressTypeCodePrefix + strings.ToUpper(s) - code, ok := AddressTypeCode_value[s] - if !ok { - return errors.New("invalid AddressTypeCode alias") + + var code AddressTypeCode + if code, err = ParseAddressTypeCode(val); err != nil { + return err } + *a = AddressTypeCode(code) return nil } @@ -164,16 +166,17 @@ func (i NationalIdentifierTypeCode) MarshalJSON() ([]byte, error) { } // Must be a pointer receiver so that we can indirect back to the correct variable -func (i *NationalIdentifierTypeCode) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return errors.New("could not parse NationalIdentifierTypeCode from value") +func (i *NationalIdentifierTypeCode) UnmarshalJSON(data []byte) (err error) { + var val interface{} + if err = json.Unmarshal(data, &val); err != nil { + return Wrap(ErrParseNationalIdentifierTypeCode, err) } - s = nationalIdentifierTypeCodePrefix + strings.ToUpper(s) - code, ok := NationalIdentifierTypeCode_value[s] - if !ok { - return errors.New("invalid NationalIdentifierTypeCode alias") + + var code NationalIdentifierTypeCode + if code, err = ParseNationalIdentifierTypeCode(val); err != nil { + return err } + *i = NationalIdentifierTypeCode(code) return nil } @@ -191,16 +194,17 @@ func (t TransliterationMethodCode) MarshalJSON() ([]byte, error) { } // Must be a pointer receiver so that we can indirect back to the correct variable -func (t *TransliterationMethodCode) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return errors.New("could not parse TransliterationMethodCode from value") +func (t *TransliterationMethodCode) UnmarshalJSON(data []byte) (err error) { + var val interface{} + if err = json.Unmarshal(data, &val); err != nil { + return Wrap(ErrParseTransliterationMethodCode, err) } - s = transliterationMethodCodePrefix + strings.ToUpper(s) - code, ok := TransliterationMethodCode_value[s] - if !ok { - return errors.New("invalid TransliterationMethodCode alias") + + var code TransliterationMethodCode + if code, err = ParseTransliterationMethodCode(val); err != nil { + return err } + *t = TransliterationMethodCode(code) return nil } @@ -224,9 +228,21 @@ func ParseNaturalPersonNameTypeCode(in any) (NaturalPersonNameTypeCode, error) { if _, ok := NaturalPersonNameTypeCode_name[val]; ok { return NaturalPersonNameTypeCode(val), nil } + case float64: + if _, ok := NaturalPersonNameTypeCode_name[int32(val)]; ok { + return NaturalPersonNameTypeCode(val), nil + } + case json.Number: + i, err := val.Int64() + if err != nil { + return 0, Wrap(ErrParseNaturalPersonNameTypeCode, err) + } + if _, ok := NaturalPersonNameTypeCode_name[int32(i)]; ok { + return NaturalPersonNameTypeCode(i), nil + } } - return 0, ErrCouldNotParseEnum + return 0, ErrInvalidNaturalPersonNameTypeCode } func ParseLegalPersonNameTypeCode(in any) (LegalPersonNameTypeCode, error) { @@ -244,9 +260,21 @@ func ParseLegalPersonNameTypeCode(in any) (LegalPersonNameTypeCode, error) { if _, ok := LegalPersonNameTypeCode_name[val]; ok { return LegalPersonNameTypeCode(val), nil } + case float64: + if _, ok := LegalPersonNameTypeCode_name[int32(val)]; ok { + return LegalPersonNameTypeCode(val), nil + } + case json.Number: + i, err := val.Int64() + if err != nil { + return 0, Wrap(ErrInvalidLegalPersonNameTypeCode, err) + } + if _, ok := LegalPersonNameTypeCode_name[int32(i)]; ok { + return LegalPersonNameTypeCode(i), nil + } } - return 0, ErrCouldNotParseEnum + return 0, ErrInvalidLegalPersonNameTypeCode } func ParseAddressTypeCode(in any) (AddressTypeCode, error) { @@ -264,9 +292,21 @@ func ParseAddressTypeCode(in any) (AddressTypeCode, error) { if _, ok := AddressTypeCode_name[val]; ok { return AddressTypeCode(val), nil } + case float64: + if _, ok := AddressTypeCode_name[int32(val)]; ok { + return AddressTypeCode(val), nil + } + case json.Number: + i, err := val.Int64() + if err != nil { + return 0, Wrap(ErrInvalidAddressTypeCode, err) + } + if _, ok := AddressTypeCode_name[int32(i)]; ok { + return AddressTypeCode(i), nil + } } - return 0, ErrCouldNotParseEnum + return 0, ErrInvalidAddressTypeCode } func ParseNationalIdentifierTypeCode(in any) (NationalIdentifierTypeCode, error) { @@ -284,9 +324,21 @@ func ParseNationalIdentifierTypeCode(in any) (NationalIdentifierTypeCode, error) if _, ok := NationalIdentifierTypeCode_name[val]; ok { return NationalIdentifierTypeCode(val), nil } + case float64: + if _, ok := NationalIdentifierTypeCode_name[int32(val)]; ok { + return NationalIdentifierTypeCode(val), nil + } + case json.Number: + i, err := val.Int64() + if err != nil { + return 0, Wrap(ErrInvalidNationalIdentifierTypeCode, err) + } + if _, ok := NationalIdentifierTypeCode_name[int32(i)]; ok { + return NationalIdentifierTypeCode(i), nil + } } - return 0, ErrCouldNotParseEnum + return 0, ErrInvalidNationalIdentifierTypeCode } func ParseTransliterationMethodCode(in any) (TransliterationMethodCode, error) { @@ -304,7 +356,19 @@ func ParseTransliterationMethodCode(in any) (TransliterationMethodCode, error) { if _, ok := TransliterationMethodCode_name[val]; ok { return TransliterationMethodCode(val), nil } + case float64: + if _, ok := TransliterationMethodCode_name[int32(val)]; ok { + return TransliterationMethodCode(val), nil + } + case json.Number: + i, err := val.Int64() + if err != nil { + return 0, Wrap(ErrInvalidTransliterationMethodCode, err) + } + if _, ok := TransliterationMethodCode_name[int32(i)]; ok { + return TransliterationMethodCode(i), nil + } } - return 0, ErrCouldNotParseEnum + return 0, ErrInvalidTransliterationMethodCode } diff --git a/pkg/ivms101/enum_test.go b/pkg/ivms101/enum_test.go index c38c9bf..d0a88d7 100644 --- a/pkg/ivms101/enum_test.go +++ b/pkg/ivms101/enum_test.go @@ -1,12 +1,412 @@ package ivms101_test import ( + "encoding/json" "testing" "github.com/stretchr/testify/require" "github.com/trisacrypto/trisa/pkg/ivms101" ) +func TestJSONMarshal(t *testing.T) { + t.Run("NaturalPersonNameTypeCode", func(t *testing.T) { + // Test an array of expected ivms101 protocol buffer enums + // to inspect whether we correctly marshal them to the correct + // compatible ivms101 format + tests := map[ivms101.NaturalPersonNameTypeCode][]byte{ + 0: []byte(`"MISC"`), + 1: []byte(`"ALIA"`), + 2: []byte(`"BIRT"`), + 3: []byte(`"MAID"`), + 4: []byte(`"LEGL"`), + } + + for code, expected := range tests { + actual, err := json.Marshal(code) + require.NoError(t, err, "could not marshal %q", code.String()) + require.Equal(t, expected, actual, "incorrect marshal for test case %q", code.String()) + } + }) + + t.Run("LegalPersonNameTypeCode", func(t *testing.T) { + // Test an array of expected ivms101 protocol buffer enums + // to inspect whether we correctly marshal them to the correct + // compatible ivms101 format + tests := map[ivms101.LegalPersonNameTypeCode][]byte{ + 0: []byte(`"MISC"`), + 1: []byte(`"LEGL"`), + 2: []byte(`"SHRT"`), + 3: []byte(`"TRAD"`), + } + + for code, expected := range tests { + actual, err := json.Marshal(code) + require.NoError(t, err, "could not marshal %q", code.String()) + require.Equal(t, expected, actual, "incorrect marshal for test case %q", code.String()) + } + }) + + t.Run("AddressTypeCode", func(t *testing.T) { + // Test an array of expected ivms101 protocol buffer enums + // to inspect whether we correctly marshal them to the correct + // compatible ivms101 format + tests := map[ivms101.AddressTypeCode][]byte{ + 0: []byte(`"MISC"`), + 1: []byte(`"HOME"`), + 2: []byte(`"BIZZ"`), + 3: []byte(`"GEOG"`), + } + + for code, expected := range tests { + actual, err := json.Marshal(code) + require.NoError(t, err, "could not marshal %q", code.String()) + require.Equal(t, expected, actual, "incorrect marshal for test case %q", code.String()) + } + }) + + t.Run("NationalIdentifierTypeCode", func(t *testing.T) { + // Test an array of expected ivms101 protocol buffer enums + // to inspect whether we correctly marshal them to the correct + // compatible ivms101 format + tests := map[ivms101.NationalIdentifierTypeCode][]byte{ + 0: []byte(`"MISC"`), + 1: []byte(`"ARNU"`), + 2: []byte(`"CCPT"`), + 3: []byte(`"RAID"`), + 4: []byte(`"DRLC"`), + 5: []byte(`"FIIN"`), + 6: []byte(`"TXID"`), + 7: []byte(`"SOCS"`), + 8: []byte(`"IDCD"`), + 9: []byte(`"LEIX"`), + } + + for code, expected := range tests { + actual, err := json.Marshal(code) + require.NoError(t, err, "could not marshal %q", code.String()) + require.Equal(t, expected, actual, "incorrect marshal for test case %q", code.String()) + } + }) + + t.Run("TransliterationMethodCode", func(t *testing.T) { + // Test an array of expected ivms101 protocol buffer enums + // to inspect whether we correctly marshal them to the correct + // compatible ivms101 format + tests := map[ivms101.TransliterationMethodCode][]byte{ + 0: []byte(`"OTHR"`), + 1: []byte(`"ARAB"`), + 2: []byte(`"ARAN"`), + 3: []byte(`"ARMN"`), + 4: []byte(`"CYRL"`), + 5: []byte(`"DEVA"`), + 6: []byte(`"GEOR"`), + 7: []byte(`"GREK"`), + 8: []byte(`"HANI"`), + 9: []byte(`"HEBR"`), + 10: []byte(`"KANA"`), + 11: []byte(`"KORE"`), + 12: []byte(`"THAI"`), + } + + for code, expected := range tests { + actual, err := json.Marshal(code) + require.NoError(t, err, "could not marshal %q", code.String()) + require.Equal(t, expected, actual, "incorrect marshal for test case %q", code.String()) + } + }) +} + +func TestJSONUnmarshal(t *testing.T) { + t.Run("NaturalPersonNameTypeCode", func(t *testing.T) { + valid := []struct { + expected ivms101.NaturalPersonNameTypeCode + message []byte + }{ + {ivms101.NaturalPersonMisc, []byte(`"MISC"`)}, + {ivms101.NaturalPersonAlias, []byte(`"ALIA"`)}, + {ivms101.NaturalPersonBirth, []byte(`"BIRT"`)}, + {ivms101.NaturalPersonMaiden, []byte(`"MAID"`)}, + {ivms101.NaturalPersonLegal, []byte(`"LEGL"`)}, + {ivms101.NaturalPersonMisc, []byte(`0`)}, + {ivms101.NaturalPersonAlias, []byte(`1`)}, + {ivms101.NaturalPersonBirth, []byte(`2`)}, + {ivms101.NaturalPersonMaiden, []byte(`3`)}, + {ivms101.NaturalPersonLegal, []byte(`4`)}, + {ivms101.NaturalPersonMisc, []byte(`"NATURAL_PERSON_NAME_TYPE_CODE_MISC"`)}, + {ivms101.NaturalPersonAlias, []byte(`"NATURAL_PERSON_NAME_TYPE_CODE_ALIA"`)}, + {ivms101.NaturalPersonBirth, []byte(`"NATURAL_PERSON_NAME_TYPE_CODE_BIRT"`)}, + {ivms101.NaturalPersonMaiden, []byte(`"NATURAL_PERSON_NAME_TYPE_CODE_MAID"`)}, + {ivms101.NaturalPersonLegal, []byte(`"NATURAL_PERSON_NAME_TYPE_CODE_LEGL"`)}, + {ivms101.NaturalPersonMisc, []byte(`"misc"`)}, + {ivms101.NaturalPersonAlias, []byte(`"alia"`)}, + {ivms101.NaturalPersonBirth, []byte(`"birt"`)}, + {ivms101.NaturalPersonMaiden, []byte(`"maid"`)}, + {ivms101.NaturalPersonLegal, []byte(`"legl"`)}, + } + + for i, tc := range valid { + var code ivms101.NaturalPersonNameTypeCode + require.NoError(t, json.Unmarshal(tc.message, &code), "could not unmarshal data in test case %d", i) + require.Equal(t, tc.expected, code, "incorrect unmarshal for test case %d", i) + } + + invalid := []struct { + target error + message []byte + }{ + {ivms101.ErrInvalidNaturalPersonNameTypeCode, []byte(`"STAGE"`)}, + {ivms101.ErrInvalidNaturalPersonNameTypeCode, []byte("{}")}, + } + + for i, tc := range invalid { + var code ivms101.NaturalPersonNameTypeCode + err := json.Unmarshal(tc.message, &code) + require.ErrorIs(t, err, tc.target, "expected error on test case %d", i) + require.Zero(t, code, "expected zero valued code on test case %d", i) + } + }) + + t.Run("LegalPersonNameTypeCode", func(t *testing.T) { + valid := []struct { + expected ivms101.LegalPersonNameTypeCode + message []byte + }{ + {ivms101.LegalPersonMisc, []byte(`"MISC"`)}, + {ivms101.LegalPersonLegal, []byte(`"LEGL"`)}, + {ivms101.LegalPersonShort, []byte(`"SHRT"`)}, + {ivms101.LegalPersonTrading, []byte(`"TRAD"`)}, + {ivms101.LegalPersonMisc, []byte(`0`)}, + {ivms101.LegalPersonLegal, []byte(`1`)}, + {ivms101.LegalPersonShort, []byte(`2`)}, + {ivms101.LegalPersonTrading, []byte(`3`)}, + {ivms101.LegalPersonMisc, []byte(`"LEGAL_PERSON_NAME_TYPE_CODE_MISC"`)}, + {ivms101.LegalPersonLegal, []byte(`"LEGAL_PERSON_NAME_TYPE_CODE_LEGL"`)}, + {ivms101.LegalPersonShort, []byte(`"LEGAL_PERSON_NAME_TYPE_CODE_SHRT"`)}, + {ivms101.LegalPersonTrading, []byte(`"LEGAL_PERSON_NAME_TYPE_CODE_TRAD"`)}, + {ivms101.LegalPersonMisc, []byte(`"misc"`)}, + {ivms101.LegalPersonLegal, []byte(`"legl"`)}, + {ivms101.LegalPersonShort, []byte(`"shrt"`)}, + {ivms101.LegalPersonTrading, []byte(`"trad"`)}, + } + + for i, tc := range valid { + var code ivms101.LegalPersonNameTypeCode + require.NoError(t, json.Unmarshal(tc.message, &code), "could not unmarshal data in test case %d", i) + require.Equal(t, tc.expected, code, "incorrect unmarshal for test case %d", i) + } + + invalid := []struct { + target error + message []byte + }{ + {ivms101.ErrInvalidLegalPersonNameTypeCode, []byte(`"SHEL"`)}, + {ivms101.ErrInvalidLegalPersonNameTypeCode, []byte(`{}`)}, + } + + for i, tc := range invalid { + var code ivms101.LegalPersonNameTypeCode + err := json.Unmarshal(tc.message, &code) + require.ErrorIs(t, err, tc.target, "expected error on test case %d", i) + require.Zero(t, code, "expected zero valued code on test case %d", i) + } + }) + + t.Run("AddressTypeCode", func(t *testing.T) { + valid := []struct { + expected ivms101.AddressTypeCode + message []byte + }{ + {ivms101.AddressTypeMisc, []byte(`"MISC"`)}, + {ivms101.AddressTypeHome, []byte(`"HOME"`)}, + {ivms101.AddressTypeBusiness, []byte(`"BIZZ"`)}, + {ivms101.AddressTypeGeographic, []byte(`"GEOG"`)}, + {ivms101.AddressTypeMisc, []byte(`0`)}, + {ivms101.AddressTypeHome, []byte(`1`)}, + {ivms101.AddressTypeBusiness, []byte(`2`)}, + {ivms101.AddressTypeGeographic, []byte(`3`)}, + {ivms101.AddressTypeMisc, []byte(`"ADDRESS_TYPE_CODE_MISC"`)}, + {ivms101.AddressTypeHome, []byte(`"ADDRESS_TYPE_CODE_HOME"`)}, + {ivms101.AddressTypeBusiness, []byte(`"ADDRESS_TYPE_CODE_BIZZ"`)}, + {ivms101.AddressTypeGeographic, []byte(`"ADDRESS_TYPE_CODE_GEOG"`)}, + {ivms101.AddressTypeMisc, []byte(`"misc"`)}, + {ivms101.AddressTypeHome, []byte(`"home"`)}, + {ivms101.AddressTypeBusiness, []byte(`"bizz"`)}, + {ivms101.AddressTypeGeographic, []byte(`"geog"`)}, + } + + for i, tc := range valid { + var code ivms101.AddressTypeCode + require.NoError(t, json.Unmarshal(tc.message, &code), "could not unmarshal data in test case %d", i) + require.Equal(t, tc.expected, code, "incorrect unmarshal for test case %d", i) + } + + invalid := []struct { + target error + message []byte + }{ + {ivms101.ErrInvalidAddressTypeCode, []byte(`"LALA"`)}, + {ivms101.ErrInvalidAddressTypeCode, []byte(`{}`)}, + } + + for i, tc := range invalid { + var code ivms101.AddressTypeCode + err := json.Unmarshal(tc.message, &code) + require.ErrorIs(t, err, tc.target, "expected error on test case %d", i) + require.Zero(t, code, "expected zero valued code on test case %d", i) + } + }) + + t.Run("NationalIdentifierTypeCode", func(t *testing.T) { + valid := []struct { + expected ivms101.NationalIdentifierTypeCode + message []byte + }{ + {ivms101.NationalIdentifierMISC, []byte(`"MISC"`)}, + {ivms101.NationalIdentifierARNU, []byte(`"ARNU"`)}, + {ivms101.NationalIdentifierCCPT, []byte(`"CCPT"`)}, + {ivms101.NationalIdentifierRAID, []byte(`"RAID"`)}, + {ivms101.NationalIdentifierDRLC, []byte(`"DRLC"`)}, + {ivms101.NationalIdentifierFIIN, []byte(`"FIIN"`)}, + {ivms101.NationalIdentifierTXID, []byte(`"TXID"`)}, + {ivms101.NationalIdentifierSOCS, []byte(`"SOCS"`)}, + {ivms101.NationalIdentifierIDCD, []byte(`"IDCD"`)}, + {ivms101.NationalIdentifierLEIX, []byte(`"LEIX"`)}, + {ivms101.NationalIdentifierMISC, []byte(`0`)}, + {ivms101.NationalIdentifierARNU, []byte(`1`)}, + {ivms101.NationalIdentifierCCPT, []byte(`2`)}, + {ivms101.NationalIdentifierRAID, []byte(`3`)}, + {ivms101.NationalIdentifierDRLC, []byte(`4`)}, + {ivms101.NationalIdentifierFIIN, []byte(`5`)}, + {ivms101.NationalIdentifierTXID, []byte(`6`)}, + {ivms101.NationalIdentifierSOCS, []byte(`7`)}, + {ivms101.NationalIdentifierIDCD, []byte(`8`)}, + {ivms101.NationalIdentifierLEIX, []byte(`9`)}, + {ivms101.NationalIdentifierMISC, []byte(`"NATIONAL_IDENTIFIER_TYPE_CODE_MISC"`)}, + {ivms101.NationalIdentifierARNU, []byte(`"NATIONAL_IDENTIFIER_TYPE_CODE_ARNU"`)}, + {ivms101.NationalIdentifierCCPT, []byte(`"NATIONAL_IDENTIFIER_TYPE_CODE_CCPT"`)}, + {ivms101.NationalIdentifierRAID, []byte(`"NATIONAL_IDENTIFIER_TYPE_CODE_RAID"`)}, + {ivms101.NationalIdentifierDRLC, []byte(`"NATIONAL_IDENTIFIER_TYPE_CODE_DRLC"`)}, + {ivms101.NationalIdentifierFIIN, []byte(`"NATIONAL_IDENTIFIER_TYPE_CODE_FIIN"`)}, + {ivms101.NationalIdentifierTXID, []byte(`"NATIONAL_IDENTIFIER_TYPE_CODE_TXID"`)}, + {ivms101.NationalIdentifierSOCS, []byte(`"NATIONAL_IDENTIFIER_TYPE_CODE_SOCS"`)}, + {ivms101.NationalIdentifierIDCD, []byte(`"NATIONAL_IDENTIFIER_TYPE_CODE_IDCD"`)}, + {ivms101.NationalIdentifierLEIX, []byte(`"NATIONAL_IDENTIFIER_TYPE_CODE_LEIX"`)}, + {ivms101.NationalIdentifierMISC, []byte(`"misc"`)}, + {ivms101.NationalIdentifierARNU, []byte(`"arnu"`)}, + {ivms101.NationalIdentifierCCPT, []byte(`"ccpt"`)}, + {ivms101.NationalIdentifierRAID, []byte(`"raid"`)}, + {ivms101.NationalIdentifierDRLC, []byte(`"drlc"`)}, + {ivms101.NationalIdentifierFIIN, []byte(`"fiin"`)}, + {ivms101.NationalIdentifierTXID, []byte(`"txid"`)}, + {ivms101.NationalIdentifierSOCS, []byte(`"socs"`)}, + {ivms101.NationalIdentifierIDCD, []byte(`"idcd"`)}, + {ivms101.NationalIdentifierLEIX, []byte(`"leix"`)}, + } + + for i, tc := range valid { + var code ivms101.NationalIdentifierTypeCode + require.NoError(t, json.Unmarshal(tc.message, &code), "could not unmarshal data in test case %d", i) + require.Equal(t, tc.expected, code, "incorrect unmarshal for test case %d", i) + } + + invalid := []struct { + target error + message []byte + }{ + {ivms101.ErrInvalidNationalIdentifierTypeCode, []byte(`"ACME"`)}, + {ivms101.ErrInvalidNationalIdentifierTypeCode, []byte(`{}`)}, + } + + for i, tc := range invalid { + var code ivms101.NationalIdentifierTypeCode + err := json.Unmarshal(tc.message, &code) + require.ErrorIs(t, err, tc.target, "expected error on test case %d", i) + require.Zero(t, code, "expected zero valued code on test case %d", i) + } + }) + + t.Run("TransliterationMethodCode", func(t *testing.T) { + valid := []struct { + expected ivms101.TransliterationMethodCode + message []byte + }{ + {ivms101.TransliterationMethodOTHR, []byte(`"OTHR"`)}, + {ivms101.TransliterationMethodARAB, []byte(`"ARAB"`)}, + {ivms101.TransliterationMethodARAN, []byte(`"ARAN"`)}, + {ivms101.TransliterationMethodARMN, []byte(`"ARMN"`)}, + {ivms101.TransliterationMethodCYRL, []byte(`"CYRL"`)}, + {ivms101.TransliterationMethodDEVA, []byte(`"DEVA"`)}, + {ivms101.TransliterationMethodGEOR, []byte(`"GEOR"`)}, + {ivms101.TransliterationMethodGREK, []byte(`"GREK"`)}, + {ivms101.TransliterationMethodHANI, []byte(`"HANI"`)}, + {ivms101.TransliterationMethodHEBR, []byte(`"HEBR"`)}, + {ivms101.TransliterationMethodKANA, []byte(`"KANA"`)}, + {ivms101.TransliterationMethodKORE, []byte(`"KORE"`)}, + {ivms101.TransliterationMethodTHAI, []byte(`"THAI"`)}, + {ivms101.TransliterationMethodOTHR, []byte(`0`)}, + {ivms101.TransliterationMethodARAB, []byte(`1`)}, + {ivms101.TransliterationMethodARAN, []byte(`2`)}, + {ivms101.TransliterationMethodARMN, []byte(`3`)}, + {ivms101.TransliterationMethodCYRL, []byte(`4`)}, + {ivms101.TransliterationMethodDEVA, []byte(`5`)}, + {ivms101.TransliterationMethodGEOR, []byte(`6`)}, + {ivms101.TransliterationMethodGREK, []byte(`7`)}, + {ivms101.TransliterationMethodHANI, []byte(`8`)}, + {ivms101.TransliterationMethodHEBR, []byte(`9`)}, + {ivms101.TransliterationMethodKANA, []byte(`10`)}, + {ivms101.TransliterationMethodKORE, []byte(`11`)}, + {ivms101.TransliterationMethodTHAI, []byte(`12`)}, + {ivms101.TransliterationMethodOTHR, []byte(`"TRANSLITERATION_METHOD_CODE_OTHR"`)}, + {ivms101.TransliterationMethodARAB, []byte(`"TRANSLITERATION_METHOD_CODE_ARAB"`)}, + {ivms101.TransliterationMethodARAN, []byte(`"TRANSLITERATION_METHOD_CODE_ARAN"`)}, + {ivms101.TransliterationMethodARMN, []byte(`"TRANSLITERATION_METHOD_CODE_ARMN"`)}, + {ivms101.TransliterationMethodCYRL, []byte(`"TRANSLITERATION_METHOD_CODE_CYRL"`)}, + {ivms101.TransliterationMethodDEVA, []byte(`"TRANSLITERATION_METHOD_CODE_DEVA"`)}, + {ivms101.TransliterationMethodGEOR, []byte(`"TRANSLITERATION_METHOD_CODE_GEOR"`)}, + {ivms101.TransliterationMethodGREK, []byte(`"TRANSLITERATION_METHOD_CODE_GREK"`)}, + {ivms101.TransliterationMethodHANI, []byte(`"TRANSLITERATION_METHOD_CODE_HANI"`)}, + {ivms101.TransliterationMethodHEBR, []byte(`"TRANSLITERATION_METHOD_CODE_HEBR"`)}, + {ivms101.TransliterationMethodKANA, []byte(`"TRANSLITERATION_METHOD_CODE_KANA"`)}, + {ivms101.TransliterationMethodKORE, []byte(`"TRANSLITERATION_METHOD_CODE_KORE"`)}, + {ivms101.TransliterationMethodTHAI, []byte(`"TRANSLITERATION_METHOD_CODE_THAI"`)}, + {ivms101.TransliterationMethodOTHR, []byte(`"othr"`)}, + {ivms101.TransliterationMethodARAB, []byte(`"arab"`)}, + {ivms101.TransliterationMethodARAN, []byte(`"aran"`)}, + {ivms101.TransliterationMethodARMN, []byte(`"armn"`)}, + {ivms101.TransliterationMethodCYRL, []byte(`"cyrl"`)}, + {ivms101.TransliterationMethodDEVA, []byte(`"deva"`)}, + {ivms101.TransliterationMethodGEOR, []byte(`"geor"`)}, + {ivms101.TransliterationMethodGREK, []byte(`"grek"`)}, + {ivms101.TransliterationMethodHANI, []byte(`"hani"`)}, + {ivms101.TransliterationMethodHEBR, []byte(`"hebr"`)}, + {ivms101.TransliterationMethodKANA, []byte(`"kana"`)}, + {ivms101.TransliterationMethodKORE, []byte(`"kore"`)}, + {ivms101.TransliterationMethodTHAI, []byte(`"thai"`)}, + } + + for i, tc := range valid { + var code ivms101.TransliterationMethodCode + require.NoError(t, json.Unmarshal(tc.message, &code), "could not unmarshal data in test case %d", i) + require.Equal(t, tc.expected, code, "incorrect unmarshal for test case %d") + } + + invalid := []struct { + target error + message []byte + }{ + {ivms101.ErrInvalidTransliterationMethodCode, []byte(`"KLINGON"`)}, + {ivms101.ErrInvalidTransliterationMethodCode, []byte(`{}`)}, + } + + for i, tc := range invalid { + var code ivms101.TransliterationMethodCode + err := json.Unmarshal(tc.message, &code) + require.ErrorIs(t, err, tc.target, "expected error on test case %d", i) + require.Zero(t, code, "expected zero valued code on test case %d", i) + } + }) +} + func TestEnumParse(t *testing.T) { t.Run("NaturalPersonNameTypeCode", func(t *testing.T) { validTestCases := []struct { @@ -45,12 +445,12 @@ func TestEnumParse(t *testing.T) { input any err error }{ - {"alias", ivms101.ErrCouldNotParseEnum}, - {2, ivms101.ErrCouldNotParseEnum}, - {"", ivms101.ErrCouldNotParseEnum}, - {"NATURAL_PERSON_NAME_TYPE_CODE_FOO", ivms101.ErrCouldNotParseEnum}, - {nil, ivms101.ErrCouldNotParseEnum}, - {int32(28), ivms101.ErrCouldNotParseEnum}, + {"alias", ivms101.ErrInvalidNaturalPersonNameTypeCode}, + {2, ivms101.ErrInvalidNaturalPersonNameTypeCode}, + {"", ivms101.ErrInvalidNaturalPersonNameTypeCode}, + {"NATURAL_PERSON_NAME_TYPE_CODE_FOO", ivms101.ErrInvalidNaturalPersonNameTypeCode}, + {nil, ivms101.ErrInvalidNaturalPersonNameTypeCode}, + {int32(28), ivms101.ErrInvalidNaturalPersonNameTypeCode}, } for i, tc := range invalidTestCases { @@ -92,12 +492,12 @@ func TestEnumParse(t *testing.T) { input any err error }{ - {"legal", ivms101.ErrCouldNotParseEnum}, - {2, ivms101.ErrCouldNotParseEnum}, - {"", ivms101.ErrCouldNotParseEnum}, - {"LEGAL_PERSON_NAME_TYPE_CODE_FOO", ivms101.ErrCouldNotParseEnum}, - {nil, ivms101.ErrCouldNotParseEnum}, - {int32(28), ivms101.ErrCouldNotParseEnum}, + {"legal", ivms101.ErrInvalidLegalPersonNameTypeCode}, + {2, ivms101.ErrInvalidLegalPersonNameTypeCode}, + {"", ivms101.ErrInvalidLegalPersonNameTypeCode}, + {"LEGAL_PERSON_NAME_TYPE_CODE_FOO", ivms101.ErrInvalidLegalPersonNameTypeCode}, + {nil, ivms101.ErrInvalidLegalPersonNameTypeCode}, + {int32(28), ivms101.ErrInvalidLegalPersonNameTypeCode}, } for i, tc := range invalidTestCases { @@ -140,12 +540,12 @@ func TestEnumParse(t *testing.T) { input any err error }{ - {"business", ivms101.ErrCouldNotParseEnum}, - {2, ivms101.ErrCouldNotParseEnum}, - {"", ivms101.ErrCouldNotParseEnum}, - {"ADDRESS_TYPE_CODE_FOO", ivms101.ErrCouldNotParseEnum}, - {nil, ivms101.ErrCouldNotParseEnum}, - {int32(28), ivms101.ErrCouldNotParseEnum}, + {"business", ivms101.ErrInvalidAddressTypeCode}, + {2, ivms101.ErrInvalidAddressTypeCode}, + {"", ivms101.ErrInvalidAddressTypeCode}, + {"ADDRESS_TYPE_CODE_FOO", ivms101.ErrInvalidAddressTypeCode}, + {nil, ivms101.ErrInvalidAddressTypeCode}, + {int32(28), ivms101.ErrInvalidAddressTypeCode}, } for i, tc := range invalidTestCases { @@ -212,12 +612,12 @@ func TestEnumParse(t *testing.T) { input any err error }{ - {"passport", ivms101.ErrCouldNotParseEnum}, - {2, ivms101.ErrCouldNotParseEnum}, - {"", ivms101.ErrCouldNotParseEnum}, - {"NATIONAL_IDENTIFIER_TYPE_CODE_FOO", ivms101.ErrCouldNotParseEnum}, - {nil, ivms101.ErrCouldNotParseEnum}, - {int32(28), ivms101.ErrCouldNotParseEnum}, + {"passport", ivms101.ErrInvalidNationalIdentifierTypeCode}, + {2, ivms101.ErrInvalidNationalIdentifierTypeCode}, + {"", ivms101.ErrInvalidNationalIdentifierTypeCode}, + {"NATIONAL_IDENTIFIER_TYPE_CODE_FOO", ivms101.ErrInvalidNationalIdentifierTypeCode}, + {nil, ivms101.ErrInvalidNationalIdentifierTypeCode}, + {int32(28), ivms101.ErrInvalidNationalIdentifierTypeCode}, } for i, tc := range invalidTestCases { @@ -296,12 +696,12 @@ func TestEnumParse(t *testing.T) { input any err error }{ - {"arabic", ivms101.ErrCouldNotParseEnum}, - {2, ivms101.ErrCouldNotParseEnum}, - {"", ivms101.ErrCouldNotParseEnum}, - {"TRANSLITERATION_METHOD_CODE_FOO", ivms101.ErrCouldNotParseEnum}, - {nil, ivms101.ErrCouldNotParseEnum}, - {int32(28), ivms101.ErrCouldNotParseEnum}, + {"arabic", ivms101.ErrInvalidTransliterationMethodCode}, + {2, ivms101.ErrInvalidTransliterationMethodCode}, + {"", ivms101.ErrInvalidTransliterationMethodCode}, + {"TRANSLITERATION_METHOD_CODE_FOO", ivms101.ErrInvalidTransliterationMethodCode}, + {nil, ivms101.ErrInvalidTransliterationMethodCode}, + {int32(28), ivms101.ErrInvalidTransliterationMethodCode}, } for i, tc := range invalidTestCases { @@ -311,285 +711,3 @@ func TestEnumParse(t *testing.T) { } }) } - -func TestMarshalNatNameCode(t *testing.T) { - // Test an array of expected ivms101 protocol buffer enums - // to inspect whether we correctly marshal them to the correct - // compatible ivms101 format - expected := map[int][]byte{ - 0: []byte(`"MISC"`), - 1: []byte(`"ALIA"`), - 2: []byte(`"BIRT"`), - 3: []byte(`"MAID"`), - 4: []byte(`"LEGL"`), - } - for c := 0; c < 5; c++ { - code := ivms101.NaturalPersonNameTypeCode(c) - data, err := code.MarshalJSON() - require.Nil(t, err) - require.Equal(t, expected[c], data) - } -} - -func TestUnmarshalNatNameCode(t *testing.T) { - // Test an array of expected compatible ivms101 codes - // to inspect whether we correctly unmarshal them to the correct - // protocol buffer enum - data := map[int][]byte{ - 0: []byte(`"MISC"`), - 1: []byte(`"ALIA"`), - 2: []byte(`"BIRT"`), - 3: []byte(`"MAID"`), - 4: []byte(`"LEGL"`), - } - for c := 0; c < 5; c++ { - var code ivms101.NaturalPersonNameTypeCode - err := code.UnmarshalJSON(data[c]) - require.Nil(t, err) - require.Equal(t, ivms101.NaturalPersonNameTypeCode(c), code) - } - - // Test than an unknown compatible ivms101 code triggers a helpful error - var unknown ivms101.NaturalPersonNameTypeCode - err := unknown.UnmarshalJSON([]byte(`"STAGE"`)) - require.EqualError(t, err, "invalid NaturalPersonNameTypeCode alias") - // And a default value of "MISC" is assigned to the object - require.Equal(t, unknown, ivms101.NaturalPersonNameTypeCode(0)) - - // Test that incorrect json input (no quotes) triggers a helpful error - var badCode ivms101.NaturalPersonNameTypeCode - err = badCode.UnmarshalJSON([]byte("ALIA")) - require.EqualError(t, err, "could not parse NaturalPersonNameTypeCode from value") - // And a default value of "MISC" is assigned to the object - require.Equal(t, badCode, ivms101.NaturalPersonNameTypeCode(0)) -} - -func TestMarshalLegNameCode(t *testing.T) { - // Test an array of expected ivms101 protocol buffer enums - // to inspect whether we correctly marshal them to the correct - // compatible ivms101 format - expected := map[int][]byte{ - 0: []byte(`"MISC"`), - 1: []byte(`"LEGL"`), - 2: []byte(`"SHRT"`), - 3: []byte(`"TRAD"`), - } - for c := 0; c < 4; c++ { - code := ivms101.LegalPersonNameTypeCode(c) - data, err := code.MarshalJSON() - require.Nil(t, err) - require.Equal(t, expected[c], data) - } -} - -func TestUnmarshalLegNameCode(t *testing.T) { - // Test an array of expected compatible ivms101 codes - // to inspect whether we correctly unmarshal them to the correct - // protocol buffer enum - data := map[int][]byte{ - 0: []byte(`"MISC"`), - 1: []byte(`"LEGL"`), - 2: []byte(`"SHRT"`), - 3: []byte(`"TRAD"`), - } - for c := 0; c < 4; c++ { - var code ivms101.LegalPersonNameTypeCode - err := code.UnmarshalJSON(data[c]) - require.Nil(t, err) - require.Equal(t, ivms101.LegalPersonNameTypeCode(c), code) - } - - // Test than an unknown compatible ivms101 code triggers a helpful error - var unknown ivms101.LegalPersonNameTypeCode - err := unknown.UnmarshalJSON([]byte(`"SHEL"`)) - require.EqualError(t, err, "invalid LegalPersonNameTypeCode alias") - // And a default value of "MISC" is assigned to the object - require.Equal(t, unknown, ivms101.LegalPersonNameTypeCode(0)) - - // Test that incorrect json input (no quotes) triggers a helpful error - var badCode ivms101.LegalPersonNameTypeCode - err = badCode.UnmarshalJSON([]byte("LEGL")) - require.EqualError(t, err, "could not parse LegalPersonNameTypeCode from value") - // And a default value of "MISC" is assigned to the object - require.Equal(t, badCode, ivms101.LegalPersonNameTypeCode(0)) -} - -func TestMarshalAddrCode(t *testing.T) { - // Test an array of expected ivms101 protocol buffer enums - // to inspect whether we correctly marshal them to the correct - // compatible ivms101 format - expected := map[int][]byte{ - 0: []byte(`"MISC"`), - 1: []byte(`"HOME"`), - 2: []byte(`"BIZZ"`), - 3: []byte(`"GEOG"`), - } - for c := 0; c < 4; c++ { - code := ivms101.AddressTypeCode(c) - data, err := code.MarshalJSON() - require.Nil(t, err) - require.Equal(t, expected[c], data) - } -} - -func TestUnmarshalAddrCode(t *testing.T) { - // Test an array of expected compatible ivms101 codes - // to inspect whether we correctly unmarshal them to the correct - // protocol buffer enum - data := map[int][]byte{ - 0: []byte(`"MISC"`), - 1: []byte(`"HOME"`), - 2: []byte(`"BIZZ"`), - 3: []byte(`"GEOG"`), - } - for c := 0; c < 4; c++ { - var code ivms101.AddressTypeCode - err := code.UnmarshalJSON(data[c]) - require.Nil(t, err) - require.Equal(t, ivms101.AddressTypeCode(c), code) - } - - // Test than an unknown compatible ivms101 code triggers a helpful error - var unknown ivms101.AddressTypeCode - err := unknown.UnmarshalJSON([]byte(`"LALA"`)) - require.EqualError(t, err, "invalid AddressTypeCode alias") - // And a default value of "MISC" is assigned to the object - require.Equal(t, unknown, ivms101.AddressTypeCode(0)) - - // Test that incorrect json input (no quotes) triggers a helpful error - var badCode ivms101.AddressTypeCode - err = badCode.UnmarshalJSON([]byte("HOME")) - require.EqualError(t, err, "could not parse AddressTypeCode from value") - // And a default value of "MISC" is assigned to the object - require.Equal(t, badCode, ivms101.AddressTypeCode(0)) -} - -func TestMarshalNatIDCode(t *testing.T) { - // Test an array of expected ivms101 protocol buffer enums - // to inspect whether we correctly marshal them to the correct - // compatible ivms101 format - expected := map[int][]byte{ - 0: []byte(`"MISC"`), - 1: []byte(`"ARNU"`), - 2: []byte(`"CCPT"`), - 3: []byte(`"RAID"`), - 4: []byte(`"DRLC"`), - 5: []byte(`"FIIN"`), - 6: []byte(`"TXID"`), - 7: []byte(`"SOCS"`), - 8: []byte(`"IDCD"`), - 9: []byte(`"LEIX"`), - } - for c := 0; c < 10; c++ { - code := ivms101.NationalIdentifierTypeCode(c) - data, err := code.MarshalJSON() - require.Nil(t, err) - require.Equal(t, expected[c], data) - } -} - -func TestUnmarshalNatIDCode(t *testing.T) { - // Test an array of expected compatible ivms101 codes - // to inspect whether we correctly unmarshal them to the correct - // protocol buffer enum - data := map[int][]byte{ - 0: []byte(`"MISC"`), - 1: []byte(`"ARNU"`), - 2: []byte(`"CCPT"`), - 3: []byte(`"RAID"`), - 4: []byte(`"DRLC"`), - 5: []byte(`"FIIN"`), - 6: []byte(`"TXID"`), - 7: []byte(`"SOCS"`), - 8: []byte(`"IDCD"`), - 9: []byte(`"LEIX"`), - } - for c := 0; c < 10; c++ { - var code ivms101.NationalIdentifierTypeCode - err := code.UnmarshalJSON(data[c]) - require.Nil(t, err) - require.Equal(t, ivms101.NationalIdentifierTypeCode(c), code) - } - - // Test than an unknown compatible ivms101 code triggers a helpful error - var unknown ivms101.NationalIdentifierTypeCode - err := unknown.UnmarshalJSON([]byte(`"ACME"`)) - require.EqualError(t, err, "invalid NationalIdentifierTypeCode alias") - // And a default value of "MISC" is assigned to the object - require.Equal(t, unknown, ivms101.NationalIdentifierTypeCode(0)) - - // Test that incorrect json input (no quotes) triggers a helpful error - var badCode ivms101.NationalIdentifierTypeCode - err = badCode.UnmarshalJSON([]byte("LEIX")) - require.EqualError(t, err, "could not parse NationalIdentifierTypeCode from value") - // And a default value of "MISC" is assigned to the object - require.Equal(t, badCode, ivms101.NationalIdentifierTypeCode(0)) -} - -func TestMarshalTransliterationCode(t *testing.T) { - // Test an array of expected ivms101 protocol buffer enums - // to inspect whether we correctly marshal them to the correct - // compatible ivms101 format - expected := map[int][]byte{ - 0: []byte(`"OTHR"`), - 1: []byte(`"ARAB"`), - 2: []byte(`"ARAN"`), - 3: []byte(`"ARMN"`), - 4: []byte(`"CYRL"`), - 5: []byte(`"DEVA"`), - 6: []byte(`"GEOR"`), - 7: []byte(`"GREK"`), - 8: []byte(`"HANI"`), - 9: []byte(`"HEBR"`), - 10: []byte(`"KANA"`), - 11: []byte(`"KORE"`), - 12: []byte(`"THAI"`), - } - for c := 0; c < 10; c++ { - code := ivms101.TransliterationMethodCode(c) - data, err := code.MarshalJSON() - require.Nil(t, err) - require.Equal(t, expected[c], data) - } -} - -func TestUnmarshalTransliterationCode(t *testing.T) { - // Test an array of expected compatible ivms101 codes - // to inspect whether we correctly unmarshal them to the correct - // protocol buffer enum - data := map[int][]byte{ - 0: []byte(`"OTHR"`), - 1: []byte(`"ARAB"`), - 2: []byte(`"ARAN"`), - 3: []byte(`"ARMN"`), - 4: []byte(`"CYRL"`), - 5: []byte(`"DEVA"`), - 6: []byte(`"GEOR"`), - 7: []byte(`"GREK"`), - 8: []byte(`"HANI"`), - 9: []byte(`"HEBR"`), - 10: []byte(`"KANA"`), - 11: []byte(`"KORE"`), - 12: []byte(`"THAI"`), - } - for c := 0; c < 10; c++ { - var code ivms101.TransliterationMethodCode - err := code.UnmarshalJSON(data[c]) - require.Nil(t, err) - require.Equal(t, ivms101.TransliterationMethodCode(c), code) - } - - // Test than an unknown compatible ivms101 code triggers a helpful error - var unknown ivms101.TransliterationMethodCode - err := unknown.UnmarshalJSON([]byte(`"KLINGON"`)) - require.EqualError(t, err, "invalid TransliterationMethodCode alias") - // And a default value of "OTHR" is assigned to the object - require.Equal(t, unknown, ivms101.TransliterationMethodCode(0)) - - // Test that incorrect json input (no quotes) triggers a helpful error - var badCode ivms101.TransliterationMethodCode - err = badCode.UnmarshalJSON([]byte("KORE")) - require.EqualError(t, err, "could not parse TransliterationMethodCode from value") - // And a default value of "OTHR" is assigned to the object - require.Equal(t, badCode, ivms101.TransliterationMethodCode(0)) -} diff --git a/pkg/ivms101/errors.go b/pkg/ivms101/errors.go index cdbc5c6..a0c0e44 100644 --- a/pkg/ivms101/errors.go +++ b/pkg/ivms101/errors.go @@ -7,9 +7,11 @@ var ( ErrNoNaturalPersonNameIdentifiers = errors.New("one or more natural person name identifiers is required") ErrInvalidNaturalPersonName = errors.New("natural person name required with max length 100 chars") ErrInvalidNaturalPersonNameTypeCode = errors.New("invalid natural person name type code") + ErrParseNaturalPersonNameTypeCode = errors.New("could not parse natural person name type code from value") ErrNoLegalPersonNameIdentifiers = errors.New("one or more legal person name identifiers is required") ErrInvalidLegalPersonName = errors.New("legal person name required with max length 100 chars") ErrInvalidLegalPersonNameTypeCode = errors.New("invalid legal person name type code") + ErrParseLegalPersonNameTypeCode = errors.New("could not parse legal person name type code from value") ErrLegalNamesPresent = errors.New("at least one name identifier must have a LEGL name identifier type") ErrInvalidCustomerNumber = errors.New("customer number can be at most 50 chars") ErrInvalidCustomerIdentification = errors.New("customer identification can be at most 50 chars") @@ -17,6 +19,7 @@ var ( ErrValidNationalIdentifierLegalPerson = errors.New("a legal person must have a national identifier of type RAID, MISC, LEIX, or TXID") ErrInvalidLEI = errors.New("national identifier required with max length 35") ErrInvalidNationalIdentifierTypeCode = errors.New("invalid national identifier type code") + ErrParseNationalIdentifierTypeCode = errors.New("could not parse national identifier type code from value") ErrCompleteNationalIdentifierCountry = errors.New("a legal person must not have a value for country if identifier type is not LEIX") ErrCompleteNationalIdentifierAuthorityEmpty = errors.New("a legal person must have a value for registration authority if identifier type is not LEIX") ErrCompleteNationalIdentifierAuthority = errors.New("a legal person must not have a value for registration authority if identifier type is LEIX") @@ -25,6 +28,24 @@ var ( ErrDateInPast = errors.New("date of birth must be a historic date, prior to current date") ErrValidAddress = errors.New("address must have at least one address line or street name + building name or number") ErrInvalidAddressTypeCode = errors.New("invalid address type code") + ErrParseAddressTypeCode = errors.New("could not parse address type code from value") ErrInvalidAddressLines = errors.New("an address can contain at most 7 address lines") - ErrCouldNotParseEnum = errors.New("unknown enum value or type") + ErrInvalidTransliterationMethodCode = errors.New("invalid transliteration method code") + ErrParseTransliterationMethodCode = errors.New("could not parse transliteration method code from value") ) + +// Wraps one error with another error for better error type checking. +type WrappedError struct { + error error + cause error +} + +func (e *WrappedError) Error() string { return e.error.Error() } + +func (e *WrappedError) Cause() error { return e.cause } + +func (e *WrappedError) Unwrap() []error { return []error{e.error, e.cause} } + +func Wrap(err, cause error) error { + return &WrappedError{error: err, cause: cause} +} diff --git a/pkg/ivms101/errors_test.go b/pkg/ivms101/errors_test.go new file mode 100644 index 0000000..6d36e14 --- /dev/null +++ b/pkg/ivms101/errors_test.go @@ -0,0 +1,18 @@ +package ivms101_test + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + "github.com/trisacrypto/trisa/pkg/ivms101" +) + +func TestWrap(t *testing.T) { + cause := &json.UnsupportedValueError{Str: "this value is unsupported"} + err := ivms101.Wrap(ivms101.ErrInvalidNaturalPersonNameTypeCode, cause) + + require.ErrorIs(t, err, ivms101.ErrInvalidNaturalPersonNameTypeCode) + require.ErrorIs(t, err, cause) + require.EqualError(t, err, ivms101.ErrInvalidNaturalPersonNameTypeCode.Error()) +} diff --git a/pkg/trisa/gds/models/v1beta1/enum.go b/pkg/trisa/gds/models/v1beta1/enum.go index 966a2c9..30d6fb0 100644 --- a/pkg/trisa/gds/models/v1beta1/enum.go +++ b/pkg/trisa/gds/models/v1beta1/enum.go @@ -1,6 +1,7 @@ package models import ( + "encoding/json" "errors" "strings" ) @@ -87,6 +88,22 @@ var ( ErrUnknownServiceState = errors.New("could not parse service state from input") ) +func (b BusinessCategory) MarshalJSON() ([]byte, error) { + return json.Marshal(b.String()) +} + +func (b *BusinessCategory) UnmarshalJSON(data []byte) (err error) { + var val interface{} + if err = json.Unmarshal(data, &val); err != nil { + return err + } + + if *b, err = ParseBusinessCategory(val); err != nil { + return err + } + return nil +} + // ParseBusinessCategory from text representation. func ParseBusinessCategory(in any) (BusinessCategory, error) { switch val := in.(type) { @@ -99,6 +116,18 @@ func ParseBusinessCategory(in any) (BusinessCategory, error) { if _, ok := BusinessCategory_name[val]; ok { return BusinessCategory(val), nil } + case float64: + if _, ok := BusinessCategory_name[int32(val)]; ok { + return BusinessCategory(val), nil + } + case json.Number: + i, err := val.Int64() + if err != nil { + return 0, err + } + if _, ok := BusinessCategory_name[int32(i)]; ok { + return BusinessCategory(i), nil + } } return 0, ErrUnknownBusinessCategory @@ -116,6 +145,22 @@ func ValidVASPCategory(in string) (string, error) { return "", ErrUnknownVASPCategory } +func (b VerificationState) MarshalJSON() ([]byte, error) { + return json.Marshal(b.String()) +} + +func (b *VerificationState) UnmarshalJSON(data []byte) (err error) { + var val interface{} + if err = json.Unmarshal(data, &val); err != nil { + return err + } + + if *b, err = ParseVerificationState(val); err != nil { + return err + } + return nil +} + func ParseVerificationState(in any) (VerificationState, error) { switch val := in.(type) { case string: @@ -127,10 +172,38 @@ func ParseVerificationState(in any) (VerificationState, error) { if _, ok := VerificationState_name[val]; ok { return VerificationState(val), nil } + case float64: + if _, ok := VerificationState_name[int32(val)]; ok { + return VerificationState(val), nil + } + case json.Number: + i, err := val.Int64() + if err != nil { + return 0, err + } + if _, ok := VerificationState_name[int32(i)]; ok { + return VerificationState(i), nil + } } return 0, ErrUnknownVerificationState } +func (b ServiceState) MarshalJSON() ([]byte, error) { + return json.Marshal(b.String()) +} + +func (b *ServiceState) UnmarshalJSON(data []byte) (err error) { + var val interface{} + if err = json.Unmarshal(data, &val); err != nil { + return err + } + + if *b, err = ParseServiceState(val); err != nil { + return err + } + return nil +} + func ParseServiceState(in any) (ServiceState, error) { switch val := in.(type) { case string: @@ -142,6 +215,18 @@ func ParseServiceState(in any) (ServiceState, error) { if _, ok := ServiceState_name[val]; ok { return ServiceState(val), nil } + case float64: + if _, ok := ServiceState_name[int32(val)]; ok { + return ServiceState(val), nil + } + case json.Number: + i, err := val.Int64() + if err != nil { + return 0, err + } + if _, ok := ServiceState_name[int32(i)]; ok { + return ServiceState(i), nil + } } return 0, ErrUnknownServiceState