owpengram-server/internal/rpc/messages_translation_rpc_test.go

142 lines
5.2 KiB
Go

package rpc
import (
"context"
"testing"
"github.com/iamxvbaba/td/clock"
"github.com/iamxvbaba/td/tg"
"github.com/iamxvbaba/td/tgerr"
"go.uber.org/zap/zaptest"
appusers "telesrv/internal/app/users"
"telesrv/internal/domain"
"telesrv/internal/store/memory"
)
type captureTranslationService struct {
request domain.TranslationRequest
disabled map[[3]int64]bool
}
func (s *captureTranslationService) Translate(_ context.Context, req domain.TranslationRequest) (domain.TranslationResult, error) {
s.request = req
out := make([]domain.TranslationText, len(req.Texts))
for i := range req.Texts {
out[i].Text = "translated:" + req.Texts[i].Text
}
return domain.TranslationResult{Texts: out}, nil
}
func translationSettingKey(userID int64, peer domain.Peer) [3]int64 {
kind := int64(1)
if peer.Type == domain.PeerTypeChannel {
kind = 2
}
return [3]int64{userID, kind, peer.ID}
}
func (s *captureTranslationService) SetPeerDisabled(_ context.Context, userID int64, peer domain.Peer, disabled bool) (bool, error) {
if s.disabled == nil {
s.disabled = map[[3]int64]bool{}
}
key := translationSettingKey(userID, peer)
previous := s.disabled[key]
s.disabled[key] = disabled
return previous != disabled, nil
}
func (s *captureTranslationService) PeerDisabled(_ context.Context, userID int64, peer domain.Peer) (bool, error) {
return s.disabled[translationSettingKey(userID, peer)], nil
}
func TestMessagesTranslateTextDirectMode(t *testing.T) {
svc := &captureTranslationService{}
r := New(Config{}, Deps{Translation: svc}, zaptest.NewLogger(t), clock.System)
ctx := WithUserID(context.Background(), 1001)
req := &tg.MessagesTranslateTextRequest{ToLang: "zh"}
req.SetText([]tg.TextWithEntities{{Text: "hello"}, {Text: "world"}})
got, err := r.onMessagesTranslateText(ctx, req)
if err != nil {
t.Fatalf("translateText: %v", err)
}
if len(got.Result) != 2 || got.Result[0].Text != "translated:hello" || got.Result[1].Text != "translated:world" {
t.Fatalf("result = %#v", got.Result)
}
if svc.request.UserID != 1001 || svc.request.ToLang != "zh" || len(svc.request.Texts) != 2 {
t.Fatalf("domain request = %#v", svc.request)
}
}
func TestMessagesTranslateTextRejectsInvalidFlags(t *testing.T) {
r := New(Config{}, Deps{Translation: &captureTranslationService{}}, zaptest.NewLogger(t), clock.System)
ctx := WithUserID(context.Background(), 1001)
if _, err := r.onMessagesTranslateText(ctx, &tg.MessagesTranslateTextRequest{ToLang: "en"}); !tgerr.Is(err, "INPUT_TEXT_EMPTY") {
t.Fatalf("empty flags err = %v", err)
}
req := &tg.MessagesTranslateTextRequest{ToLang: "en"}
req.SetPeer(&tg.InputPeerUser{UserID: 2})
req.SetID([]int{1})
req.SetText([]tg.TextWithEntities{{Text: "both"}})
if _, err := r.onMessagesTranslateText(ctx, req); !tgerr.Is(err, "INPUT_TEXT_EMPTY") {
t.Fatalf("both modes err = %v", err)
}
}
func TestMessagesTogglePeerTranslationsAndProjection(t *testing.T) {
svc := &captureTranslationService{}
r := New(Config{}, Deps{Translation: svc}, zaptest.NewLogger(t), clock.System)
ctx := WithUserID(context.Background(), 1001)
peer := &tg.InputPeerUser{UserID: 2002}
if ok, err := r.onMessagesTogglePeerTranslations(ctx, &tg.MessagesTogglePeerTranslationsRequest{Disabled: true, Peer: peer}); err != nil || !ok {
t.Fatalf("toggle = %v/%v", ok, err)
}
full := tg.UserFull{ID: 2002}
if err := r.applyTranslationDisabledToUserFull(ctx, 1001, 2002, &full); err != nil {
t.Fatalf("projection: %v", err)
}
if !full.TranslationsDisabled {
t.Fatal("userFull.translations_disabled = false")
}
}
func TestMessagesTogglePeerTranslationsValidatesUserAccessHash(t *testing.T) {
ctx := context.Background()
userStore := memory.NewUserStore()
owner, err := userStore.Create(ctx, domain.User{Phone: "+10000000001", FirstName: "Owner", AccessHash: 11})
if err != nil {
t.Fatal(err)
}
peer, err := userStore.Create(ctx, domain.User{Phone: "+10000000002", FirstName: "Peer", AccessHash: 22})
if err != nil {
t.Fatal(err)
}
svc := &captureTranslationService{}
r := New(Config{}, Deps{Users: appusers.NewService(userStore), Translation: svc}, zaptest.NewLogger(t), clock.System)
ownerCtx := WithUserID(ctx, owner.ID)
_, err = r.onMessagesTogglePeerTranslations(ownerCtx, &tg.MessagesTogglePeerTranslationsRequest{
Disabled: true,
Peer: &tg.InputPeerUser{UserID: peer.ID, AccessHash: peer.AccessHash + 1},
})
if !tgerr.Is(err, "PEER_ID_INVALID") {
t.Fatalf("bad access hash err = %v, want PEER_ID_INVALID", err)
}
if len(svc.disabled) != 0 {
t.Fatalf("bad access hash wrote settings: %#v", svc.disabled)
}
}
func TestMessagesTranslateTextRejectsBotCaller(t *testing.T) {
ctx := context.Background()
userStore := memory.NewUserStore()
bot, err := userStore.Create(ctx, domain.User{Phone: "+10000000003", FirstName: "Bot", AccessHash: 33, Bot: true})
if err != nil {
t.Fatal(err)
}
r := New(Config{}, Deps{Users: appusers.NewService(userStore), Translation: &captureTranslationService{}}, zaptest.NewLogger(t), clock.System)
req := &tg.MessagesTranslateTextRequest{ToLang: "en"}
req.SetText([]tg.TextWithEntities{{Text: "hello"}})
if _, err := r.onMessagesTranslateText(WithUserID(ctx, bot.ID), req); !tgerr.Is(err, "BOT_METHOD_INVALID") {
t.Fatalf("bot translate err = %v, want BOT_METHOD_INVALID", err)
}
}