localization_test.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package localization
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http/httptest"
  6. "sort"
  7. "testing"
  8. "github.com/nicksnyder/go-i18n/v2/i18n"
  9. )
  10. func TestLocalizationService(t *testing.T) {
  11. service := NewLocalizationService()
  12. loadingStrMap := map[string]string{
  13. "de": "Ladevorgang...",
  14. "en": "Loading...",
  15. "es": "Cargando...",
  16. "et": "Laadin...",
  17. "fil": "Naglo-load...",
  18. "fr": "Chargement...",
  19. "ja": "ロード中...",
  20. "is": "Hleður...",
  21. "nb": "Laster inn...",
  22. "nl": "Laden...",
  23. "nn": "Lastar inn...",
  24. "pl": "Ładowanie...",
  25. "pt-BR": "Carregando...",
  26. "tr": "Yükleniyor...",
  27. "ru": "Загрузка...",
  28. "uk": "Завантаження...",
  29. "vi": "Đang nạp...",
  30. "zh-CN": "加载中...",
  31. "zh-TW": "載入中...",
  32. "sv": "Laddar...",
  33. }
  34. var keys []string
  35. for lang := range loadingStrMap {
  36. keys = append(keys, lang)
  37. }
  38. sort.Strings(keys)
  39. for _, lang := range keys {
  40. expected := loadingStrMap[lang]
  41. t.Run(fmt.Sprintf("%s localization", lang), func(t *testing.T) {
  42. localizer := service.GetLocalizer(lang)
  43. result := localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "loading"})
  44. if result != expected {
  45. t.Errorf("Expected '%s', got '%s'", expected, result)
  46. }
  47. })
  48. }
  49. // Test for requiredKeys localization
  50. requiredKeys := []string{
  51. "loading", "why_am_i_seeing", "protected_by", "protected_from", "made_with",
  52. "mascot_design", "try_again", "go_home", "javascript_required",
  53. }
  54. for _, lang := range keys {
  55. t.Run(fmt.Sprintf("All required keys exist in %s", lang), func(t *testing.T) {
  56. loc := service.GetLocalizer(lang)
  57. for _, key := range requiredKeys {
  58. result := loc.MustLocalize(&i18n.LocalizeConfig{MessageID: key})
  59. if result == "" {
  60. t.Errorf("Key '%s' returned empty string", key)
  61. }
  62. }
  63. })
  64. }
  65. }
  66. type manifest struct {
  67. SupportedLanguages []string `json:"supportedLanguages"`
  68. }
  69. func loadManifest(t *testing.T) manifest {
  70. t.Helper()
  71. fin, err := localeFS.Open("locales/manifest.json")
  72. if err != nil {
  73. t.Fatal(err)
  74. }
  75. defer fin.Close()
  76. var result manifest
  77. if err := json.NewDecoder(fin).Decode(&result); err != nil {
  78. t.Fatal(err)
  79. }
  80. return result
  81. }
  82. func TestComprehensiveTranslations(t *testing.T) {
  83. service := NewLocalizationService()
  84. var translations = map[string]any{}
  85. fin, err := localeFS.Open("locales/en.json")
  86. if err != nil {
  87. t.Fatal(err)
  88. }
  89. defer fin.Close()
  90. if err := json.NewDecoder(fin).Decode(&translations); err != nil {
  91. t.Fatal(err)
  92. }
  93. var keys []string
  94. for k := range translations {
  95. keys = append(keys, k)
  96. }
  97. sort.Strings(keys)
  98. manifest := loadManifest(t)
  99. if len(manifest.SupportedLanguages) == 0 {
  100. t.Fatal("no languages loaded")
  101. }
  102. for _, lang := range loadManifest(t).SupportedLanguages {
  103. t.Run(lang, func(t *testing.T) {
  104. loc := service.GetLocalizer(lang)
  105. sl := SimpleLocalizer{Localizer: loc}
  106. service_lang := sl.GetLang()
  107. if service_lang != lang {
  108. t.Error("Localizer language not same as specified")
  109. }
  110. for _, key := range keys {
  111. t.Run(key, func(t *testing.T) {
  112. if result := sl.T(key); result == "" {
  113. t.Error("key not defined")
  114. }
  115. })
  116. }
  117. })
  118. }
  119. }
  120. func TestAcceptLanguageQualityFactors(t *testing.T) {
  121. service := NewLocalizationService()
  122. testCases := []struct {
  123. name string
  124. acceptLanguage string
  125. expectedLang string
  126. }{
  127. {"simple_en", "en", "en"},
  128. {"simple_de", "de", "de"},
  129. {"en_GB_with_lower_priority_de", "en-GB,de-DE;q=0.5", "en"},
  130. {"en_GB_only", "en-GB", "en"},
  131. {"de_with_lower_priority_en", "de,en;q=0.5", "de"},
  132. {"de_DE_with_lower_priority_en", "de-DE,en;q=0.5", "de"},
  133. {"fr_with_lower_priority_de", "fr,de;q=0.5", "fr"},
  134. {"zh_CN_regional", "zh-CN", "zh-CN"},
  135. {"zh_TW_regional", "zh-TW", "zh-TW"},
  136. {"pt_BR_regional", "pt-BR", "pt-BR"},
  137. {"complex_header", "fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7,de;q=0.5", "fr"},
  138. }
  139. for _, tc := range testCases {
  140. t.Run(tc.name, func(t *testing.T) {
  141. req := httptest.NewRequest("GET", "/", nil)
  142. req.Header.Set("Accept-Language", tc.acceptLanguage)
  143. localizer := service.GetLocalizerFromRequest(req)
  144. sl := &SimpleLocalizer{Localizer: localizer}
  145. gotLang := sl.GetLang()
  146. if gotLang != tc.expectedLang {
  147. t.Errorf("Accept-Language %q: expected %s, got %s", tc.acceptLanguage, tc.expectedLang, gotLang)
  148. }
  149. })
  150. }
  151. }