diff --git a/assets/location.go b/assets/location.go index b7903c97f..0b16bbd93 100644 --- a/assets/location.go +++ b/assets/location.go @@ -40,5 +40,5 @@ import "github.com/nyaruka/goflow/envs" // @asset location type LocationHierarchy interface { FindByPath(path envs.LocationPath) *envs.Location - FindByName(name string, level envs.LocationLevel, parent *envs.Location) []*envs.Location + FindByName(env envs.Environment, name string, level envs.LocationLevel, parent *envs.Location) []*envs.Location } diff --git a/envs/cleaner.go b/envs/cleaner.go deleted file mode 100644 index f93528cc2..000000000 --- a/envs/cleaner.go +++ /dev/null @@ -1,106 +0,0 @@ -package envs - -import ( - "encoding/json" - "strings" - - "github.com/nyaruka/gocommon/stringsx" - "github.com/pkg/errors" -) - -// Cleaner is a named function that "cleans" a string. -type Cleaner struct { - type_ string - fn func(string) string -} - -func (c Cleaner) String() string { - return c.type_ -} - -func (c Cleaner) MarshalJSON() ([]byte, error) { - return json.Marshal(c.String()) -} - -func (c *Cleaner) UnmarshalJSON(d []byte) error { - var type_ string - if err := json.Unmarshal(d, &type_); err != nil { - return err - } - - for _, cl := range cleaners { - if type_ == cl.type_ { - *c = cl - return nil - } - } - return errors.Errorf("%s is not a valid cleaner", type_) -} - -var CleanConfusables = Cleaner{ - "confusables", - func(s string) string { return stringsx.Skeleton(s) }, -} - -// https://en.wikipedia.org/wiki/Persian_alphabet#Deviations_from_the_Arabic_script -var farsiToArabic = map[rune]rune{ - '۰': '٠', // U+06F0 > U+0660 (0) - '۱': '١', // U+06F1 > U+0661 (1) - '۲': '٢', // U+06F2 > U+0662 (2) - '۳': '٣', // U+06F3 > U+0663 (3) - '۴': '٤', // U+06F4 > U+0664 (4) - '۵': '٥', // U+06F5 > U+0665 (5) - '۶': '٦', // U+06F6 > U+0666 (6) - '۷': '۷', // U+06F7 > U+0667 (7) - '۸': '٨', // U+06F8 > U+0668 (8) - '۹': '٩', // U+06F9 > U+0669 (9) - 'ی': 'ي', // U+06CC > U+064A (yeh) - 'ک': 'ك', // U+06A9 > U+0643 (kāf) -} - -var CleanFarsiToArabic = Cleaner{ - "farsi_to_arabic", - func(s string) string { return replaceRunes(s, farsiToArabic) }, -} - -var arabicToFarsi = map[rune]rune{ - '٠': '۰', // U+0660 > U+06F0 (0) - '١': '۱', // U+0661 > U+06F1 (1) - '٢': '۲', // U+06F2 > U+0662 (2) - '٣': '۳', // U+06F3 > U+0663 (3) - '٤': '۴', // U+06F4 > U+0664 (4) - '٥': '۵', // U+06F5 > U+0665 (5) - '٦': '۶', // U+06F6 > U+0666 (6) - '٧': '۷', // U+06F7 > U+0667 (7) - '٨': '۸', // U+06F8 > U+0668 (8) - '٩': '۹', // U+06F9 > U+0669 (9) - 'ى': 'ی', // U+0649 > U+06CC (alef maksura) - 'ي': 'ی', // U+064A > U+06CC (yeh) - 'ك': 'ک', // U+0643 > U+06A9 (kāf) -} - -var CleanArabicToFarsi = Cleaner{ - "arabic_to_farsi", - func(s string) string { return replaceRunes(s, arabicToFarsi) }, -} - -func CleanInput(env Environment, s string) string { - for _, f := range env.InputCleaners() { - s = f.fn(s) - } - return s -} - -var cleaners = []Cleaner{CleanConfusables, CleanFarsiToArabic, CleanArabicToFarsi} - -func replaceRunes(s string, mapping map[rune]rune) string { - var sb strings.Builder - for _, r := range s { - if repl, found := mapping[r]; found { - sb.WriteRune(repl) - } else { - sb.WriteRune(r) - } - } - return sb.String() -} diff --git a/envs/cleaner_test.go b/envs/cleaner_test.go deleted file mode 100644 index 251af6e7d..000000000 --- a/envs/cleaner_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package envs_test - -import ( - "encoding/json" - "strconv" - "testing" - - "github.com/nyaruka/gocommon/jsonx" - "github.com/nyaruka/goflow/envs" - "github.com/stretchr/testify/assert" -) - -func TestCleaners(t *testing.T) { - tcs := []struct { - cleaner envs.Cleaner - input string - cleaned string - }{ - {envs.CleanConfusables, "", ""}, - {envs.CleanConfusables, "𝕟𝔂𝛼𝐫ᴜ𝞳𝕒", "nyaruka"}, - {envs.CleanFarsiToArabic, "۰۱۲۳۴۵۶۷۸۹", "٠١٢٣٤٥٦۷٨٩"}, - {envs.CleanFarsiToArabic, "بلی", "\u0628\u0644\u064A"}, // ends with farsi yeh - {envs.CleanFarsiToArabic, "بلي", "\u0628\u0644\u064A"}, // ends with arabic yeh - {envs.CleanArabicToFarsi, "٠١٢٣٤٥٦۷٨٩", "۰۱۲۳۴۵۶۷۸۹"}, - {envs.CleanArabicToFarsi, "بلى", "\u0628\u0644\u06CC"}, // ends with farsi yeh (unchanged) - {envs.CleanArabicToFarsi, "بلى", "\u0628\u0644\u06CC"}, // ends with alef maksura - {envs.CleanArabicToFarsi, "بلي", "\u0628\u0644\u06CC"}, // ends with arabic yeh - } - - for _, tc := range tcs { - env := envs.NewBuilder().WithInputCleaners(tc.cleaner).Build() - - assert.Equal(t, tc.cleaned, envs.CleanInput(env, tc.input), "%s mismatch for input %s (%s)", - tc.cleaner, strconv.QuoteToASCII(tc.input), strconv.QuoteToASCII(tc.cleaned)) - } - - assert.Equal(t, `confusables`, envs.CleanConfusables.String()) - assert.Equal(t, []byte(`"confusables"`), jsonx.MustMarshal(envs.CleanConfusables)) - - var cleaner envs.Cleaner - jsonx.MustUnmarshal([]byte(`"arabic_to_farsi"`), &cleaner) - assert.Equal(t, envs.CleanArabicToFarsi.String(), cleaner.String()) - - err := json.Unmarshal([]byte(`"xxx"`), &cleaner) - assert.EqualError(t, err, "xxx is not a valid cleaner") -} diff --git a/envs/collate.go b/envs/collate.go new file mode 100644 index 000000000..2232d724b --- /dev/null +++ b/envs/collate.go @@ -0,0 +1,69 @@ +package envs + +import ( + "strings" + + "github.com/nyaruka/gocommon/stringsx" + "golang.org/x/text/unicode/norm" +) + +type Collation string + +const ( + CollationDefault Collation = "default" + CollationConfusables Collation = "confusables" + CollationArabicFarsi Collation = "arabic_farsi" +) + +type collateTransformer func(string) string + +// https://en.wikipedia.org/wiki/Persian_alphabet#Deviations_from_the_Arabic_script +var arabicToFarsi = map[rune]rune{ + '٠': '۰', // U+0660 > U+06F0 (0) + '١': '۱', // U+0661 > U+06F1 (1) + '٢': '۲', // U+06F2 > U+0662 (2) + '٣': '۳', // U+06F3 > U+0663 (3) + '٤': '۴', // U+06F4 > U+0664 (4) + '٥': '۵', // U+06F5 > U+0665 (5) + '٦': '۶', // U+06F6 > U+0666 (6) + '٧': '۷', // U+06F7 > U+0667 (7) + '٨': '۸', // U+06F8 > U+0668 (8) + '٩': '۹', // U+06F9 > U+0669 (9) + 'ى': 'ی', // U+0649 > U+06CC (alef maksura) + 'ي': 'ی', // U+064A > U+06CC (yeh) + 'ك': 'ک', // U+0643 > U+06A9 (kāf) +} + +var transformers = map[Collation]collateTransformer{ + CollationDefault: func(s string) string { + return strings.ToLower(s) + }, + CollationConfusables: func(s string) string { + return strings.ToLower(stringsx.Skeleton(s)) + }, + CollationArabicFarsi: func(s string) string { + return strings.ToLower(replaceRunes(norm.NFKD.String(s), arabicToFarsi)) + }, +} + +// CollateEquals returns true if the given strings are equal in the given environment's collation +func CollateEquals(env Environment, s, t string) bool { + return CollateTransform(env, s) == CollateTransform(env, t) +} + +// CollateTransform transforms the given string into it's form to be used for collation. +func CollateTransform(env Environment, s string) string { + return transformers[env.InputCollation()](s) +} + +func replaceRunes(s string, mapping map[rune]rune) string { + var sb strings.Builder + for _, r := range s { + if repl, found := mapping[r]; found { + sb.WriteRune(repl) + } else { + sb.WriteRune(r) + } + } + return sb.String() +} diff --git a/envs/collate_test.go b/envs/collate_test.go new file mode 100644 index 000000000..420db2f6a --- /dev/null +++ b/envs/collate_test.go @@ -0,0 +1,64 @@ +package envs_test + +import ( + "strconv" + "testing" + + "github.com/nyaruka/goflow/envs" + "github.com/stretchr/testify/assert" +) + +func TestCollation(t *testing.T) { + + tcs := []struct { + collation envs.Collation + input string + transform string + equals map[string]bool + }{ + {envs.CollationDefault, "AbcD", "abcd", map[string]bool{ + "acde": false, + "aBCd": true, + }}, + {envs.CollationConfusables, "𝕟𝔂𝛼𝐫ᴜ𝞳𝕒", "nyaruka", map[string]bool{ + "trileet": false, + "Nyaruka": true, + "𝒩ɣaruka": true, + }}, + {envs.CollationArabicFarsi, "٠١٢٣٤٥٦۷٨٩", "۰۱۲۳۴۵۶۷۸۹", map[string]bool{ + "٤٥٦۷": false, + "٠١٢٣٤٥٦۷٨٩": true, + "۰۱۲۳۴۵۶۷۸۹": true, + }}, + {envs.CollationArabicFarsi, "\u0628\u0644\u06CC", "\u0628\u0644\u06CC", map[string]bool{ // ends with farsi yeh (unchanged) + "\u0628\u0644": false, + "\u0628\u0644\u0649": true, // ends with alef maksura + "\u0628\u0644\u064A": true, // ends with arabic yeh + }}, + {envs.CollationArabicFarsi, "\u0628\u0644\u0649", "\u0628\u0644\u06CC", map[string]bool{ // ends with alef maksura + "\u0628\u0644\u06CC": true, // ends with farsi yeh + "\u0628\u0644\u064A": true, // ends with arabic yeh + }}, + {envs.CollationArabicFarsi, "\u0628\u0644\u064A", "\u0628\u0644\u06CC", map[string]bool{ // ends with arabic yeh + "\u0628\u0644\u06CC": true, // ends with farsi yeh + "\u0628\u0644\u0649": true, // ends with alef maksura + }}, + {envs.CollationArabicFarsi, "\u0643\u0627\u0641", "\u06A9\u0627\u0641", map[string]bool{ // starts with arabic kaf + "\u0643\u0627\u0641": true, // starts with arabic kaf + "\u06A9\u0627\u0641": true, // starts with farsi kaf + "\uFEDB\u0627\u0641": true, // starts with explicit initial form kaf + }}, + {envs.CollationArabicFarsi, "YES", "yes", map[string]bool{"yes": true, "no": false}}, + } + + for _, tc := range tcs { + env := envs.NewBuilder().WithInputCollation(tc.collation).Build() + + assert.Equal(t, tc.transform, envs.CollateTransform(env, tc.input), "%s transform mismatch for input %s (%s)", + tc.collation, strconv.QuoteToASCII(tc.input), strconv.QuoteToASCII(tc.transform)) + + for eqStr, eqResult := range tc.equals { + assert.Equal(t, eqResult, envs.CollateEquals(env, tc.input, eqStr)) + } + } +} diff --git a/envs/environment.go b/envs/environment.go index ec264abf4..04c45f61e 100644 --- a/envs/environment.go +++ b/envs/environment.go @@ -34,8 +34,8 @@ type Environment interface { AllowedLanguages() []Language DefaultCountry() Country NumberFormat() *NumberFormat + InputCollation() Collation RedactionPolicy() RedactionPolicy - InputCleaners() []Cleaner DefaultLanguage() Language DefaultLocale() Locale @@ -56,7 +56,7 @@ type environment struct { defaultCountry Country numberFormat *NumberFormat redactionPolicy RedactionPolicy - inputCleaners []Cleaner + inputCollation Collation } func (e *environment) DateFormat() DateFormat { return e.dateFormat } @@ -65,8 +65,8 @@ func (e *environment) Timezone() *time.Location { return e.timezone } func (e *environment) AllowedLanguages() []Language { return e.allowedLanguages } func (e *environment) DefaultCountry() Country { return e.defaultCountry } func (e *environment) NumberFormat() *NumberFormat { return e.numberFormat } +func (e *environment) InputCollation() Collation { return e.inputCollation } func (e *environment) RedactionPolicy() RedactionPolicy { return e.redactionPolicy } -func (e *environment) InputCleaners() []Cleaner { return e.inputCleaners } // DefaultLanguage is the first allowed language func (e *environment) DefaultLanguage() Language { @@ -104,8 +104,8 @@ type envEnvelope struct { AllowedLanguages []Language `json:"allowed_languages,omitempty" validate:"omitempty,dive,language"` NumberFormat *NumberFormat `json:"number_format,omitempty"` DefaultCountry Country `json:"default_country,omitempty" validate:"omitempty,country"` + InputCollation Collation `json:"input_collation"` RedactionPolicy RedactionPolicy `json:"redaction_policy" validate:"omitempty,eq=none|eq=urns"` - InputCleaners []Cleaner `json:"input_cleaners,omitempty"` } // ReadEnvironment reads an environment from the given JSON @@ -123,8 +123,8 @@ func ReadEnvironment(data json.RawMessage) (Environment, error) { env.allowedLanguages = envelope.AllowedLanguages env.defaultCountry = envelope.DefaultCountry env.numberFormat = envelope.NumberFormat + env.inputCollation = envelope.InputCollation env.redactionPolicy = envelope.RedactionPolicy - env.inputCleaners = envelope.InputCleaners tz, err := time.LoadLocation(envelope.Timezone) if err != nil { @@ -143,8 +143,8 @@ func (e *environment) toEnvelope() *envEnvelope { AllowedLanguages: e.allowedLanguages, DefaultCountry: e.defaultCountry, NumberFormat: e.numberFormat, + InputCollation: e.inputCollation, RedactionPolicy: e.redactionPolicy, - InputCleaners: e.inputCleaners, } } @@ -172,8 +172,8 @@ func NewBuilder() *EnvironmentBuilder { allowedLanguages: nil, defaultCountry: NilCountry, numberFormat: DefaultNumberFormat, + inputCollation: CollationDefault, redactionPolicy: RedactionPolicyNone, - inputCleaners: nil, }, } } @@ -210,13 +210,13 @@ func (b *EnvironmentBuilder) WithNumberFormat(numberFormat *NumberFormat) *Envir return b } -func (b *EnvironmentBuilder) WithRedactionPolicy(redactionPolicy RedactionPolicy) *EnvironmentBuilder { - b.env.redactionPolicy = redactionPolicy +func (b *EnvironmentBuilder) WithInputCollation(col Collation) *EnvironmentBuilder { + b.env.inputCollation = col return b } -func (b *EnvironmentBuilder) WithInputCleaners(cs ...Cleaner) *EnvironmentBuilder { - b.env.inputCleaners = cs +func (b *EnvironmentBuilder) WithRedactionPolicy(redactionPolicy RedactionPolicy) *EnvironmentBuilder { + b.env.redactionPolicy = redactionPolicy return b } diff --git a/envs/environment_test.go b/envs/environment_test.go index 2f189232a..8f6250854 100644 --- a/envs/environment_test.go +++ b/envs/environment_test.go @@ -63,11 +63,13 @@ func TestEnvironmentMarshaling(t *testing.T) { assert.Equal(t, []envs.Language{envs.Language("eng"), envs.Language("fra")}, env.AllowedLanguages()) assert.Equal(t, envs.Country("RW"), env.DefaultCountry()) assert.Equal(t, "en-RW", env.DefaultLocale().ToBCP47()) + assert.Equal(t, envs.CollationDefault, env.InputCollation()) + assert.Equal(t, envs.RedactionPolicyNone, env.RedactionPolicy()) assert.Nil(t, env.LocationResolver()) data, err := jsonx.Marshal(env) require.NoError(t, err) - assert.Equal(t, string(data), `{"date_format":"DD-MM-YYYY","time_format":"tt:mm:ss","timezone":"Africa/Kigali","allowed_languages":["eng","fra"],"number_format":{"decimal_symbol":".","digit_grouping_symbol":","},"default_country":"RW","redaction_policy":"none"}`) + assert.Equal(t, string(data), `{"date_format":"DD-MM-YYYY","time_format":"tt:mm:ss","timezone":"Africa/Kigali","allowed_languages":["eng","fra"],"number_format":{"decimal_symbol":".","digit_grouping_symbol":","},"default_country":"RW","input_collation":"default","redaction_policy":"none"}`) } func TestEnvironmentEqual(t *testing.T) { diff --git a/envs/location_test.go b/envs/location_test.go index 49de58fd7..777dbff69 100644 --- a/envs/location_test.go +++ b/envs/location_test.go @@ -57,7 +57,9 @@ var locationHierarchyJSON = ` }` func TestLocationHierarchy(t *testing.T) { - hierarchy, err := envs.ReadLocationHierarchy(json.RawMessage(locationHierarchyJSON)) + env := envs.NewBuilder().Build() + + hierarchy, err := envs.ReadLocationHierarchy(env, json.RawMessage(locationHierarchyJSON)) assert.NoError(t, err) rwanda := hierarchy.Root() @@ -90,18 +92,18 @@ func TestLocationHierarchy(t *testing.T) { assert.Equal(t, gasabo, ndera.Parent()) assert.Equal(t, 0, len(ndera.Children())) - assert.Equal(t, []*envs.Location{rwanda}, hierarchy.FindByName("RWaNdA", envs.LocationLevel(0), nil)) - assert.Equal(t, []*envs.Location{kigali}, hierarchy.FindByName("kigari", envs.LocationLevel(1), nil)) - assert.Equal(t, []*envs.Location{kigali}, hierarchy.FindByName("rwanda > kigali city", envs.LocationLevel(1), nil)) - assert.Equal(t, []*envs.Location{kigali}, hierarchy.FindByName("kigari", envs.LocationLevel(1), rwanda)) - assert.Equal(t, []*envs.Location{gasabo}, hierarchy.FindByName("GASABO", envs.LocationLevel(2), nil)) - assert.Equal(t, []*envs.Location{gasabo}, hierarchy.FindByName("GASABO", envs.LocationLevel(2), kigali)) - assert.Equal(t, []*envs.Location{ndera}, hierarchy.FindByName("RWANDA > kigali city > gasabo > ndera", envs.LocationLevel(3), nil)) - - assert.Equal(t, []*envs.Location{}, hierarchy.FindByName("boston", envs.LocationLevel(1), nil)) // no such name - assert.Equal(t, []*envs.Location{}, hierarchy.FindByName("kigari", envs.LocationLevel(8), nil)) // no such level - assert.Equal(t, []*envs.Location{}, hierarchy.FindByName("kigari", envs.LocationLevel(2), nil)) // wrong level - assert.Equal(t, []*envs.Location{}, hierarchy.FindByName("kigari", envs.LocationLevel(2), gasabo)) // wrong parent + assert.Equal(t, []*envs.Location{rwanda}, hierarchy.FindByName(env, "RWaNdA", envs.LocationLevel(0), nil)) + assert.Equal(t, []*envs.Location{kigali}, hierarchy.FindByName(env, "kigari", envs.LocationLevel(1), nil)) + assert.Equal(t, []*envs.Location{kigali}, hierarchy.FindByName(env, "rwanda > kigali city", envs.LocationLevel(1), nil)) + assert.Equal(t, []*envs.Location{kigali}, hierarchy.FindByName(env, "kigari", envs.LocationLevel(1), rwanda)) + assert.Equal(t, []*envs.Location{gasabo}, hierarchy.FindByName(env, "GASABO", envs.LocationLevel(2), nil)) + assert.Equal(t, []*envs.Location{gasabo}, hierarchy.FindByName(env, "GASABO", envs.LocationLevel(2), kigali)) + assert.Equal(t, []*envs.Location{ndera}, hierarchy.FindByName(env, "RWANDA > kigali city > gasabo > ndera", envs.LocationLevel(3), nil)) + + assert.Equal(t, []*envs.Location{}, hierarchy.FindByName(env, "boston", envs.LocationLevel(1), nil)) // no such name + assert.Equal(t, []*envs.Location{}, hierarchy.FindByName(env, "kigari", envs.LocationLevel(8), nil)) // no such level + assert.Equal(t, []*envs.Location{}, hierarchy.FindByName(env, "kigari", envs.LocationLevel(2), nil)) // wrong level + assert.Equal(t, []*envs.Location{}, hierarchy.FindByName(env, "kigari", envs.LocationLevel(2), gasabo)) // wrong parent assert.Equal(t, rwanda, hierarchy.FindByPath(envs.LocationPath("RWANDA"))) assert.Equal(t, kigali, hierarchy.FindByPath("RWANDA > KIGALI CITY")) diff --git a/envs/locations.go b/envs/locations.go index ab7939c9e..61ba25afd 100644 --- a/envs/locations.go +++ b/envs/locations.go @@ -16,8 +16,8 @@ type LocationPath string // LocationResolver is used to resolve locations from names or hierarchical paths type LocationResolver interface { - FindLocations(string, LocationLevel, *Location) []*Location - FindLocationsFuzzy(string, LocationLevel, *Location) []*Location + FindLocations(Environment, string, LocationLevel, *Location) []*Location + FindLocationsFuzzy(Environment, string, LocationLevel, *Location) []*Location LookupLocation(LocationPath) *Location } @@ -118,12 +118,14 @@ func (p locationPathLookup) lookup(path LocationPath) *Location { return p[path. // location names aren't always unique in a given level - i.e. you can have two wards with the same name, but different parents type locationNameLookup map[string][]*Location -func (n locationNameLookup) addLookup(name string, location *Location) { - name = strings.ToLower(name) +func (n locationNameLookup) addLookup(env Environment, name string, location *Location) { + name = CollateTransform(env, name) n[name] = append(n[name], location) } -func (n locationNameLookup) lookup(name string) []*Location { return n[strings.ToLower(name)] } +func (n locationNameLookup) lookup(env Environment, name string) []*Location { + return n[CollateTransform(env, name)] +} // LocationHierarchy is a hierarical tree of locations type LocationHierarchy struct { @@ -135,14 +137,14 @@ type LocationHierarchy struct { } // NewLocationHierarchy cretes a new location hierarchy -func NewLocationHierarchy(root *Location, numLevels int) *LocationHierarchy { +func NewLocationHierarchy(env Environment, root *Location, numLevels int) *LocationHierarchy { h := &LocationHierarchy{} - h.initializeFromRoot(root, numLevels) + h.initializeFromRoot(env, root, numLevels) return h } // NewLocationHierarchy cretes a new location hierarchy -func (h *LocationHierarchy) initializeFromRoot(root *Location, numLevels int) { +func (h *LocationHierarchy) initializeFromRoot(env Environment, root *Location, numLevels int) { h.root = root h.levelLookups = make([]locationNameLookup, numLevels) h.pathLookup = make(locationPathLookup) @@ -160,17 +162,17 @@ func (h *LocationHierarchy) initializeFromRoot(root *Location, numLevels int) { } h.pathLookup.addLookup(location.path, location) - h.addNameLookups(location) + h.addNameLookups(env, location) }) } -func (h *LocationHierarchy) addNameLookups(location *Location) { +func (h *LocationHierarchy) addNameLookups(env Environment, location *Location) { lookups := h.levelLookups[int(location.level)] - lookups.addLookup(location.name, location) + lookups.addLookup(env, location.name, location) // include any aliases as names too for _, alias := range location.aliases { - lookups.addLookup(alias, location) + lookups.addLookup(env, alias, location) } } @@ -180,7 +182,7 @@ func (h *LocationHierarchy) Root() *Location { } // FindByName looks for all locations in the hierarchy with the given level and name or alias -func (h *LocationHierarchy) FindByName(name string, level LocationLevel, parent *Location) []*Location { +func (h *LocationHierarchy) FindByName(env Environment, name string, level LocationLevel, parent *Location) []*Location { // try it as a path first if it looks possible if level == 0 || IsPossibleLocationPath(name) { @@ -191,7 +193,7 @@ func (h *LocationHierarchy) FindByName(name string, level LocationLevel, parent } if int(level) < len(h.levelLookups) { - matches := h.levelLookups[int(level)].lookup(name) + matches := h.levelLookups[int(level)].lookup(env, name) if matches != nil { // if a parent is specified, filter the matches by it if parent != nil { @@ -221,8 +223,11 @@ func (h *LocationHierarchy) UnmarshalJSON(data []byte) error { return err } + // TODO this method is only used to load static assets and they're only used for testing.. but this isn't ideal + env := NewBuilder().Build() + root := locationFromEnvelope(&le, LocationLevel(0), nil) - h.initializeFromRoot(root, 4) + h.initializeFromRoot(env, root, 4) return nil } @@ -253,7 +258,7 @@ func locationFromEnvelope(envelope *locationEnvelope, currentLevel LocationLevel } // ReadLocationHierarchy reads a location hierarchy from the given JSON -func ReadLocationHierarchy(data json.RawMessage) (*LocationHierarchy, error) { +func ReadLocationHierarchy(env Environment, data json.RawMessage) (*LocationHierarchy, error) { var le locationEnvelope if err := utils.UnmarshalAndValidate(data, &le); err != nil { return nil, err @@ -261,5 +266,5 @@ func ReadLocationHierarchy(data json.RawMessage) (*LocationHierarchy, error) { root := locationFromEnvelope(&le, LocationLevel(0), nil) - return NewLocationHierarchy(root, 4), nil + return NewLocationHierarchy(env, root, 4), nil } diff --git a/flows/environment.go b/flows/environment.go index da4be8f99..7356a7c42 100644 --- a/flows/environment.go +++ b/flows/environment.go @@ -38,8 +38,8 @@ type assetLocationResolver struct { } // FindLocations returns locations with the matching name (case-insensitive), level and parent (optional) -func (r *assetLocationResolver) FindLocations(name string, level envs.LocationLevel, parent *envs.Location) []*envs.Location { - return r.locations.FindByName(name, level, parent) +func (r *assetLocationResolver) FindLocations(env envs.Environment, name string, level envs.LocationLevel, parent *envs.Location) []*envs.Location { + return r.locations.FindByName(env, name, level, parent) } // FindLocationsFuzzy returns matching locations like FindLocations but attempts the following strategies @@ -48,15 +48,15 @@ func (r *assetLocationResolver) FindLocations(name string, level envs.LocationLe // 2. Match with punctuation removed // 3. Split input into words and try to match each word // 4. Try to match pairs of words -func (r *assetLocationResolver) FindLocationsFuzzy(text string, level envs.LocationLevel, parent *envs.Location) []*envs.Location { +func (r *assetLocationResolver) FindLocationsFuzzy(env envs.Environment, text string, level envs.LocationLevel, parent *envs.Location) []*envs.Location { // try matching name exactly - if locations := r.FindLocations(text, level, parent); len(locations) > 0 { + if locations := r.FindLocations(env, text, level, parent); len(locations) > 0 { return locations } // try with punctuation removed stripped := strings.TrimSpace(regexp.MustCompile(`[\s\p{P}]+`).ReplaceAllString(text, "")) - if locations := r.FindLocations(stripped, level, parent); len(locations) > 0 { + if locations := r.FindLocations(env, stripped, level, parent); len(locations) > 0 { return locations } @@ -64,7 +64,7 @@ func (r *assetLocationResolver) FindLocationsFuzzy(text string, level envs.Locat re := regexp.MustCompile(`[\p{L}\d]+(-[\p{L}\d]+)*`) words := re.FindAllString(text, -1) for _, word := range words { - if locations := r.FindLocations(word, level, parent); len(locations) > 0 { + if locations := r.FindLocations(env, word, level, parent); len(locations) > 0 { return locations } } @@ -72,7 +72,7 @@ func (r *assetLocationResolver) FindLocationsFuzzy(text string, level envs.Locat // try with each pair of words for i := 0; i < len(words)-1; i++ { wordPair := strings.Join(words[i:i+2], " ") - if locations := r.FindLocations(wordPair, level, parent); len(locations) > 0 { + if locations := r.FindLocations(env, wordPair, level, parent); len(locations) > 0 { return locations } } diff --git a/flows/environment_test.go b/flows/environment_test.go index 3724ccd2b..1b81f17a4 100644 --- a/flows/environment_test.go +++ b/flows/environment_test.go @@ -89,7 +89,7 @@ func TestAssetsEnvironment(t *testing.T) { kigali := aenv.LocationResolver().LookupLocation("Rwanda > Kigali City") assert.Equal(t, "Kigali City", kigali.Name()) - matches := aenv.LocationResolver().FindLocationsFuzzy("gisozi town", flows.LocationLevelWard, nil) + matches := aenv.LocationResolver().FindLocationsFuzzy(env, "gisozi town", flows.LocationLevelWard, nil) assert.Equal(t, 1, len(matches)) assert.Equal(t, "Gisozi", matches[0].Name()) } diff --git a/flows/events/base_test.go b/flows/events/base_test.go index 160bf991b..f3a865ee2 100644 --- a/flows/events/base_test.go +++ b/flows/events/base_test.go @@ -382,6 +382,7 @@ func TestEventMarshaling(t *testing.T) { ], "date_format": "DD-MM-YYYY", "default_country": "US", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/flows/field.go b/flows/field.go index dac140449..cd477436a 100644 --- a/flows/field.go +++ b/flows/field.go @@ -233,15 +233,15 @@ func (f FieldValues) Parse(env envs.Environment, fields *FieldAssets, field *Fie if field.Type() == assets.FieldTypeWard { parent := f.getFirstLocationValue(env, fields, assets.FieldTypeDistrict) if parent != nil { - matchingLocations = locations.FindLocationsFuzzy(rawValue, LocationLevelWard, parent) + matchingLocations = locations.FindLocationsFuzzy(env, rawValue, LocationLevelWard, parent) } } else if field.Type() == assets.FieldTypeDistrict { parent := f.getFirstLocationValue(env, fields, assets.FieldTypeState) if parent != nil { - matchingLocations = locations.FindLocationsFuzzy(rawValue, LocationLevelDistrict, parent) + matchingLocations = locations.FindLocationsFuzzy(env, rawValue, LocationLevelDistrict, parent) } } else if field.Type() == assets.FieldTypeState { - matchingLocations = locations.FindLocationsFuzzy(rawValue, LocationLevelState, nil) + matchingLocations = locations.FindLocationsFuzzy(env, rawValue, LocationLevelState, nil) } if len(matchingLocations) > 0 { diff --git a/flows/inputs/msg.go b/flows/inputs/msg.go index 29fa7f0b2..b77e3de8b 100644 --- a/flows/inputs/msg.go +++ b/flows/inputs/msg.go @@ -42,7 +42,7 @@ func NewMsg(s flows.Session, msg *flows.MsgIn, createdOn time.Time) *MsgInput { return &MsgInput{ baseInput: newBaseInput(TypeMsg, flows.InputUUID(msg.UUID()), channel, createdOn), urn: flows.NewContactURN(msg.URN(), nil), - text: envs.CleanInput(s.Environment(), msg.Text()), + text: msg.Text(), attachments: msg.Attachments(), externalID: msg.ExternalID(), } diff --git a/flows/inputs/msg_test.go b/flows/inputs/msg_test.go index b9db6923f..6c615236e 100644 --- a/flows/inputs/msg_test.go +++ b/flows/inputs/msg_test.go @@ -26,7 +26,7 @@ func TestMsgInput(t *testing.T) { flows.MsgUUID("f51d7220-10b3-4faa-a91c-1ae70beaae3e"), urns.URN("tel:+1234567890"), assets.NewChannelReference("57f1078f-88aa-46f4-a59a-948a5739c03d", "Nexmo"), - "ℋ𝓲 there!", + "Hi there!", []utils.Attachment{ "image/jpg:http://example.com/test.jpg", "video/mp4:http://example.com/test.mp4", @@ -48,7 +48,7 @@ func TestMsgInput(t *testing.T) { "channel": flows.Context(env, channel), "created_on": types.NewXDateTime(input.CreatedOn()), "urn": types.NewXText("tel:+1234567890"), - "text": types.NewXText("Hi there!"), // cleaned + "text": types.NewXText("Hi there!"), "attachments": types.NewXArray(types.NewXText("image/jpg:http://example.com/test.jpg"), types.NewXText("video/mp4:http://example.com/test.mp4")), "external_id": types.NewXText("ext12345"), }), flows.Context(env, input)) diff --git a/flows/routers/cases/tests.go b/flows/routers/cases/tests.go index 72836504f..71ded8d87 100644 --- a/flows/routers/cases/tests.go +++ b/flows/routers/cases/tests.go @@ -199,7 +199,7 @@ func HasGroup(env envs.Environment, args ...types.XValue) types.XValue { // // @test has_phrase(text, phrase) func HasPhrase(env envs.Environment, text types.XText, test types.XText) types.XValue { - return testStringTokens(env, text, test, hasPhraseTest) + return testTextTokens(env, text, test, hasPhraseTest) } // HasAllWords tests whether all the `words` are contained in `text` @@ -212,7 +212,7 @@ func HasPhrase(env envs.Environment, text types.XText, test types.XText) types.X // // @test has_all_words(text, words) func HasAllWords(env envs.Environment, text types.XText, test types.XText) types.XValue { - return testStringTokens(env, text, test, hasAllWordsTest) + return testTextTokens(env, text, test, hasAllWordsTest) } // HasAnyWord tests whether any of the `words` are contained in the `text` @@ -225,7 +225,7 @@ func HasAllWords(env envs.Environment, text types.XText, test types.XText) types // // @test has_any_word(text, words) func HasAnyWord(env envs.Environment, text types.XText, test types.XText) types.XValue { - return testStringTokens(env, text, test, hasAnyWordTest) + return testTextTokens(env, text, test, hasAnyWordTest) } // HasOnlyPhrase tests whether the `text` contains only `phrase` @@ -241,7 +241,7 @@ func HasAnyWord(env envs.Environment, text types.XText, test types.XText) types. // // @test has_only_phrase(text, phrase) func HasOnlyPhrase(env envs.Environment, text types.XText, test types.XText) types.XValue { - return testStringTokens(env, text, test, hasOnlyPhraseTest) + return testTextTokens(env, text, test, hasOnlyPhraseTest) } // HasText tests whether there the text has any characters in it @@ -608,7 +608,7 @@ func HasState(env envs.Environment, text types.XText) types.XValue { return types.NewXErrorf("can't find locations in environment which is not location enabled") } - states := locations.FindLocationsFuzzy(text.Native(), flows.LocationLevelState, nil) + states := locations.FindLocationsFuzzy(env, text.Native(), flows.LocationLevelState, nil) if len(states) > 0 { return NewTrueResult(types.NewXText(string(states[0].Path()))) } @@ -643,9 +643,9 @@ func HasDistrict(env envs.Environment, args ...types.XValue) types.XValue { } } - states := locations.FindLocationsFuzzy(stateText.Native(), flows.LocationLevelState, nil) + states := locations.FindLocationsFuzzy(env, stateText.Native(), flows.LocationLevelState, nil) if len(states) > 0 { - districts := locations.FindLocationsFuzzy(text.Native(), flows.LocationLevelDistrict, states[0]) + districts := locations.FindLocationsFuzzy(env, text.Native(), flows.LocationLevelDistrict, states[0]) if len(districts) > 0 { return NewTrueResult(types.NewXText(string(districts[0].Path()))) } @@ -653,7 +653,7 @@ func HasDistrict(env envs.Environment, args ...types.XValue) types.XValue { // try without a parent state - it's ok as long as we get a single match if stateText.Empty() { - districts := locations.FindLocationsFuzzy(text.Native(), flows.LocationLevelDistrict, nil) + districts := locations.FindLocationsFuzzy(env, text.Native(), flows.LocationLevelDistrict, nil) if len(districts) == 1 { return NewTrueResult(types.NewXText(string(districts[0].Path()))) } @@ -700,11 +700,11 @@ func HasWard(env envs.Environment, args ...types.XValue) types.XValue { } } - states := locations.FindLocationsFuzzy(stateText.Native(), flows.LocationLevelState, nil) + states := locations.FindLocationsFuzzy(env, stateText.Native(), flows.LocationLevelState, nil) if len(states) > 0 { - districts := locations.FindLocationsFuzzy(districtText.Native(), flows.LocationLevelDistrict, states[0]) + districts := locations.FindLocationsFuzzy(env, districtText.Native(), flows.LocationLevelDistrict, states[0]) if len(districts) > 0 { - wards := locations.FindLocationsFuzzy(text.Native(), flows.LocationLevelWard, districts[0]) + wards := locations.FindLocationsFuzzy(env, text.Native(), flows.LocationLevelWard, districts[0]) if len(wards) > 0 { return NewTrueResult(types.NewXText(string(wards[0].Path()))) } @@ -713,7 +713,7 @@ func HasWard(env envs.Environment, args ...types.XValue) types.XValue { // try without a parent district - it's ok as long as we get a single match if districtText.Empty() { - wards := locations.FindLocationsFuzzy(text.Native(), flows.LocationLevelWard, nil) + wards := locations.FindLocationsFuzzy(env, text.Native(), flows.LocationLevelWard, nil) if len(wards) == 1 { return NewTrueResult(types.NewXText(string(wards[0].Path()))) } @@ -726,20 +726,16 @@ func HasWard(env envs.Environment, args ...types.XValue) types.XValue { // Text Test Functions //------------------------------------------------------------------------------------------ -type stringTokenTest func(origHayTokens []string, hayTokens []string, pinTokens []string) types.XValue +type stringTokenTest func(env envs.Environment, hayTokens []string, pinTokens []string) types.XValue -func testStringTokens(env envs.Environment, str types.XText, testStr types.XText, testFunc stringTokenTest) types.XValue { - hayStack := strings.TrimSpace(str.Native()) - needle := strings.TrimSpace(testStr.Native()) +func testTextTokens(env envs.Environment, str types.XText, testStr types.XText, testFunc stringTokenTest) types.XValue { + hays := utils.TokenizeString(strings.TrimSpace(str.Native())) + needles := utils.TokenizeString(strings.TrimSpace(testStr.Native())) - origHays := utils.TokenizeString(hayStack) - hays := utils.TokenizeString(strings.ToLower(hayStack)) - needles := utils.TokenizeString(strings.ToLower(needle)) - - return testFunc(origHays, hays, needles) + return testFunc(env, hays, needles) } -func hasPhraseTest(origHays []string, hays []string, pins []string) types.XValue { +func hasPhraseTest(env envs.Environment, hays []string, pins []string) types.XValue { if len(pins) == 0 { return NewTrueResult(types.XTextEmpty) } @@ -747,8 +743,8 @@ func hasPhraseTest(origHays []string, hays []string, pins []string) types.XValue pinIdx := 0 matches := make([]string, len(pins)) for i, hay := range hays { - if hay == pins[pinIdx] { - matches[pinIdx] = origHays[i] + if envs.CollateEquals(env, hay, pins[pinIdx]) { + matches[pinIdx] = hays[i] pinIdx++ if pinIdx == len(pins) { break @@ -765,21 +761,21 @@ func hasPhraseTest(origHays []string, hays []string, pins []string) types.XValue return FalseResult } -func hasAllWordsTest(origHays []string, hays []string, pins []string) types.XValue { +func hasAllWordsTest(env envs.Environment, hays []string, pins []string) types.XValue { matches := make([]string, 0, len(pins)) pinMatches := make([]int, len(pins)) for i, hay := range hays { matched := false for j, pin := range pins { - if hay == pin { + if envs.CollateEquals(env, hay, pin) { matched = true pinMatches[j]++ } } if matched { - matches = append(matches, origHays[i]) + matches = append(matches, hays[i]) } } @@ -799,18 +795,18 @@ func hasAllWordsTest(origHays []string, hays []string, pins []string) types.XVal return FalseResult } -func hasAnyWordTest(origHays []string, hays []string, pins []string) types.XValue { +func hasAnyWordTest(env envs.Environment, hays []string, pins []string) types.XValue { matches := make([]string, 0, len(pins)) for i, hay := range hays { matched := false for _, pin := range pins { - if hay == pin { + if envs.CollateEquals(env, hay, pin) { matched = true break } } if matched { - matches = append(matches, origHays[i]) + matches = append(matches, hays[i]) } } @@ -822,7 +818,7 @@ func hasAnyWordTest(origHays []string, hays []string, pins []string) types.XValu return FalseResult } -func hasOnlyPhraseTest(origHays []string, hays []string, pins []string) types.XValue { +func hasOnlyPhraseTest(env envs.Environment, hays []string, pins []string) types.XValue { // must be same length if len(hays) != len(pins) { return FalseResult @@ -831,10 +827,10 @@ func hasOnlyPhraseTest(origHays []string, hays []string, pins []string) types.XV // and every token must match matches := make([]string, 0, len(pins)) for i := range hays { - if hays[i] != pins[i] { + if !envs.CollateEquals(env, hays[i], pins[i]) { return FalseResult } - matches = append(matches, origHays[i]) + matches = append(matches, hays[i]) } return NewTrueResult(types.NewXText(strings.Join(matches, " "))) diff --git a/flows/triggers/testdata/TestTriggerMarshaling_campaign.snap b/flows/triggers/testdata/TestTriggerMarshaling_campaign.snap index ffb2a1f15..4fe347e7a 100644 --- a/flows/triggers/testdata/TestTriggerMarshaling_campaign.snap +++ b/flows/triggers/testdata/TestTriggerMarshaling_campaign.snap @@ -8,6 +8,7 @@ "decimal_symbol": ".", "digit_grouping_symbol": "," }, + "input_collation": "default", "redaction_policy": "none" }, "flow": { diff --git a/flows/triggers/testdata/TestTriggerMarshaling_channel_incoming_call.snap b/flows/triggers/testdata/TestTriggerMarshaling_channel_incoming_call.snap index b29ebdce2..e0e69d11e 100644 --- a/flows/triggers/testdata/TestTriggerMarshaling_channel_incoming_call.snap +++ b/flows/triggers/testdata/TestTriggerMarshaling_channel_incoming_call.snap @@ -8,6 +8,7 @@ "decimal_symbol": ".", "digit_grouping_symbol": "," }, + "input_collation": "default", "redaction_policy": "none" }, "flow": { diff --git a/flows/triggers/testdata/TestTriggerMarshaling_channel_new_conversation.snap b/flows/triggers/testdata/TestTriggerMarshaling_channel_new_conversation.snap index a55a87390..2a3ada9dd 100644 --- a/flows/triggers/testdata/TestTriggerMarshaling_channel_new_conversation.snap +++ b/flows/triggers/testdata/TestTriggerMarshaling_channel_new_conversation.snap @@ -8,6 +8,7 @@ "decimal_symbol": ".", "digit_grouping_symbol": "," }, + "input_collation": "default", "redaction_policy": "none" }, "flow": { diff --git a/flows/triggers/testdata/TestTriggerMarshaling_flow_action.snap b/flows/triggers/testdata/TestTriggerMarshaling_flow_action.snap index 333f0c5bb..775c84825 100644 --- a/flows/triggers/testdata/TestTriggerMarshaling_flow_action.snap +++ b/flows/triggers/testdata/TestTriggerMarshaling_flow_action.snap @@ -8,6 +8,7 @@ "decimal_symbol": ".", "digit_grouping_symbol": "," }, + "input_collation": "default", "redaction_policy": "none" }, "flow": { diff --git a/flows/triggers/testdata/TestTriggerMarshaling_flow_action_ivr.snap b/flows/triggers/testdata/TestTriggerMarshaling_flow_action_ivr.snap index c41c5d46e..618fa2740 100644 --- a/flows/triggers/testdata/TestTriggerMarshaling_flow_action_ivr.snap +++ b/flows/triggers/testdata/TestTriggerMarshaling_flow_action_ivr.snap @@ -8,6 +8,7 @@ "decimal_symbol": ".", "digit_grouping_symbol": "," }, + "input_collation": "default", "redaction_policy": "none" }, "flow": { diff --git a/flows/triggers/testdata/TestTriggerMarshaling_manual.snap b/flows/triggers/testdata/TestTriggerMarshaling_manual.snap index dbc38bea1..92ec37b4a 100644 --- a/flows/triggers/testdata/TestTriggerMarshaling_manual.snap +++ b/flows/triggers/testdata/TestTriggerMarshaling_manual.snap @@ -8,6 +8,7 @@ "decimal_symbol": ".", "digit_grouping_symbol": "," }, + "input_collation": "default", "redaction_policy": "none" }, "flow": { diff --git a/flows/triggers/testdata/TestTriggerMarshaling_manual_ivr.snap b/flows/triggers/testdata/TestTriggerMarshaling_manual_ivr.snap index c496114e1..2bcba6e2a 100644 --- a/flows/triggers/testdata/TestTriggerMarshaling_manual_ivr.snap +++ b/flows/triggers/testdata/TestTriggerMarshaling_manual_ivr.snap @@ -8,6 +8,7 @@ "decimal_symbol": ".", "digit_grouping_symbol": "," }, + "input_collation": "default", "redaction_policy": "none" }, "flow": { diff --git a/flows/triggers/testdata/TestTriggerMarshaling_manual_minimal.snap b/flows/triggers/testdata/TestTriggerMarshaling_manual_minimal.snap index f0e2a503b..8a3965fdc 100644 --- a/flows/triggers/testdata/TestTriggerMarshaling_manual_minimal.snap +++ b/flows/triggers/testdata/TestTriggerMarshaling_manual_minimal.snap @@ -8,6 +8,7 @@ "decimal_symbol": ".", "digit_grouping_symbol": "," }, + "input_collation": "default", "redaction_policy": "none" }, "flow": { diff --git a/flows/triggers/testdata/TestTriggerMarshaling_msg.snap b/flows/triggers/testdata/TestTriggerMarshaling_msg.snap index 9366c268a..02a4e3600 100644 --- a/flows/triggers/testdata/TestTriggerMarshaling_msg.snap +++ b/flows/triggers/testdata/TestTriggerMarshaling_msg.snap @@ -8,6 +8,7 @@ "decimal_symbol": ".", "digit_grouping_symbol": "," }, + "input_collation": "default", "redaction_policy": "none" }, "flow": { diff --git a/flows/triggers/testdata/TestTriggerMarshaling_ticket_closed.snap b/flows/triggers/testdata/TestTriggerMarshaling_ticket_closed.snap index 149f829a7..ec8e05d08 100644 --- a/flows/triggers/testdata/TestTriggerMarshaling_ticket_closed.snap +++ b/flows/triggers/testdata/TestTriggerMarshaling_ticket_closed.snap @@ -8,6 +8,7 @@ "decimal_symbol": ".", "digit_grouping_symbol": "," }, + "input_collation": "default", "redaction_policy": "none" }, "flow": { diff --git a/test/session.go b/test/session.go index 77c631bec..9d24f9662 100644 --- a/test/session.go +++ b/test/session.go @@ -602,7 +602,7 @@ func NewSessionBuilder() *SessionBuilder { WithDateFormat(envs.DateFormatDayMonthYear). WithDefaultCountry("US"). WithAllowedLanguages([]envs.Language{"eng", "spa"}). - WithInputCleaners(envs.CleanConfusables). + WithInputCollation(envs.CollationConfusables). Build() return &SessionBuilder{ diff --git a/test/testdata/runner/airtime.test_successful_transfer.json b/test/testdata/runner/airtime.test_successful_transfer.json index 7b3495b9e..cb8e24943 100644 --- a/test/testdata/runner/airtime.test_successful_transfer.json +++ b/test/testdata/runner/airtime.test_successful_transfer.json @@ -198,6 +198,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -308,6 +309,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/all_actions.test.json b/test/testdata/runner/all_actions.test.json index 888c2d955..c16373a35 100644 --- a/test/testdata/runner/all_actions.test.json +++ b/test/testdata/runner/all_actions.test.json @@ -466,6 +466,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -967,6 +968,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/brochure.test.json b/test/testdata/runner/brochure.test.json index 5296fea0d..8305f61a2 100644 --- a/test/testdata/runner/brochure.test.json +++ b/test/testdata/runner/brochure.test.json @@ -61,6 +61,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -147,6 +148,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -270,6 +272,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -439,6 +442,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/date_parse.test.json b/test/testdata/runner/date_parse.test.json index 231816640..a2fe2fe57 100644 --- a/test/testdata/runner/date_parse.test.json +++ b/test/testdata/runner/date_parse.test.json @@ -53,6 +53,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -133,6 +134,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -250,6 +252,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -409,6 +412,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/default_result.test.json b/test/testdata/runner/default_result.test.json index 71e0d4322..53e795d67 100644 --- a/test/testdata/runner/default_result.test.json +++ b/test/testdata/runner/default_result.test.json @@ -58,6 +58,7 @@ }, "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -246,6 +247,7 @@ }, "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/empty.test.json b/test/testdata/runner/empty.test.json index 873e15278..02221ecbe 100644 --- a/test/testdata/runner/empty.test.json +++ b/test/testdata/runner/empty.test.json @@ -29,6 +29,7 @@ }, "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/enter_flow_loop.test.json b/test/testdata/runner/enter_flow_loop.test.json index c42ffbe50..805a6c6ea 100644 --- a/test/testdata/runner/enter_flow_loop.test.json +++ b/test/testdata/runner/enter_flow_loop.test.json @@ -49,6 +49,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -124,6 +125,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -272,6 +274,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -507,6 +510,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -649,6 +653,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -1031,6 +1036,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -1093,6 +1099,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -1505,6 +1512,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/enter_flow_terminal.test.json b/test/testdata/runner/enter_flow_terminal.test.json index b6c386411..22577c53e 100644 --- a/test/testdata/runner/enter_flow_terminal.test.json +++ b/test/testdata/runner/enter_flow_terminal.test.json @@ -65,6 +65,7 @@ }, "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/expirations.test_all_expire.json b/test/testdata/runner/expirations.test_all_expire.json index 130ee7a52..9e72e647e 100644 --- a/test/testdata/runner/expirations.test_all_expire.json +++ b/test/testdata/runner/expirations.test_all_expire.json @@ -72,6 +72,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -214,6 +215,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -297,6 +299,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -474,6 +477,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -557,6 +561,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -769,6 +774,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -819,6 +825,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -1037,6 +1044,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/expirations.test_input_for_all.json b/test/testdata/runner/expirations.test_input_for_all.json index 451947e93..f5a284d25 100644 --- a/test/testdata/runner/expirations.test_input_for_all.json +++ b/test/testdata/runner/expirations.test_input_for_all.json @@ -72,6 +72,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -214,6 +215,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -311,6 +313,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -519,6 +522,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -616,6 +620,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -883,6 +888,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -947,6 +953,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -1244,6 +1251,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/extra.test.json b/test/testdata/runner/extra.test.json index 8bc1885df..ca081a586 100644 --- a/test/testdata/runner/extra.test.json +++ b/test/testdata/runner/extra.test.json @@ -132,6 +132,7 @@ }, "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -387,6 +388,7 @@ }, "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/field_clear.test.json b/test/testdata/runner/field_clear.test.json index 4fd2442cc..b76b0b21f 100644 --- a/test/testdata/runner/field_clear.test.json +++ b/test/testdata/runner/field_clear.test.json @@ -58,6 +58,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -144,6 +145,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/initial_wait.test.json b/test/testdata/runner/initial_wait.test.json index 46d8df68c..fbf3f754f 100644 --- a/test/testdata/runner/initial_wait.test.json +++ b/test/testdata/runner/initial_wait.test.json @@ -70,6 +70,7 @@ }, "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -181,6 +182,7 @@ }, "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/ivr_dial.busy.json b/test/testdata/runner/ivr_dial.busy.json index 14234522d..b48785a6f 100644 --- a/test/testdata/runner/ivr_dial.busy.json +++ b/test/testdata/runner/ivr_dial.busy.json @@ -39,6 +39,7 @@ ], "date_format": "YYYY-MM-DD", "default_country": "US", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -119,6 +120,7 @@ ], "date_format": "YYYY-MM-DD", "default_country": "US", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -186,6 +188,7 @@ ], "date_format": "YYYY-MM-DD", "default_country": "US", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -295,6 +298,7 @@ ], "date_format": "YYYY-MM-DD", "default_country": "US", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/ivr_dial.invalid_phone.json b/test/testdata/runner/ivr_dial.invalid_phone.json index 1d40fad28..d058581bd 100644 --- a/test/testdata/runner/ivr_dial.invalid_phone.json +++ b/test/testdata/runner/ivr_dial.invalid_phone.json @@ -44,6 +44,7 @@ ], "date_format": "YYYY-MM-DD", "default_country": "US", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -139,6 +140,7 @@ ], "date_format": "YYYY-MM-DD", "default_country": "US", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/legacy_favorites.test.json b/test/testdata/runner/legacy_favorites.test.json index 96ee6a859..9b104bcf1 100644 --- a/test/testdata/runner/legacy_favorites.test.json +++ b/test/testdata/runner/legacy_favorites.test.json @@ -48,6 +48,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -122,6 +123,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -221,6 +223,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -364,6 +367,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -450,6 +454,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -642,6 +647,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/legacy_registration.test.json b/test/testdata/runner/legacy_registration.test.json index 465880e55..8dc2ead00 100644 --- a/test/testdata/runner/legacy_registration.test.json +++ b/test/testdata/runner/legacy_registration.test.json @@ -50,6 +50,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -126,6 +127,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -229,6 +231,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -376,6 +379,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -473,6 +477,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -676,6 +681,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -801,6 +807,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -1081,6 +1088,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/legacy_subflow.test.json b/test/testdata/runner/legacy_subflow.test.json index bab2af0dc..5c76a0ce1 100644 --- a/test/testdata/runner/legacy_subflow.test.json +++ b/test/testdata/runner/legacy_subflow.test.json @@ -50,6 +50,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -126,6 +127,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -223,6 +225,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -364,6 +367,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -428,6 +432,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -589,6 +594,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/legacy_timeout.test.json b/test/testdata/runner/legacy_timeout.test.json index 56e21ede3..dce1680c7 100644 --- a/test/testdata/runner/legacy_timeout.test.json +++ b/test/testdata/runner/legacy_timeout.test.json @@ -55,6 +55,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -136,6 +137,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -214,6 +216,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -341,6 +344,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/legacy_webhook.test.json b/test/testdata/runner/legacy_webhook.test.json index 39fc1dcb8..d05fb3f5d 100644 --- a/test/testdata/runner/legacy_webhook.test.json +++ b/test/testdata/runner/legacy_webhook.test.json @@ -76,6 +76,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -183,6 +184,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/nlu_booking.flight.json b/test/testdata/runner/nlu_booking.flight.json index a2eefe7b1..f2a49bc13 100644 --- a/test/testdata/runner/nlu_booking.flight.json +++ b/test/testdata/runner/nlu_booking.flight.json @@ -49,6 +49,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -123,6 +124,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -279,6 +281,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -515,6 +518,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/no_contact.test.json b/test/testdata/runner/no_contact.test.json index 63000270f..9c2f3838b 100644 --- a/test/testdata/runner/no_contact.test.json +++ b/test/testdata/runner/no_contact.test.json @@ -45,6 +45,7 @@ "session": { "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -129,6 +130,7 @@ "trigger": { "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/node_loop.test.json b/test/testdata/runner/node_loop.test.json index 8f956e51a..217d5996d 100644 --- a/test/testdata/runner/node_loop.test.json +++ b/test/testdata/runner/node_loop.test.json @@ -2240,6 +2240,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -4401,6 +4402,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/number_quiz.exceed_limit.json b/test/testdata/runner/number_quiz.exceed_limit.json index f2e39b6a7..388b3c201 100644 --- a/test/testdata/runner/number_quiz.exceed_limit.json +++ b/test/testdata/runner/number_quiz.exceed_limit.json @@ -54,6 +54,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -134,6 +135,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -243,6 +245,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -398,6 +401,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -507,6 +511,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -720,6 +725,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -816,6 +822,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -1076,6 +1083,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/phone_number.test.json b/test/testdata/runner/phone_number.test.json index a80927e97..5374e691b 100644 --- a/test/testdata/runner/phone_number.test.json +++ b/test/testdata/runner/phone_number.test.json @@ -54,6 +54,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -134,6 +135,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -235,6 +237,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -384,6 +387,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -501,6 +505,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -713,6 +718,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/redact_urns.test.json b/test/testdata/runner/redact_urns.test.json index 5642e4c60..ab304353c 100644 --- a/test/testdata/runner/redact_urns.test.json +++ b/test/testdata/runner/redact_urns.test.json @@ -69,6 +69,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -158,6 +159,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/resthook.test.json b/test/testdata/runner/resthook.test.json index 5a8dc401c..25eedb575 100644 --- a/test/testdata/runner/resthook.test.json +++ b/test/testdata/runner/resthook.test.json @@ -133,6 +133,7 @@ }, "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/router_tests.test.json b/test/testdata/runner/router_tests.test.json index d473d82f7..a290ddc16 100644 --- a/test/testdata/runner/router_tests.test.json +++ b/test/testdata/runner/router_tests.test.json @@ -120,6 +120,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -282,6 +283,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/smart_groups.test.json b/test/testdata/runner/smart_groups.test.json index 954fc0e91..12d1880bc 100644 --- a/test/testdata/runner/smart_groups.test.json +++ b/test/testdata/runner/smart_groups.test.json @@ -236,6 +236,7 @@ }, "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/smart_groups_correction.test.json b/test/testdata/runner/smart_groups_correction.test.json index 74aa49b78..1e40d6892 100644 --- a/test/testdata/runner/smart_groups_correction.test.json +++ b/test/testdata/runner/smart_groups_correction.test.json @@ -54,6 +54,7 @@ }, "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/stop.test.json b/test/testdata/runner/stop.test.json index 50d59d85c..f65cbc7d6 100644 --- a/test/testdata/runner/stop.test.json +++ b/test/testdata/runner/stop.test.json @@ -66,6 +66,7 @@ ], "date_format": "MM-DD-YYYY", "default_country": "US", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -188,6 +189,7 @@ ], "date_format": "MM-DD-YYYY", "default_country": "US", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/subflow.test.json b/test/testdata/runner/subflow.test.json index 07866a51b..bd5b9688c 100644 --- a/test/testdata/runner/subflow.test.json +++ b/test/testdata/runner/subflow.test.json @@ -79,6 +79,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -206,6 +207,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -329,6 +331,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -544,6 +547,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/subflow.test_resume_with_expiration.json b/test/testdata/runner/subflow.test_resume_with_expiration.json index a39cbfd62..1d5a87376 100644 --- a/test/testdata/runner/subflow.test_resume_with_expiration.json +++ b/test/testdata/runner/subflow.test_resume_with_expiration.json @@ -79,6 +79,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -206,6 +207,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -288,6 +290,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -443,6 +446,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/subflow_loop_with_wait.test.json b/test/testdata/runner/subflow_loop_with_wait.test.json index e5b99a699..51cb8d971 100644 --- a/test/testdata/runner/subflow_loop_with_wait.test.json +++ b/test/testdata/runner/subflow_loop_with_wait.test.json @@ -84,6 +84,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -214,6 +215,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -348,6 +350,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -585,6 +588,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/subflow_other.test.json b/test/testdata/runner/subflow_other.test.json index 0a3f0330c..3fffcfa4a 100644 --- a/test/testdata/runner/subflow_other.test.json +++ b/test/testdata/runner/subflow_other.test.json @@ -94,6 +94,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -233,6 +234,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -345,6 +347,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -560,6 +563,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -695,6 +699,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -987,6 +992,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -1099,6 +1105,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -1456,6 +1463,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -1556,6 +1564,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -1958,6 +1967,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/ticketing.test.json b/test/testdata/runner/ticketing.test.json index c49403a0d..2d30e8d68 100644 --- a/test/testdata/runner/ticketing.test.json +++ b/test/testdata/runner/ticketing.test.json @@ -46,6 +46,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -117,6 +118,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -266,6 +268,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -451,6 +454,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/triggered.test.json b/test/testdata/runner/triggered.test.json index 403d69b30..b920a0d62 100644 --- a/test/testdata/runner/triggered.test.json +++ b/test/testdata/runner/triggered.test.json @@ -48,6 +48,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -124,6 +125,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/two_questions.test.json b/test/testdata/runner/two_questions.test.json index 1c070fbf8..60ee13630 100644 --- a/test/testdata/runner/two_questions.test.json +++ b/test/testdata/runner/two_questions.test.json @@ -63,6 +63,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -145,6 +146,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -174,6 +176,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -304,6 +307,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -360,6 +364,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -509,6 +514,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -624,6 +630,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -680,6 +687,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -897,6 +905,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/two_questions.test_resume_with_expiration.json b/test/testdata/runner/two_questions.test_resume_with_expiration.json index 3dabb9565..8f1a5ade9 100644 --- a/test/testdata/runner/two_questions.test_resume_with_expiration.json +++ b/test/testdata/runner/two_questions.test_resume_with_expiration.json @@ -55,6 +55,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -137,6 +138,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -192,6 +194,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -280,6 +283,7 @@ "fra" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/two_questions_offline.test.json b/test/testdata/runner/two_questions_offline.test.json index 5a6eeb4d8..13f7872ac 100644 --- a/test/testdata/runner/two_questions_offline.test.json +++ b/test/testdata/runner/two_questions_offline.test.json @@ -46,6 +46,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -119,6 +120,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -213,6 +215,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -344,6 +347,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -441,6 +445,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -624,6 +629,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -687,6 +693,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -887,6 +894,7 @@ "eng" ], "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/webhook_migrated.test.json b/test/testdata/runner/webhook_migrated.test.json index 8ec91aa4e..924dad10b 100644 --- a/test/testdata/runner/webhook_migrated.test.json +++ b/test/testdata/runner/webhook_migrated.test.json @@ -32,6 +32,7 @@ }, "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -182,6 +183,7 @@ }, "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," diff --git a/test/testdata/runner/webhook_results.test.json b/test/testdata/runner/webhook_results.test.json index 5d1761b88..5e5e7e0d5 100644 --- a/test/testdata/runner/webhook_results.test.json +++ b/test/testdata/runner/webhook_results.test.json @@ -88,6 +88,7 @@ }, "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -328,6 +329,7 @@ }, "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": "," @@ -626,6 +628,7 @@ }, "environment": { "date_format": "YYYY-MM-DD", + "input_collation": "default", "number_format": { "decimal_symbol": ".", "digit_grouping_symbol": ","