mg-transport-core/core/localizer_test.go
Neur0toxine c79b3b0c0f
Sentry update, go 1.15 support
* Clone() method in Localizer component allows to clone it just like LocalizationMiddleware does.
* RavenClientInterface contains all *raven.Client method, which allows external use without type casting.
* Tests and godoc fix for Go 1.15.
2020-11-12 10:23:27 +03:00

238 lines
6.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package core
import (
"io/ioutil"
"math/rand"
"net/http"
"net/http/httptest"
"net/url"
"os"
"path"
"sync"
"testing"
"time"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"golang.org/x/text/language"
)
var (
testTranslationsDir = path.Join(os.TempDir(), "translations_test_dir")
testLangFiles = map[string][]byte{
"translate.en.yml": []byte("message: Test message\nmessage_template: Test message with {{.data}}"),
"translate.es.yml": []byte("message: Mensaje de prueba\nmessage_template: Mensaje de prueba con {{.data}}"),
"translate.ru.yml": []byte("message: Тестовое сообщение\nmessage_template: Тестовое сообщение с {{.data}}"),
}
)
func createTestLangFiles(t *testing.T) {
for name, data := range testLangFiles {
fileName := path.Join(testTranslationsDir, name)
if _, err := os.Stat(testTranslationsDir); err != nil && os.IsNotExist(err) {
err := os.Mkdir(testTranslationsDir, os.ModePerm)
require.Nil(t, err)
}
if _, err := os.Stat(fileName); err != nil && os.IsNotExist(err) {
err = ioutil.WriteFile(fileName, data, os.ModePerm)
require.Nil(t, err)
}
}
}
type LocalizerTest struct {
suite.Suite
localizer *Localizer
}
func (l *LocalizerTest) SetupSuite() {
createTestLangFiles(l.T())
l.localizer = NewLocalizer(language.English, DefaultLocalizerMatcher(), testTranslationsDir)
}
func (l *LocalizerTest) Test_SetLocale() {
defer func() {
require.Nil(l.T(), recover())
}()
l.localizer.SetLocale("es")
assert.Equal(l.T(), "Mensaje de prueba", l.localizer.GetLocalizedMessage("message"))
l.localizer.SetLocale("en")
assert.Equal(l.T(), "Test message", l.localizer.GetLocalizedMessage("message"))
}
func (l *LocalizerTest) Test_LocalizationMiddleware_Context() {
l.localizer.Preload(DefaultLanguages)
middlewareFunc := l.localizer.LocalizationMiddleware()
require.NotNil(l.T(), middlewareFunc)
enContext := l.getContextWithLang(language.English)
esContext := l.getContextWithLang(language.Spanish)
ruContext := l.getContextWithLang(language.Russian)
middlewareFunc(enContext)
middlewareFunc(esContext)
middlewareFunc(ruContext)
defer func() {
assert.Nil(l.T(), recover())
}()
enLocalizer := MustGetContextLocalizer(enContext)
esLocalizer := MustGetContextLocalizer(esContext)
ruLocalizer := MustGetContextLocalizer(ruContext)
assert.NotNil(l.T(), enLocalizer)
assert.NotNil(l.T(), esLocalizer)
assert.NotNil(l.T(), ruLocalizer)
assert.Equal(l.T(), language.English, enLocalizer.LanguageTag)
assert.Equal(l.T(), language.Spanish, esLocalizer.LanguageTag)
assert.Equal(l.T(), language.Russian, ruLocalizer.LanguageTag)
assert.Equal(l.T(), "Test message", enLocalizer.GetLocalizedMessage("message"))
assert.Equal(l.T(), "Mensaje de prueba", esLocalizer.GetLocalizedMessage("message"))
assert.Equal(l.T(), "Тестовое сообщение", ruLocalizer.GetLocalizedMessage("message"))
}
func (l *LocalizerTest) Test_LocalizationMiddleware_Httptest() {
var wg sync.WaitGroup
rand.Seed(time.Now().UnixNano())
l.localizer.Preload(DefaultLanguages)
langMsgMap := map[language.Tag]string{
language.English: "Test message",
language.Russian: "Тестовое сообщение",
language.Spanish: "Mensaje de prueba",
}
fw := gin.New()
fw.Use(l.localizer.LocalizationMiddleware())
fw.GET("/test", func(c *gin.Context) {
loc := MustGetContextLocalizer(c)
c.String(http.StatusOK, loc.GetLocalizedMessage("message"))
})
for i := 0; i < 1000; i++ {
wg.Add(1)
go func(m map[language.Tag]string, wg *sync.WaitGroup) {
var tag language.Tag
switch rand.Intn(3-1) + 1 {
case 1:
tag = language.English
case 2:
tag = language.Russian
case 3:
tag = language.Spanish
}
req, err := http.NewRequest(http.MethodGet, "/test", nil)
require.NoError(l.T(), err)
req.Header.Add("Accept-Language", tag.String())
rr := httptest.NewRecorder()
fw.ServeHTTP(rr, req)
assert.Equal(l.T(), m[tag], rr.Body.String())
wg.Done()
}(langMsgMap, &wg)
}
wg.Wait()
}
func (l *LocalizerTest) Test_LocalizationFuncMap() {
functions := l.localizer.LocalizationFuncMap()
_, ok := functions["trans"]
assert.True(l.T(), ok)
}
func (l *LocalizerTest) Test_GetLocalizedMessage() {
defer func() {
require.Nil(l.T(), recover())
}()
message := l.localizer.GetLocalizedMessage("message")
assert.Equal(l.T(), "Test message", message)
}
func (l *LocalizerTest) Test_Clone() {
defer func() {
require.Nil(l.T(), recover())
}()
localizer := l.localizer.Clone()
localizer.SetLanguage(language.Russian)
assert.NotEqual(l.T(), l.localizer.LanguageTag, localizer.LanguageTag)
assert.Equal(l.T(), "Test message", l.localizer.GetLocalizedMessage("message"))
assert.Equal(l.T(), "Тестовое сообщение", localizer.GetLocalizedMessage("message"))
}
func (l *LocalizerTest) Test_GetLocalizedTemplateMessage() {
defer func() {
require.Nil(l.T(), recover())
}()
message := l.localizer.GetLocalizedTemplateMessage("message_template", map[string]interface{}{"data": "template"})
assert.Equal(l.T(), "Test message with template", message)
}
func (l *LocalizerTest) Test_BadRequestLocalized() {
status, resp := l.localizer.BadRequestLocalized("message")
assert.Equal(l.T(), http.StatusBadRequest, status)
assert.Equal(l.T(), "Test message", resp.(ErrorResponse).Error)
}
// getContextWithLang generates context with Accept-Language header
func (l *LocalizerTest) getContextWithLang(tag language.Tag) *gin.Context {
urlInstance, _ := url.Parse("https://example.com")
headers := http.Header{}
headers.Add("Accept-Language", tag.String())
return &gin.Context{
Request: &http.Request{
Method: "GET",
URL: urlInstance,
Proto: "https",
Header: headers,
Host: "example.com",
},
Keys: map[string]interface{}{},
}
}
func (l *LocalizerTest) TearDownSuite() {
err := os.RemoveAll(testTranslationsDir)
require.Nil(l.T(), err)
}
func TestLocalizer_Suite(t *testing.T) {
suite.Run(t, new(LocalizerTest))
}
func TestLocalizer_DefaultLocalizerMatcher(t *testing.T) {
assert.NotNil(t, DefaultLocalizerMatcher())
}
func TestLocalizer_DefaultLocalizerBundle(t *testing.T) {
assert.NotNil(t, DefaultLocalizerBundle())
}
func TestLocalizer_LocalizerBundle(t *testing.T) {
assert.NotNil(t, LocalizerBundle(language.Russian))
}
func TestLocalizer_NoDirectory(t *testing.T) {
defer func() {
assert.NotNil(t, recover())
}()
_ = NewLocalizer(
language.English,
DefaultLocalizerMatcher(),
path.Join(os.TempDir(), "this directory should not exist"),
)
}