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) +// } +// }