mg-transport-core/core/localizer_test.go
Neur0toxine d15ed7ffec
Static analysis (#23)
* lint stage for a workflow
* golangci-lint config
* lint only new code or last commit
* run lint only for pull requests
2021-02-09 14:57:14 +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"),
)
}