diff --git a/perxis-proto b/perxis-proto index fc23183a86463b2aa81e3b7570fad1f873c1e435..e0a5fab4b9acafc339c182afd64077640c88fecd 160000 --- a/perxis-proto +++ b/perxis-proto @@ -1 +1 @@ -Subproject commit fc23183a86463b2aa81e3b7570fad1f873c1e435 +Subproject commit e0a5fab4b9acafc339c182afd64077640c88fecd diff --git a/pkg/schema/localizer/localizer.go b/pkg/schema/localizer/localizer.go index 907ade5b5e603e1132d733cbb91604b45f87fc20..86e43ed47c2304806bd16404ae61b8cb6c0973e4 100644 --- a/pkg/schema/localizer/localizer.go +++ b/pkg/schema/localizer/localizer.go @@ -98,19 +98,22 @@ func (l *Localizer) ExtractTranslation(data map[string]interface{}, translations return data, nil } - fallbackData := data var exist bool - if !fallback.IsDefault() { - if fallbackData, exist = translations[fallback.ID]; !exist { - fallbackData = data - } - } - - // extract translation fallback -> target if translation, exist = translations[target.ID]; !exist { return make(map[string]interface{}), nil } + var fallbackData map[string]interface{} + if fallbackData, exist = translations[fallback.ID]; !exist { + return l.extractTranslation(translation, data) + } + + // localize default -> fallback - нужно для корректного сравнения нельзя делать просто extract из прореженных данных fallback + if fallbackData, err = l.localize(fallbackData, data); err != nil { + return nil, err + } + + // extract translation default -> target return l.extractTranslation(translation, fallbackData) } diff --git a/pkg/schema/localizer/localizer_test.go b/pkg/schema/localizer/localizer_test.go index 21b334d488dbbc513163545806c414ce963e8ea9..ded5628dcdd2ec0686243a0da08ef8612d498777 100644 --- a/pkg/schema/localizer/localizer_test.go +++ b/pkg/schema/localizer/localizer_test.go @@ -369,7 +369,7 @@ func TestLocalizer_localize(t *testing.T) { } } -func TestLocalizer_deLocalize(t *testing.T) { +func TestLocalizer_extractTranslation(t *testing.T) { s := schema.New( "a", field.String(), @@ -757,3 +757,149 @@ func TestLocalizer_getTargetAndFallBackLocales(t *testing.T) { }) } } + +func TestLocalizer_ExtractTranslations(t *testing.T) { + + s := schema.New( + "a", field.String(), + ) + + tests := []struct { + data map[string]interface{} + translations map[string]map[string]interface{} + want map[string]interface{} + cfg Config + name string + wantErr bool + }{ + { + name: "Extract default", + data: map[string]interface{}{"a": "bbb"}, + translations: map[string]map[string]interface{}{"en": {"a": "bbb"}}, + cfg: Config{ + LocaleID: "en", + Schema: s, + Locales: []*locales.Locale{ + {ID: "en"}, + {ID: "default"}, + }, + }, + want: map[string]interface{}{}, + }, + { + name: "Extract default not same", + data: map[string]interface{}{"a": "aaa"}, + translations: map[string]map[string]interface{}{"en": {"a": "bbb"}}, + cfg: Config{ + LocaleID: "en", + Schema: s, + Locales: []*locales.Locale{ + {ID: "en"}, + {ID: "default"}, + }, + }, + want: map[string]interface{}{"a": "bbb"}, + }, + { + name: "Extract default empty", + data: map[string]interface{}{"a": "aaa"}, + translations: map[string]map[string]interface{}{"en": {}}, + cfg: Config{ + LocaleID: "en", + Schema: s, + Locales: []*locales.Locale{ + {ID: "en"}, + {ID: "default"}, + }, + }, + want: map[string]interface{}{}, + }, + { + name: "Extract fallback", + data: map[string]interface{}{"a": "aaa"}, + translations: map[string]map[string]interface{}{"ru": {"a": "bbb"}, "en": {"a": "bbb"}}, + cfg: Config{ + LocaleID: "ru", + Schema: s, + Locales: []*locales.Locale{ + {ID: "ru", Fallback: "en"}, + {ID: "en"}, + {ID: "default"}, + }, + }, + want: map[string]interface{}{}, + }, + { + name: "Extract fallback with extracted field", + data: map[string]interface{}{"a": "aaa"}, + translations: map[string]map[string]interface{}{"ru": {"a": "bbb"}, "en": {}}, + cfg: Config{ + LocaleID: "ru", + Schema: s, + Locales: []*locales.Locale{ + {ID: "ru", Fallback: "en"}, + {ID: "en"}, + {ID: "default"}, + }, + }, + want: map[string]interface{}{"a": "bbb"}, + }, + { + name: "Extract fallback with empty field", + data: map[string]interface{}{"a": "aaa"}, + translations: map[string]map[string]interface{}{"ru": {}, "en": {"a": "bbb"}}, + cfg: Config{ + LocaleID: "ru", + Schema: s, + Locales: []*locales.Locale{ + {ID: "ru", Fallback: "en"}, + {ID: "en"}, + {ID: "default"}, + }, + }, + want: map[string]interface{}{}, + }, + { + name: "Extract fallback with same as default", + data: map[string]interface{}{"a": "aaa"}, + translations: map[string]map[string]interface{}{"ru": {"a": "aaa"}, "en": {"a": "bbb"}}, + cfg: Config{ + LocaleID: "ru", + Schema: s, + Locales: []*locales.Locale{ + {ID: "ru", Fallback: "en"}, + {ID: "en"}, + {ID: "default"}, + }, + }, + want: map[string]interface{}{"a": "aaa"}, + }, + { + name: "Extract fallback with same", + data: map[string]interface{}{"a": "aaa"}, + translations: map[string]map[string]interface{}{"ru": {"a": "aaa"}, "en": {"a": "aaa"}}, + cfg: Config{ + LocaleID: "ru", + Schema: s, + Locales: []*locales.Locale{ + {ID: "ru", Fallback: "en"}, + {ID: "en"}, + {ID: "default"}, + }, + }, + want: map[string]interface{}{}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + l := NewLocalizer(tt.cfg) + got, err := l.ExtractTranslation(tt.data, tt.translations) + if !tt.wantErr { + require.NoError(t, err) + assert.Equal(t, tt.want, got) + return + } + require.Error(t, err) + }) + } +}