290 lines
8.8 KiB
Diff
290 lines
8.8 KiB
Diff
From c8edf2cb4dc675444b2cba285f9c642f069bc81c Mon Sep 17 00:00:00 2001
|
||
From: Vencislav Atanasov <user890104@users.noreply.github.com>
|
||
Date: Wed, 22 Nov 2023 23:52:16 +0200
|
||
Subject: [PATCH 03/10] Add tests for replying to UTF-8 messages, use runes to
|
||
substring by character offset instead of byte offset (#418)
|
||
Content-Type: text/plain; charset="utf-8"
|
||
Content-Transfer-Encoding: 8bit
|
||
|
||
Co-authored-by: Tim Zabel <Tjzabel21@gmail.com>
|
||
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
||
---
|
||
internal/handlers/telegram/handler.go | 4 +-
|
||
internal/handlers/telegram/handler_test.go | 124 ++++++++++++++++-----
|
||
internal/handlers/telegram/helpers.go | 6 +-
|
||
internal/handlers/telegram/helpers_test.go | 63 +++++++++--
|
||
4 files changed, 156 insertions(+), 41 deletions(-)
|
||
|
||
diff --git a/internal/handlers/telegram/handler.go b/internal/handlers/telegram/handler.go
|
||
index 12404273adf4..2600b1dc42ef 100644
|
||
--- a/internal/handlers/telegram/handler.go
|
||
+++ b/internal/handlers/telegram/handler.go
|
||
@@ -97,8 +97,8 @@ func replyHandler(tg *Client, u tgbotapi.Update) {
|
||
replyUser := GetUsername(tg.IRCSettings.ShowZWSP, u.Message.ReplyToMessage.From)
|
||
|
||
// Only show a portion of the reply text
|
||
- if len(replyText) > tg.Settings.ReplyLength {
|
||
- replyText = replyText[0:tg.Settings.ReplyLength] + "…"
|
||
+ if replyTextAsRunes := []rune(replyText); len(replyTextAsRunes) > tg.Settings.ReplyLength {
|
||
+ replyText = string(replyTextAsRunes[:tg.Settings.ReplyLength]) + "…"
|
||
}
|
||
|
||
formatted := fmt.Sprintf("%s%s%s %sRe %s: %s%s %s",
|
||
diff --git a/internal/handlers/telegram/handler_test.go b/internal/handlers/telegram/handler_test.go
|
||
index a2413c70d616..e356c5b54433 100644
|
||
--- a/internal/handlers/telegram/handler_test.go
|
||
+++ b/internal/handlers/telegram/handler_test.go
|
||
@@ -762,39 +762,107 @@ func TestMessageReply(t *testing.T) {
|
||
testChat := &tgbotapi.Chat{
|
||
ID: 100,
|
||
}
|
||
- initMessage := &tgbotapi.Message{
|
||
- From: testUser,
|
||
- Text: "Initial Text",
|
||
- Chat: testChat,
|
||
- }
|
||
- correct := "<replyUser> [Re test: Initial Text] Response Text"
|
||
|
||
- updateObj := tgbotapi.Update{
|
||
- Message: &tgbotapi.Message{
|
||
- From: replyUser,
|
||
- Text: "Response Text",
|
||
- Chat: testChat,
|
||
- ReplyToMessage: initMessage,
|
||
+ tests := []struct {
|
||
+ name string
|
||
+ updateFn func() tgbotapi.Update
|
||
+ expected string
|
||
+ }{
|
||
+ {
|
||
+ name: "ascii",
|
||
+ updateFn: func() tgbotapi.Update {
|
||
+ return tgbotapi.Update{
|
||
+ Message: &tgbotapi.Message{
|
||
+ From: replyUser,
|
||
+ Text: "Response Text",
|
||
+ Chat: testChat,
|
||
+ ReplyToMessage: &tgbotapi.Message{
|
||
+ From: testUser,
|
||
+ Text: "Initial Text",
|
||
+ Chat: testChat,
|
||
+ },
|
||
+ },
|
||
+ }
|
||
+ },
|
||
+ expected: "<replyUser> [Re test: Initial Text] Response Text",
|
||
},
|
||
- }
|
||
- clientObj := &Client{
|
||
- Settings: &internal.TelegramSettings{
|
||
- Prefix: "<",
|
||
- Suffix: ">",
|
||
- ReplyPrefix: "[",
|
||
- ReplySuffix: "]",
|
||
- ReplyLength: 15,
|
||
- ChatID: 100,
|
||
+ {
|
||
+ name: "cyrillic-short",
|
||
+ updateFn: func() tgbotapi.Update {
|
||
+ return tgbotapi.Update{
|
||
+ Message: &tgbotapi.Message{
|
||
+ From: replyUser,
|
||
+ Text: "Response Text",
|
||
+ Chat: testChat,
|
||
+ ReplyToMessage: &tgbotapi.Message{
|
||
+ From: testUser,
|
||
+ Text: "Тест",
|
||
+ Chat: testChat,
|
||
+ },
|
||
+ },
|
||
+ }
|
||
+ },
|
||
+ expected: "<replyUser> [Re test: Тест] Response Text",
|
||
},
|
||
- IRCSettings: &internal.IRCSettings{
|
||
- ShowZWSP: false,
|
||
+ {
|
||
+ name: "cyrillic-long",
|
||
+ updateFn: func() tgbotapi.Update {
|
||
+ return tgbotapi.Update{
|
||
+ Message: &tgbotapi.Message{
|
||
+ From: replyUser,
|
||
+ Text: "Response Text",
|
||
+ Chat: testChat,
|
||
+ ReplyToMessage: &tgbotapi.Message{
|
||
+ From: testUser,
|
||
+ Text: "Уикипедия е свободна енциклопедия",
|
||
+ Chat: testChat,
|
||
+ },
|
||
+ },
|
||
+ }
|
||
+ },
|
||
+ expected: "<replyUser> [Re test: Уикипедия е сво…] Response Text",
|
||
},
|
||
- sendToIrc: func(s string) {
|
||
- assert.Equal(t, correct, s)
|
||
+ {
|
||
+ name: "japanese-long",
|
||
+ updateFn: func() tgbotapi.Update {
|
||
+ return tgbotapi.Update{
|
||
+ Message: &tgbotapi.Message{
|
||
+ From: replyUser,
|
||
+ Text: "Response Text",
|
||
+ Chat: testChat,
|
||
+ ReplyToMessage: &tgbotapi.Message{
|
||
+ From: testUser,
|
||
+ Text: "1234567テストテストテスト",
|
||
+ Chat: testChat,
|
||
+ },
|
||
+ },
|
||
+ }
|
||
+ },
|
||
+ expected: "<replyUser> [Re test: 1234567テストテストテス…] Response Text",
|
||
},
|
||
}
|
||
|
||
- messageHandler(clientObj, updateObj)
|
||
+ for _, test := range tests {
|
||
+ t.Run(test.name, func(t *testing.T) {
|
||
+ clientObj := &Client{
|
||
+ Settings: &internal.TelegramSettings{
|
||
+ Prefix: "<",
|
||
+ Suffix: ">",
|
||
+ ReplyPrefix: "[",
|
||
+ ReplySuffix: "]",
|
||
+ ReplyLength: 15,
|
||
+ ChatID: 100,
|
||
+ },
|
||
+ IRCSettings: &internal.IRCSettings{
|
||
+ ShowZWSP: false,
|
||
+ },
|
||
+ sendToIrc: func(actual string) {
|
||
+ assert.Equal(t, test.expected, actual)
|
||
+ },
|
||
+ }
|
||
+ messageHandler(clientObj, test.updateFn())
|
||
+ })
|
||
+ }
|
||
}
|
||
|
||
func TestMessageReplyZwsp(t *testing.T) {
|
||
@@ -891,8 +959,8 @@ func TestLocationHandlerWithLocationEnabled(t *testing.T) {
|
||
LastName: "123",
|
||
}
|
||
|
||
- // https://pkg.go.dev/github.com/go-telegram-bot-api/telegram-bot-api#Location
|
||
- location := &tgbotapi.Location{
|
||
+ // https://pkg.go.dev/github.com/go-telegram-bot-api/telegram-bot-api#Location
|
||
+ location := &tgbotapi.Location{
|
||
Latitude: 43.0845274,
|
||
Longitude: -77.6781174,
|
||
}
|
||
diff --git a/internal/handlers/telegram/helpers.go b/internal/handlers/telegram/helpers.go
|
||
index f092979a9ffd..19b65ab722e3 100644
|
||
--- a/internal/handlers/telegram/helpers.go
|
||
+++ b/internal/handlers/telegram/helpers.go
|
||
@@ -37,7 +37,8 @@ Adds ZWSP to username to prevent username pinging across platform.
|
||
func GetFullUserZwsp(u *tgbotapi.User) string {
|
||
// Add ZWSP to prevent pinging across platforms
|
||
// See https://github.com/42wim/matterbridge/issues/175
|
||
- return u.FirstName + " (@" + u.UserName[:1] + "\u200b" + u.UserName[1:] + ")"
|
||
+ userNameAsRunes := []rune(u.UserName)
|
||
+ return u.FirstName + " (@" + string(userNameAsRunes[:1]) + "\u200b" + string(userNameAsRunes[1:]) + ")"
|
||
}
|
||
|
||
/*
|
||
@@ -47,7 +48,8 @@ username.
|
||
func ZwspUsername(u *tgbotapi.User) string {
|
||
// Add ZWSP to prevent pinging across platforms
|
||
// See https://github.com/42wim/matterbridge/issues/175
|
||
- return u.UserName[:1] + "\u200b" + u.UserName[1:]
|
||
+ userNameAsRunes := []rune(u.UserName)
|
||
+ return string(userNameAsRunes[:1]) + "\u200b" + string(userNameAsRunes[1:])
|
||
}
|
||
|
||
/*
|
||
diff --git a/internal/handlers/telegram/helpers_test.go b/internal/handlers/telegram/helpers_test.go
|
||
index 52eaa475c409..710f5a2c3ad7 100644
|
||
--- a/internal/handlers/telegram/helpers_test.go
|
||
+++ b/internal/handlers/telegram/helpers_test.go
|
||
@@ -16,12 +16,34 @@ func TestGetFullUsername(t *testing.T) {
|
||
}
|
||
|
||
func TestGetFullUserZwsp(t *testing.T) {
|
||
- user := &tgbotapi.User{ID: 1, FirstName: "John", UserName: "jsmith"}
|
||
- correct := user.FirstName + " (@" + user.UserName[:1] +
|
||
- "\u200b" + user.UserName[1:] + ")"
|
||
- name := GetFullUsername(true, user)
|
||
+ tests := []struct {
|
||
+ name string
|
||
+ user *tgbotapi.User
|
||
+ expected string
|
||
+ }{
|
||
+ {
|
||
+ name: "ascii",
|
||
+ user: &tgbotapi.User{ID: 1, FirstName: "John", UserName: "jsmith"},
|
||
+ expected: "John (@j\u200bsmith)",
|
||
+ },
|
||
+ {
|
||
+ name: "cyrillic",
|
||
+ user: &tgbotapi.User{ID: 1, FirstName: "Иван", UserName: "иван"},
|
||
+ expected: "Иван (@и\u200bван)",
|
||
+ },
|
||
+ {
|
||
+ name: "japanese",
|
||
+ user: &tgbotapi.User{ID: 1, FirstName: "まこと", UserName: "まこと"},
|
||
+ expected: "まこと (@ま\u200bこと)",
|
||
+ },
|
||
+ }
|
||
|
||
- assert.Equal(t, correct, name)
|
||
+ for _, test := range tests {
|
||
+ t.Run(test.name, func(t *testing.T) {
|
||
+ actual := GetFullUsername(true, test.user)
|
||
+ assert.Equal(t, test.expected, actual)
|
||
+ })
|
||
+ }
|
||
}
|
||
|
||
func TestGetFullNoUsername(t *testing.T) {
|
||
@@ -49,9 +71,32 @@ func TestGetUsername(t *testing.T) {
|
||
}
|
||
|
||
func TestZwspUsername(t *testing.T) {
|
||
- user := &tgbotapi.User{ID: 1, FirstName: "John", UserName: "jsmith"}
|
||
- correct := "j" + "\u200b" + "smith"
|
||
- name := GetUsername(true, user)
|
||
+ tests := []struct {
|
||
+ name string
|
||
+ user *tgbotapi.User
|
||
+ expected string
|
||
+ }{
|
||
+ {
|
||
+ name: "ascii",
|
||
+ user: &tgbotapi.User{ID: 1, FirstName: "John", UserName: "jsmith"},
|
||
+ expected: "j\u200bsmith",
|
||
+ },
|
||
+ {
|
||
+ name: "cyrillic",
|
||
+ user: &tgbotapi.User{ID: 1, FirstName: "Иван", UserName: "иван"},
|
||
+ expected: "и\u200bван",
|
||
+ },
|
||
+ {
|
||
+ name: "japanese",
|
||
+ user: &tgbotapi.User{ID: 1, FirstName: "まこと", UserName: "まこと"},
|
||
+ expected: "ま\u200bこと",
|
||
+ },
|
||
+ }
|
||
|
||
- assert.Equal(t, correct, name)
|
||
+ for _, test := range tests {
|
||
+ t.Run(test.name, func(t *testing.T) {
|
||
+ actual := GetUsername(true, test.user)
|
||
+ assert.Equal(t, test.expected, actual)
|
||
+ })
|
||
+ }
|
||
}
|
||
--
|
||
2.41.0
|
||
|