FILE / ScuroNeko/Laniakea

tgapi/api101_test.go

Исходный файл и его история в репозитории.
FILE main
Files
ScuroNeko f03a081ed6
Golang lint / lint (pull_request) Successful in 1m20s
Golang lint / lint (push) Successful in 4m8s
(new): rich message support
(fix): runtime reliability
(tests): regression coverage
(doc): v1.1 release notes
2026-08-12 16:34:44 +03:00

210 lines
7.5 KiB
Go

package tgapi
import (
"encoding/json"
"strings"
"testing"
)
func TestEditMessageTextMarshalsInputRichMessage(t *testing.T) {
params := EditMessageText{
ChatID: 1,
MessageID: 2,
RichMessage: &InputRichMessage{
HTML: "<p>hi</p>",
SkipEntityDetection: true,
},
}
data, err := json.Marshal(params)
if err != nil {
t.Fatalf("Marshal returned error: %v", err)
}
got := string(data)
for _, want := range []string{`"rich_message":{"html":`, `"skip_entity_detection":true`} {
if !strings.Contains(got, want) {
t.Fatalf("missing %s in editMessageText JSON: %s", want, got)
}
}
if strings.Contains(got, `"blocks"`) {
t.Fatalf("rich_message must be an InputRichMessage, not a block tree: %s", got)
}
if strings.Contains(got, `"text"`) {
t.Fatalf("empty text must be omitted when editing rich content: %s", got)
}
}
func TestSendRichMessageDraftMarshal(t *testing.T) {
params := SendRichMessageDraft{
ChatID: 1,
DraftID: 7,
RichMessage: InputRichMessage{Markdown: "*hi*"},
}
data, err := json.Marshal(params)
if err != nil {
t.Fatalf("Marshal returned error: %v", err)
}
got := string(data)
for _, want := range []string{`"chat_id":1`, `"draft_id":7`, `"rich_message":{"markdown":"*hi*"}`} {
if !strings.Contains(got, want) {
t.Fatalf("missing %s in sendRichMessageDraft JSON: %s", want, got)
}
}
}
func TestInputRichMessageContentMarshal(t *testing.T) {
content := InputRichMessageContent{
RichMessage: InputRichMessage{HTML: "<p>hi</p>"},
}
data, err := json.Marshal(content)
if err != nil {
t.Fatalf("Marshal returned error: %v", err)
}
if got := string(data); !strings.Contains(got, `"rich_message":{"html":`) {
t.Fatalf("unexpected InputRichMessageContent JSON: %s", got)
}
}
func TestInputRichMessageMediaMarshal(t *testing.T) {
message := InputRichMessage{
HTML: `<video src="tg://video?id=intro"></video>`,
Media: []InputRichMessageMedia{{
ID: "intro",
Media: InputMedia{Type: InputMediaTypeVideo, Media: "attach://intro"},
}},
}
data, err := json.Marshal(message)
if err != nil {
t.Fatalf("Marshal returned error: %v", err)
}
var got struct {
Media []struct {
ID string `json:"id"`
Media InputMedia `json:"media"`
} `json:"media"`
}
if err := json.Unmarshal(data, &got); err != nil {
t.Fatalf("Unmarshal returned error: %v", err)
}
if len(got.Media) != 1 || got.Media[0].ID != "intro" {
t.Fatalf("unexpected media: %+v", got.Media)
}
if got.Media[0].Media.Type != InputMediaTypeVideo || got.Media[0].Media.Media != "attach://intro" {
t.Fatalf("unexpected embedded media: %+v", got.Media[0].Media)
}
}
func TestEphemeralMethodsMarshalReceiverUserID(t *testing.T) {
cases := []struct {
name string
params any
}{
{"edit text", EditEphemeralMessageText{ChatID: 1, ReceiverUserID: 2, EphemeralMessageID: 3, Text: "updated"}},
{"edit media", EditEphemeralMessageMedia{ChatID: 1, ReceiverUserID: 2, EphemeralMessageID: 3, Media: InputMedia{Type: InputMediaTypePhoto, Media: "photo-id"}}},
{"edit caption", EditEphemeralMessageCaption{ChatID: 1, ReceiverUserID: 2, EphemeralMessageID: 3, Caption: "updated"}},
{"edit markup", EditEphemeralMessageReplyMarkup{ChatID: 1, ReceiverUserID: 2, EphemeralMessageID: 3}},
{"delete", DeleteEphemeralMessage{ChatID: 1, ReceiverUserID: 2, EphemeralMessageID: 3}},
}
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
data, err := json.Marshal(tt.params)
if err != nil {
t.Fatalf("Marshal returned error: %v", err)
}
var fields map[string]json.RawMessage
if err := json.Unmarshal(data, &fields); err != nil {
t.Fatalf("Unmarshal returned error: %v", err)
}
if _, ok := fields["receiver_user_id"]; !ok {
t.Fatalf("receiver_user_id is missing from %s", data)
}
if _, ok := fields["reciever_user_id"]; ok {
t.Fatalf("misspelled receiver_user_id is present in %s", data)
}
})
}
}
func TestEphemeralSendParametersMarshal(t *testing.T) {
cases := []struct {
name string
params any
}{
{"message", SendMessage{ChatID: 1, Text: "text", ReceiverUserID: 2, CallbackQueryID: "callback"}},
{"animation", SendAnimation{ChatID: 1, Animation: "animation", ReceiverUserID: 2, CallbackQueryID: "callback"}},
{"audio", SendAudio{ChatID: 1, Audio: "audio", ReceiverUserID: 2, CallbackQueryID: "callback"}},
{"document", SendDocument{ChatID: 1, Document: "document", ReceiverUserID: 2, CallbackQueryID: "callback"}},
{"photo", SendPhoto{ChatID: 1, Photo: "photo", ReceiverUserID: 2, CallbackQueryID: "callback"}},
{"sticker", SendSticker{ChatID: 1, Sticker: "sticker", ReceiverUserID: 2, CallbackQueryID: "callback"}},
{"video", SendVideo{ChatID: 1, Video: "video", ReceiverUserID: 2, CallbackQueryID: "callback"}},
{"video note", SendVideoNote{ChatID: 1, VideoNote: "video-note", ReceiverUserID: 2, CallbackQueryID: "callback"}},
{"voice", SendVoice{ChatID: 1, Voice: "voice", ReceiverUserID: 2, CallbackQueryID: "callback"}},
{"contact", SendContact{ChatID: 1, PhoneNumber: "+10000000000", FirstName: "A", ReceiverUserID: 2, CallbackQueryID: "callback"}},
{"location", SendLocation{ChatID: 1, Latitude: 1, Longitude: 2, ReceiverUserID: 2, CallbackQueryID: "callback"}},
{"venue", SendVenue{ChatID: 1, Latitude: 1, Longitude: 2, Title: "Venue", Address: "Address", ReceiverUserID: 2, CallbackQueryID: "callback"}},
}
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
data, err := json.Marshal(tt.params)
if err != nil {
t.Fatalf("Marshal returned error: %v", err)
}
if !strings.Contains(string(data), `"receiver_user_id":2`) || !strings.Contains(string(data), `"callback_query_id":"callback"`) {
t.Fatalf("missing ephemeral parameters in %s", data)
}
})
}
}
func TestInputPollOptionMediaLinkMarshal(t *testing.T) {
media := InputPollOptionMedia{Type: "link", URL: "https://example.com"}
data, err := json.Marshal(media)
if err != nil {
t.Fatalf("Marshal returned error: %v", err)
}
got := string(data)
if got != `{"type":"link","url":"https://example.com"}` {
t.Fatalf("unexpected link media JSON: %s", got)
}
}
func TestPollMediaUnmarshalLink(t *testing.T) {
var media PollMedia
if err := json.Unmarshal([]byte(`{"link":{"url":"https://example.com"}}`), &media); err != nil {
t.Fatalf("Unmarshal returned error: %v", err)
}
if media.Link == nil || media.Link.URL != "https://example.com" {
t.Fatalf("unexpected poll media link: %+v", media.Link)
}
}
func TestChatJoinRequestUnmarshalQueryID(t *testing.T) {
payload := `{"chat":{"id":1},"from":{"id":2,"first_name":"A"},"user_chat_id":2,"date":3,"query_id":"q42"}`
var req ChatJoinRequest
if err := json.Unmarshal([]byte(payload), &req); err != nil {
t.Fatalf("Unmarshal returned error: %v", err)
}
if req.QueryID == nil || *req.QueryID != "q42" {
t.Fatalf("unexpected query_id: %+v", req.QueryID)
}
}
func TestAnswerChatJoinRequestQueryResultValues(t *testing.T) {
if JoinRequestApprove != "approve" || JoinRequestDecline != "decline" || JoinRequestQueue != "queue" {
t.Fatalf("unexpected join request query result values: %q %q %q",
JoinRequestApprove, JoinRequestDecline, JoinRequestQueue)
}
}
func TestUserUnmarshalSupportsJoinRequestQueries(t *testing.T) {
var user User
if err := json.Unmarshal([]byte(`{"id":1,"first_name":"A","supports_join_request_queries":true}`), &user); err != nil {
t.Fatalf("Unmarshal returned error: %v", err)
}
if user.SupportsJoinRequestQueries == nil || !*user.SupportsJoinRequestQueries {
t.Fatalf("unexpected supports_join_request_queries: %+v", user.SupportsJoinRequestQueries)
}
}