From f70bd7e672c554d38b1b4d0b73bd3616fa93a9e5 Mon Sep 17 00:00:00 2001 From: Ilja Lapkovskis Date: Thu, 18 Jan 2024 22:45:49 +0200 Subject: [PATCH 01/12] WIP: Separate test. Refactor a bunch of it. --- bot_mock_test.go | 55 + bot_test.go | 2138 ++++++++++++++++++--------------- go.mod | 16 +- go.sum | 18 + mockgen.go | 3 + tests/bot_integration_test.go | 922 ++++++++++++++ 6 files changed, 2170 insertions(+), 982 deletions(-) create mode 100644 bot_mock_test.go create mode 100644 mockgen.go create mode 100644 tests/bot_integration_test.go diff --git a/bot_mock_test.go b/bot_mock_test.go new file mode 100644 index 0000000..731e5f7 --- /dev/null +++ b/bot_mock_test.go @@ -0,0 +1,55 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: bot.go +// +// Generated by this command: +// +// mockgen -destination=bot_mock_test.go -package=tgbotapi -source=bot.go +// + +// Package tgbotapi is a generated GoMock package. +package tgbotapi + +import ( + http "net/http" + reflect "reflect" + + gomock "go.uber.org/mock/gomock" +) + +// MockHTTPClient is a mock of HTTPClient interface. +type MockHTTPClient struct { + ctrl *gomock.Controller + recorder *MockHTTPClientMockRecorder +} + +// MockHTTPClientMockRecorder is the mock recorder for MockHTTPClient. +type MockHTTPClientMockRecorder struct { + mock *MockHTTPClient +} + +// NewMockHTTPClient creates a new mock instance. +func NewMockHTTPClient(ctrl *gomock.Controller) *MockHTTPClient { + mock := &MockHTTPClient{ctrl: ctrl} + mock.recorder = &MockHTTPClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockHTTPClient) EXPECT() *MockHTTPClientMockRecorder { + return m.recorder +} + +// Do mocks base method. +func (m *MockHTTPClient) Do(req *http.Request) (*http.Response, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Do", req) + ret0, _ := ret[0].(*http.Response) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Do indicates an expected call of Do. +func (mr *MockHTTPClientMockRecorder) Do(req any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Do", reflect.TypeOf((*MockHTTPClient)(nil).Do), req) +} diff --git a/bot_test.go b/bot_test.go index 40633d6..e67f69c 100644 --- a/bot_test.go +++ b/bot_test.go @@ -1,10 +1,14 @@ package tgbotapi import ( + "bytes" + "fmt" + "io" "net/http" - "os" "testing" - "time" + + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" ) const ( @@ -34,21 +38,24 @@ func (t testLogger) Printf(format string, v ...interface{}) { t.t.Logf(format, v...) } -func getBot(t *testing.T) (*BotAPI, error) { - bot, err := NewBotAPI(TestToken) - bot.Debug = true - - logger := testLogger{t} - SetLogger(logger) - - if err != nil { - t.Error(err) - } - - return bot, err +func prepareHttpClient(t *testing.T) *MockHTTPClient { + ctrl := gomock.NewController(t) + httpMock := NewMockHTTPClient(ctrl) + return httpMock } -func TestNewBotAPI_notoken(t *testing.T) { +func expectGetMe(t *testing.T, c *MockHTTPClient) { + meResp := `{"ok": true, "result": {"id": 123456789, "is_bot": true, "first_name": "MyBot", "username": "my_bot"}}` + c.EXPECT(). + Do(gomock.Any()). + DoAndReturn(func(req *http.Request) (*http.Response, error) { + valid := isRequestValid(req, TestToken, "getMe") + require.True(t, valid) + return newOKResponse(meResp), nil + }) +} + +func TestNewBotAPI_empty_token(t *testing.T) { _, err := NewBotAPI("") if err == nil { @@ -56,1007 +63,1178 @@ func TestNewBotAPI_notoken(t *testing.T) { } } +func isRequestValid(r *http.Request, token, path string) bool { + return r.Method == http.MethodPost && + r.URL.Path == fmt.Sprintf("/bot%s/%s", token, path) && + r.URL.Scheme == "https" +} + +func newOKResponse(body string) *http.Response { + return &http.Response{ + StatusCode: http.StatusOK, + Status: http.StatusText(http.StatusOK), + Body: io.NopCloser(bytes.NewBufferString(body)), + Header: make(http.Header), + } +} + func TestGetUpdates(t *testing.T) { - bot, _ := getBot(t) + updateResp := `{ + "ok": true, + "result": [ + { + "update_id": 123456789, + "message": { + "message_id": 111, + "from": { + "id": 222, + "is_bot": false, + "first_name": "John", + "username": "john_doe" + }, + "chat": { + "id": 333, + "first_name": "John", + "username": "john_doe", + "type": "private" + }, + "date": 1640001112, + "text": "Hello, bot!" + } + } + ] + }` + + client := prepareHttpClient(t) + defer client.ctrl.Finish() + expectGetMe(t, client) + + client.EXPECT(). + Do(gomock.Any()). + DoAndReturn(func(req *http.Request) (*http.Response, error) { + valid := isRequestValid(req, TestToken, "getUpdates") + require.True(t, valid) + return newOKResponse(updateResp), nil + }) + + bot, err := NewBotAPIWithClient(TestToken, APIEndpoint, client) + require.NoError(t, err) u := NewUpdate(0) - - _, err := bot.GetUpdates(u) - - if err != nil { - t.Error(err) - } + _, err = bot.GetUpdates(u) + require.NoError(t, err) } func TestSendWithMessage(t *testing.T) { - bot, _ := getBot(t) + client := prepareHttpClient(t) + defer client.ctrl.Finish() + + responseBody := `{ + "ok": true, + "result": { + "message_id": 123, + "from": { + "id": 123456789, + "is_bot": true, + "first_name": "MyBot", + "username": "my_bot" + }, + "chat": { + "id": 987654321, + "first_name": "John", + "username": "john_doe", + "type": "private" + }, + "date": 1640001112, + "text": "Hello, John!" + } + }` + + expectGetMe(t, client) + + client.EXPECT(). + Do(gomock.Any()). + DoAndReturn(func(req *http.Request) (*http.Response, error) { + valid := isRequestValid(req, TestToken, "sendMessage") + require.True(t, valid) + return newOKResponse(responseBody), nil + }) + + bot, err := NewBotAPIWithClient(TestToken, APIEndpoint, client) + require.NoError(t, err) msg := NewMessage(ChatID, "A test message from the test library in telegram-bot-api") msg.ParseMode = ModeMarkdown - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } + _, err = bot.Send(msg) + require.NoError(t, err) } func TestSendWithMessageReply(t *testing.T) { - bot, _ := getBot(t) + client := prepareHttpClient(t) + defer client.ctrl.Finish() + + responseBody := `{ + "ok": true, + "result": { + "message_id": 123, + "from": { + "id": 123456789, + "is_bot": true, + "first_name": "MyBot", + "username": "my_bot" + }, + "chat": { + "id": 987654321, + "first_name": "John", + "username": "john_doe", + "type": "private" + }, + "date": 1640001112, + "text": "Hello, John!" + } + }` + + expectGetMe(t, client) + + client.EXPECT(). + Do(gomock.Any()). + DoAndReturn(func(req *http.Request) (*http.Response, error) { + valid := isRequestValid(req, TestToken, "sendMessage") + require.True(t, valid) + return newOKResponse(responseBody), nil + }) + + bot, err := NewBotAPIWithClient(TestToken, APIEndpoint, client) + require.NoError(t, err) msg := NewMessage(ChatID, "A test message from the test library in telegram-bot-api") msg.ReplyParameters.MessageID = ReplyToMessageID - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } + _, err = bot.Send(msg) + require.NoError(t, err) } -func TestSendWithMessageForward(t *testing.T) { - bot, _ := getBot(t) - - msg := NewForward(ChatID, ChatID, ReplyToMessageID) - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} +//func TestSendWithMessageForward(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewForward(ChatID, ChatID, ReplyToMessageID) +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} func TestCopyMessage(t *testing.T) { - bot, _ := getBot(t) + client := prepareHttpClient(t) + defer client.ctrl.Finish() + expectGetMe(t, client) + + responseBody := `{ + "ok": true, + "result": { + "message_id": 123, + "from": { + "id": 123456789, + "is_bot": true, + "first_name": "MyBot", + "username": "my_bot" + }, + "chat": { + "id": 987654321, + "first_name": "John", + "username": "john_doe", + "type": "private" + }, + "date": 1640001112, + "text": "Hello, John!" + } + }` + + client.EXPECT(). + Do(gomock.Any()). + DoAndReturn(func(req *http.Request) (*http.Response, error) { + valid := isRequestValid(req, TestToken, "sendMessage") + require.True(t, valid) + return newOKResponse(responseBody), nil + }) + + client.EXPECT(). + Do(gomock.Any()). + DoAndReturn(func(req *http.Request) (*http.Response, error) { + valid := isRequestValid(req, TestToken, "copyMessage") + require.True(t, valid) + return newOKResponse(responseBody), nil + }) + + bot, err := NewBotAPIWithClient(TestToken, APIEndpoint, client) + require.NoError(t, err) msg := NewMessage(ChatID, "A test message from the test library in telegram-bot-api") message, err := bot.Send(msg) - if err != nil { - t.Error(err) - } + require.NoError(t, err) copyMessageConfig := NewCopyMessage(SupergroupChatID, message.Chat.ID, message.MessageID) messageID, err := bot.CopyMessage(copyMessageConfig) - if err != nil { - t.Error(err) - } + require.NoError(t, err) - if messageID.MessageID == message.MessageID { - t.Error("copied message ID was the same as original message") - } + require.Equal(t, messageID.MessageID, message.MessageID) } -func TestSendWithNewPhoto(t *testing.T) { - bot, _ := getBot(t) - - msg := NewPhoto(ChatID, FilePath("tests/image.jpg")) - msg.Caption = "Test" - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithNewPhotoWithFileBytes(t *testing.T) { - bot, _ := getBot(t) - - data, _ := os.ReadFile("tests/image.jpg") - b := FileBytes{Name: "image.jpg", Bytes: data} - - msg := NewPhoto(ChatID, b) - msg.Caption = "Test" - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithNewPhotoWithFileReader(t *testing.T) { - bot, _ := getBot(t) - - f, _ := os.Open("tests/image.jpg") - reader := FileReader{Name: "image.jpg", Reader: f} - - msg := NewPhoto(ChatID, reader) - msg.Caption = "Test" - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithNewPhotoReply(t *testing.T) { - bot, _ := getBot(t) - - msg := NewPhoto(ChatID, FilePath("tests/image.jpg")) - msg.ReplyParameters.MessageID = ReplyToMessageID - - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendNewPhotoToChannel(t *testing.T) { - bot, _ := getBot(t) - - msg := NewPhotoToChannel(Channel, FilePath("tests/image.jpg")) - msg.Caption = "Test" - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - t.Fail() - } -} - -func TestSendNewPhotoToChannelFileBytes(t *testing.T) { - bot, _ := getBot(t) - - data, _ := os.ReadFile("tests/image.jpg") - b := FileBytes{Name: "image.jpg", Bytes: data} - - msg := NewPhotoToChannel(Channel, b) - msg.Caption = "Test" - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - t.Fail() - } -} - -func TestSendNewPhotoToChannelFileReader(t *testing.T) { - bot, _ := getBot(t) - - f, _ := os.Open("tests/image.jpg") - reader := FileReader{Name: "image.jpg", Reader: f} - - msg := NewPhotoToChannel(Channel, reader) - msg.Caption = "Test" - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - t.Fail() - } -} - -func TestSendWithExistingPhoto(t *testing.T) { - bot, _ := getBot(t) - - msg := NewPhoto(ChatID, FileID(ExistingPhotoFileID)) - msg.Caption = "Test" - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithNewDocument(t *testing.T) { - bot, _ := getBot(t) - - msg := NewDocument(ChatID, FilePath("tests/image.jpg")) - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithNewDocumentAndThumb(t *testing.T) { - bot, _ := getBot(t) - - msg := NewDocument(ChatID, FilePath("tests/voice.ogg")) - msg.Thumb = FilePath("tests/image.jpg") - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithExistingDocument(t *testing.T) { - bot, _ := getBot(t) - - msg := NewDocument(ChatID, FileID(ExistingDocumentFileID)) - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithNewAudio(t *testing.T) { - bot, _ := getBot(t) - - msg := NewAudio(ChatID, FilePath("tests/audio.mp3")) - msg.Title = "TEST" - msg.Duration = 10 - msg.Performer = "TEST" - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithExistingAudio(t *testing.T) { - bot, _ := getBot(t) - - msg := NewAudio(ChatID, FileID(ExistingAudioFileID)) - msg.Title = "TEST" - msg.Duration = 10 - msg.Performer = "TEST" - - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithNewVoice(t *testing.T) { - bot, _ := getBot(t) - - msg := NewVoice(ChatID, FilePath("tests/voice.ogg")) - msg.Duration = 10 - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithExistingVoice(t *testing.T) { - bot, _ := getBot(t) - - msg := NewVoice(ChatID, FileID(ExistingVoiceFileID)) - msg.Duration = 10 - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithContact(t *testing.T) { - bot, _ := getBot(t) - - contact := NewContact(ChatID, "5551234567", "Test") - - if _, err := bot.Send(contact); err != nil { - t.Error(err) - } -} - -func TestSendWithLocation(t *testing.T) { - bot, _ := getBot(t) - - _, err := bot.Send(NewLocation(ChatID, 40, 40)) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithVenue(t *testing.T) { - bot, _ := getBot(t) - - venue := NewVenue(ChatID, "A Test Location", "123 Test Street", 40, 40) - - if _, err := bot.Send(venue); err != nil { - t.Error(err) - } -} - -func TestSendWithNewVideo(t *testing.T) { - bot, _ := getBot(t) - - msg := NewVideo(ChatID, FilePath("tests/video.mp4")) - msg.Duration = 10 - msg.Caption = "TEST" - - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithExistingVideo(t *testing.T) { - bot, _ := getBot(t) - - msg := NewVideo(ChatID, FileID(ExistingVideoFileID)) - msg.Duration = 10 - msg.Caption = "TEST" - - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithNewVideoNote(t *testing.T) { - bot, _ := getBot(t) - - msg := NewVideoNote(ChatID, 240, FilePath("tests/videonote.mp4")) - msg.Duration = 10 - - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithExistingVideoNote(t *testing.T) { - bot, _ := getBot(t) - - msg := NewVideoNote(ChatID, 240, FileID(ExistingVideoNoteFileID)) - msg.Duration = 10 - - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithNewSticker(t *testing.T) { - bot, _ := getBot(t) - - msg := NewSticker(ChatID, FilePath("tests/image.jpg")) - - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithExistingSticker(t *testing.T) { - bot, _ := getBot(t) - - msg := NewSticker(ChatID, FileID(ExistingStickerFileID)) - - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithNewStickerAndKeyboardHide(t *testing.T) { - bot, _ := getBot(t) - - msg := NewSticker(ChatID, FilePath("tests/image.jpg")) - msg.ReplyMarkup = ReplyKeyboardRemove{ - RemoveKeyboard: true, - Selective: false, - } - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithExistingStickerAndKeyboardHide(t *testing.T) { - bot, _ := getBot(t) - - msg := NewSticker(ChatID, FileID(ExistingStickerFileID)) - msg.ReplyMarkup = ReplyKeyboardRemove{ - RemoveKeyboard: true, - Selective: false, - } - - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - } -} - -func TestSendWithDice(t *testing.T) { - bot, _ := getBot(t) - - msg := NewDice(ChatID) - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - t.Fail() - } - -} - -func TestSendWithDiceWithEmoji(t *testing.T) { - bot, _ := getBot(t) - - msg := NewDiceWithEmoji(ChatID, "🏀") - _, err := bot.Send(msg) - - if err != nil { - t.Error(err) - t.Fail() - } - -} - -func TestGetFile(t *testing.T) { - bot, _ := getBot(t) - - file := FileConfig{ - FileID: ExistingPhotoFileID, - } - - _, err := bot.GetFile(file) - - if err != nil { - t.Error(err) - } -} - -func TestSendChatConfig(t *testing.T) { - bot, _ := getBot(t) - - _, err := bot.Request(NewChatAction(ChatID, ChatTyping)) - - if err != nil { - t.Error(err) - } -} - -// TODO: identify why this isn't working -// func TestSendEditMessage(t *testing.T) { -// bot, _ := getBot(t) - -// msg, err := bot.Send(NewMessage(ChatID, "Testing editing.")) -// if err != nil { -// t.Error(err) -// } - -// edit := EditMessageTextConfig{ -// BaseEdit: BaseEdit{ -// ChatID: ChatID, -// MessageID: msg.MessageID, -// }, -// Text: "Updated text.", -// } - -// _, err = bot.Send(edit) -// if err != nil { -// t.Error(err) -// } -// } - -func TestGetUserProfilePhotos(t *testing.T) { - bot, _ := getBot(t) - - _, err := bot.GetUserProfilePhotos(NewUserProfilePhotos(ChatID)) - if err != nil { - t.Error(err) - } -} - -func TestSetWebhookWithCert(t *testing.T) { - bot, _ := getBot(t) - - time.Sleep(time.Second * 2) - - bot.Request(DeleteWebhookConfig{}) - - wh, err := NewWebhookWithCert("https://example.com/tgbotapi-test/"+bot.Token, FilePath("tests/cert.pem")) - - if err != nil { - t.Error(err) - } - _, err = bot.Request(wh) - - if err != nil { - t.Error(err) - } - - _, err = bot.GetWebhookInfo() - - if err != nil { - t.Error(err) - } - - bot.Request(DeleteWebhookConfig{}) -} - -func TestSetWebhookWithoutCert(t *testing.T) { - bot, _ := getBot(t) - - time.Sleep(time.Second * 2) - - bot.Request(DeleteWebhookConfig{}) - - wh, err := NewWebhook("https://example.com/tgbotapi-test/" + bot.Token) - - if err != nil { - t.Error(err) - } - - _, err = bot.Request(wh) - - if err != nil { - t.Error(err) - } - - info, err := bot.GetWebhookInfo() - - if err != nil { - t.Error(err) - } - if info.MaxConnections == 0 { - t.Errorf("Expected maximum connections to be greater than 0") - } - if info.LastErrorDate != 0 { - t.Errorf("failed to set webhook: %s", info.LastErrorMessage) - } - - bot.Request(DeleteWebhookConfig{}) -} - -func TestSendWithMediaGroupPhotoVideo(t *testing.T) { - bot, _ := getBot(t) - - cfg := NewMediaGroup(ChatID, []interface{}{ - NewInputMediaPhoto(FileURL("https://github.com/go-telegram-bot-api/telegram-bot-api/raw/0a3a1c8716c4cd8d26a262af9f12dcbab7f3f28c/tests/image.jpg")), - NewInputMediaPhoto(FilePath("tests/image.jpg")), - NewInputMediaVideo(FilePath("tests/video.mp4")), - }) - - messages, err := bot.SendMediaGroup(cfg) - if err != nil { - t.Error(err) - } - - if messages == nil { - t.Error("No received messages") - } - - if len(messages) != len(cfg.Media) { - t.Errorf("Different number of messages: %d", len(messages)) - } -} - -func TestSendWithMediaGroupDocument(t *testing.T) { - bot, _ := getBot(t) - - cfg := NewMediaGroup(ChatID, []interface{}{ - NewInputMediaDocument(FileURL("https://i.imgur.com/unQLJIb.jpg")), - NewInputMediaDocument(FilePath("tests/image.jpg")), - }) - - messages, err := bot.SendMediaGroup(cfg) - if err != nil { - t.Error(err) - } - - if messages == nil { - t.Error("No received messages") - } - - if len(messages) != len(cfg.Media) { - t.Errorf("Different number of messages: %d", len(messages)) - } -} - -func TestSendWithMediaGroupAudio(t *testing.T) { - bot, _ := getBot(t) - - cfg := NewMediaGroup(ChatID, []interface{}{ - NewInputMediaAudio(FilePath("tests/audio.mp3")), - NewInputMediaAudio(FilePath("tests/audio.mp3")), - }) - - messages, err := bot.SendMediaGroup(cfg) - if err != nil { - t.Error(err) - } - - if messages == nil { - t.Error("No received messages") - } - - if len(messages) != len(cfg.Media) { - t.Errorf("Different number of messages: %d", len(messages)) - } -} - -func ExampleNewBotAPI() { - bot, err := NewBotAPI("MyAwesomeBotToken") - if err != nil { - panic(err) - } - - bot.Debug = true - - log.Printf("Authorized on account %s", bot.Self.UserName) - - u := NewUpdate(0) - u.Timeout = 60 - - updates := bot.GetUpdatesChan(u) - - // Optional: wait for updates and clear them if you don't want to handle - // a large backlog of old messages - time.Sleep(time.Millisecond * 500) - updates.Clear() - - for update := range updates { - if update.Message == nil { - continue - } - - log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text) - - msg := NewMessage(update.Message.Chat.ID, update.Message.Text) - msg.ReplyParameters.MessageID = update.Message.MessageID - - bot.Send(msg) - } -} - -func ExampleNewWebhook() { - bot, err := NewBotAPI("MyAwesomeBotToken") - if err != nil { - panic(err) - } - - bot.Debug = true - - log.Printf("Authorized on account %s", bot.Self.UserName) - - wh, err := NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, FilePath("cert.pem")) - - if err != nil { - panic(err) - } - - _, err = bot.Request(wh) - - if err != nil { - panic(err) - } - - info, err := bot.GetWebhookInfo() - - if err != nil { - panic(err) - } - - if info.LastErrorDate != 0 { - log.Printf("failed to set webhook: %s", info.LastErrorMessage) - } - - updates := bot.ListenForWebhook("/" + bot.Token) - go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil) - - for update := range updates { - log.Printf("%+v\n", update) - } -} - -func ExampleWebhookHandler() { - bot, err := NewBotAPI("MyAwesomeBotToken") - if err != nil { - panic(err) - } - - bot.Debug = true - - log.Printf("Authorized on account %s", bot.Self.UserName) - - wh, err := NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, FilePath("cert.pem")) - - if err != nil { - panic(err) - } - - _, err = bot.Request(wh) - if err != nil { - panic(err) - } - info, err := bot.GetWebhookInfo() - if err != nil { - panic(err) - } - if info.LastErrorDate != 0 { - log.Printf("[Telegram callback failed]%s", info.LastErrorMessage) - } - - http.HandleFunc("/"+bot.Token, func(w http.ResponseWriter, r *http.Request) { - update, err := bot.HandleUpdate(r) - if err != nil { - log.Printf("%+v\n", err.Error()) - } else { - log.Printf("%+v\n", *update) - } - }) - - go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil) -} - -func ExampleInlineConfig() { - bot, err := NewBotAPI("MyAwesomeBotToken") // create new bot - if err != nil { - panic(err) - } - - log.Printf("Authorized on account %s", bot.Self.UserName) - - u := NewUpdate(0) - u.Timeout = 60 - - updates := bot.GetUpdatesChan(u) - - for update := range updates { - if update.InlineQuery == nil { // if no inline query, ignore it - continue - } - - article := NewInlineQueryResultArticle(update.InlineQuery.ID, "Echo", update.InlineQuery.Query) - article.Description = update.InlineQuery.Query - - inlineConf := InlineConfig{ - InlineQueryID: update.InlineQuery.ID, - IsPersonal: true, - CacheTime: 0, - Results: []interface{}{article}, - } - - if _, err := bot.Request(inlineConf); err != nil { - log.Println(err) - } - } -} - -func TestDeleteMessage(t *testing.T) { - bot, _ := getBot(t) - - msg := NewMessage(ChatID, "A test message from the test library in telegram-bot-api") - msg.ParseMode = ModeMarkdown - message, _ := bot.Send(msg) - - deleteMessageConfig := DeleteMessageConfig{ - BaseChatMessage: BaseChatMessage{ - ChatConfig: ChatConfig{ - ChatID: message.Chat.ID, - }, - MessageID: message.MessageID, - }, - } - _, err := bot.Request(deleteMessageConfig) - - if err != nil { - t.Error(err) - } -} - -func TestPinChatMessage(t *testing.T) { - bot, _ := getBot(t) - - msg := NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api") - msg.ParseMode = ModeMarkdown - message, _ := bot.Send(msg) - - pinChatMessageConfig := PinChatMessageConfig{ - BaseChatMessage: BaseChatMessage{ - ChatConfig: ChatConfig{ - ChatID: ChatID, - }, - MessageID: message.MessageID, - }, - DisableNotification: false, - } - _, err := bot.Request(pinChatMessageConfig) - - if err != nil { - t.Error(err) - } -} - -func TestUnpinChatMessage(t *testing.T) { - bot, _ := getBot(t) - - msg := NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api") - msg.ParseMode = ModeMarkdown - message, _ := bot.Send(msg) - - // We need pin message to unpin something - pinChatMessageConfig := PinChatMessageConfig{ - BaseChatMessage: BaseChatMessage{ - ChatConfig: ChatConfig{ - ChatID: message.Chat.ID, - }, - MessageID: message.MessageID, - }, - DisableNotification: false, - } - - if _, err := bot.Request(pinChatMessageConfig); err != nil { - t.Error(err) - } - - unpinChatMessageConfig := UnpinChatMessageConfig{ - BaseChatMessage: BaseChatMessage{ - ChatConfig: ChatConfig{ - ChatID: message.Chat.ID, - }, - MessageID: message.MessageID, - }, - } - - if _, err := bot.Request(unpinChatMessageConfig); err != nil { - t.Error(err) - } -} - -func TestUnpinAllChatMessages(t *testing.T) { - bot, _ := getBot(t) - - msg := NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api") - msg.ParseMode = ModeMarkdown - message, _ := bot.Send(msg) - - pinChatMessageConfig := PinChatMessageConfig{ - BaseChatMessage: BaseChatMessage{ - ChatConfig: ChatConfig{ - ChatID: message.Chat.ID, - }, - MessageID: message.MessageID, - }, - DisableNotification: true, - } - - if _, err := bot.Request(pinChatMessageConfig); err != nil { - t.Error(err) - } - - unpinAllChatMessagesConfig := UnpinAllChatMessagesConfig{ - ChatConfig: ChatConfig{ChatID: message.Chat.ID}, - } - - if _, err := bot.Request(unpinAllChatMessagesConfig); err != nil { - t.Error(err) - } -} - -func TestPolls(t *testing.T) { - bot, _ := getBot(t) - - poll := NewPoll(SupergroupChatID, "Are polls working?", "Yes", "No") - - msg, err := bot.Send(poll) - if err != nil { - t.Error(err) - } - - result, err := bot.StopPoll(NewStopPoll(SupergroupChatID, msg.MessageID)) - if err != nil { - t.Error(err) - } - - if result.Question != "Are polls working?" { - t.Error("Poll question did not match") - } - - if !result.IsClosed { - t.Error("Poll did not end") - } - - if result.Options[0].Text != "Yes" || result.Options[0].VoterCount != 0 || result.Options[1].Text != "No" || result.Options[1].VoterCount != 0 { - t.Error("Poll options were incorrect") - } -} - -func TestSendDice(t *testing.T) { - bot, _ := getBot(t) - - dice := NewDice(ChatID) - - msg, err := bot.Send(dice) - if err != nil { - t.Error("Unable to send dice roll") - } - - if msg.Dice == nil { - t.Error("Dice roll was not received") - } -} - -func TestCommands(t *testing.T) { - bot, _ := getBot(t) - - setCommands := NewSetMyCommands(BotCommand{ - Command: "test", - Description: "a test command", - }) - - if _, err := bot.Request(setCommands); err != nil { - t.Error("Unable to set commands") - } - - commands, err := bot.GetMyCommands() - if err != nil { - t.Error("Unable to get commands") - } - - if len(commands) != 1 { - t.Error("Incorrect number of commands returned") - } - - if commands[0].Command != "test" || commands[0].Description != "a test command" { - t.Error("Commands were incorrectly set") - } - - setCommands = NewSetMyCommandsWithScope(NewBotCommandScopeAllPrivateChats(), BotCommand{ - Command: "private", - Description: "a private command", - }) - - if _, err := bot.Request(setCommands); err != nil { - t.Error("Unable to set commands") - } - - commands, err = bot.GetMyCommandsWithConfig(NewGetMyCommandsWithScope(NewBotCommandScopeAllPrivateChats())) - if err != nil { - t.Error("Unable to get commands") - } - - if len(commands) != 1 { - t.Error("Incorrect number of commands returned") - } - - if commands[0].Command != "private" || commands[0].Description != "a private command" { - t.Error("Commands were incorrectly set") - } -} - -// TODO: figure out why test is failing +//func TestSendWithNewPhoto(t *testing.T) { +// bot, _ := configureBot(t) // -// func TestEditMessageMedia(t *testing.T) { -// bot, _ := getBot(t) - -// msg := NewPhoto(ChatID, "tests/image.jpg") -// msg.Caption = "Test" -// m, err := bot.Send(msg) - -// if err != nil { -// t.Error(err) -// } - -// edit := EditMessageMediaConfig{ -// BaseEdit: BaseEdit{ -// ChatID: ChatID, -// MessageID: m.MessageID, -// }, -// Media: NewInputMediaVideo(FilePath("tests/video.mp4")), -// } - -// _, err = bot.Request(edit) -// if err != nil { -// t.Error(err) -// } -// } +// msg := NewPhoto(ChatID, FilePath("tests/image.jpg")) +// msg.Caption = "Test" +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithNewPhotoWithFileBytes(t *testing.T) { +// bot, _ := configureBot(t) +// +// data, _ := os.ReadFile("tests/image.jpg") +// b := FileBytes{Name: "image.jpg", Bytes: data} +// +// msg := NewPhoto(ChatID, b) +// msg.Caption = "Test" +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithNewPhotoWithFileReader(t *testing.T) { +// bot, _ := configureBot(t) +// +// f, _ := os.Open("tests/image.jpg") +// reader := FileReader{Name: "image.jpg", Reader: f} +// +// msg := NewPhoto(ChatID, reader) +// msg.Caption = "Test" +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithNewPhotoReply(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewPhoto(ChatID, FilePath("tests/image.jpg")) +// msg.ReplyParameters.MessageID = ReplyToMessageID +// +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendNewPhotoToChannel(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewPhotoToChannel(Channel, FilePath("tests/image.jpg")) +// msg.Caption = "Test" +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// t.Fail() +// } +//} +// +//func TestSendNewPhotoToChannelFileBytes(t *testing.T) { +// bot, _ := configureBot(t) +// +// data, _ := os.ReadFile("tests/image.jpg") +// b := FileBytes{Name: "image.jpg", Bytes: data} +// +// msg := NewPhotoToChannel(Channel, b) +// msg.Caption = "Test" +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// t.Fail() +// } +//} +// +//func TestSendNewPhotoToChannelFileReader(t *testing.T) { +// bot, _ := configureBot(t) +// +// f, _ := os.Open("tests/image.jpg") +// reader := FileReader{Name: "image.jpg", Reader: f} +// +// msg := NewPhotoToChannel(Channel, reader) +// msg.Caption = "Test" +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// t.Fail() +// } +//} +// +//func TestSendWithExistingPhoto(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewPhoto(ChatID, FileID(ExistingPhotoFileID)) +// msg.Caption = "Test" +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithNewDocument(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewDocument(ChatID, FilePath("tests/image.jpg")) +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithNewDocumentAndThumb(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewDocument(ChatID, FilePath("tests/voice.ogg")) +// msg.Thumb = FilePath("tests/image.jpg") +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithExistingDocument(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewDocument(ChatID, FileID(ExistingDocumentFileID)) +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithNewAudio(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewAudio(ChatID, FilePath("tests/audio.mp3")) +// msg.Title = "TEST" +// msg.Duration = 10 +// msg.Performer = "TEST" +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithExistingAudio(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewAudio(ChatID, FileID(ExistingAudioFileID)) +// msg.Title = "TEST" +// msg.Duration = 10 +// msg.Performer = "TEST" +// +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithNewVoice(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewVoice(ChatID, FilePath("tests/voice.ogg")) +// msg.Duration = 10 +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithExistingVoice(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewVoice(ChatID, FileID(ExistingVoiceFileID)) +// msg.Duration = 10 +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithContact(t *testing.T) { +// bot, _ := configureBot(t) +// +// contact := NewContact(ChatID, "5551234567", "Test") +// +// if _, err := bot.Send(contact); err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithLocation(t *testing.T) { +// bot, _ := configureBot(t) +// +// _, err := bot.Send(NewLocation(ChatID, 40, 40)) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithVenue(t *testing.T) { +// bot, _ := configureBot(t) +// +// venue := NewVenue(ChatID, "A Test Location", "123 Test Street", 40, 40) +// +// if _, err := bot.Send(venue); err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithNewVideo(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewVideo(ChatID, FilePath("tests/video.mp4")) +// msg.Duration = 10 +// msg.Caption = "TEST" +// +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithExistingVideo(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewVideo(ChatID, FileID(ExistingVideoFileID)) +// msg.Duration = 10 +// msg.Caption = "TEST" +// +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithNewVideoNote(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewVideoNote(ChatID, 240, FilePath("tests/videonote.mp4")) +// msg.Duration = 10 +// +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithExistingVideoNote(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewVideoNote(ChatID, 240, FileID(ExistingVideoNoteFileID)) +// msg.Duration = 10 +// +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithNewSticker(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewSticker(ChatID, FilePath("tests/image.jpg")) +// +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithExistingSticker(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewSticker(ChatID, FileID(ExistingStickerFileID)) +// +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithNewStickerAndKeyboardHide(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewSticker(ChatID, FilePath("tests/image.jpg")) +// msg.ReplyMarkup = ReplyKeyboardRemove{ +// RemoveKeyboard: true, +// Selective: false, +// } +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithExistingStickerAndKeyboardHide(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewSticker(ChatID, FileID(ExistingStickerFileID)) +// msg.ReplyMarkup = ReplyKeyboardRemove{ +// RemoveKeyboard: true, +// Selective: false, +// } +// +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendWithDice(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewDice(ChatID) +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// t.Fail() +// } +// +//} +// +//func TestSendWithDiceWithEmoji(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewDiceWithEmoji(ChatID, "🏀") +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// t.Fail() +// } +// +//} +// +//func TestGetFile(t *testing.T) { +// bot, _ := configureBot(t) +// +// file := FileConfig{ +// FileID: ExistingPhotoFileID, +// } +// +// _, err := bot.GetFile(file) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSendChatConfig(t *testing.T) { +// bot, _ := configureBot(t) +// +// _, err := bot.Request(NewChatAction(ChatID, ChatTyping)) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//// TODO: identify why this isn't working +//// func TestSendEditMessage(t *testing.T) { +//// bot, _ := configureBot(t) +// +//// msg, err := bot.Send(NewMessage(ChatID, "Testing editing.")) +//// if err != nil { +//// t.Error(err) +//// } +// +//// edit := EditMessageTextConfig{ +//// BaseEdit: BaseEdit{ +//// ChatID: ChatID, +//// MessageID: msg.MessageID, +//// }, +//// Text: "Updated text.", +//// } +// +//// _, err = bot.Send(edit) +//// if err != nil { +//// t.Error(err) +//// } +//// } +// +//func TestGetUserProfilePhotos(t *testing.T) { +// bot, _ := configureBot(t) +// +// _, err := bot.GetUserProfilePhotos(NewUserProfilePhotos(ChatID)) +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestSetWebhookWithCert(t *testing.T) { +// bot, _ := configureBot(t) +// +// time.Sleep(time.Second * 2) +// +// bot.Request(DeleteWebhookConfig{}) +// +// wh, err := NewWebhookWithCert("https://example.com/tgbotapi-test/"+bot.Token, FilePath("tests/cert.pem")) +// +// if err != nil { +// t.Error(err) +// } +// _, err = bot.Request(wh) +// +// if err != nil { +// t.Error(err) +// } +// +// _, err = bot.GetWebhookInfo() +// +// if err != nil { +// t.Error(err) +// } +// +// bot.Request(DeleteWebhookConfig{}) +//} +// +//func TestSetWebhookWithoutCert(t *testing.T) { +// bot, _ := configureBot(t) +// +// time.Sleep(time.Second * 2) +// +// bot.Request(DeleteWebhookConfig{}) +// +// wh, err := NewWebhook("https://example.com/tgbotapi-test/" + bot.Token) +// +// if err != nil { +// t.Error(err) +// } +// +// _, err = bot.Request(wh) +// +// if err != nil { +// t.Error(err) +// } +// +// info, err := bot.GetWebhookInfo() +// +// if err != nil { +// t.Error(err) +// } +// if info.MaxConnections == 0 { +// t.Errorf("Expected maximum connections to be greater than 0") +// } +// if info.LastErrorDate != 0 { +// t.Errorf("failed to set webhook: %s", info.LastErrorMessage) +// } +// +// bot.Request(DeleteWebhookConfig{}) +//} +// +//func TestSendWithMediaGroupPhotoVideo(t *testing.T) { +// bot, _ := configureBot(t) +// +// cfg := NewMediaGroup(ChatID, []interface{}{ +// NewInputMediaPhoto(FileURL("https://github.com/go-telegram-bot-api/telegram-bot-api/raw/0a3a1c8716c4cd8d26a262af9f12dcbab7f3f28c/tests/image.jpg")), +// NewInputMediaPhoto(FilePath("tests/image.jpg")), +// NewInputMediaVideo(FilePath("tests/video.mp4")), +// }) +// +// messages, err := bot.SendMediaGroup(cfg) +// if err != nil { +// t.Error(err) +// } +// +// if messages == nil { +// t.Error("No received messages") +// } +// +// if len(messages) != len(cfg.Media) { +// t.Errorf("Different number of messages: %d", len(messages)) +// } +//} +// +//func TestSendWithMediaGroupDocument(t *testing.T) { +// bot, _ := configureBot(t) +// +// cfg := NewMediaGroup(ChatID, []interface{}{ +// NewInputMediaDocument(FileURL("https://i.imgur.com/unQLJIb.jpg")), +// NewInputMediaDocument(FilePath("tests/image.jpg")), +// }) +// +// messages, err := bot.SendMediaGroup(cfg) +// if err != nil { +// t.Error(err) +// } +// +// if messages == nil { +// t.Error("No received messages") +// } +// +// if len(messages) != len(cfg.Media) { +// t.Errorf("Different number of messages: %d", len(messages)) +// } +//} +// +//func TestSendWithMediaGroupAudio(t *testing.T) { +// bot, _ := configureBot(t) +// +// cfg := NewMediaGroup(ChatID, []interface{}{ +// NewInputMediaAudio(FilePath("tests/audio.mp3")), +// NewInputMediaAudio(FilePath("tests/audio.mp3")), +// }) +// +// messages, err := bot.SendMediaGroup(cfg) +// if err != nil { +// t.Error(err) +// } +// +// if messages == nil { +// t.Error("No received messages") +// } +// +// if len(messages) != len(cfg.Media) { +// t.Errorf("Different number of messages: %d", len(messages)) +// } +//} +// +//func ExampleNewBotAPI() { +// bot, err := NewBotAPI("MyAwesomeBotToken") +// if err != nil { +// panic(err) +// } +// +// bot.Debug = true +// +// log.Printf("Authorized on account %s", bot.Self.UserName) +// +// u := NewUpdate(0) +// u.Timeout = 60 +// +// updates := bot.GetUpdatesChan(u) +// +// // Optional: wait for updates and clear them if you don't want to handle +// // a large backlog of old messages +// time.Sleep(time.Millisecond * 500) +// updates.Clear() +// +// for update := range updates { +// if update.Message == nil { +// continue +// } +// +// log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text) +// +// msg := NewMessage(update.Message.Chat.ID, update.Message.Text) +// msg.ReplyParameters.MessageID = update.Message.MessageID +// +// bot.Send(msg) +// } +//} +// +//func ExampleNewWebhook() { +// bot, err := NewBotAPI("MyAwesomeBotToken") +// if err != nil { +// panic(err) +// } +// +// bot.Debug = true +// +// log.Printf("Authorized on account %s", bot.Self.UserName) +// +// wh, err := NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, FilePath("cert.pem")) +// +// if err != nil { +// panic(err) +// } +// +// _, err = bot.Request(wh) +// +// if err != nil { +// panic(err) +// } +// +// info, err := bot.GetWebhookInfo() +// +// if err != nil { +// panic(err) +// } +// +// if info.LastErrorDate != 0 { +// log.Printf("failed to set webhook: %s", info.LastErrorMessage) +// } +// +// updates := bot.ListenForWebhook("/" + bot.Token) +// go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil) +// +// for update := range updates { +// log.Printf("%+v\n", update) +// } +//} +// +//func ExampleWebhookHandler() { +// bot, err := NewBotAPI("MyAwesomeBotToken") +// if err != nil { +// panic(err) +// } +// +// bot.Debug = true +// +// log.Printf("Authorized on account %s", bot.Self.UserName) +// +// wh, err := NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, FilePath("cert.pem")) +// +// if err != nil { +// panic(err) +// } +// +// _, err = bot.Request(wh) +// if err != nil { +// panic(err) +// } +// info, err := bot.GetWebhookInfo() +// if err != nil { +// panic(err) +// } +// if info.LastErrorDate != 0 { +// log.Printf("[Telegram callback failed]%s", info.LastErrorMessage) +// } +// +// http.HandleFunc("/"+bot.Token, func(w http.ResponseWriter, r *http.Request) { +// update, err := bot.HandleUpdate(r) +// if err != nil { +// log.Printf("%+v\n", err.Error()) +// } else { +// log.Printf("%+v\n", *update) +// } +// }) +// +// go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil) +//} +// +//func ExampleInlineConfig() { +// bot, err := NewBotAPI("MyAwesomeBotToken") // create new bot +// if err != nil { +// panic(err) +// } +// +// log.Printf("Authorized on account %s", bot.Self.UserName) +// +// u := NewUpdate(0) +// u.Timeout = 60 +// +// updates := bot.GetUpdatesChan(u) +// +// for update := range updates { +// if update.InlineQuery == nil { // if no inline query, ignore it +// continue +// } +// +// article := NewInlineQueryResultArticle(update.InlineQuery.ID, "Echo", update.InlineQuery.Query) +// article.Description = update.InlineQuery.Query +// +// inlineConf := InlineConfig{ +// InlineQueryID: update.InlineQuery.ID, +// IsPersonal: true, +// CacheTime: 0, +// Results: []interface{}{article}, +// } +// +// if _, err := bot.Request(inlineConf); err != nil { +// log.Println(err) +// } +// } +//} +// +//func TestDeleteMessage(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewMessage(ChatID, "A test message from the test library in telegram-bot-api") +// msg.ParseMode = ModeMarkdown +// message, _ := bot.Send(msg) +// +// deleteMessageConfig := DeleteMessageConfig{ +// BaseChatMessage: BaseChatMessage{ +// ChatConfig: ChatConfig{ +// ChatID: message.Chat.ID, +// }, +// MessageID: message.MessageID, +// }, +// } +// _, err := bot.Request(deleteMessageConfig) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestPinChatMessage(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api") +// msg.ParseMode = ModeMarkdown +// message, _ := bot.Send(msg) +// +// pinChatMessageConfig := PinChatMessageConfig{ +// BaseChatMessage: BaseChatMessage{ +// ChatConfig: ChatConfig{ +// ChatID: ChatID, +// }, +// MessageID: message.MessageID, +// }, +// DisableNotification: false, +// } +// _, err := bot.Request(pinChatMessageConfig) +// +// if err != nil { +// t.Error(err) +// } +//} +// +//func TestUnpinChatMessage(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api") +// msg.ParseMode = ModeMarkdown +// message, _ := bot.Send(msg) +// +// // We need pin message to unpin something +// pinChatMessageConfig := PinChatMessageConfig{ +// BaseChatMessage: BaseChatMessage{ +// ChatConfig: ChatConfig{ +// ChatID: message.Chat.ID, +// }, +// MessageID: message.MessageID, +// }, +// DisableNotification: false, +// } +// +// if _, err := bot.Request(pinChatMessageConfig); err != nil { +// t.Error(err) +// } +// +// unpinChatMessageConfig := UnpinChatMessageConfig{ +// BaseChatMessage: BaseChatMessage{ +// ChatConfig: ChatConfig{ +// ChatID: message.Chat.ID, +// }, +// MessageID: message.MessageID, +// }, +// } +// +// if _, err := bot.Request(unpinChatMessageConfig); err != nil { +// t.Error(err) +// } +//} +// +//func TestUnpinAllChatMessages(t *testing.T) { +// bot, _ := configureBot(t) +// +// msg := NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api") +// msg.ParseMode = ModeMarkdown +// message, _ := bot.Send(msg) +// +// pinChatMessageConfig := PinChatMessageConfig{ +// BaseChatMessage: BaseChatMessage{ +// ChatConfig: ChatConfig{ +// ChatID: message.Chat.ID, +// }, +// MessageID: message.MessageID, +// }, +// DisableNotification: true, +// } +// +// if _, err := bot.Request(pinChatMessageConfig); err != nil { +// t.Error(err) +// } +// +// unpinAllChatMessagesConfig := UnpinAllChatMessagesConfig{ +// ChatConfig: ChatConfig{ChatID: message.Chat.ID}, +// } +// +// if _, err := bot.Request(unpinAllChatMessagesConfig); err != nil { +// t.Error(err) +// } +//} +// +//func TestPolls(t *testing.T) { +// bot, _ := configureBot(t) +// +// poll := NewPoll(SupergroupChatID, "Are polls working?", "Yes", "No") +// +// msg, err := bot.Send(poll) +// if err != nil { +// t.Error(err) +// } +// +// result, err := bot.StopPoll(NewStopPoll(SupergroupChatID, msg.MessageID)) +// if err != nil { +// t.Error(err) +// } +// +// if result.Question != "Are polls working?" { +// t.Error("Poll question did not match") +// } +// +// if !result.IsClosed { +// t.Error("Poll did not end") +// } +// +// if result.Options[0].Text != "Yes" || result.Options[0].VoterCount != 0 || result.Options[1].Text != "No" || result.Options[1].VoterCount != 0 { +// t.Error("Poll options were incorrect") +// } +//} +// +//func TestSendDice(t *testing.T) { +// bot, _ := configureBot(t) +// +// dice := NewDice(ChatID) +// +// msg, err := bot.Send(dice) +// if err != nil { +// t.Error("Unable to send dice roll") +// } +// +// if msg.Dice == nil { +// t.Error("Dice roll was not received") +// } +//} +// +//func TestCommands(t *testing.T) { +// bot, _ := configureBot(t) +// +// setCommands := NewSetMyCommands(BotCommand{ +// Command: "test", +// Description: "a test command", +// }) +// +// if _, err := bot.Request(setCommands); err != nil { +// t.Error("Unable to set commands") +// } +// +// commands, err := bot.GetMyCommands() +// if err != nil { +// t.Error("Unable to get commands") +// } +// +// if len(commands) != 1 { +// t.Error("Incorrect number of commands returned") +// } +// +// if commands[0].Command != "test" || commands[0].Description != "a test command" { +// t.Error("Commands were incorrectly set") +// } +// +// setCommands = NewSetMyCommandsWithScope(NewBotCommandScopeAllPrivateChats(), BotCommand{ +// Command: "private", +// Description: "a private command", +// }) +// +// if _, err := bot.Request(setCommands); err != nil { +// t.Error("Unable to set commands") +// } +// +// commands, err = bot.GetMyCommandsWithConfig(NewGetMyCommandsWithScope(NewBotCommandScopeAllPrivateChats())) +// if err != nil { +// t.Error("Unable to get commands") +// } +// +// if len(commands) != 1 { +// t.Error("Incorrect number of commands returned") +// } +// +// if commands[0].Command != "private" || commands[0].Description != "a private command" { +// t.Error("Commands were incorrectly set") +// } +//} +// +//// TODO: figure out why test is failing +//// +//// func TestEditMessageMedia(t *testing.T) { +//// bot, _ := configureBot(t) +// +//// msg := NewPhoto(ChatID, "tests/image.jpg") +//// msg.Caption = "Test" +//// m, err := bot.Send(msg) +// +//// if err != nil { +//// t.Error(err) +//// } +// +//// edit := EditMessageMediaConfig{ +//// BaseEdit: BaseEdit{ +//// ChatID: ChatID, +//// MessageID: m.MessageID, +//// }, +//// Media: NewInputMediaVideo(FilePath("tests/video.mp4")), +//// } +// +//// _, err = bot.Request(edit) +//// if err != nil { +//// t.Error(err) +//// } +//// } +// +//func TestPrepareInputMediaForParams(t *testing.T) { +// media := []interface{}{ +// NewInputMediaPhoto(FilePath("tests/image.jpg")), +// NewInputMediaVideo(FileID("test")), +// } +// +// prepared := prepareInputMediaForParams(media) +// +// if media[0].(InputMediaPhoto).Media != FilePath("tests/image.jpg") { +// t.Error("Original media was changed") +// } +// +// if prepared[0].(InputMediaPhoto).Media != fileAttach("attach://file-0") { +// t.Error("New media was not replaced") +// } +// +// if prepared[1].(InputMediaVideo).Media != FileID("test") { +// t.Error("Passthrough value was not the same") +// } +//} func TestPrepareInputMediaForParams(t *testing.T) { - media := []interface{}{ - NewInputMediaPhoto(FilePath("tests/image.jpg")), + media := []any{ + NewInputMediaPhoto(FilePath("./image.jpg")), NewInputMediaVideo(FileID("test")), } prepared := prepareInputMediaForParams(media) - if media[0].(InputMediaPhoto).Media != FilePath("tests/image.jpg") { + if media[0].(InputMediaPhoto).Media != FilePath("./image.jpg") { t.Error("Original media was changed") } diff --git a/go.mod b/go.mod index 167e5e4..50de042 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,15 @@ -module github.com/go-telegram-bot-api/telegram-bot-api/v5 +module github.com/eli-l/telegram-bot-api/v5 -go 1.16 +go 1.21 + +require github.com/stretchr/testify v1.8.4 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + go.uber.org/mock v0.4.0 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/sys v0.16.0 // indirect + golang.org/x/tools v0.17.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum index e69de29..47c3a79 100644 --- a/go.sum +++ b/go.sum @@ -0,0 +1,18 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/mockgen.go b/mockgen.go new file mode 100644 index 0000000..ba1b254 --- /dev/null +++ b/mockgen.go @@ -0,0 +1,3 @@ +package tgbotapi + +//go:generate mockgen -destination=bot_mock_test.go -package=tgbotapi -source=bot.go diff --git a/tests/bot_integration_test.go b/tests/bot_integration_test.go new file mode 100644 index 0000000..f21c691 --- /dev/null +++ b/tests/bot_integration_test.go @@ -0,0 +1,922 @@ +package tests + +import ( + "fmt" + "net/http" + "os" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/eli-l/telegram-bot-api/v5" +) + +const ( + TestToken = "6152026236:AAHccoTeFxTezeSceAOKRMZW_A5vaIFo4aI" + ChatID = 6064981043 + Channel = "@testapiintegration" + SupergroupChatID = -1002055786965 + ReplyToMessageID = 1 + ExistingPhotoFileID = "AgACAgIAAxkDAAEBFUZhIALQ9pZN4BUe8ZSzUU_2foSo1AACnrMxG0BucEhezsBWOgcikQEAAwIAA20AAyAE" + ExistingDocumentFileID = "BQADAgADOQADjMcoCcioX1GrDvp3Ag" + ExistingAudioFileID = "BQADAgADRgADjMcoCdXg3lSIN49lAg" + ExistingVoiceFileID = "AwADAgADWQADjMcoCeul6r_q52IyAg" + ExistingVideoFileID = "BAADAgADZgADjMcoCav432kYe0FRAg" + ExistingVideoNoteFileID = "DQADAgADdQAD70cQSUK41dLsRMqfAg" + ExistingStickerFileID = "BQADAgADcwADjMcoCbdl-6eB--YPAg" +) + +type testLogger struct { + t *testing.T +} + +func (t testLogger) Println(v ...interface{}) { + t.t.Log(v...) +} + +func (t testLogger) Printf(format string, v ...interface{}) { + t.t.Logf(format, v...) +} + +func getBot(t *testing.T) (*tgbotapi.BotAPI, error) { + bot, err := tgbotapi.NewBotAPI(TestToken) + require.NoError(t, err) + bot.Debug = true + + logger := testLogger{t} + err = tgbotapi.SetLogger(logger) + require.NoError(t, err) + + return bot, err +} + +func TestNewBotAPI_notoken(t *testing.T) { + _, err := tgbotapi.NewBotAPI("") + require.Error(t, err) +} + +func TestGetUpdates(t *testing.T) { + bot, _ := getBot(t) + + u := tgbotapi.NewUpdate(0) + + _, err := bot.GetUpdates(u) + require.NoError(t, err) +} + +func TestSendWithMessage(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewMessage(ChatID, "A test message from the test library in telegram-bot-api") + msg.ParseMode = tgbotapi.ModeMarkdown + _, err := bot.Send(msg) + require.NoError(t, err) +} + +func TestSendWithMessageReply(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewMessage(ChatID, "A test message from the test library in telegram-bot-api") + msg.ReplyParameters.MessageID = ReplyToMessageID + _, err := bot.Send(msg) + require.NoError(t, err) +} + +func TestSendWithMessageForward(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewForward(ChatID, ChatID, ReplyToMessageID) + _, err := bot.Send(msg) + require.NoError(t, err) +} + +func TestCopyMessage(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewMessage(ChatID, "A test message from the test library in telegram-bot-api") + message, err := bot.Send(msg) + require.NoError(t, err) + + copyMessageConfig := tgbotapi.NewCopyMessage(SupergroupChatID, message.Chat.ID, message.MessageID) + messageID, err := bot.CopyMessage(copyMessageConfig) + require.NoError(t, err) + require.NotEqual(t, message.MessageID, messageID.MessageID) +} + +func TestSendWithNewPhoto(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewPhoto(ChatID, tgbotapi.FilePath("./image.jpg")) + msg.Caption = "Test" + _, err := bot.Send(msg) + require.NoError(t, err) +} + +func TestSendWithNewPhotoWithFileBytes(t *testing.T) { + bot, _ := getBot(t) + + data, _ := os.ReadFile("./image.jpg") + b := tgbotapi.FileBytes{Name: "image.jpg", Bytes: data} + + msg := tgbotapi.NewPhoto(ChatID, b) + msg.Caption = "Test" + _, err := bot.Send(msg) + require.NoError(t, err) +} + +func TestSendWithNewPhotoWithFileReader(t *testing.T) { + bot, _ := getBot(t) + + f, _ := os.Open("./image.jpg") + reader := tgbotapi.FileReader{Name: "image.jpg", Reader: f} + + msg := tgbotapi.NewPhoto(ChatID, reader) + msg.Caption = "Test" + _, err := bot.Send(msg) + require.NoError(t, err) +} + +func TestSendWithNewPhotoReply(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewPhoto(ChatID, tgbotapi.FilePath("./image.jpg")) + msg.ReplyParameters.MessageID = ReplyToMessageID + + _, err := bot.Send(msg) + require.NoError(t, err) +} + +func TestSendNewPhotoToChannel(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewPhotoToChannel(Channel, tgbotapi.FilePath("./image.jpg")) + msg.Caption = "Test" + _, err := bot.Send(msg) + require.NoError(t, err) +} + +func TestSendNewPhotoToChannelFileBytes(t *testing.T) { + bot, _ := getBot(t) + + data, _ := os.ReadFile("./image.jpg") + b := tgbotapi.FileBytes{Name: "image.jpg", Bytes: data} + + msg := tgbotapi.NewPhotoToChannel(Channel, b) + msg.Caption = "Test" + _, err := bot.Send(msg) + require.NoError(t, err) +} + +func TestSendNewPhotoToChannelFileReader(t *testing.T) { + bot, _ := getBot(t) + + f, _ := os.Open("./image.jpg") + reader := tgbotapi.FileReader{Name: "image.jpg", Reader: f} + + msg := tgbotapi.NewPhotoToChannel(Channel, reader) + msg.Caption = "Test" + _, err := bot.Send(msg) + require.NoError(t, err) +} + +// TODO: fix this +//func TestSendWithExistingPhoto(t *testing.T) { +// bot, _ := getBot(t) +// +// msg := tgbotapi.NewPhoto(ChatID, tgbotapi.FileID(ExistingPhotoFileID)) +// msg.Caption = "Test" +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} + +func TestSendWithNewDocument(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewDocument(ChatID, tgbotapi.FilePath("./image.jpg")) + _, err := bot.Send(msg) + require.NoError(t, err) +} + +func TestSendWithNewDocumentAndThumb(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewDocument(ChatID, tgbotapi.FilePath("./voice.ogg")) + msg.Thumb = tgbotapi.FilePath("./image.jpg") + _, err := bot.Send(msg) + require.NoError(t, err) +} + +// TODO: fix this +//func TestSendWithExistingDocument(t *testing.T) { +// bot, _ := getBot(t) +// +// msg := tgbotapi.NewDocument(ChatID, tgbotapi.FileID(ExistingDocumentFileID)) +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} + +func TestSendWithNewAudio(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewAudio(ChatID, tgbotapi.FilePath("./audio.mp3")) + msg.Title = "TEST" + msg.Duration = 10 + msg.Performer = "TEST" + _, err := bot.Send(msg) + require.NoError(t, err) +} + +// TODO: fix this +//func TestSendWithExistingAudio(t *testing.T) { +// bot, _ := getBot(t) +// +// msg := tgbotapi.NewAudio(ChatID, tgbotapi.FileID(ExistingAudioFileID)) +// msg.Title = "TEST" +// msg.Duration = 10 +// msg.Performer = "TEST" +// +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} + +func TestSendWithNewVoice(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewVoice(ChatID, tgbotapi.FilePath("./voice.ogg")) + msg.Duration = 10 + _, err := bot.Send(msg) + require.NoError(t, err) +} + +// TODO: fix this +//func TestSendWithExistingVoice(t *testing.T) { +// bot, _ := getBot(t) +// +// msg := tgbotapi.NewVoice(ChatID, tgbotapi.FileID(ExistingVoiceFileID)) +// msg.Duration = 10 +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} + +func TestSendWithContact(t *testing.T) { + bot, _ := getBot(t) + + contact := tgbotapi.NewContact(ChatID, "5551234567", "Test") + + _, err := bot.Send(contact) + require.NoError(t, err) +} + +func TestSendWithLocation(t *testing.T) { + bot, _ := getBot(t) + + _, err := bot.Send(tgbotapi.NewLocation(ChatID, 40, 40)) + require.NoError(t, err) +} + +func TestSendWithVenue(t *testing.T) { + bot, _ := getBot(t) + + venue := tgbotapi.NewVenue(ChatID, "A Test Location", "123 Test Street", 40, 40) + + _, err := bot.Send(venue) + require.NoError(t, err) +} + +func TestSendWithNewVideo(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewVideo(ChatID, tgbotapi.FilePath("./video.mp4")) + msg.Duration = 10 + msg.Caption = "TEST" + + _, err := bot.Send(msg) + require.NoError(t, err) +} + +// TODO: fix this +//func TestSendWithExistingVideo(t *testing.T) { +// bot, _ := getBot(t) +// +// msg := tgbotapi.NewVideo(ChatID, tgbotapi.FileID(ExistingVideoFileID)) +// msg.Duration = 10 +// msg.Caption = "TEST" +// +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} + +func TestSendWithNewVideoNote(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewVideoNote(ChatID, 240, tgbotapi.FilePath("./videonote.mp4")) + msg.Duration = 10 + + _, err := bot.Send(msg) + require.NoError(t, err) +} + +// TODO: fix this +//func TestSendWithExistingVideoNote(t *testing.T) { +// bot, _ := getBot(t) +// +// msg := tgbotapi.NewVideoNote(ChatID, 240, tgbotapi.FileID(ExistingVideoNoteFileID)) +// msg.Duration = 10 +// +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} + +func TestSendWithNewSticker(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewSticker(ChatID, tgbotapi.FilePath("./image.jpg")) + + _, err := bot.Send(msg) + require.NoError(t, err) +} + +// TODO: fix this +//func TestSendWithExistingSticker(t *testing.T) { +// bot, _ := getBot(t) +// +// msg := tgbotapi.NewSticker(ChatID, tgbotapi.FileID(ExistingStickerFileID)) +// +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} + +func TestSendWithNewStickerAndKeyboardHide(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewSticker(ChatID, tgbotapi.FilePath("./image.jpg")) + msg.ReplyMarkup = tgbotapi.ReplyKeyboardRemove{ + RemoveKeyboard: true, + Selective: false, + } + _, err := bot.Send(msg) + require.NoError(t, err) +} + +// TODO: fix this +//func TestSendWithExistingStickerAndKeyboardHide(t *testing.T) { +// bot, _ := getBot(t) +// +// msg := tgbotapi.NewSticker(ChatID, tgbotapi.FileID(ExistingStickerFileID)) +// msg.ReplyMarkup = tgbotapi.ReplyKeyboardRemove{ +// RemoveKeyboard: true, +// Selective: false, +// } +// +// _, err := bot.Send(msg) +// +// if err != nil { +// t.Error(err) +// } +//} + +func TestSendWithDice(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewDice(ChatID) + _, err := bot.Send(msg) + require.NoError(t, err) +} + +func TestSendWithDiceWithEmoji(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewDiceWithEmoji(ChatID, "🏀") + _, err := bot.Send(msg) + require.NoError(t, err) +} + +// TODO: fix this +//func TestGetFile(t *testing.T) { +// bot, _ := getBot(t) +// +// file := tgbotapi.FileConfig{ +// FileID: ExistingPhotoFileID, +// } +// +// _, err := bot.GetFile(file) +// +// if err != nil { +// t.Error(err) +// } +//} + +func TestSendChatConfig(t *testing.T) { + bot, _ := getBot(t) + + _, err := bot.Request(tgbotapi.NewChatAction(ChatID, tgbotapi.ChatTyping)) + require.NoError(t, err) +} + +// TODO: identify why this isn't working +// func TestSendEditMessage(t *testing.T) { +// bot, _ := getBot(t) + +// msg, err := bot.Send(NewMessage(ChatID, "Testing editing.")) +// if err != nil { +// t.Error(err) +// } + +// edit := EditMessageTextConfig{ +// BaseEdit: BaseEdit{ +// ChatID: ChatID, +// MessageID: msg.MessageID, +// }, +// Text: "Updated text.", +// } + +// _, err = bot.Send(edit) +// if err != nil { +// t.Error(err) +// } +// } + +func TestGetUserProfilePhotos(t *testing.T) { + bot, _ := getBot(t) + + _, err := bot.GetUserProfilePhotos(tgbotapi.NewUserProfilePhotos(ChatID)) + require.NoError(t, err) +} + +func TestSetWebhookWithCert(t *testing.T) { + bot, _ := getBot(t) + + time.Sleep(time.Second * 2) + + bot.Request(tgbotapi.DeleteWebhookConfig{}) + + wh, err := tgbotapi.NewWebhookWithCert("https://example.com/tgbotapi-test/"+bot.Token, tgbotapi.FilePath("./cert.pem")) + require.NoError(t, err) + _, err = bot.Request(wh) + require.NoError(t, err) + + _, err = bot.GetWebhookInfo() + require.NoError(t, err) + + _, err = bot.Request(tgbotapi.DeleteWebhookConfig{}) + require.NoError(t, err) +} + +func TestSetWebhookWithoutCert(t *testing.T) { + bot, _ := getBot(t) + + time.Sleep(time.Second * 2) + + bot.Request(tgbotapi.DeleteWebhookConfig{}) + + wh, err := tgbotapi.NewWebhook("https://example.com/tgbotapi-test/" + bot.Token) + require.NoError(t, err) + + _, err = bot.Request(wh) + require.NoError(t, err) + + info, err := bot.GetWebhookInfo() + require.NoError(t, err) + require.NotEqual(t, 0, info.MaxConnections) + require.Equal(t, 0, info.LastErrorDate) + _, err = bot.Request(tgbotapi.DeleteWebhookConfig{}) + require.NoError(t, err) +} + +func TestSendWithMediaGroupPhotoVideo(t *testing.T) { + bot, _ := getBot(t) + + cfg := tgbotapi.NewMediaGroup(ChatID, []interface{}{ + tgbotapi.NewInputMediaPhoto(tgbotapi.FileURL("https://github.com/go-telegram-bot-api/telegram-bot-api/raw/0a3a1c8716c4cd8d26a262af9f12dcbab7f3f28c/tests/image.jpg")), + tgbotapi.NewInputMediaPhoto(tgbotapi.FilePath("./image.jpg")), + tgbotapi.NewInputMediaVideo(tgbotapi.FilePath("./video.mp4")), + }) + + messages, err := bot.SendMediaGroup(cfg) + require.NoError(t, err) + require.NotNil(t, messages) + require.Equal(t, len(cfg.Media), len(messages)) +} + +func TestSendWithMediaGroupDocument(t *testing.T) { + bot, _ := getBot(t) + + cfg := tgbotapi.NewMediaGroup(ChatID, []interface{}{ + tgbotapi.NewInputMediaDocument(tgbotapi.FileURL("https://i.imgur.com/unQLJIb.jpg")), + tgbotapi.NewInputMediaDocument(tgbotapi.FilePath("./image.jpg")), + }) + + messages, err := bot.SendMediaGroup(cfg) + require.NoError(t, err) + require.NotNil(t, messages) + require.Equal(t, len(cfg.Media), len(messages)) +} + +func TestSendWithMediaGroupAudio(t *testing.T) { + bot, _ := getBot(t) + + cfg := tgbotapi.NewMediaGroup(ChatID, []interface{}{ + tgbotapi.NewInputMediaAudio(tgbotapi.FilePath("./audio.mp3")), + tgbotapi.NewInputMediaAudio(tgbotapi.FilePath("./audio.mp3")), + }) + + messages, err := bot.SendMediaGroup(cfg) + require.NoError(t, err) + require.NotNil(t, messages) + require.Equal(t, len(cfg.Media), len(messages)) +} + +func ExampleNewBotAPI() { + bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken") + if err != nil { + panic(err) + } + + bot.Debug = true + + fmt.Printf("Authorized on account %s", bot.Self.UserName) + u := tgbotapi.NewUpdate(0) + u.Timeout = 60 + + updates := bot.GetUpdatesChan(u) + + // Optional: wait for updates and clear them if you don't want to handle + // a large backlog of old messages + time.Sleep(time.Millisecond * 500) + updates.Clear() + + for update := range updates { + if update.Message == nil { + continue + } + + fmt.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text) + + msg := tgbotapi.NewMessage(update.Message.Chat.ID, update.Message.Text) + msg.ReplyParameters.MessageID = update.Message.MessageID + + _, err := bot.Send(msg) + if err != nil { + panic(err) + } + } +} + +func ExampleNewWebhook() { + bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken") + if err != nil { + panic(err) + } + + bot.Debug = true + + fmt.Printf("Authorized on account %s", bot.Self.UserName) + + wh, err := tgbotapi.NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, tgbotapi.FilePath("cert.pem")) + + if err != nil { + panic(err) + } + + _, err = bot.Request(wh) + + if err != nil { + panic(err) + } + + info, err := bot.GetWebhookInfo() + + if err != nil { + panic(err) + } + + if info.LastErrorDate != 0 { + fmt.Printf("failed to set webhook: %s", info.LastErrorMessage) + } + + updates := bot.ListenForWebhook("/" + bot.Token) + go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil) + + for update := range updates { + fmt.Printf("%+v\n", update) + } +} + +func ExampleWebhookHandler() { + bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken") + if err != nil { + panic(err) + } + + bot.Debug = true + + fmt.Printf("Authorized on account %s", bot.Self.UserName) + + wh, err := tgbotapi.NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, tgbotapi.FilePath("cert.pem")) + + if err != nil { + panic(err) + } + + _, err = bot.Request(wh) + if err != nil { + panic(err) + } + info, err := bot.GetWebhookInfo() + if err != nil { + panic(err) + } + if info.LastErrorDate != 0 { + fmt.Printf("[Telegram callback failed]%s", info.LastErrorMessage) + } + + http.HandleFunc("/"+bot.Token, func(w http.ResponseWriter, r *http.Request) { + update, err := bot.HandleUpdate(r) + if err != nil { + fmt.Printf("%+v\n", err.Error()) + } else { + fmt.Printf("%+v\n", *update) + } + }) + + go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil) +} + +func ExampleInlineConfig() { + bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken") // create new bot + if err != nil { + panic(err) + } + + fmt.Printf("Authorized on account %s", bot.Self.UserName) + + u := tgbotapi.NewUpdate(0) + u.Timeout = 60 + + updates := bot.GetUpdatesChan(u) + + for update := range updates { + if update.InlineQuery == nil { // if no inline query, ignore it + continue + } + + article := tgbotapi.NewInlineQueryResultArticle(update.InlineQuery.ID, "Echo", update.InlineQuery.Query) + article.Description = update.InlineQuery.Query + + inlineConf := tgbotapi.InlineConfig{ + InlineQueryID: update.InlineQuery.ID, + IsPersonal: true, + CacheTime: 0, + Results: []interface{}{article}, + } + + if _, err := bot.Request(inlineConf); err != nil { + fmt.Println(err) + } + } +} + +func TestDeleteMessage(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewMessage(ChatID, "A test message from the test library in telegram-bot-api") + msg.ParseMode = tgbotapi.ModeMarkdown + message, _ := bot.Send(msg) + + deleteMessageConfig := tgbotapi.DeleteMessageConfig{ + BaseChatMessage: tgbotapi.BaseChatMessage{ + ChatConfig: tgbotapi.ChatConfig{ + ChatID: message.Chat.ID, + }, + MessageID: message.MessageID, + }, + } + _, err := bot.Request(deleteMessageConfig) + + if err != nil { + t.Error(err) + } +} + +func TestPinChatMessage(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api") + msg.ParseMode = tgbotapi.ModeMarkdown + message, _ := bot.Send(msg) + + pinChatMessageConfig := tgbotapi.PinChatMessageConfig{ + BaseChatMessage: tgbotapi.BaseChatMessage{ + ChatConfig: tgbotapi.ChatConfig{ + ChatID: ChatID, + }, + MessageID: message.MessageID, + }, + DisableNotification: false, + } + _, err := bot.Request(pinChatMessageConfig) + + if err != nil { + t.Error(err) + } +} + +func TestUnpinChatMessage(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api") + msg.ParseMode = tgbotapi.ModeMarkdown + message, err := bot.Send(msg) + require.NoError(t, err) + + // We need pin message to unpin something + pinChatMessageConfig := tgbotapi.PinChatMessageConfig{ + BaseChatMessage: tgbotapi.BaseChatMessage{ + ChatConfig: tgbotapi.ChatConfig{ + ChatID: message.Chat.ID, + }, + MessageID: message.MessageID, + }, + DisableNotification: false, + } + + _, err = bot.Request(pinChatMessageConfig) + require.NoError(t, err) + + unpinChatMessageConfig := tgbotapi.UnpinChatMessageConfig{ + BaseChatMessage: tgbotapi.BaseChatMessage{ + ChatConfig: tgbotapi.ChatConfig{ + ChatID: message.Chat.ID, + }, + MessageID: message.MessageID, + }, + } + + _, err = bot.Request(unpinChatMessageConfig) + require.NoError(t, err) +} + +func TestUnpinAllChatMessages(t *testing.T) { + bot, _ := getBot(t) + + msg := tgbotapi.NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api") + msg.ParseMode = tgbotapi.ModeMarkdown + message, _ := bot.Send(msg) + + pinChatMessageConfig := tgbotapi.PinChatMessageConfig{ + BaseChatMessage: tgbotapi.BaseChatMessage{ + ChatConfig: tgbotapi.ChatConfig{ + ChatID: message.Chat.ID, + }, + MessageID: message.MessageID, + }, + DisableNotification: true, + } + + _, err := bot.Request(pinChatMessageConfig) + require.NoError(t, err) + + unpinAllChatMessagesConfig := tgbotapi.UnpinAllChatMessagesConfig{ + ChatConfig: tgbotapi.ChatConfig{ChatID: message.Chat.ID}, + } + + _, err = bot.Request(unpinAllChatMessagesConfig) + require.NoError(t, err) +} + +func TestPolls(t *testing.T) { + bot, _ := getBot(t) + + poll := tgbotapi.NewPoll(SupergroupChatID, "Are polls working?", "Yes", "No") + + msg, err := bot.Send(poll) + if err != nil { + t.Error(err) + } + + result, err := bot.StopPoll(tgbotapi.NewStopPoll(SupergroupChatID, msg.MessageID)) + if err != nil { + t.Error(err) + } + + if result.Question != "Are polls working?" { + t.Error("Poll question did not match") + } + + if !result.IsClosed { + t.Error("Poll did not end") + } + + if result.Options[0].Text != "Yes" || result.Options[0].VoterCount != 0 || result.Options[1].Text != "No" || result.Options[1].VoterCount != 0 { + t.Error("Poll options were incorrect") + } +} + +// TODO: TG reports this as unsupported +func TestSendDice(t *testing.T) { + bot, err := getBot(t) + require.NoError(t, err) + + dice := tgbotapi.NewDice(ChatID) + + msg, err := bot.Send(dice) + require.NoError(t, err) + require.NotNil(t, msg.Dice) +} + +func TestCommands(t *testing.T) { + bot, _ := getBot(t) + + setCommands := tgbotapi.NewSetMyCommands(tgbotapi.BotCommand{ + Command: "test", + Description: "a test command", + }) + + if _, err := bot.Request(setCommands); err != nil { + t.Error("Unable to set commands") + } + + commands, err := bot.GetMyCommands() + if err != nil { + t.Error("Unable to get commands") + } + + if len(commands) != 1 { + t.Error("Incorrect number of commands returned") + } + + if commands[0].Command != "test" || commands[0].Description != "a test command" { + t.Error("Commands were incorrectly set") + } + + setCommands = tgbotapi.NewSetMyCommandsWithScope(tgbotapi.NewBotCommandScopeAllPrivateChats(), tgbotapi.BotCommand{ + Command: "private", + Description: "a private command", + }) + + if _, err := bot.Request(setCommands); err != nil { + t.Error("Unable to set commands") + } + + commands, err = bot.GetMyCommandsWithConfig(tgbotapi.NewGetMyCommandsWithScope(tgbotapi.NewBotCommandScopeAllPrivateChats())) + if err != nil { + t.Error("Unable to get commands") + } + + if len(commands) != 1 { + t.Error("Incorrect number of commands returned") + } + + if commands[0].Command != "private" || commands[0].Description != "a private command" { + t.Error("Commands were incorrectly set") + } +} + +// TODO: figure out why test is failing +// +// func TestEditMessageMedia(t *testing.T) { +// bot, _ := getBot(t) + +// msg := NewPhoto(ChatID, "./image.jpg") +// msg.Caption = "Test" +// m, err := bot.Send(msg) + +// if err != nil { +// t.Error(err) +// } + +// edit := EditMessageMediaConfig{ +// BaseEdit: BaseEdit{ +// ChatID: ChatID, +// MessageID: m.MessageID, +// }, +// Media: NewInputMediaVideo(FilePath("./video.mp4")), +// } + +// _, err = bot.Request(edit) +// if err != nil { +// t.Error(err) +// } +// } From 18ddf275ef7bad5980caea8d014360a1bb3452f3 Mon Sep 17 00:00:00 2001 From: Ilja Lapkovskis Date: Thu, 18 Jan 2024 22:47:57 +0200 Subject: [PATCH 02/12] Bump go version used for tests --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 48b2859..a94ff54 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v2 with: - go-version: ^1.15 + go-version: ^1.21 id: go - name: Check out code into the Go module directory From f6bd2d0113a60cb268c8045dc4bd19f313166d36 Mon Sep 17 00:00:00 2001 From: Ilja Lapkovskis Date: Fri, 19 Jan 2024 17:40:39 +0200 Subject: [PATCH 03/12] Move sensitive credentials to the secrets --- .env | 6 ++++ .github/workflows/integration_tests.yml | 36 +++++++++++++++++++ .../workflows/{test.yml => unit_tests.yml} | 2 +- bot_test.go | 28 +++------------ tests/bot_integration_test.go | 32 ++++++++++++++--- 5 files changed, 74 insertions(+), 30 deletions(-) create mode 100644 .env create mode 100644 .github/workflows/integration_tests.yml rename .github/workflows/{test.yml => unit_tests.yml} (92%) diff --git a/.env b/.env new file mode 100644 index 0000000..30f3f41 --- /dev/null +++ b/.env @@ -0,0 +1,6 @@ +# Env vars used to run integration tests with Telegram Bot API +TELEGRAM_TESTBOT_TOKEN= +TELEGRAM_SUPERGROUP_CHAT_ID= +TELEGRAM_CHANNEL= +TELEGRAM_CHAT_ID= +TELEGRAM_REPLY_TO_MESSAGE_ID= \ No newline at end of file diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml new file mode 100644 index 0000000..4a77490 --- /dev/null +++ b/.github/workflows/integration_tests.yml @@ -0,0 +1,36 @@ +name: Integration Tests + +on: + push: + branches: + - master + - develop + pull_request: + branches: + - master +jobs: + build: + name: Test + runs-on: ubuntu-latest + env: + TELEGRAM_TESTBOT_TOKEN=${{ secrets.TELEGRAM_TESTBOT_TOKEN }} + steps: + - name: Set up Go 1.x + uses: actions/setup-go@v2 + with: + go-version: ^1.21 + id: go + + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + + - name: Build + run: go build -v . + + - name: Test + run: go test -coverprofile=coverage.out -covermode=atomic -v tests/. + + - name: Upload coverage report + uses: codecov/codecov-action@v1 + with: + file: ./coverage.out diff --git a/.github/workflows/test.yml b/.github/workflows/unit_tests.yml similarity index 92% rename from .github/workflows/test.yml rename to .github/workflows/unit_tests.yml index a94ff54..8e1550c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/unit_tests.yml @@ -1,4 +1,4 @@ -name: Test +name: Unit Tests on: push: diff --git a/bot_test.go b/bot_test.go index e67f69c..a9d1550 100644 --- a/bot_test.go +++ b/bot_test.go @@ -12,32 +12,12 @@ import ( ) const ( - TestToken = "153667468:AAHlSHlMqSt1f_uFmVRJbm5gntu2HI4WW8I" - ChatID = 76918703 - Channel = "@tgbotapitest" - SupergroupChatID = -1001120141283 - ReplyToMessageID = 35 - ExistingPhotoFileID = "AgACAgIAAxkDAAEBFUZhIALQ9pZN4BUe8ZSzUU_2foSo1AACnrMxG0BucEhezsBWOgcikQEAAwIAA20AAyAE" - ExistingDocumentFileID = "BQADAgADOQADjMcoCcioX1GrDvp3Ag" - ExistingAudioFileID = "BQADAgADRgADjMcoCdXg3lSIN49lAg" - ExistingVoiceFileID = "AwADAgADWQADjMcoCeul6r_q52IyAg" - ExistingVideoFileID = "BAADAgADZgADjMcoCav432kYe0FRAg" - ExistingVideoNoteFileID = "DQADAgADdQAD70cQSUK41dLsRMqfAg" - ExistingStickerFileID = "BQADAgADcwADjMcoCbdl-6eB--YPAg" + TestToken = "153667468:AAHlSHlMqSt1f_uFmVRJbm5gntu2HI4WW8I" + ChatID = 111 + SupergroupChatID = -1111 + ReplyToMessageID = 1 ) -type testLogger struct { - t *testing.T -} - -func (t testLogger) Println(v ...interface{}) { - t.t.Log(v...) -} - -func (t testLogger) Printf(format string, v ...interface{}) { - t.t.Logf(format, v...) -} - func prepareHttpClient(t *testing.T) *MockHTTPClient { ctrl := gomock.NewController(t) httpMock := NewMockHTTPClient(ctrl) diff --git a/tests/bot_integration_test.go b/tests/bot_integration_test.go index f21c691..ac0de31 100644 --- a/tests/bot_integration_test.go +++ b/tests/bot_integration_test.go @@ -4,6 +4,7 @@ import ( "fmt" "net/http" "os" + "strconv" "testing" "time" @@ -13,11 +14,6 @@ import ( ) const ( - TestToken = "6152026236:AAHccoTeFxTezeSceAOKRMZW_A5vaIFo4aI" - ChatID = 6064981043 - Channel = "@testapiintegration" - SupergroupChatID = -1002055786965 - ReplyToMessageID = 1 ExistingPhotoFileID = "AgACAgIAAxkDAAEBFUZhIALQ9pZN4BUe8ZSzUU_2foSo1AACnrMxG0BucEhezsBWOgcikQEAAwIAA20AAyAE" ExistingDocumentFileID = "BQADAgADOQADjMcoCcioX1GrDvp3Ag" ExistingAudioFileID = "BQADAgADRgADjMcoCdXg3lSIN49lAg" @@ -27,6 +23,32 @@ const ( ExistingStickerFileID = "BQADAgADcwADjMcoCbdl-6eB--YPAg" ) +var ( + TestToken string + Channel string + ChatID int64 + SupergroupChatID int64 + ReplyToMessageID int +) + +func init() { + var err error + TestToken = os.Getenv("TELEGRAM_TESTBOT_TOKEN") + SupergroupChatID, err = strconv.ParseInt(os.Getenv("TELEGRAM_SUPERGROUP_CHAT_ID"), 10, 64) + if err != nil { + panic(err) + } + Channel = os.Getenv("TELEGRAM_CHANNEL") + ChatID, err = strconv.ParseInt(os.Getenv("TELEGRAM_CHAT_ID"), 10, 64) + if err != nil { + panic(err) + } + ReplyToMessageID, err = strconv.Atoi(os.Getenv("TELEGRAM_REPLY_TO_MESSAGE_ID")) + if err != nil { + panic(err) + } +} + type testLogger struct { t *testing.T } From 61382545e674130da6c4181535c145e58212970d Mon Sep 17 00:00:00 2001 From: Ilja Lapkovskis Date: Fri, 19 Jan 2024 17:43:08 +0200 Subject: [PATCH 04/12] Pass envvars for integration tests from secrets.: --- .github/workflows/integration_tests.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index 4a77490..0d454d8 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -13,7 +13,11 @@ jobs: name: Test runs-on: ubuntu-latest env: - TELEGRAM_TESTBOT_TOKEN=${{ secrets.TELEGRAM_TESTBOT_TOKEN }} + TELEGRAM_TESTBOT_TOKEN: ${{ secrets.TELEGRAM_TESTBOT_TOKEN }} + TELEGRAM_CHANNEL: ${{ secrets.TELEGRAM_CHANNEL }} + TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }} + TELEGRAM_REPLY_TO_MESSAGE_ID: ${{ secrets.TELEGRAM_REPLY_TO_MESSAGE_ID }} + TELEGRAM_SUPERGROUP_CHAT_ID: ${{ secrets.TELEGRAM_SUPERGROUP_CHAT_ID }} steps: - name: Set up Go 1.x uses: actions/setup-go@v2 From d75067e4310aaa7e18020850592c1e399823d660 Mon Sep 17 00:00:00 2001 From: Ilja Lapkovskis Date: Fri, 19 Jan 2024 17:47:53 +0200 Subject: [PATCH 05/12] Add .env to .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index d3083e5..b76b94f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ coverage.out tmp/ book/ .vscode/ + +.env \ No newline at end of file From 7dcae0346000efe76767d56833cb1e161bec1c8d Mon Sep 17 00:00:00 2001 From: Ilja Lapkovskis Date: Fri, 19 Jan 2024 17:48:13 +0200 Subject: [PATCH 06/12] Adjust integration test path --- .github/workflows/integration_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index 0d454d8..8577c1d 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -32,7 +32,7 @@ jobs: run: go build -v . - name: Test - run: go test -coverprofile=coverage.out -covermode=atomic -v tests/. + run: go test -coverprofile=coverage.out -covermode=atomic -v ./tests/. - name: Upload coverage report uses: codecov/codecov-action@v1 From cf24606853e2923dccec08017d2e0fe4bf5d4f27 Mon Sep 17 00:00:00 2001 From: Ilja Lapkovskis Date: Fri, 19 Jan 2024 17:51:04 +0200 Subject: [PATCH 07/12] Run units on any branch. Run integration on master push/PR --- .github/workflows/integration_tests.yml | 1 - .github/workflows/unit_tests.yml | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index 8577c1d..c345c73 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -4,7 +4,6 @@ on: push: branches: - master - - develop pull_request: branches: - master diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 8e1550c..22ce96e 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -3,8 +3,7 @@ name: Unit Tests on: push: branches: - - master - - develop + - '**' pull_request: jobs: From eaa9c00f3dc15faff21f67ae31a1e2fed8a92056 Mon Sep 17 00:00:00 2001 From: Ilja Lapkovskis Date: Fri, 19 Jan 2024 19:48:07 +0200 Subject: [PATCH 08/12] Cleanup unit tests. --- bot_test.go | 966 +--------------------------------------------------- 1 file changed, 3 insertions(+), 963 deletions(-) diff --git a/bot_test.go b/bot_test.go index a9d1550..35a5d5a 100644 --- a/bot_test.go +++ b/bot_test.go @@ -12,7 +12,7 @@ import ( ) const ( - TestToken = "153667468:AAHlSHlMqSt1f_uFmVRJbm5gntu2HI4WW8I" + TestToken = "ThisIsATestTokenNoMatterWhatItContains" ChatID = 111 SupergroupChatID = -1111 ReplyToMessageID = 1 @@ -35,12 +35,9 @@ func expectGetMe(t *testing.T, c *MockHTTPClient) { }) } -func TestNewBotAPI_empty_token(t *testing.T) { +func TestNewBotInstance_WithEmptyToken(t *testing.T) { _, err := NewBotAPI("") - - if err == nil { - t.Error(err) - } + require.Error(t, err) } func isRequestValid(r *http.Request, token, path string) bool { @@ -193,17 +190,6 @@ func TestSendWithMessageReply(t *testing.T) { require.NoError(t, err) } -//func TestSendWithMessageForward(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewForward(ChatID, ChatID, ReplyToMessageID) -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} - func TestCopyMessage(t *testing.T) { client := prepareHttpClient(t) defer client.ctrl.Finish() @@ -260,952 +246,6 @@ func TestCopyMessage(t *testing.T) { require.Equal(t, messageID.MessageID, message.MessageID) } -//func TestSendWithNewPhoto(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewPhoto(ChatID, FilePath("tests/image.jpg")) -// msg.Caption = "Test" -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithNewPhotoWithFileBytes(t *testing.T) { -// bot, _ := configureBot(t) -// -// data, _ := os.ReadFile("tests/image.jpg") -// b := FileBytes{Name: "image.jpg", Bytes: data} -// -// msg := NewPhoto(ChatID, b) -// msg.Caption = "Test" -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithNewPhotoWithFileReader(t *testing.T) { -// bot, _ := configureBot(t) -// -// f, _ := os.Open("tests/image.jpg") -// reader := FileReader{Name: "image.jpg", Reader: f} -// -// msg := NewPhoto(ChatID, reader) -// msg.Caption = "Test" -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithNewPhotoReply(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewPhoto(ChatID, FilePath("tests/image.jpg")) -// msg.ReplyParameters.MessageID = ReplyToMessageID -// -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendNewPhotoToChannel(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewPhotoToChannel(Channel, FilePath("tests/image.jpg")) -// msg.Caption = "Test" -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// t.Fail() -// } -//} -// -//func TestSendNewPhotoToChannelFileBytes(t *testing.T) { -// bot, _ := configureBot(t) -// -// data, _ := os.ReadFile("tests/image.jpg") -// b := FileBytes{Name: "image.jpg", Bytes: data} -// -// msg := NewPhotoToChannel(Channel, b) -// msg.Caption = "Test" -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// t.Fail() -// } -//} -// -//func TestSendNewPhotoToChannelFileReader(t *testing.T) { -// bot, _ := configureBot(t) -// -// f, _ := os.Open("tests/image.jpg") -// reader := FileReader{Name: "image.jpg", Reader: f} -// -// msg := NewPhotoToChannel(Channel, reader) -// msg.Caption = "Test" -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// t.Fail() -// } -//} -// -//func TestSendWithExistingPhoto(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewPhoto(ChatID, FileID(ExistingPhotoFileID)) -// msg.Caption = "Test" -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithNewDocument(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewDocument(ChatID, FilePath("tests/image.jpg")) -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithNewDocumentAndThumb(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewDocument(ChatID, FilePath("tests/voice.ogg")) -// msg.Thumb = FilePath("tests/image.jpg") -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithExistingDocument(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewDocument(ChatID, FileID(ExistingDocumentFileID)) -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithNewAudio(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewAudio(ChatID, FilePath("tests/audio.mp3")) -// msg.Title = "TEST" -// msg.Duration = 10 -// msg.Performer = "TEST" -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithExistingAudio(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewAudio(ChatID, FileID(ExistingAudioFileID)) -// msg.Title = "TEST" -// msg.Duration = 10 -// msg.Performer = "TEST" -// -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithNewVoice(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewVoice(ChatID, FilePath("tests/voice.ogg")) -// msg.Duration = 10 -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithExistingVoice(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewVoice(ChatID, FileID(ExistingVoiceFileID)) -// msg.Duration = 10 -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithContact(t *testing.T) { -// bot, _ := configureBot(t) -// -// contact := NewContact(ChatID, "5551234567", "Test") -// -// if _, err := bot.Send(contact); err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithLocation(t *testing.T) { -// bot, _ := configureBot(t) -// -// _, err := bot.Send(NewLocation(ChatID, 40, 40)) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithVenue(t *testing.T) { -// bot, _ := configureBot(t) -// -// venue := NewVenue(ChatID, "A Test Location", "123 Test Street", 40, 40) -// -// if _, err := bot.Send(venue); err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithNewVideo(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewVideo(ChatID, FilePath("tests/video.mp4")) -// msg.Duration = 10 -// msg.Caption = "TEST" -// -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithExistingVideo(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewVideo(ChatID, FileID(ExistingVideoFileID)) -// msg.Duration = 10 -// msg.Caption = "TEST" -// -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithNewVideoNote(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewVideoNote(ChatID, 240, FilePath("tests/videonote.mp4")) -// msg.Duration = 10 -// -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithExistingVideoNote(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewVideoNote(ChatID, 240, FileID(ExistingVideoNoteFileID)) -// msg.Duration = 10 -// -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithNewSticker(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewSticker(ChatID, FilePath("tests/image.jpg")) -// -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithExistingSticker(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewSticker(ChatID, FileID(ExistingStickerFileID)) -// -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithNewStickerAndKeyboardHide(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewSticker(ChatID, FilePath("tests/image.jpg")) -// msg.ReplyMarkup = ReplyKeyboardRemove{ -// RemoveKeyboard: true, -// Selective: false, -// } -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithExistingStickerAndKeyboardHide(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewSticker(ChatID, FileID(ExistingStickerFileID)) -// msg.ReplyMarkup = ReplyKeyboardRemove{ -// RemoveKeyboard: true, -// Selective: false, -// } -// -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendWithDice(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewDice(ChatID) -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// t.Fail() -// } -// -//} -// -//func TestSendWithDiceWithEmoji(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewDiceWithEmoji(ChatID, "🏀") -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// t.Fail() -// } -// -//} -// -//func TestGetFile(t *testing.T) { -// bot, _ := configureBot(t) -// -// file := FileConfig{ -// FileID: ExistingPhotoFileID, -// } -// -// _, err := bot.GetFile(file) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSendChatConfig(t *testing.T) { -// bot, _ := configureBot(t) -// -// _, err := bot.Request(NewChatAction(ChatID, ChatTyping)) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//// TODO: identify why this isn't working -//// func TestSendEditMessage(t *testing.T) { -//// bot, _ := configureBot(t) -// -//// msg, err := bot.Send(NewMessage(ChatID, "Testing editing.")) -//// if err != nil { -//// t.Error(err) -//// } -// -//// edit := EditMessageTextConfig{ -//// BaseEdit: BaseEdit{ -//// ChatID: ChatID, -//// MessageID: msg.MessageID, -//// }, -//// Text: "Updated text.", -//// } -// -//// _, err = bot.Send(edit) -//// if err != nil { -//// t.Error(err) -//// } -//// } -// -//func TestGetUserProfilePhotos(t *testing.T) { -// bot, _ := configureBot(t) -// -// _, err := bot.GetUserProfilePhotos(NewUserProfilePhotos(ChatID)) -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestSetWebhookWithCert(t *testing.T) { -// bot, _ := configureBot(t) -// -// time.Sleep(time.Second * 2) -// -// bot.Request(DeleteWebhookConfig{}) -// -// wh, err := NewWebhookWithCert("https://example.com/tgbotapi-test/"+bot.Token, FilePath("tests/cert.pem")) -// -// if err != nil { -// t.Error(err) -// } -// _, err = bot.Request(wh) -// -// if err != nil { -// t.Error(err) -// } -// -// _, err = bot.GetWebhookInfo() -// -// if err != nil { -// t.Error(err) -// } -// -// bot.Request(DeleteWebhookConfig{}) -//} -// -//func TestSetWebhookWithoutCert(t *testing.T) { -// bot, _ := configureBot(t) -// -// time.Sleep(time.Second * 2) -// -// bot.Request(DeleteWebhookConfig{}) -// -// wh, err := NewWebhook("https://example.com/tgbotapi-test/" + bot.Token) -// -// if err != nil { -// t.Error(err) -// } -// -// _, err = bot.Request(wh) -// -// if err != nil { -// t.Error(err) -// } -// -// info, err := bot.GetWebhookInfo() -// -// if err != nil { -// t.Error(err) -// } -// if info.MaxConnections == 0 { -// t.Errorf("Expected maximum connections to be greater than 0") -// } -// if info.LastErrorDate != 0 { -// t.Errorf("failed to set webhook: %s", info.LastErrorMessage) -// } -// -// bot.Request(DeleteWebhookConfig{}) -//} -// -//func TestSendWithMediaGroupPhotoVideo(t *testing.T) { -// bot, _ := configureBot(t) -// -// cfg := NewMediaGroup(ChatID, []interface{}{ -// NewInputMediaPhoto(FileURL("https://github.com/go-telegram-bot-api/telegram-bot-api/raw/0a3a1c8716c4cd8d26a262af9f12dcbab7f3f28c/tests/image.jpg")), -// NewInputMediaPhoto(FilePath("tests/image.jpg")), -// NewInputMediaVideo(FilePath("tests/video.mp4")), -// }) -// -// messages, err := bot.SendMediaGroup(cfg) -// if err != nil { -// t.Error(err) -// } -// -// if messages == nil { -// t.Error("No received messages") -// } -// -// if len(messages) != len(cfg.Media) { -// t.Errorf("Different number of messages: %d", len(messages)) -// } -//} -// -//func TestSendWithMediaGroupDocument(t *testing.T) { -// bot, _ := configureBot(t) -// -// cfg := NewMediaGroup(ChatID, []interface{}{ -// NewInputMediaDocument(FileURL("https://i.imgur.com/unQLJIb.jpg")), -// NewInputMediaDocument(FilePath("tests/image.jpg")), -// }) -// -// messages, err := bot.SendMediaGroup(cfg) -// if err != nil { -// t.Error(err) -// } -// -// if messages == nil { -// t.Error("No received messages") -// } -// -// if len(messages) != len(cfg.Media) { -// t.Errorf("Different number of messages: %d", len(messages)) -// } -//} -// -//func TestSendWithMediaGroupAudio(t *testing.T) { -// bot, _ := configureBot(t) -// -// cfg := NewMediaGroup(ChatID, []interface{}{ -// NewInputMediaAudio(FilePath("tests/audio.mp3")), -// NewInputMediaAudio(FilePath("tests/audio.mp3")), -// }) -// -// messages, err := bot.SendMediaGroup(cfg) -// if err != nil { -// t.Error(err) -// } -// -// if messages == nil { -// t.Error("No received messages") -// } -// -// if len(messages) != len(cfg.Media) { -// t.Errorf("Different number of messages: %d", len(messages)) -// } -//} -// -//func ExampleNewBotAPI() { -// bot, err := NewBotAPI("MyAwesomeBotToken") -// if err != nil { -// panic(err) -// } -// -// bot.Debug = true -// -// log.Printf("Authorized on account %s", bot.Self.UserName) -// -// u := NewUpdate(0) -// u.Timeout = 60 -// -// updates := bot.GetUpdatesChan(u) -// -// // Optional: wait for updates and clear them if you don't want to handle -// // a large backlog of old messages -// time.Sleep(time.Millisecond * 500) -// updates.Clear() -// -// for update := range updates { -// if update.Message == nil { -// continue -// } -// -// log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text) -// -// msg := NewMessage(update.Message.Chat.ID, update.Message.Text) -// msg.ReplyParameters.MessageID = update.Message.MessageID -// -// bot.Send(msg) -// } -//} -// -//func ExampleNewWebhook() { -// bot, err := NewBotAPI("MyAwesomeBotToken") -// if err != nil { -// panic(err) -// } -// -// bot.Debug = true -// -// log.Printf("Authorized on account %s", bot.Self.UserName) -// -// wh, err := NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, FilePath("cert.pem")) -// -// if err != nil { -// panic(err) -// } -// -// _, err = bot.Request(wh) -// -// if err != nil { -// panic(err) -// } -// -// info, err := bot.GetWebhookInfo() -// -// if err != nil { -// panic(err) -// } -// -// if info.LastErrorDate != 0 { -// log.Printf("failed to set webhook: %s", info.LastErrorMessage) -// } -// -// updates := bot.ListenForWebhook("/" + bot.Token) -// go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil) -// -// for update := range updates { -// log.Printf("%+v\n", update) -// } -//} -// -//func ExampleWebhookHandler() { -// bot, err := NewBotAPI("MyAwesomeBotToken") -// if err != nil { -// panic(err) -// } -// -// bot.Debug = true -// -// log.Printf("Authorized on account %s", bot.Self.UserName) -// -// wh, err := NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, FilePath("cert.pem")) -// -// if err != nil { -// panic(err) -// } -// -// _, err = bot.Request(wh) -// if err != nil { -// panic(err) -// } -// info, err := bot.GetWebhookInfo() -// if err != nil { -// panic(err) -// } -// if info.LastErrorDate != 0 { -// log.Printf("[Telegram callback failed]%s", info.LastErrorMessage) -// } -// -// http.HandleFunc("/"+bot.Token, func(w http.ResponseWriter, r *http.Request) { -// update, err := bot.HandleUpdate(r) -// if err != nil { -// log.Printf("%+v\n", err.Error()) -// } else { -// log.Printf("%+v\n", *update) -// } -// }) -// -// go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil) -//} -// -//func ExampleInlineConfig() { -// bot, err := NewBotAPI("MyAwesomeBotToken") // create new bot -// if err != nil { -// panic(err) -// } -// -// log.Printf("Authorized on account %s", bot.Self.UserName) -// -// u := NewUpdate(0) -// u.Timeout = 60 -// -// updates := bot.GetUpdatesChan(u) -// -// for update := range updates { -// if update.InlineQuery == nil { // if no inline query, ignore it -// continue -// } -// -// article := NewInlineQueryResultArticle(update.InlineQuery.ID, "Echo", update.InlineQuery.Query) -// article.Description = update.InlineQuery.Query -// -// inlineConf := InlineConfig{ -// InlineQueryID: update.InlineQuery.ID, -// IsPersonal: true, -// CacheTime: 0, -// Results: []interface{}{article}, -// } -// -// if _, err := bot.Request(inlineConf); err != nil { -// log.Println(err) -// } -// } -//} -// -//func TestDeleteMessage(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewMessage(ChatID, "A test message from the test library in telegram-bot-api") -// msg.ParseMode = ModeMarkdown -// message, _ := bot.Send(msg) -// -// deleteMessageConfig := DeleteMessageConfig{ -// BaseChatMessage: BaseChatMessage{ -// ChatConfig: ChatConfig{ -// ChatID: message.Chat.ID, -// }, -// MessageID: message.MessageID, -// }, -// } -// _, err := bot.Request(deleteMessageConfig) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestPinChatMessage(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api") -// msg.ParseMode = ModeMarkdown -// message, _ := bot.Send(msg) -// -// pinChatMessageConfig := PinChatMessageConfig{ -// BaseChatMessage: BaseChatMessage{ -// ChatConfig: ChatConfig{ -// ChatID: ChatID, -// }, -// MessageID: message.MessageID, -// }, -// DisableNotification: false, -// } -// _, err := bot.Request(pinChatMessageConfig) -// -// if err != nil { -// t.Error(err) -// } -//} -// -//func TestUnpinChatMessage(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api") -// msg.ParseMode = ModeMarkdown -// message, _ := bot.Send(msg) -// -// // We need pin message to unpin something -// pinChatMessageConfig := PinChatMessageConfig{ -// BaseChatMessage: BaseChatMessage{ -// ChatConfig: ChatConfig{ -// ChatID: message.Chat.ID, -// }, -// MessageID: message.MessageID, -// }, -// DisableNotification: false, -// } -// -// if _, err := bot.Request(pinChatMessageConfig); err != nil { -// t.Error(err) -// } -// -// unpinChatMessageConfig := UnpinChatMessageConfig{ -// BaseChatMessage: BaseChatMessage{ -// ChatConfig: ChatConfig{ -// ChatID: message.Chat.ID, -// }, -// MessageID: message.MessageID, -// }, -// } -// -// if _, err := bot.Request(unpinChatMessageConfig); err != nil { -// t.Error(err) -// } -//} -// -//func TestUnpinAllChatMessages(t *testing.T) { -// bot, _ := configureBot(t) -// -// msg := NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api") -// msg.ParseMode = ModeMarkdown -// message, _ := bot.Send(msg) -// -// pinChatMessageConfig := PinChatMessageConfig{ -// BaseChatMessage: BaseChatMessage{ -// ChatConfig: ChatConfig{ -// ChatID: message.Chat.ID, -// }, -// MessageID: message.MessageID, -// }, -// DisableNotification: true, -// } -// -// if _, err := bot.Request(pinChatMessageConfig); err != nil { -// t.Error(err) -// } -// -// unpinAllChatMessagesConfig := UnpinAllChatMessagesConfig{ -// ChatConfig: ChatConfig{ChatID: message.Chat.ID}, -// } -// -// if _, err := bot.Request(unpinAllChatMessagesConfig); err != nil { -// t.Error(err) -// } -//} -// -//func TestPolls(t *testing.T) { -// bot, _ := configureBot(t) -// -// poll := NewPoll(SupergroupChatID, "Are polls working?", "Yes", "No") -// -// msg, err := bot.Send(poll) -// if err != nil { -// t.Error(err) -// } -// -// result, err := bot.StopPoll(NewStopPoll(SupergroupChatID, msg.MessageID)) -// if err != nil { -// t.Error(err) -// } -// -// if result.Question != "Are polls working?" { -// t.Error("Poll question did not match") -// } -// -// if !result.IsClosed { -// t.Error("Poll did not end") -// } -// -// if result.Options[0].Text != "Yes" || result.Options[0].VoterCount != 0 || result.Options[1].Text != "No" || result.Options[1].VoterCount != 0 { -// t.Error("Poll options were incorrect") -// } -//} -// -//func TestSendDice(t *testing.T) { -// bot, _ := configureBot(t) -// -// dice := NewDice(ChatID) -// -// msg, err := bot.Send(dice) -// if err != nil { -// t.Error("Unable to send dice roll") -// } -// -// if msg.Dice == nil { -// t.Error("Dice roll was not received") -// } -//} -// -//func TestCommands(t *testing.T) { -// bot, _ := configureBot(t) -// -// setCommands := NewSetMyCommands(BotCommand{ -// Command: "test", -// Description: "a test command", -// }) -// -// if _, err := bot.Request(setCommands); err != nil { -// t.Error("Unable to set commands") -// } -// -// commands, err := bot.GetMyCommands() -// if err != nil { -// t.Error("Unable to get commands") -// } -// -// if len(commands) != 1 { -// t.Error("Incorrect number of commands returned") -// } -// -// if commands[0].Command != "test" || commands[0].Description != "a test command" { -// t.Error("Commands were incorrectly set") -// } -// -// setCommands = NewSetMyCommandsWithScope(NewBotCommandScopeAllPrivateChats(), BotCommand{ -// Command: "private", -// Description: "a private command", -// }) -// -// if _, err := bot.Request(setCommands); err != nil { -// t.Error("Unable to set commands") -// } -// -// commands, err = bot.GetMyCommandsWithConfig(NewGetMyCommandsWithScope(NewBotCommandScopeAllPrivateChats())) -// if err != nil { -// t.Error("Unable to get commands") -// } -// -// if len(commands) != 1 { -// t.Error("Incorrect number of commands returned") -// } -// -// if commands[0].Command != "private" || commands[0].Description != "a private command" { -// t.Error("Commands were incorrectly set") -// } -//} -// -//// TODO: figure out why test is failing -//// -//// func TestEditMessageMedia(t *testing.T) { -//// bot, _ := configureBot(t) -// -//// msg := NewPhoto(ChatID, "tests/image.jpg") -//// msg.Caption = "Test" -//// m, err := bot.Send(msg) -// -//// if err != nil { -//// t.Error(err) -//// } -// -//// edit := EditMessageMediaConfig{ -//// BaseEdit: BaseEdit{ -//// ChatID: ChatID, -//// MessageID: m.MessageID, -//// }, -//// Media: NewInputMediaVideo(FilePath("tests/video.mp4")), -//// } -// -//// _, err = bot.Request(edit) -//// if err != nil { -//// t.Error(err) -//// } -//// } -// -//func TestPrepareInputMediaForParams(t *testing.T) { -// media := []interface{}{ -// NewInputMediaPhoto(FilePath("tests/image.jpg")), -// NewInputMediaVideo(FileID("test")), -// } -// -// prepared := prepareInputMediaForParams(media) -// -// if media[0].(InputMediaPhoto).Media != FilePath("tests/image.jpg") { -// t.Error("Original media was changed") -// } -// -// if prepared[0].(InputMediaPhoto).Media != fileAttach("attach://file-0") { -// t.Error("New media was not replaced") -// } -// -// if prepared[1].(InputMediaVideo).Media != FileID("test") { -// t.Error("Passthrough value was not the same") -// } -//} - func TestPrepareInputMediaForParams(t *testing.T) { media := []any{ NewInputMediaPhoto(FilePath("./image.jpg")), From 64480f90889e45a514095dd6f1b771e244154b0f Mon Sep 17 00:00:00 2001 From: Ilja Lapkovskis Date: Fri, 19 Jan 2024 23:46:58 +0200 Subject: [PATCH 09/12] Refactor some integration tests. --- tests/bot_integration_test.go | 132 ++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 62 deletions(-) diff --git a/tests/bot_integration_test.go b/tests/bot_integration_test.go index ac0de31..1da8b65 100644 --- a/tests/bot_integration_test.go +++ b/tests/bot_integration_test.go @@ -14,9 +14,7 @@ import ( ) const ( - ExistingPhotoFileID = "AgACAgIAAxkDAAEBFUZhIALQ9pZN4BUe8ZSzUU_2foSo1AACnrMxG0BucEhezsBWOgcikQEAAwIAA20AAyAE" - ExistingDocumentFileID = "BQADAgADOQADjMcoCcioX1GrDvp3Ag" - ExistingAudioFileID = "BQADAgADRgADjMcoCdXg3lSIN49lAg" + ExistingDocumentFileID = "BQACAgQAAxkBAAIBlWWq0525h50qLvTvedniXBoF-0cNAAJNFAACtIdZUaDyZwc4Cj8cNAQ" ExistingVoiceFileID = "AwADAgADWQADjMcoCeul6r_q52IyAg" ExistingVideoFileID = "BAADAgADZgADjMcoCav432kYe0FRAg" ExistingVideoNoteFileID = "DQADAgADdQAD70cQSUK41dLsRMqfAg" @@ -83,8 +81,9 @@ func TestGetUpdates(t *testing.T) { u := tgbotapi.NewUpdate(0) - _, err := bot.GetUpdates(u) + up, err := bot.GetUpdates(u) require.NoError(t, err) + require.NotNil(t, up) } func TestSendWithMessage(t *testing.T) { @@ -170,12 +169,29 @@ func TestSendWithNewPhotoReply(t *testing.T) { } func TestSendNewPhotoToChannel(t *testing.T) { - bot, _ := getBot(t) - - msg := tgbotapi.NewPhotoToChannel(Channel, tgbotapi.FilePath("./image.jpg")) - msg.Caption = "Test" - _, err := bot.Send(msg) + var photoID string + bot, err := getBot(t) require.NoError(t, err) + + t.Run("send photo to channel", func(t *testing.T) { + msg := tgbotapi.NewPhotoToChannel(Channel, tgbotapi.FilePath("./image.jpg")) + msg.Caption = "Test" + m, err := bot.Send(msg) + require.NoError(t, err) + require.NotNil(t, m) + pl := len(m.Photo) > 0 + require.True(t, pl) + photoID = m.Photo[0].FileID + }) + + t.Run("send photo to channel with existing photo", func(t *testing.T) { + msg := tgbotapi.NewPhoto(ChatID, tgbotapi.FileID(photoID)) + msg.Caption = "Test existing" + m, err := bot.Send(msg) + require.NoError(t, err) + require.NotEmpty(t, m) + }) + } func TestSendNewPhotoToChannelFileBytes(t *testing.T) { @@ -198,22 +214,11 @@ func TestSendNewPhotoToChannelFileReader(t *testing.T) { msg := tgbotapi.NewPhotoToChannel(Channel, reader) msg.Caption = "Test" - _, err := bot.Send(msg) + m, err := bot.Send(msg) require.NoError(t, err) -} + require.NotNil(t, m) -// TODO: fix this -//func TestSendWithExistingPhoto(t *testing.T) { -// bot, _ := getBot(t) -// -// msg := tgbotapi.NewPhoto(ChatID, tgbotapi.FileID(ExistingPhotoFileID)) -// msg.Caption = "Test" -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} +} func TestSendWithNewDocument(t *testing.T) { bot, _ := getBot(t) @@ -224,52 +229,56 @@ func TestSendWithNewDocument(t *testing.T) { } func TestSendWithNewDocumentAndThumb(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) msg := tgbotapi.NewDocument(ChatID, tgbotapi.FilePath("./voice.ogg")) msg.Thumb = tgbotapi.FilePath("./image.jpg") - _, err := bot.Send(msg) + m, err := bot.Send(msg) + require.NoError(t, err) + require.NotNil(t, m) + require.NotEmpty(t, m.Document.FileID) + +} + +func TestSendWithExistingDocument(t *testing.T) { + bot, err := getBot(t) + require.NoError(t, err) + + msg := tgbotapi.NewDocument(ChatID, tgbotapi.FileID(ExistingDocumentFileID)) + m, err := bot.Send(msg) + require.NotNil(t, m) require.NoError(t, err) } -// TODO: fix this -//func TestSendWithExistingDocument(t *testing.T) { -// bot, _ := getBot(t) -// -// msg := tgbotapi.NewDocument(ChatID, tgbotapi.FileID(ExistingDocumentFileID)) -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} - -func TestSendWithNewAudio(t *testing.T) { - bot, _ := getBot(t) - - msg := tgbotapi.NewAudio(ChatID, tgbotapi.FilePath("./audio.mp3")) - msg.Title = "TEST" - msg.Duration = 10 - msg.Performer = "TEST" - _, err := bot.Send(msg) +func TestSendWithAudio(t *testing.T) { + var FileID string + bot, err := getBot(t) require.NoError(t, err) -} -// TODO: fix this -//func TestSendWithExistingAudio(t *testing.T) { -// bot, _ := getBot(t) -// -// msg := tgbotapi.NewAudio(ChatID, tgbotapi.FileID(ExistingAudioFileID)) -// msg.Title = "TEST" -// msg.Duration = 10 -// msg.Performer = "TEST" -// -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} + t.Run("send new audio file", func(t *testing.T) { + + msg := tgbotapi.NewAudio(ChatID, tgbotapi.FilePath("./audio.mp3")) + msg.Title = "TEST" + msg.Duration = 10 + msg.Performer = "TEST" + m, err := bot.Send(msg) + require.NotNil(t, m) + require.NoError(t, err) + require.NotEmpty(t, m.Audio.FileID) + FileID = m.Audio.FileID + }) + + t.Run("send existing audio file", func(t *testing.T) { + msgExist := tgbotapi.NewAudio(ChatID, tgbotapi.FileID(FileID)) + msgExist.Title = "TEST EXIST" + msgExist.Duration = 10 + msgExist.Performer = "TEST EXIST" + m, err := bot.Send(msgExist) + require.NotNil(t, m) + require.NoError(t, err) + }) +} func TestSendWithNewVoice(t *testing.T) { bot, _ := getBot(t) @@ -346,7 +355,6 @@ func TestSendWithNewVideo(t *testing.T) { func TestSendWithNewVideoNote(t *testing.T) { bot, _ := getBot(t) - msg := tgbotapi.NewVideoNote(ChatID, 240, tgbotapi.FilePath("./videonote.mp4")) msg.Duration = 10 From 40e1c9b680477b59e41e464d1da66c0984d1048e Mon Sep 17 00:00:00 2001 From: Ilja Lapkovskis Date: Sat, 20 Jan 2024 16:29:08 +0200 Subject: [PATCH 10/12] Separate tests. Finish integration test refactoring --- example_bot.go | 123 ++++++++ tests/bot_integration_test.go | 562 ++++++++++++++-------------------- 2 files changed, 361 insertions(+), 324 deletions(-) create mode 100644 example_bot.go diff --git a/example_bot.go b/example_bot.go new file mode 100644 index 0000000..b268f26 --- /dev/null +++ b/example_bot.go @@ -0,0 +1,123 @@ +package tgbotapi + +import ( + "fmt" + "net/http" + "time" +) + +func ExampleNewBotAPI() { + bot, err := NewBotAPI("MyAwesomeBotToken") + if err != nil { + panic(err) + } + + bot.Debug = true + + fmt.Printf("Authorized on account %s", bot.Self.UserName) + u := NewUpdate(0) + u.Timeout = 60 + + updates := bot.GetUpdatesChan(u) + + // Optional: wait for updates and clear them if you don't want to handle + // a large backlog of old messages + time.Sleep(time.Millisecond * 500) + updates.Clear() + + for update := range updates { + if update.Message == nil { + continue + } + + fmt.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text) + + msg := NewMessage(update.Message.Chat.ID, update.Message.Text) + msg.ReplyParameters.MessageID = update.Message.MessageID + + _, err := bot.Send(msg) + if err != nil { + panic(err) + } + } +} + +func ExampleNewWebhook() { + bot, err := NewBotAPI("MyAwesomeBotToken") + if err != nil { + panic(err) + } + + bot.Debug = true + + fmt.Printf("Authorized on account %s", bot.Self.UserName) + + wh, err := NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, FilePath("cert.pem")) + + if err != nil { + panic(err) + } + + _, err = bot.Request(wh) + + if err != nil { + panic(err) + } + + info, err := bot.GetWebhookInfo() + + if err != nil { + panic(err) + } + + if info.LastErrorDate != 0 { + fmt.Printf("failed to set webhook: %s", info.LastErrorMessage) + } + + updates := bot.ListenForWebhook("/" + bot.Token) + go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil) + + for update := range updates { + fmt.Printf("%+v\n", update) + } +} + +func ExampleWebhookHandler() { + bot, err := NewBotAPI("MyAwesomeBotToken") + if err != nil { + panic(err) + } + + bot.Debug = true + + fmt.Printf("Authorized on account %s", bot.Self.UserName) + + wh, err := NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, FilePath("cert.pem")) + + if err != nil { + panic(err) + } + + _, err = bot.Request(wh) + if err != nil { + panic(err) + } + info, err := bot.GetWebhookInfo() + if err != nil { + panic(err) + } + if info.LastErrorDate != 0 { + fmt.Printf("[Telegram callback failed]%s", info.LastErrorMessage) + } + + http.HandleFunc("/"+bot.Token, func(w http.ResponseWriter, r *http.Request) { + update, err := bot.HandleUpdate(r) + if err != nil { + fmt.Printf("%+v\n", err.Error()) + } else { + fmt.Printf("%+v\n", *update) + } + }) + + go http.ListenAndServeTLS("0.0.0.0:8443", "./tests/cert.pem", "./tests/key.pem", nil) +} diff --git a/tests/bot_integration_test.go b/tests/bot_integration_test.go index 1da8b65..3f8e5dd 100644 --- a/tests/bot_integration_test.go +++ b/tests/bot_integration_test.go @@ -2,7 +2,6 @@ package tests import ( "fmt" - "net/http" "os" "strconv" "testing" @@ -13,20 +12,13 @@ import ( "github.com/eli-l/telegram-bot-api/v5" ) -const ( - ExistingDocumentFileID = "BQACAgQAAxkBAAIBlWWq0525h50qLvTvedniXBoF-0cNAAJNFAACtIdZUaDyZwc4Cj8cNAQ" - ExistingVoiceFileID = "AwADAgADWQADjMcoCeul6r_q52IyAg" - ExistingVideoFileID = "BAADAgADZgADjMcoCav432kYe0FRAg" - ExistingVideoNoteFileID = "DQADAgADdQAD70cQSUK41dLsRMqfAg" - ExistingStickerFileID = "BQADAgADcwADjMcoCbdl-6eB--YPAg" -) - var ( TestToken string Channel string ChatID int64 SupergroupChatID int64 ReplyToMessageID int + Debug = false ) func init() { @@ -62,7 +54,7 @@ func (t testLogger) Printf(format string, v ...interface{}) { func getBot(t *testing.T) (*tgbotapi.BotAPI, error) { bot, err := tgbotapi.NewBotAPI(TestToken) require.NoError(t, err) - bot.Debug = true + bot.Debug = Debug logger := testLogger{t} err = tgbotapi.SetLogger(logger) @@ -72,13 +64,14 @@ func getBot(t *testing.T) (*tgbotapi.BotAPI, error) { } func TestNewBotAPI_notoken(t *testing.T) { - _, err := tgbotapi.NewBotAPI("") + bot, err := tgbotapi.NewBotAPI("") require.Error(t, err) + require.Nil(t, bot) } func TestGetUpdates(t *testing.T) { - bot, _ := getBot(t) - + bot, err := getBot(t) + require.NoError(t, err) u := tgbotapi.NewUpdate(0) up, err := bot.GetUpdates(u) @@ -87,33 +80,40 @@ func TestGetUpdates(t *testing.T) { } func TestSendWithMessage(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) msg := tgbotapi.NewMessage(ChatID, "A test message from the test library in telegram-bot-api") msg.ParseMode = tgbotapi.ModeMarkdown - _, err := bot.Send(msg) + m, err := bot.Send(msg) require.NoError(t, err) + require.NotNil(t, m) } func TestSendWithMessageReply(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) msg := tgbotapi.NewMessage(ChatID, "A test message from the test library in telegram-bot-api") msg.ReplyParameters.MessageID = ReplyToMessageID - _, err := bot.Send(msg) + m, err := bot.Send(msg) require.NoError(t, err) + require.NotNil(t, m) } func TestSendWithMessageForward(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) msg := tgbotapi.NewForward(ChatID, ChatID, ReplyToMessageID) - _, err := bot.Send(msg) + m, err := bot.Send(msg) require.NoError(t, err) + require.NotNil(t, m) } func TestCopyMessage(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) msg := tgbotapi.NewMessage(ChatID, "A test message from the test library in telegram-bot-api") message, err := bot.Send(msg) @@ -126,12 +126,14 @@ func TestCopyMessage(t *testing.T) { } func TestSendWithNewPhoto(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) msg := tgbotapi.NewPhoto(ChatID, tgbotapi.FilePath("./image.jpg")) msg.Caption = "Test" - _, err := bot.Send(msg) + m, err := bot.Send(msg) require.NoError(t, err) + require.NotNil(t, m) } func TestSendWithNewPhotoWithFileBytes(t *testing.T) { @@ -147,25 +149,30 @@ func TestSendWithNewPhotoWithFileBytes(t *testing.T) { } func TestSendWithNewPhotoWithFileReader(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) - f, _ := os.Open("./image.jpg") + f, err := os.Open("./image.jpg") + require.NoError(t, err) reader := tgbotapi.FileReader{Name: "image.jpg", Reader: f} msg := tgbotapi.NewPhoto(ChatID, reader) msg.Caption = "Test" - _, err := bot.Send(msg) + m, err := bot.Send(msg) require.NoError(t, err) + require.NotNil(t, m) } func TestSendWithNewPhotoReply(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) msg := tgbotapi.NewPhoto(ChatID, tgbotapi.FilePath("./image.jpg")) msg.ReplyParameters.MessageID = ReplyToMessageID - _, err := bot.Send(msg) + m, err := bot.Send(msg) require.NoError(t, err) + require.NotNil(t, m) } func TestSendNewPhotoToChannel(t *testing.T) { @@ -185,6 +192,7 @@ func TestSendNewPhotoToChannel(t *testing.T) { }) t.Run("send photo to channel with existing photo", func(t *testing.T) { + require.NotEmpty(t, photoID) msg := tgbotapi.NewPhoto(ChatID, tgbotapi.FileID(photoID)) msg.Caption = "Test existing" m, err := bot.Send(msg) @@ -195,21 +203,26 @@ func TestSendNewPhotoToChannel(t *testing.T) { } func TestSendNewPhotoToChannelFileBytes(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) - data, _ := os.ReadFile("./image.jpg") + data, err := os.ReadFile("./image.jpg") + require.NoError(t, err) b := tgbotapi.FileBytes{Name: "image.jpg", Bytes: data} msg := tgbotapi.NewPhotoToChannel(Channel, b) msg.Caption = "Test" - _, err := bot.Send(msg) + m, err := bot.Send(msg) require.NoError(t, err) + require.NotNil(t, m) } func TestSendNewPhotoToChannelFileReader(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) - f, _ := os.Open("./image.jpg") + f, err := os.Open("./image.jpg") + require.NoError(t, err) reader := tgbotapi.FileReader{Name: "image.jpg", Reader: f} msg := tgbotapi.NewPhotoToChannel(Channel, reader) @@ -221,34 +234,52 @@ func TestSendNewPhotoToChannelFileReader(t *testing.T) { } func TestSendWithNewDocument(t *testing.T) { - bot, _ := getBot(t) - - msg := tgbotapi.NewDocument(ChatID, tgbotapi.FilePath("./image.jpg")) - _, err := bot.Send(msg) + var FileID string + bot, err := getBot(t) require.NoError(t, err) + + t.Run("send new document", func(t *testing.T) { + msg := tgbotapi.NewDocument(ChatID, tgbotapi.FilePath("./image.jpg")) + m, err := bot.Send(msg) + require.NoError(t, err) + require.NotNil(t, m) + require.NotEmpty(t, m.Document.FileID) + FileID = m.Document.FileID + }) + + t.Run("get document", func(t *testing.T) { + f, err := bot.GetFile(tgbotapi.FileConfig{FileID: FileID}) + require.NoError(t, err) + require.NotNil(t, f) + require.Equal(t, FileID, f.FileID) + }) + } func TestSendWithNewDocumentAndThumb(t *testing.T) { + var FileID string + bot, err := getBot(t) require.NoError(t, err) - msg := tgbotapi.NewDocument(ChatID, tgbotapi.FilePath("./voice.ogg")) - msg.Thumb = tgbotapi.FilePath("./image.jpg") - m, err := bot.Send(msg) - require.NoError(t, err) - require.NotNil(t, m) - require.NotEmpty(t, m.Document.FileID) + t.Run("send new document and thumb", func(t *testing.T) { + msg := tgbotapi.NewDocument(ChatID, tgbotapi.FilePath("./voice.ogg")) + msg.Thumb = tgbotapi.FilePath("./image.jpg") + m, err := bot.Send(msg) + require.NoError(t, err) + require.NotNil(t, m) + require.NotEmpty(t, m.Document.FileID) + FileID = m.Document.FileID + }) -} + t.Run("send existing document", func(t *testing.T) { + require.NotEmpty(t, FileID) + msg := tgbotapi.NewDocument(ChatID, tgbotapi.FileID(FileID)) + m, err := bot.Send(msg) + require.NotNil(t, m) + require.NoError(t, err) + }) -func TestSendWithExistingDocument(t *testing.T) { - bot, err := getBot(t) - require.NoError(t, err) - - msg := tgbotapi.NewDocument(ChatID, tgbotapi.FileID(ExistingDocumentFileID)) - m, err := bot.Send(msg) - require.NotNil(t, m) - require.NoError(t, err) } func TestSendWithAudio(t *testing.T) { @@ -270,6 +301,7 @@ func TestSendWithAudio(t *testing.T) { }) t.Run("send existing audio file", func(t *testing.T) { + require.NotEmpty(t, FileID) msgExist := tgbotapi.NewAudio(ChatID, tgbotapi.FileID(FileID)) msgExist.Title = "TEST EXIST" msgExist.Duration = 10 @@ -281,183 +313,193 @@ func TestSendWithAudio(t *testing.T) { } func TestSendWithNewVoice(t *testing.T) { - bot, _ := getBot(t) + var FileID string - msg := tgbotapi.NewVoice(ChatID, tgbotapi.FilePath("./voice.ogg")) - msg.Duration = 10 - _, err := bot.Send(msg) + bot, err := getBot(t) require.NoError(t, err) + + t.Run("send new voice file", func(t *testing.T) { + msg := tgbotapi.NewVoice(ChatID, tgbotapi.FilePath("./voice.ogg")) + msg.Duration = 10 + m, err := bot.Send(msg) + require.NoError(t, err) + require.NotNil(t, m) + require.NotEmpty(t, m.Voice.FileID) + FileID = m.Voice.FileID + }) + + t.Run("send existing voice file", func(t *testing.T) { + require.NotEmpty(t, FileID) + msg := tgbotapi.NewVoice(ChatID, tgbotapi.FileID(FileID)) + msg.Duration = 10 + m, err := bot.Send(msg) + require.NoError(t, err) + require.NotNil(t, m) + }) } -// TODO: fix this -//func TestSendWithExistingVoice(t *testing.T) { -// bot, _ := getBot(t) -// -// msg := tgbotapi.NewVoice(ChatID, tgbotapi.FileID(ExistingVoiceFileID)) -// msg.Duration = 10 -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} - func TestSendWithContact(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) contact := tgbotapi.NewContact(ChatID, "5551234567", "Test") - _, err := bot.Send(contact) + m, err := bot.Send(contact) require.NoError(t, err) + require.NotNil(t, m) } func TestSendWithLocation(t *testing.T) { - bot, _ := getBot(t) - - _, err := bot.Send(tgbotapi.NewLocation(ChatID, 40, 40)) + bot, err := getBot(t) require.NoError(t, err) + + m, err := bot.Send(tgbotapi.NewLocation(ChatID, 40, 40)) + require.NoError(t, err) + require.NotNil(t, m) } func TestSendWithVenue(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) venue := tgbotapi.NewVenue(ChatID, "A Test Location", "123 Test Street", 40, 40) - _, err := bot.Send(venue) + m, err := bot.Send(venue) require.NoError(t, err) + require.NotNil(t, m) } func TestSendWithNewVideo(t *testing.T) { - bot, _ := getBot(t) + var FileID string - msg := tgbotapi.NewVideo(ChatID, tgbotapi.FilePath("./video.mp4")) - msg.Duration = 10 - msg.Caption = "TEST" - - _, err := bot.Send(msg) + bot, err := getBot(t) require.NoError(t, err) -} -// TODO: fix this -//func TestSendWithExistingVideo(t *testing.T) { -// bot, _ := getBot(t) -// -// msg := tgbotapi.NewVideo(ChatID, tgbotapi.FileID(ExistingVideoFileID)) -// msg.Duration = 10 -// msg.Caption = "TEST" -// -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} + t.Run("send new video file", func(t *testing.T) { + msg := tgbotapi.NewVideo(ChatID, tgbotapi.FilePath("./video.mp4")) + msg.Duration = 10 + msg.Caption = "TEST" + + m, err := bot.Send(msg) + require.NoError(t, err) + require.NotNil(t, m) + require.NotEmpty(t, m.Video.FileID) + FileID = m.Video.FileID + }) + + t.Run("send existing video file", func(t *testing.T) { + require.NotEmpty(t, FileID) + msg := tgbotapi.NewVideo(ChatID, tgbotapi.FileID(FileID)) + msg.Duration = 10 + msg.Caption = "TEST EXIST" + m, err := bot.Send(msg) + require.NoError(t, err) + require.NotNil(t, m) + }) +} func TestSendWithNewVideoNote(t *testing.T) { - bot, _ := getBot(t) - msg := tgbotapi.NewVideoNote(ChatID, 240, tgbotapi.FilePath("./videonote.mp4")) - msg.Duration = 10 + var FileID string - _, err := bot.Send(msg) + bot, err := getBot(t) require.NoError(t, err) -} -// TODO: fix this -//func TestSendWithExistingVideoNote(t *testing.T) { -// bot, _ := getBot(t) -// -// msg := tgbotapi.NewVideoNote(ChatID, 240, tgbotapi.FileID(ExistingVideoNoteFileID)) -// msg.Duration = 10 -// -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} + t.Run("send new video note file", func(t *testing.T) { + msg := tgbotapi.NewVideoNote(ChatID, 240, tgbotapi.FilePath("./videonote.mp4")) + msg.Duration = 10 + + m, err := bot.Send(msg) + require.NoError(t, err) + require.NotEmpty(t, m.VideoNote.FileID) + FileID = m.VideoNote.FileID + }) + + t.Run("send existing video note file", func(t *testing.T) { + require.NotEmpty(t, FileID) + msg := tgbotapi.NewVideoNote(ChatID, 240, tgbotapi.FileID(FileID)) + msg.Duration = 10 + m, err := bot.Send(msg) + require.NoError(t, err) + require.NotNil(t, m) + }) +} func TestSendWithNewSticker(t *testing.T) { - bot, _ := getBot(t) + var FileID string - msg := tgbotapi.NewSticker(ChatID, tgbotapi.FilePath("./image.jpg")) - - _, err := bot.Send(msg) + bot, err := getBot(t) require.NoError(t, err) -} -// TODO: fix this -//func TestSendWithExistingSticker(t *testing.T) { -// bot, _ := getBot(t) -// -// msg := tgbotapi.NewSticker(ChatID, tgbotapi.FileID(ExistingStickerFileID)) -// -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} + t.Run("send new sticker file", func(t *testing.T) { + msg := tgbotapi.NewSticker(ChatID, tgbotapi.FilePath("./image.jpg")) + m, err := bot.Send(msg) + require.NoError(t, err) + require.NotNil(t, m) + require.NotEmpty(t, m.Sticker.FileID) + FileID = m.Sticker.FileID + }) + + t.Run("send existing sticker file", func(t *testing.T) { + require.NotEmpty(t, FileID) + msg := tgbotapi.NewSticker(ChatID, tgbotapi.FileID(FileID)) + m, err := bot.Send(msg) + require.NoError(t, err) + require.NotNil(t, m) + }) +} func TestSendWithNewStickerAndKeyboardHide(t *testing.T) { - bot, _ := getBot(t) + var FileID string - msg := tgbotapi.NewSticker(ChatID, tgbotapi.FilePath("./image.jpg")) - msg.ReplyMarkup = tgbotapi.ReplyKeyboardRemove{ - RemoveKeyboard: true, - Selective: false, - } - _, err := bot.Send(msg) + bot, err := getBot(t) require.NoError(t, err) + + t.Run("send new sticker file", func(t *testing.T) { + msg := tgbotapi.NewSticker(ChatID, tgbotapi.FilePath("./image.jpg")) + msg.ReplyMarkup = tgbotapi.ReplyKeyboardRemove{ + RemoveKeyboard: true, + Selective: false, + } + m, err := bot.Send(msg) + require.NoError(t, err) + require.NotNil(t, m) + require.NotEmpty(t, m.Sticker.FileID) + FileID = m.Sticker.FileID + }) + + t.Run("send existing sticker file", func(t *testing.T) { + require.NotEmpty(t, FileID) + msg := tgbotapi.NewSticker(ChatID, tgbotapi.FileID(FileID)) + msg.ReplyMarkup = tgbotapi.ReplyKeyboardRemove{ + RemoveKeyboard: true, + Selective: false, + } + m, err := bot.Send(msg) + require.NoError(t, err) + require.NotNil(t, m) + }) } -// TODO: fix this -//func TestSendWithExistingStickerAndKeyboardHide(t *testing.T) { -// bot, _ := getBot(t) -// -// msg := tgbotapi.NewSticker(ChatID, tgbotapi.FileID(ExistingStickerFileID)) -// msg.ReplyMarkup = tgbotapi.ReplyKeyboardRemove{ -// RemoveKeyboard: true, -// Selective: false, -// } -// -// _, err := bot.Send(msg) -// -// if err != nil { -// t.Error(err) -// } -//} - func TestSendWithDice(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) msg := tgbotapi.NewDice(ChatID) - _, err := bot.Send(msg) + m, err := bot.Send(msg) require.NoError(t, err) + require.NotNil(t, m) } func TestSendWithDiceWithEmoji(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) msg := tgbotapi.NewDiceWithEmoji(ChatID, "🏀") - _, err := bot.Send(msg) + m, err := bot.Send(msg) require.NoError(t, err) + require.NotNil(t, m) } -// TODO: fix this -//func TestGetFile(t *testing.T) { -// bot, _ := getBot(t) -// -// file := tgbotapi.FileConfig{ -// FileID: ExistingPhotoFileID, -// } -// -// _, err := bot.GetFile(file) -// -// if err != nil { -// t.Error(err) -// } -//} - func TestSendChatConfig(t *testing.T) { bot, _ := getBot(t) @@ -515,7 +557,8 @@ func TestSetWebhookWithCert(t *testing.T) { } func TestSetWebhookWithoutCert(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) time.Sleep(time.Second * 2) @@ -536,7 +579,8 @@ func TestSetWebhookWithoutCert(t *testing.T) { } func TestSendWithMediaGroupPhotoVideo(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) cfg := tgbotapi.NewMediaGroup(ChatID, []interface{}{ tgbotapi.NewInputMediaPhoto(tgbotapi.FileURL("https://github.com/go-telegram-bot-api/telegram-bot-api/raw/0a3a1c8716c4cd8d26a262af9f12dcbab7f3f28c/tests/image.jpg")), @@ -551,7 +595,8 @@ func TestSendWithMediaGroupPhotoVideo(t *testing.T) { } func TestSendWithMediaGroupDocument(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) cfg := tgbotapi.NewMediaGroup(ChatID, []interface{}{ tgbotapi.NewInputMediaDocument(tgbotapi.FileURL("https://i.imgur.com/unQLJIb.jpg")), @@ -565,7 +610,8 @@ func TestSendWithMediaGroupDocument(t *testing.T) { } func TestSendWithMediaGroupAudio(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) cfg := tgbotapi.NewMediaGroup(ChatID, []interface{}{ tgbotapi.NewInputMediaAudio(tgbotapi.FilePath("./audio.mp3")), @@ -578,122 +624,6 @@ func TestSendWithMediaGroupAudio(t *testing.T) { require.Equal(t, len(cfg.Media), len(messages)) } -func ExampleNewBotAPI() { - bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken") - if err != nil { - panic(err) - } - - bot.Debug = true - - fmt.Printf("Authorized on account %s", bot.Self.UserName) - u := tgbotapi.NewUpdate(0) - u.Timeout = 60 - - updates := bot.GetUpdatesChan(u) - - // Optional: wait for updates and clear them if you don't want to handle - // a large backlog of old messages - time.Sleep(time.Millisecond * 500) - updates.Clear() - - for update := range updates { - if update.Message == nil { - continue - } - - fmt.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text) - - msg := tgbotapi.NewMessage(update.Message.Chat.ID, update.Message.Text) - msg.ReplyParameters.MessageID = update.Message.MessageID - - _, err := bot.Send(msg) - if err != nil { - panic(err) - } - } -} - -func ExampleNewWebhook() { - bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken") - if err != nil { - panic(err) - } - - bot.Debug = true - - fmt.Printf("Authorized on account %s", bot.Self.UserName) - - wh, err := tgbotapi.NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, tgbotapi.FilePath("cert.pem")) - - if err != nil { - panic(err) - } - - _, err = bot.Request(wh) - - if err != nil { - panic(err) - } - - info, err := bot.GetWebhookInfo() - - if err != nil { - panic(err) - } - - if info.LastErrorDate != 0 { - fmt.Printf("failed to set webhook: %s", info.LastErrorMessage) - } - - updates := bot.ListenForWebhook("/" + bot.Token) - go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil) - - for update := range updates { - fmt.Printf("%+v\n", update) - } -} - -func ExampleWebhookHandler() { - bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken") - if err != nil { - panic(err) - } - - bot.Debug = true - - fmt.Printf("Authorized on account %s", bot.Self.UserName) - - wh, err := tgbotapi.NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, tgbotapi.FilePath("cert.pem")) - - if err != nil { - panic(err) - } - - _, err = bot.Request(wh) - if err != nil { - panic(err) - } - info, err := bot.GetWebhookInfo() - if err != nil { - panic(err) - } - if info.LastErrorDate != 0 { - fmt.Printf("[Telegram callback failed]%s", info.LastErrorMessage) - } - - http.HandleFunc("/"+bot.Token, func(w http.ResponseWriter, r *http.Request) { - update, err := bot.HandleUpdate(r) - if err != nil { - fmt.Printf("%+v\n", err.Error()) - } else { - fmt.Printf("%+v\n", *update) - } - }) - - go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil) -} - func ExampleInlineConfig() { bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken") // create new bot if err != nil { @@ -864,7 +794,6 @@ func TestPolls(t *testing.T) { } } -// TODO: TG reports this as unsupported func TestSendDice(t *testing.T) { bot, err := getBot(t) require.NoError(t, err) @@ -877,51 +806,36 @@ func TestSendDice(t *testing.T) { } func TestCommands(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) setCommands := tgbotapi.NewSetMyCommands(tgbotapi.BotCommand{ Command: "test", Description: "a test command", }) - if _, err := bot.Request(setCommands); err != nil { - t.Error("Unable to set commands") - } + _, err = bot.Request(setCommands) + require.NoError(t, err) commands, err := bot.GetMyCommands() - if err != nil { - t.Error("Unable to get commands") - } - - if len(commands) != 1 { - t.Error("Incorrect number of commands returned") - } - - if commands[0].Command != "test" || commands[0].Description != "a test command" { - t.Error("Commands were incorrectly set") - } + require.NoError(t, err) + require.Equal(t, 1, len(commands)) + require.Equal(t, "test", commands[0].Command) + require.Equal(t, "a test command", commands[0].Description) setCommands = tgbotapi.NewSetMyCommandsWithScope(tgbotapi.NewBotCommandScopeAllPrivateChats(), tgbotapi.BotCommand{ Command: "private", Description: "a private command", }) - if _, err := bot.Request(setCommands); err != nil { - t.Error("Unable to set commands") - } + _, err = bot.Request(setCommands) + require.NoError(t, err) commands, err = bot.GetMyCommandsWithConfig(tgbotapi.NewGetMyCommandsWithScope(tgbotapi.NewBotCommandScopeAllPrivateChats())) - if err != nil { - t.Error("Unable to get commands") - } - - if len(commands) != 1 { - t.Error("Incorrect number of commands returned") - } - - if commands[0].Command != "private" || commands[0].Description != "a private command" { - t.Error("Commands were incorrectly set") - } + require.NoError(t, err) + require.Equal(t, 1, len(commands)) + require.Equal(t, "private", commands[0].Command) + require.Equal(t, "a private command", commands[0].Description) } // TODO: figure out why test is failing From 5e497cfcba5cbefa6060e77f4ff5f064f27b4705 Mon Sep 17 00:00:00 2001 From: Ilja Lapkovskis Date: Sat, 20 Jan 2024 16:40:58 +0200 Subject: [PATCH 11/12] Fix all tests. --- tests/bot_integration_test.go | 102 ++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 47 deletions(-) diff --git a/tests/bot_integration_test.go b/tests/bot_integration_test.go index 3f8e5dd..5d48f8b 100644 --- a/tests/bot_integration_test.go +++ b/tests/bot_integration_test.go @@ -137,15 +137,18 @@ func TestSendWithNewPhoto(t *testing.T) { } func TestSendWithNewPhotoWithFileBytes(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) - data, _ := os.ReadFile("./image.jpg") + data, err := os.ReadFile("./image.jpg") + require.NoError(t, err) b := tgbotapi.FileBytes{Name: "image.jpg", Bytes: data} msg := tgbotapi.NewPhoto(ChatID, b) msg.Caption = "Test" - _, err := bot.Send(msg) + m, err := bot.Send(msg) require.NoError(t, err) + require.NotNil(t, m) } func TestSendWithNewPhotoWithFileReader(t *testing.T) { @@ -501,34 +504,38 @@ func TestSendWithDiceWithEmoji(t *testing.T) { } func TestSendChatConfig(t *testing.T) { - bot, _ := getBot(t) - - _, err := bot.Request(tgbotapi.NewChatAction(ChatID, tgbotapi.ChatTyping)) + bot, err := getBot(t) require.NoError(t, err) + + m, err := bot.Request(tgbotapi.NewChatAction(ChatID, tgbotapi.ChatTyping)) + require.NoError(t, err) + require.NotNil(t, m) } -// TODO: identify why this isn't working -// func TestSendEditMessage(t *testing.T) { -// bot, _ := getBot(t) +func TestSendEditMessage(t *testing.T) { + bot, err := getBot(t) + require.NoError(t, err) -// msg, err := bot.Send(NewMessage(ChatID, "Testing editing.")) -// if err != nil { -// t.Error(err) -// } + msg, err := bot.Send(tgbotapi.NewMessage(ChatID, "Testing editing.")) + require.NoError(t, err) + require.NotNil(t, msg) -// edit := EditMessageTextConfig{ -// BaseEdit: BaseEdit{ -// ChatID: ChatID, -// MessageID: msg.MessageID, -// }, -// Text: "Updated text.", -// } + edit := tgbotapi.EditMessageTextConfig{ + BaseEdit: tgbotapi.BaseEdit{ + BaseChatMessage: tgbotapi.BaseChatMessage{ + MessageID: msg.MessageID, + ChatConfig: tgbotapi.ChatConfig{ + ChatID: ChatID, + }, + }, + }, + Text: "Updated text.", + } -// _, err = bot.Send(edit) -// if err != nil { -// t.Error(err) -// } -// } + m, err := bot.Send(edit) + require.NoError(t, err) + require.NotNil(t, m) +} func TestGetUserProfilePhotos(t *testing.T) { bot, _ := getBot(t) @@ -839,28 +846,29 @@ func TestCommands(t *testing.T) { } // TODO: figure out why test is failing -// -// func TestEditMessageMedia(t *testing.T) { -// bot, _ := getBot(t) +func TestEditMessageMedia(t *testing.T) { + bot, err := getBot(t) + require.NoError(t, err) -// msg := NewPhoto(ChatID, "./image.jpg") -// msg.Caption = "Test" -// m, err := bot.Send(msg) + msg := tgbotapi.NewPhoto(ChatID, tgbotapi.FilePath("./image.jpg")) + msg.Caption = "Test" + m, err := bot.Send(msg) + require.NoError(t, err) + require.NotNil(t, m) -// if err != nil { -// t.Error(err) -// } + edit := tgbotapi.EditMessageMediaConfig{ + BaseEdit: tgbotapi.BaseEdit{ + BaseChatMessage: tgbotapi.BaseChatMessage{ + MessageID: m.MessageID, + ChatConfig: tgbotapi.ChatConfig{ + ChatID: ChatID, + }, + }, + }, + Media: tgbotapi.NewInputMediaVideo(tgbotapi.FilePath("./video.mp4")), + } -// edit := EditMessageMediaConfig{ -// BaseEdit: BaseEdit{ -// ChatID: ChatID, -// MessageID: m.MessageID, -// }, -// Media: NewInputMediaVideo(FilePath("./video.mp4")), -// } - -// _, err = bot.Request(edit) -// if err != nil { -// t.Error(err) -// } -// } + res, err := bot.Request(edit) + require.NoError(t, err) + require.NotNil(t, res) +} From e41be9f71847f32935de5f3d9f11b051ecedafd9 Mon Sep 17 00:00:00 2001 From: Ilja Lapkovskis Date: Sat, 20 Jan 2024 16:51:34 +0200 Subject: [PATCH 12/12] Fix failing test. --- tests/bot_integration_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/bot_integration_test.go b/tests/bot_integration_test.go index 5d48f8b..629a0dd 100644 --- a/tests/bot_integration_test.go +++ b/tests/bot_integration_test.go @@ -688,11 +688,13 @@ func TestDeleteMessage(t *testing.T) { } func TestPinChatMessage(t *testing.T) { - bot, _ := getBot(t) + bot, err := getBot(t) + require.NoError(t, err) msg := tgbotapi.NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api") msg.ParseMode = tgbotapi.ModeMarkdown - message, _ := bot.Send(msg) + message, err := bot.Send(msg) + require.NoError(t, err) pinChatMessageConfig := tgbotapi.PinChatMessageConfig{ BaseChatMessage: tgbotapi.BaseChatMessage{ @@ -703,11 +705,9 @@ func TestPinChatMessage(t *testing.T) { }, DisableNotification: false, } - _, err := bot.Request(pinChatMessageConfig) - - if err != nil { - t.Error(err) - } + res, err := bot.Request(pinChatMessageConfig) + require.NoError(t, err) + require.NotNil(t, res) } func TestUnpinChatMessage(t *testing.T) {