snapshot of https://github.com/mattermost/mattermost.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Nightly Race / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 1s
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Nightly Race / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 1s
This commit is contained in:
448
server/channels/store/storetest/autotranslation.go
Normal file
448
server/channels/store/storetest/autotranslation.go
Normal file
@@ -0,0 +1,448 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package storetest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/request"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/store"
|
||||
)
|
||||
|
||||
func TestAutoTranslationStore(t *testing.T, rctx request.CTX, ss store.Store, s SqlStore) {
|
||||
t.Run("IsUserEnabled", func(t *testing.T) { testAutoTranslationIsUserEnabled(t, rctx, ss) })
|
||||
t.Run("GetUserLanguage", func(t *testing.T) { testAutoTranslationGetUserLanguage(t, rctx, ss) })
|
||||
t.Run("GetActiveDestinationLanguages", func(t *testing.T) { testAutoTranslationGetActiveDestinationLanguages(t, rctx, ss) })
|
||||
t.Run("GetAllForObject", func(t *testing.T) { testAutoTranslationGetAllForObject(t, ss) })
|
||||
}
|
||||
|
||||
func testAutoTranslationIsUserEnabled(t *testing.T, rctx request.CTX, ss store.Store) {
|
||||
// Setup: Create team, channel, and user
|
||||
team := &model.Team{
|
||||
DisplayName: "Test Team",
|
||||
Name: "test-team-" + model.NewId(),
|
||||
Email: "test@example.com",
|
||||
Type: model.TeamOpen,
|
||||
}
|
||||
team, err := ss.Team().Save(team)
|
||||
require.NoError(t, err)
|
||||
|
||||
channel := &model.Channel{
|
||||
TeamId: team.Id,
|
||||
DisplayName: "Test Channel",
|
||||
Name: "test-channel-" + model.NewId(),
|
||||
Type: model.ChannelTypeOpen,
|
||||
}
|
||||
channel, nErr := ss.Channel().Save(rctx, channel, 999)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
user := &model.User{
|
||||
Email: "test@example.com",
|
||||
Username: "testuser" + model.NewId(),
|
||||
Locale: "en",
|
||||
}
|
||||
user, nErr = ss.User().Save(rctx, user)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
defer func() {
|
||||
_ = ss.Team().PermanentDelete(team.Id)
|
||||
_ = ss.Channel().PermanentDelete(rctx, channel.Id)
|
||||
_ = ss.User().PermanentDelete(rctx, user.Id)
|
||||
}()
|
||||
|
||||
// Add user to channel
|
||||
member := &model.ChannelMember{
|
||||
ChannelId: channel.Id,
|
||||
UserId: user.Id,
|
||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||
}
|
||||
_, nErr = ss.Channel().SaveMember(rctx, member)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
t.Run("returns false when channel is disabled", func(t *testing.T) {
|
||||
// Channel autotranslation is disabled by default
|
||||
enabled, err := ss.AutoTranslation().IsUserEnabled(user.Id, channel.Id)
|
||||
require.NoError(t, err)
|
||||
assert.False(t, enabled)
|
||||
})
|
||||
|
||||
t.Run("returns false when channel enabled but user disabled", func(t *testing.T) {
|
||||
// Enable channel autotranslation
|
||||
channel.AutoTranslation = true
|
||||
channel, nErr = ss.Channel().Update(rctx, channel)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
// Disable user autotranslation (AutoTranslationDisabled = true means disabled)
|
||||
member.AutoTranslationDisabled = true
|
||||
_, nErr = ss.Channel().UpdateMember(rctx, member)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
enabled, getUserEnabledErr := ss.AutoTranslation().IsUserEnabled(user.Id, channel.Id)
|
||||
require.NoError(t, getUserEnabledErr)
|
||||
assert.False(t, enabled)
|
||||
})
|
||||
|
||||
t.Run("returns true when both channel and user enabled", func(t *testing.T) {
|
||||
// Enable channel autotranslation
|
||||
channel.AutoTranslation = true
|
||||
channel, nErr = ss.Channel().Update(rctx, channel)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
// Enable user autotranslation
|
||||
member.AutoTranslationDisabled = false
|
||||
_, nErr = ss.Channel().UpdateMember(rctx, member)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
// Verify both are enabled
|
||||
enabled, getUserEnabledErr := ss.AutoTranslation().IsUserEnabled(user.Id, channel.Id)
|
||||
require.NoError(t, getUserEnabledErr)
|
||||
assert.True(t, enabled)
|
||||
})
|
||||
|
||||
t.Run("returns false after disabling user", func(t *testing.T) {
|
||||
// Ensure channel is enabled
|
||||
channel.AutoTranslation = true
|
||||
channel, nErr = ss.Channel().Update(rctx, channel)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
// Disable user autotranslation
|
||||
member.AutoTranslationDisabled = true
|
||||
_, nErr = ss.Channel().UpdateMember(rctx, member)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
// Verify user is disabled
|
||||
enabled, nErr := ss.AutoTranslation().IsUserEnabled(user.Id, channel.Id)
|
||||
require.NoError(t, nErr)
|
||||
assert.False(t, enabled)
|
||||
})
|
||||
|
||||
t.Run("returns false for non-existent user or channel", func(t *testing.T) {
|
||||
enabled, nErr := ss.AutoTranslation().IsUserEnabled("nonexistent", channel.Id)
|
||||
require.NoError(t, nErr)
|
||||
assert.False(t, enabled)
|
||||
})
|
||||
}
|
||||
|
||||
func testAutoTranslationGetUserLanguage(t *testing.T, rctx request.CTX, ss store.Store) {
|
||||
// Setup: Create team, channel, and users with different locales
|
||||
team := &model.Team{
|
||||
DisplayName: "Test Team",
|
||||
Name: "test-team-" + model.NewId(),
|
||||
Email: "test@example.com",
|
||||
Type: model.TeamOpen,
|
||||
}
|
||||
team, err := ss.Team().Save(team)
|
||||
require.NoError(t, err)
|
||||
|
||||
channel := &model.Channel{
|
||||
TeamId: team.Id,
|
||||
DisplayName: "Test Channel",
|
||||
Name: "test-channel-" + model.NewId(),
|
||||
Type: model.ChannelTypeOpen,
|
||||
}
|
||||
channel, nErr := ss.Channel().Save(rctx, channel, 999)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
userEN := &model.User{
|
||||
Email: "test-en@example.com",
|
||||
Username: "testuser-en-" + model.NewId(),
|
||||
Locale: "en",
|
||||
}
|
||||
userEN, nErr = ss.User().Save(rctx, userEN)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
userES := &model.User{
|
||||
Email: "test-es@example.com",
|
||||
Username: "testuser-es-" + model.NewId(),
|
||||
Locale: "es",
|
||||
}
|
||||
userES, nErr = ss.User().Save(rctx, userES)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
defer func() {
|
||||
_ = ss.Team().PermanentDelete(team.Id)
|
||||
_ = ss.Channel().PermanentDelete(rctx, channel.Id)
|
||||
_ = ss.User().PermanentDelete(rctx, userEN.Id)
|
||||
_ = ss.User().PermanentDelete(rctx, userES.Id)
|
||||
}()
|
||||
|
||||
members := make(map[string]*model.ChannelMember)
|
||||
// Add users to channel
|
||||
for _, user := range []*model.User{userEN, userES} {
|
||||
member := &model.ChannelMember{
|
||||
ChannelId: channel.Id,
|
||||
UserId: user.Id,
|
||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||
}
|
||||
_, nErr = ss.Channel().SaveMember(rctx, member)
|
||||
require.NoError(t, nErr)
|
||||
members[user.Id] = member
|
||||
}
|
||||
|
||||
t.Run("returns empty when channel disabled", func(t *testing.T) {
|
||||
locale, appErr := ss.AutoTranslation().GetUserLanguage(userEN.Id, channel.Id)
|
||||
require.NoError(t, appErr)
|
||||
assert.Empty(t, locale)
|
||||
})
|
||||
|
||||
t.Run("returns empty when channel enabled but user disabled", func(t *testing.T) {
|
||||
channel.AutoTranslation = true
|
||||
channel, nErr = ss.Channel().Update(rctx, channel)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
// Disable user autotranslation (AutoTranslationDisabled = true means disabled)
|
||||
members[userEN.Id].AutoTranslationDisabled = true
|
||||
_, nErr = ss.Channel().UpdateMember(rctx, members[userEN.Id])
|
||||
require.NoError(t, nErr)
|
||||
|
||||
locale, getLocaleErr := ss.AutoTranslation().GetUserLanguage(userEN.Id, channel.Id)
|
||||
require.NoError(t, getLocaleErr)
|
||||
assert.Empty(t, locale)
|
||||
})
|
||||
|
||||
t.Run("returns user locale when both enabled", func(t *testing.T) {
|
||||
// Enable channel
|
||||
channel.AutoTranslation = true
|
||||
channel, nErr = ss.Channel().Update(rctx, channel)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
// Enable user (set AutoTranslationDisabled = false)
|
||||
members[userEN.Id].AutoTranslationDisabled = false
|
||||
_, nErr = ss.Channel().UpdateMember(rctx, members[userEN.Id])
|
||||
require.NoError(t, nErr)
|
||||
|
||||
// Get language
|
||||
locale, getLocaleErr := ss.AutoTranslation().GetUserLanguage(userEN.Id, channel.Id)
|
||||
require.NoError(t, getLocaleErr)
|
||||
assert.Equal(t, "en", locale)
|
||||
})
|
||||
|
||||
t.Run("returns correct locale for different users", func(t *testing.T) {
|
||||
// Enable channel
|
||||
channel.AutoTranslation = true
|
||||
channel, nErr = ss.Channel().Update(rctx, channel)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
// Enable both users (set AutoTranslationDisabled = false)
|
||||
members[userEN.Id].AutoTranslationDisabled = false
|
||||
_, nErr = ss.Channel().UpdateMember(rctx, members[userEN.Id])
|
||||
require.NoError(t, nErr)
|
||||
members[userES.Id].AutoTranslationDisabled = false
|
||||
_, nErr = ss.Channel().UpdateMember(rctx, members[userES.Id])
|
||||
require.NoError(t, nErr)
|
||||
|
||||
// Verify English user
|
||||
locale, nErr := ss.AutoTranslation().GetUserLanguage(userEN.Id, channel.Id)
|
||||
require.NoError(t, nErr)
|
||||
assert.Equal(t, "en", locale)
|
||||
|
||||
// Verify Spanish user
|
||||
locale, nErr = ss.AutoTranslation().GetUserLanguage(userES.Id, channel.Id)
|
||||
require.NoError(t, nErr)
|
||||
assert.Equal(t, "es", locale)
|
||||
})
|
||||
}
|
||||
|
||||
func testAutoTranslationGetActiveDestinationLanguages(t *testing.T, rctx request.CTX, ss store.Store) {
|
||||
// Setup: Create team, channel, and users with different locales
|
||||
team := &model.Team{
|
||||
DisplayName: "Test Team",
|
||||
Name: "test-team-" + model.NewId(),
|
||||
Email: "test@example.com",
|
||||
Type: model.TeamOpen,
|
||||
}
|
||||
team, err := ss.Team().Save(team)
|
||||
require.NoError(t, err)
|
||||
|
||||
channel := &model.Channel{
|
||||
TeamId: team.Id,
|
||||
DisplayName: "Test Channel",
|
||||
Name: "test-channel-" + model.NewId(),
|
||||
Type: model.ChannelTypeOpen,
|
||||
}
|
||||
channel, nErr := ss.Channel().Save(rctx, channel, 999)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
defer func() {
|
||||
_ = ss.Team().PermanentDelete(team.Id)
|
||||
_ = ss.Channel().PermanentDelete(rctx, channel.Id)
|
||||
}()
|
||||
|
||||
// Create users with different locales
|
||||
users := make([]*model.User, 0)
|
||||
locales := []string{"en", "es", "fr", "de", "en"} // Note: duplicate "en"
|
||||
|
||||
for i, locale := range locales {
|
||||
user := &model.User{
|
||||
Email: model.NewId() + "@example.com",
|
||||
Username: "testuser-" + model.NewId(),
|
||||
Locale: locale,
|
||||
}
|
||||
user, nErr = ss.User().Save(rctx, user)
|
||||
require.NoError(t, nErr)
|
||||
defer func() {
|
||||
_ = ss.User().PermanentDelete(rctx, user.Id)
|
||||
}()
|
||||
users = append(users, user)
|
||||
|
||||
// Add user to channel
|
||||
member := &model.ChannelMember{
|
||||
ChannelId: channel.Id,
|
||||
UserId: user.Id,
|
||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||
}
|
||||
if i >= 4 { // Disable autotranslation for 5th user only
|
||||
member.AutoTranslationDisabled = true
|
||||
}
|
||||
_, nErr = ss.Channel().SaveMember(rctx, member)
|
||||
require.NoError(t, nErr)
|
||||
}
|
||||
|
||||
t.Run("returns empty when channel disabled", func(t *testing.T) {
|
||||
languages, appErr := ss.AutoTranslation().GetActiveDestinationLanguages(channel.Id, "", nil)
|
||||
require.NoError(t, appErr)
|
||||
assert.Empty(t, languages)
|
||||
})
|
||||
|
||||
t.Run("returns all enabled user languages", func(t *testing.T) {
|
||||
// Enable channel
|
||||
channel.AutoTranslation = true
|
||||
channel, nErr = ss.Channel().Update(rctx, channel)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
languages, appErr := ss.AutoTranslation().GetActiveDestinationLanguages(channel.Id, "", nil)
|
||||
require.NoError(t, appErr)
|
||||
|
||||
// Should return en, es, fr, de (4 unique languages, 5th user is disabled)
|
||||
assert.Len(t, languages, 4)
|
||||
assert.Contains(t, languages, "en")
|
||||
assert.Contains(t, languages, "es")
|
||||
assert.Contains(t, languages, "fr")
|
||||
assert.Contains(t, languages, "de")
|
||||
})
|
||||
|
||||
t.Run("excludes specified user", func(t *testing.T) {
|
||||
// Enable channel
|
||||
channel.AutoTranslation = true
|
||||
channel, nErr = ss.Channel().Update(rctx, channel)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
// Exclude Spanish user
|
||||
languages, appErr := ss.AutoTranslation().GetActiveDestinationLanguages(channel.Id, users[1].Id, nil)
|
||||
require.NoError(t, appErr)
|
||||
|
||||
// Should return en, fr, de (excluded es)
|
||||
assert.Len(t, languages, 3)
|
||||
assert.Contains(t, languages, "en")
|
||||
assert.NotContains(t, languages, "es")
|
||||
assert.Contains(t, languages, "fr")
|
||||
assert.Contains(t, languages, "de")
|
||||
})
|
||||
|
||||
t.Run("filters to specific users", func(t *testing.T) {
|
||||
// Enable channel
|
||||
channel.AutoTranslation = true
|
||||
channel, nErr = ss.Channel().Update(rctx, channel)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
// Filter to only first two users (en, es)
|
||||
filterIDs := []string{users[0].Id, users[1].Id}
|
||||
languages, appErr := ss.AutoTranslation().GetActiveDestinationLanguages(channel.Id, "", filterIDs)
|
||||
require.NoError(t, appErr)
|
||||
|
||||
// Should return only en, es
|
||||
assert.Len(t, languages, 2)
|
||||
assert.Contains(t, languages, "en")
|
||||
assert.Contains(t, languages, "es")
|
||||
})
|
||||
|
||||
t.Run("filters and excludes user", func(t *testing.T) {
|
||||
// Enable channel
|
||||
channel.AutoTranslation = true
|
||||
channel, nErr = ss.Channel().Update(rctx, channel)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
// Filter to first two users but exclude the first one
|
||||
filterIDs := []string{users[0].Id, users[1].Id}
|
||||
languages, appErr := ss.AutoTranslation().GetActiveDestinationLanguages(channel.Id, users[0].Id, filterIDs)
|
||||
require.NoError(t, appErr)
|
||||
|
||||
// Should return only es
|
||||
assert.Len(t, languages, 1)
|
||||
assert.Contains(t, languages, "es")
|
||||
})
|
||||
}
|
||||
|
||||
func testAutoTranslationGetAllForObject(t *testing.T, ss store.Store) {
|
||||
objectID := model.NewId()
|
||||
objectType := model.TranslationObjectTypePost
|
||||
|
||||
t.Run("returns empty for nonexistent object", func(t *testing.T) {
|
||||
results, err := ss.AutoTranslation().GetAllForObject(objectType, model.NewId())
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, results)
|
||||
})
|
||||
|
||||
t.Run("returns all translations for an object", func(t *testing.T) {
|
||||
// Save translations in two languages
|
||||
err := ss.AutoTranslation().Save(&model.Translation{
|
||||
ObjectID: objectID,
|
||||
ObjectType: objectType,
|
||||
Lang: "es",
|
||||
Provider: "test",
|
||||
Type: model.TranslationTypeString,
|
||||
Text: "hola",
|
||||
State: model.TranslationStateReady,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
err = ss.AutoTranslation().Save(&model.Translation{
|
||||
ObjectID: objectID,
|
||||
ObjectType: objectType,
|
||||
Lang: "fr",
|
||||
Provider: "test",
|
||||
Type: model.TranslationTypeString,
|
||||
Text: "bonjour",
|
||||
State: model.TranslationStateReady,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
results, err := ss.AutoTranslation().GetAllForObject(objectType, objectID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, results, 2)
|
||||
|
||||
langToText := make(map[string]string)
|
||||
for _, tr := range results {
|
||||
assert.Equal(t, objectID, tr.ObjectID)
|
||||
assert.Equal(t, objectType, tr.ObjectType)
|
||||
langToText[tr.Lang] = tr.Text
|
||||
}
|
||||
assert.Equal(t, "hola", langToText["es"])
|
||||
assert.Equal(t, "bonjour", langToText["fr"])
|
||||
})
|
||||
|
||||
t.Run("does not return translations for other objects", func(t *testing.T) {
|
||||
otherID := model.NewId()
|
||||
err := ss.AutoTranslation().Save(&model.Translation{
|
||||
ObjectID: otherID,
|
||||
ObjectType: objectType,
|
||||
Lang: "de",
|
||||
Provider: "test",
|
||||
Type: model.TranslationTypeString,
|
||||
Text: "hallo",
|
||||
State: model.TranslationStateReady,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
results, err := ss.AutoTranslation().GetAllForObject(objectType, objectID)
|
||||
require.NoError(t, err)
|
||||
for _, tr := range results {
|
||||
assert.Equal(t, objectID, tr.ObjectID)
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user