github.com/mattermost/mattermost-plugin-api@v0.1.4/i18n/i18n_test.go (about)

     1  package i18n_test
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"testing"
     7  
     8  	"github.com/mattermost/mattermost-server/v6/model"
     9  	"github.com/mattermost/mattermost-server/v6/plugin"
    10  	"github.com/mattermost/mattermost-server/v6/plugin/plugintest"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/mock"
    13  	"github.com/stretchr/testify/require"
    14  	"golang.org/x/text/language"
    15  
    16  	"github.com/mattermost/mattermost-plugin-api/i18n"
    17  )
    18  
    19  func ExampleInitBundle() {
    20  	type Plugin struct {
    21  		plugin.MattermostPlugin
    22  
    23  		b *i18n.Bundle
    24  	}
    25  
    26  	p := Plugin{}
    27  	b, err := i18n.InitBundle(p.API, filepath.Join("assets", "i18n"))
    28  	if err != nil {
    29  		panic(err)
    30  	}
    31  
    32  	p.b = b
    33  }
    34  
    35  func TestInitBundle(t *testing.T) {
    36  	t.Run("fine", func(t *testing.T) {
    37  		dir, err := os.MkdirTemp("", "")
    38  		require.NoError(t, err)
    39  
    40  		defer os.RemoveAll(dir)
    41  
    42  		// Create assets/i18n dir
    43  		i18nDir := filepath.Join(dir, "assets", "i18n")
    44  		err = os.MkdirAll(i18nDir, 0o700)
    45  		require.NoError(t, err)
    46  
    47  		file := filepath.Join(i18nDir, "active.de.json")
    48  		content := []byte("{}")
    49  		err = os.WriteFile(file, content, 0o600)
    50  		require.NoError(t, err)
    51  
    52  		// Add en translation file.
    53  		// InitBundle should ignore it.
    54  		file = filepath.Join(i18nDir, "active.en.json")
    55  		content = []byte("")
    56  		err = os.WriteFile(file, content, 0o600)
    57  		require.NoError(t, err)
    58  
    59  		// Add json junk file
    60  		file = filepath.Join(i18nDir, "foo.json")
    61  		content = []byte("")
    62  		err = os.WriteFile(file, content, 0o600)
    63  		require.NoError(t, err)
    64  
    65  		// Add active. junk file
    66  		file = filepath.Join(i18nDir, "active.foo")
    67  		content = []byte("")
    68  		err = os.WriteFile(file, content, 0o600)
    69  		require.NoError(t, err)
    70  
    71  		api := &plugintest.API{}
    72  		api.On("GetBundlePath").Return(dir, nil)
    73  		defer api.AssertExpectations(t)
    74  
    75  		b, err := i18n.InitBundle(api, "assets/i18n")
    76  		assert.NoError(t, err)
    77  		assert.NotNil(t, b)
    78  
    79  		assert.ElementsMatch(t, []language.Tag{language.English, language.German}, b.LanguageTags())
    80  	})
    81  
    82  	t.Run("fine", func(t *testing.T) {
    83  		dir, err := os.MkdirTemp("", "")
    84  		require.NoError(t, err)
    85  
    86  		defer os.RemoveAll(dir)
    87  
    88  		// Create assets/i18n dir
    89  		i18nDir := filepath.Join(dir, "assets", "i18n")
    90  		err = os.MkdirAll(i18nDir, 0o700)
    91  		require.NoError(t, err)
    92  
    93  		file := filepath.Join(i18nDir, "active.de.json")
    94  		content := []byte("{}")
    95  		err = os.WriteFile(file, content, 0o600)
    96  		require.NoError(t, err)
    97  
    98  		// Add translation file with invalid content
    99  		file = filepath.Join(i18nDir, "active.es.json")
   100  		content = []byte("foo bar")
   101  		err = os.WriteFile(file, content, 0o600)
   102  		require.NoError(t, err)
   103  
   104  		api := &plugintest.API{}
   105  		api.On("GetBundlePath").Return(dir, nil)
   106  		defer api.AssertExpectations(t)
   107  
   108  		b, err := i18n.InitBundle(api, "assets/i18n")
   109  		assert.Error(t, err)
   110  		assert.Nil(t, b)
   111  	})
   112  }
   113  
   114  func TestLocalizeDefaultMessage(t *testing.T) {
   115  	t.Run("fine", func(t *testing.T) {
   116  		api := &plugintest.API{}
   117  		defaultServerLocale := "en"
   118  		api.On("GetConfig").Return(&model.Config{
   119  			LocalizationSettings: model.LocalizationSettings{
   120  				DefaultServerLocale: &defaultServerLocale,
   121  			},
   122  		})
   123  		api.On("GetBundlePath").Return(".", nil)
   124  		defer api.AssertExpectations(t)
   125  
   126  		b, err := i18n.InitBundle(api, ".")
   127  		require.NoError(t, err)
   128  
   129  		l := b.GetServerLocalizer()
   130  		m := &i18n.Message{
   131  			Other: "test message",
   132  		}
   133  
   134  		assert.Equal(t, m.Other, b.LocalizeDefaultMessage(l, m))
   135  	})
   136  
   137  	t.Run("empty message", func(t *testing.T) {
   138  		api := &plugintest.API{}
   139  		defaultServerLocale := "en"
   140  		api.On("GetConfig").Return(&model.Config{
   141  			LocalizationSettings: model.LocalizationSettings{
   142  				DefaultServerLocale: &defaultServerLocale,
   143  			},
   144  		})
   145  		api.On("GetBundlePath").Return(".", nil)
   146  		api.On("LogWarn", mock.AnythingOfType("string"),
   147  			mock.AnythingOfType("string"), mock.AnythingOfType("string"),
   148  			mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return()
   149  		defer api.AssertExpectations(t)
   150  
   151  		b, err := i18n.InitBundle(api, ".")
   152  		require.NoError(t, err)
   153  
   154  		l := b.GetServerLocalizer()
   155  		m := &i18n.Message{}
   156  
   157  		assert.Equal(t, "", b.LocalizeDefaultMessage(l, m))
   158  	})
   159  }
   160  
   161  func TestLocalizeWithConfig(t *testing.T) {
   162  	t.Run("fine", func(t *testing.T) {
   163  		api := &plugintest.API{}
   164  		defaultServerLocale := "en"
   165  		api.On("GetConfig").Return(&model.Config{
   166  			LocalizationSettings: model.LocalizationSettings{
   167  				DefaultServerLocale: &defaultServerLocale,
   168  			},
   169  		})
   170  		api.On("GetBundlePath").Return(".", nil)
   171  		defer api.AssertExpectations(t)
   172  
   173  		b, err := i18n.InitBundle(api, ".")
   174  		require.NoError(t, err)
   175  
   176  		l := b.GetServerLocalizer()
   177  		lc := &i18n.LocalizeConfig{
   178  			DefaultMessage: &i18n.Message{
   179  				Other: "test messsage",
   180  			},
   181  		}
   182  
   183  		assert.Equal(t, lc.DefaultMessage.Other, b.LocalizeWithConfig(l, lc))
   184  	})
   185  
   186  	t.Run("empty config", func(t *testing.T) {
   187  		api := &plugintest.API{}
   188  		defaultServerLocale := "en"
   189  		api.On("GetConfig").Return(&model.Config{
   190  			LocalizationSettings: model.LocalizationSettings{
   191  				DefaultServerLocale: &defaultServerLocale,
   192  			},
   193  		})
   194  		api.On("GetBundlePath").Return(".", nil)
   195  		api.On("LogWarn", mock.AnythingOfType("string"),
   196  			mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return()
   197  		defer api.AssertExpectations(t)
   198  
   199  		b, err := i18n.InitBundle(api, ".")
   200  		require.NoError(t, err)
   201  
   202  		l := b.GetServerLocalizer()
   203  		lc := &i18n.LocalizeConfig{}
   204  
   205  		assert.Equal(t, "", b.LocalizeWithConfig(l, lc))
   206  	})
   207  
   208  	t.Run("empty message", func(t *testing.T) {
   209  		api := &plugintest.API{}
   210  		defaultServerLocale := "en"
   211  		api.On("GetConfig").Return(&model.Config{
   212  			LocalizationSettings: model.LocalizationSettings{
   213  				DefaultServerLocale: &defaultServerLocale,
   214  			},
   215  		})
   216  		api.On("GetBundlePath").Return(".", nil)
   217  		api.On("LogWarn", mock.AnythingOfType("string"),
   218  			mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return()
   219  		defer api.AssertExpectations(t)
   220  
   221  		b, err := i18n.InitBundle(api, ".")
   222  		require.NoError(t, err)
   223  
   224  		l := b.GetServerLocalizer()
   225  		lc := &i18n.LocalizeConfig{
   226  			DefaultMessage: &i18n.Message{},
   227  		}
   228  
   229  		assert.Equal(t, "", b.LocalizeWithConfig(l, lc))
   230  	})
   231  }
   232  func TestGetUserLocalizer(t *testing.T) {
   233  	t.Run("fine", func(t *testing.T) {
   234  		api := &plugintest.API{}
   235  		api.On("GetUser", "userID").Return(&model.User{
   236  			Locale: "de",
   237  		}, nil)
   238  		api.On("GetBundlePath").Return(".", nil)
   239  		defer api.AssertExpectations(t)
   240  
   241  		b, err := i18n.InitBundle(api, ".")
   242  		require.NoError(t, err)
   243  
   244  		l := b.GetUserLocalizer("userID")
   245  		assert.NotNil(t, l)
   246  
   247  		enMessage := &i18n.Message{
   248  			Other: "a",
   249  		}
   250  
   251  		deMessage := &i18n.Message{
   252  			Other: "b",
   253  		}
   254  
   255  		err = b.Bundle.AddMessages(language.German, deMessage)
   256  		require.NoError(t, err)
   257  
   258  		assert.Equal(t, deMessage.Other, b.LocalizeDefaultMessage(l, enMessage))
   259  	})
   260  
   261  	t.Run("error", func(t *testing.T) {
   262  		api := &plugintest.API{}
   263  		defaultServerLocale := "es"
   264  		api.On("GetConfig").Return(&model.Config{
   265  			LocalizationSettings: model.LocalizationSettings{
   266  				DefaultServerLocale: &defaultServerLocale,
   267  			},
   268  		})
   269  		api.On("GetBundlePath").Return(".", nil)
   270  		api.On("GetUser", "userID").Return(nil, &model.AppError{})
   271  		api.On("LogWarn", mock.AnythingOfType("string"),
   272  			mock.AnythingOfType("string"), mock.AnythingOfType("string"),
   273  			mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return()
   274  		defer api.AssertExpectations(t)
   275  
   276  		b, err := i18n.InitBundle(api, ".")
   277  		require.NoError(t, err)
   278  
   279  		l := b.GetUserLocalizer("userID")
   280  		assert.NotNil(t, l)
   281  
   282  		enMessage := &i18n.Message{
   283  			Other: "a",
   284  		}
   285  
   286  		esMessage := &i18n.Message{
   287  			Other: "b",
   288  		}
   289  
   290  		err = b.Bundle.AddMessages(language.Spanish, esMessage)
   291  		require.NoError(t, err)
   292  
   293  		assert.Equal(t, esMessage.Other, b.LocalizeDefaultMessage(l, enMessage))
   294  	})
   295  }