mg-bot-api-client-go/v1/client_test.go

1160 lines
25 KiB
Go
Raw Normal View History

2018-08-03 18:11:37 +03:00
package v1
import (
2021-11-25 12:51:29 +03:00
"bytes"
2019-03-07 12:58:09 +03:00
"encoding/json"
2018-09-01 00:41:29 +03:00
"fmt"
2018-08-29 02:44:06 +03:00
"log"
2018-09-20 11:41:20 +03:00
"math/rand"
2018-08-29 02:44:06 +03:00
"net/http"
2018-08-03 18:11:37 +03:00
"os"
2018-08-29 02:44:06 +03:00
"strconv"
2018-09-01 00:41:29 +03:00
"strings"
2018-08-29 02:44:06 +03:00
"testing"
2018-09-20 11:41:20 +03:00
"time"
2018-08-29 02:44:06 +03:00
"github.com/joho/godotenv"
"github.com/stretchr/testify/assert"
2021-06-11 14:33:44 +03:00
"gopkg.in/h2non/gock.v1"
2018-08-03 18:11:37 +03:00
)
2018-09-20 11:41:20 +03:00
const (
letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
letterIdxBits = 6 // 6 bits to represent a letter index
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
)
var src = rand.NewSource(time.Now().UnixNano())
2018-08-29 02:44:06 +03:00
func TestMain(m *testing.M) {
if os.Getenv("DEVELOPER_NODE") == "1" {
err := godotenv.Load("../.env")
if err != nil {
log.Fatal("Error loading .env file")
}
}
2019-03-07 12:58:09 +03:00
os.Exit(m.Run())
2018-08-29 02:44:06 +03:00
}
2018-08-03 18:11:37 +03:00
var (
2019-03-07 12:58:09 +03:00
mgURL = "https://api.example.com"
mgToken = "test_token"
debug, _ = strconv.ParseBool(os.Getenv("DEBUG"))
2018-08-03 18:11:37 +03:00
)
2024-02-09 09:44:36 +03:00
func client(opts ...Option) *MgClient {
2019-03-07 12:58:09 +03:00
if debug != false {
2024-02-09 09:44:36 +03:00
opts = append(opts, OptionDebug())
2019-03-07 12:58:09 +03:00
}
2018-12-26 17:38:41 +03:00
2024-02-09 09:44:36 +03:00
return New(mgURL, mgToken, opts...)
2018-08-03 18:11:37 +03:00
}
2018-08-29 02:44:06 +03:00
func TestMgClient_Bots(t *testing.T) {
c := client()
2019-03-07 12:58:09 +03:00
defer gock.Off()
gock.New(mgURL).
Get("/api/bot/v1/bots").
Reply(200).
BodyString(`[{"id": 1, "name": "Test Bot", "created_at": "2018-01-01T00:00:00.000000Z", "is_active": true, "is_self": true}]`)
2018-08-29 02:44:06 +03:00
req := BotsRequest{Active: 1}
data, status, err := c.Bots(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data)
for _, bot := range data {
assert.NotEmpty(t, bot.CreatedAt)
}
}
func TestMgClient_Channels(t *testing.T) {
c := client()
2019-03-07 12:58:09 +03:00
defer gock.Off()
gock.New(mgURL).
Get("/api/bot/v1/channels").
Reply(200).
2021-02-03 14:27:53 +03:00
BodyString(`[
{
"id": 1,
"type": "custom",
"name": "Test custom channel",
"settings": {
"customer_external_id": "phone",
"sending_policy": {
"new_customer": "no",
"after_reply_timeout": "template"
},
"status": {
"delivered": "both",
"read": "receive"
},
"text": {
"creating": "both",
"editing": "receive",
"quoting": "send",
"deleting": "receive",
"max_chars_count": 777
},
"product": {
"creating": "receive",
"editing": "receive",
"deleting": "receive"
},
"order": {
"creating": "receive",
"editing": "receive",
"deleting": "receive"
},
"image": {
"creating": "both",
"quoting": "receive",
"editing": "none",
"deleting": "receive",
"max_items_count": 1,
"note_max_chars_count": 777
},
"file": {
"creating": "both",
"quoting": "receive",
"editing": "none",
"deleting": "receive",
"max_items_count": 1,
"note_max_chars_count": 777
},
"suggestions": {
"text": "receive",
"email": "receive",
"phone": "receive"
}
},
"created_at": "2018-01-01T00:00:00.000000Z",
"updated_at": null,
"activated_at": "2018-01-01T00:00:00.000000Z",
"deactivated_at": null,
"is_active": true
}
]`)
channels, status, err := c.Channels(ChannelsRequest{Active: 1})
2018-08-29 02:44:06 +03:00
assert.NoError(t, err)
2021-02-03 14:27:53 +03:00
assert.Equal(t, 200, status)
assert.Len(t, channels, 1)
ch := channels[0]
assert.Equal(t, uint64(1), ch.ID)
assert.Equal(t, ChannelTypeCustom, ch.Type)
assert.Equal(t, "Test custom channel", ch.Name)
assert.Equal(t, "2018-01-01T00:00:00.000000Z", ch.CreatedAt)
assert.Empty(t, ch.UpdatedAt)
assert.Equal(t, "2018-01-01T00:00:00.000000Z", ch.ActivatedAt)
assert.Empty(t, ch.DeactivatedAt)
assert.True(t, ch.IsActive)
chs := ch.Settings
assert.Equal(t, "phone", chs.CustomerExternalID)
assert.Equal(t, "no", chs.SendingPolicy.NewCustomer)
assert.Equal(t, "template", chs.SendingPolicy.AfterReplyTimeout)
assert.Equal(t, ChannelFeatureBoth, chs.Status.Delivered)
assert.Equal(t, ChannelFeatureReceive, chs.Status.Read)
assert.Equal(t, ChannelFeatureBoth, chs.Text.Creating)
assert.Equal(t, ChannelFeatureReceive, chs.Text.Editing)
assert.Equal(t, ChannelFeatureSend, chs.Text.Quoting)
assert.Equal(t, ChannelFeatureReceive, chs.Text.Deleting)
assert.Equal(t, uint16(777), chs.Text.MaxCharsCount)
assert.Equal(t, ChannelFeatureReceive, chs.Product.Creating)
assert.Equal(t, ChannelFeatureReceive, chs.Product.Editing)
assert.Equal(t, ChannelFeatureReceive, chs.Product.Deleting)
assert.Equal(t, ChannelFeatureReceive, chs.Order.Creating)
assert.Equal(t, ChannelFeatureReceive, chs.Order.Editing)
assert.Equal(t, ChannelFeatureReceive, chs.Order.Deleting)
assert.Equal(t, ChannelFeatureBoth, chs.Image.Creating)
assert.Equal(t, ChannelFeatureNone, chs.Image.Editing)
assert.Equal(t, ChannelFeatureReceive, chs.Image.Quoting)
assert.Equal(t, ChannelFeatureReceive, chs.Image.Deleting)
assert.Equal(t, 1, chs.Image.MaxItemsCount)
assert.Equal(t, uint16(777), chs.Image.NoteMaxCharsCount)
assert.Equal(t, ChannelFeatureBoth, chs.File.Creating)
assert.Equal(t, ChannelFeatureNone, chs.File.Editing)
assert.Equal(t, ChannelFeatureReceive, chs.File.Quoting)
assert.Equal(t, ChannelFeatureReceive, chs.File.Deleting)
assert.Equal(t, 1, chs.File.MaxItemsCount)
assert.Equal(t, uint16(777), chs.File.NoteMaxCharsCount)
assert.Equal(t, ChannelFeatureReceive, chs.Suggestions.Text)
assert.Equal(t, ChannelFeatureReceive, chs.Suggestions.Email)
assert.Equal(t, ChannelFeatureReceive, chs.Suggestions.Phone)
2018-08-29 02:44:06 +03:00
}
func TestMgClient_Users(t *testing.T) {
c := client()
2019-03-07 12:58:09 +03:00
defer gock.Off()
gock.New(mgURL).
Get("/api/bot/v1/users").
Reply(200).
BodyString(`[{"id": 1, "external_id":"1", "username": "Test", "first_name":"Test", "last_name":"Test", "created_at": "2018-01-01T00:00:00.000000Z", "is_active": true, "is_online": true, "is_technical_account": true}]`)
2019-03-07 12:58:09 +03:00
2018-08-29 02:44:06 +03:00
req := UsersRequest{Active: 1}
data, status, err := c.Users(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data)
for _, user := range data {
assert.Equal(t, uint64(1), user.ID)
assert.Equal(t, "1", user.ExternalID)
assert.Equal(t, "Test", user.Username)
assert.Equal(t, "Test", user.FirstName)
assert.Equal(t, "Test", user.LastName)
assert.Equal(t, "2018-01-01T00:00:00.000000Z", user.CreatedAt)
assert.Equal(t, true, user.IsActive)
assert.Equal(t, true, user.IsOnline)
assert.Equal(t, true, user.IsTechnicalAccount)
2018-08-29 02:44:06 +03:00
}
}
func TestMgClient_Customers(t *testing.T) {
c := client()
2019-03-07 12:58:09 +03:00
defer gock.Off()
response := `
[
{
"id": 1,
"channel_id": 1,
"created_at":
"2018-01-01T00:00:00.000000Z",
"utm": {
"source": "test"
}
},
{
"id": 2,
"channel_id": 1,
"created_at":
"2018-01-01T00:00:00.000000Z",
"utm": {
"source": null
}
},
{
"id": 3,
"channel_id": 1,
"created_at":
"2018-01-01T00:00:00.000000Z",
"utm": null
},
{
"id": 4,
"channel_id": 1,
"created_at": "2018-01-01T00:00:00.000000Z"
}
]`
2019-03-07 12:58:09 +03:00
gock.New(mgURL).
Get("/api/bot/v1/customers").
Reply(200).
BodyString(response)
2019-03-07 12:58:09 +03:00
2018-08-29 02:44:06 +03:00
req := CustomersRequest{}
data, status, err := c.Customers(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data)
for _, customer := range data {
assert.NotEmpty(t, customer.ChannelId)
}
assert.Equal(t, "test", data[0].Utm.Source)
assert.Equal(t, "", data[1].Utm.Source)
assert.Nil(t, data[2].Utm)
assert.Nil(t, data[3].Utm)
2018-08-29 02:44:06 +03:00
}
func TestMgClient_Chats(t *testing.T) {
c := client()
2019-03-07 12:58:09 +03:00
defer gock.Off()
gock.New(mgURL).
Get("/api/bot/v1/chats").
Reply(200).
2024-07-16 11:40:08 +03:00
BodyString(`[
{"id": 2,"customer": {"id": 2, "name": "Foo"}, "created_at": "2018-01-01T00:00:00.000000Z"},
{"id": 3,"customer": {"id": 3, "name": "Bar"}, "created_at": "2018-01-02T00:00:00.000000Z"}
]`)
2019-03-07 12:58:09 +03:00
2024-07-16 11:40:08 +03:00
req := ChatsRequest{
ChannelType: ChannelTypeTelegram,
SinceID: 1,
}
2018-08-29 02:44:06 +03:00
data, status, err := c.Chats(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data)
for _, chat := range data {
assert.NotEmpty(t, chat.Customer.Name)
}
}
func TestMgClient_Members(t *testing.T) {
c := client()
2019-03-07 12:58:09 +03:00
defer gock.Off()
gock.New(mgURL).
Get("/api/bot/v1/members").
Reply(200).
BodyString(`[{"id": 1,"user_id": 1, "chat_id": 1, "created_at": "2018-01-01T00:00:00.000000Z"}]`)
2018-08-29 02:44:06 +03:00
req := MembersRequest{State: ChatMemberStateLeaved}
data, status, err := c.Members(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
for _, member := range data {
assert.NotEmpty(t, member.ChatID)
}
}
func TestMgClient_Dialogs(t *testing.T) {
c := client()
2019-03-07 12:58:09 +03:00
defer gock.Off()
gock.New(mgURL).
Get("/api/bot/v1/dialogs").
Reply(200).
BodyString(`[{"id": 1, "chat_id": 1, "created_at": "2018-01-01T00:00:00.000000Z"}]`)
2023-08-15 15:43:53 +03:00
req := DialogsRequest{Active: 0, SinceID: 1}
2018-08-29 02:44:06 +03:00
data, status, err := c.Dialogs(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data)
for _, dialog := range data {
assert.NotEmpty(t, dialog.ChatID)
}
}
func TestMgClient_DialogAssign(t *testing.T) {
c := client()
2019-03-07 12:58:09 +03:00
d := 1
u := 1
req := DialogAssignRequest{DialogID: uint64(d), UserID: uint64(u)}
r, _ := json.Marshal(req)
defer gock.Off()
gock.New(mgURL).
Patch("/api/bot/v1/dialogs/1/assign").
JSON(r).
Reply(400).
BodyString(`{"errors": ["dialog is not the latest in the chat"]}`)
2018-08-29 02:44:06 +03:00
_, status, err := c.DialogAssign(req)
assert.Error(t, err)
assert.Equal(t, http.StatusBadRequest, status)
}
2020-07-14 14:37:46 +03:00
func TestMgClient_DialogUnassign(t *testing.T) {
c := client()
defer gock.Off()
t.Run("success", func(t *testing.T) {
gock.New(mgURL).
Patch("/api/bot/v1/dialogs/777/unassign").
Reply(200).
BodyString(`{"previous_responsible": {"id": 111, "type": "bot", "assigned_at": "2020-07-14T14:11:44.000000Z"}}`)
resp, status, err := c.DialogUnassign(777)
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, status)
assert.Equal(t, int64(111), resp.PreviousResponsible.ID)
assert.Equal(t, "bot", resp.PreviousResponsible.Type)
assert.Equal(t, "2020-07-14T14:11:44.000000Z", resp.PreviousResponsible.AssignAt)
})
t.Run("dialog not latest in chat", func(t *testing.T) {
gock.New(mgURL).
Patch("/api/bot/v1/dialogs/666/unassign").
Reply(400).
BodyString(`{"errors": ["dialog is not the latest in the chat"]}`)
_, status, err := c.DialogUnassign(666)
assert.Error(t, err, "dialog is not the latest in the chat")
assert.Equal(t, http.StatusBadRequest, status)
})
t.Run("dialog is not assigned", func(t *testing.T) {
gock.New(mgURL).
Patch("/api/bot/v1/dialogs/555/unassign").
Reply(400).
BodyString(`{"errors": ["dialog is not assigned"]}`)
_, status, err := c.DialogUnassign(555)
assert.Error(t, err)
assert.Equal(t, http.StatusBadRequest, status)
})
t.Run("dialog not found", func(t *testing.T) {
gock.New(mgURL).
Patch("/api/bot/v1/dialogs/444/unassign").
Reply(404).
BodyString(`{"errors": ["dialog #444 not found"]}`)
_, status, err := c.DialogUnassign(444)
assert.Error(t, err)
assert.Equal(t, http.StatusNotFound, status)
})
}
2018-08-29 02:44:06 +03:00
func TestMgClient_DialogClose(t *testing.T) {
c := client()
2019-03-07 12:58:09 +03:00
i := 1
defer gock.Off()
gock.New(mgURL).
Delete("/api/bot/v1/dialogs/1/close").
Reply(400).
BodyString(`{"errors": ["dialog #1 not found"]}`)
_, status, err := c.DialogClose(uint64(i))
2018-08-29 02:44:06 +03:00
assert.Error(t, err)
assert.Equal(t, http.StatusBadRequest, status)
}
func TestMgClient_DialogsTagsAdd(t *testing.T) {
c := client()
color := ColorBlue
req := DialogTagsAddRequest{
DialogID: uint64(1),
Tags: []TagsAdd{
{Name: "foo", ColorCode: nil},
{Name: "bar", ColorCode: &color},
},
}
r, _ := json.Marshal(req)
defer gock.Off()
gock.New(mgURL).
Patch("/api/bot/v1/dialogs/1/tags/add").
JSON(r).
Reply(200).
BodyString(`{}`)
status, err := c.DialogsTagsAdd(req)
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, status)
}
func TestMgClient_DialogsTagsDelete(t *testing.T) {
c := client()
req := DialogTagsDeleteRequest{
DialogID: uint64(1),
Tags: []TagsDelete{
{Name: "foo"},
{Name: "bar"},
},
}
r, _ := json.Marshal(req)
defer gock.Off()
gock.New(mgURL).
Patch("/api/bot/v1/dialogs/1/tags/delete").
JSON(r).
Reply(200).
BodyString(`{}`)
status, err := c.DialogTagsDelete(req)
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, status)
}
2018-08-29 02:44:06 +03:00
func TestMgClient_Messages(t *testing.T) {
c := client()
2019-03-07 12:58:09 +03:00
defer gock.Off()
gock.New(mgURL).
Get("/api/bot/v1/messages").
Reply(200).
BodyString(`[{"id": 1, "time": "2018-01-01T00:00:00+03:00", "type": "text", "scope": "public", "chat_id": 1, "is_read": false, "is_edit": false, "status": "received", "created_at": "2018-01-01T00:00:00.000000Z"}]`)
2018-08-29 02:44:06 +03:00
req := MessagesRequest{ChannelType: ChannelTypeTelegram, Scope: MessageScopePublic}
data, status, err := c.Messages(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data)
for _, message := range data {
2018-12-26 17:38:41 +03:00
assert.NotEmpty(t, message.ID)
2018-08-29 02:44:06 +03:00
}
}
func TestMgClient_MessagesDialog(t *testing.T) {
t.Parallel()
c := client()
defer gock.Off()
gock.New(mgURL).
Get("/api/bot/v1/messages").
Reply(200).
BodyString(`[
{
"id": 1,
"time": "2024-11-14T20:48:21Z",
"type": "system",
"scope": "private",
"chat_id": 1,
"is_read": false,
"is_edit": false,
"status": "received",
"dialog": {
"id": 2054
},
"action": "dialog_closed",
"channel_id": 71,
"created_at": "2024-11-14T20:48:21.907566Z",
"updated_at": "2024-11-14T20:48:21.907566Z"
},
{
"id": 2,
"time": "2024-11-14T19:58:42Z",
"type": "text",
"scope": "public",
"chat_id": 1,
"is_read": false,
"is_edit": false,
"status": "failed",
"from": {
"id": 1,
"external_id": "1",
"type": "user",
"avatar": "http://avatars-test.jpeg",
"name": "John Smith",
"first_name": "John",
"last_name": "Smith",
"available": true
},
"dialog": {
"id": 2054
},
"error": {
"code": "malformed_response"
},
"content": "Message from user John Smith",
"quote": null,
"channel_id": 71,
"created_at": "2024-11-14T19:58:42.933025Z",
"updated_at": "2024-11-14T19:58:45.01619Z"
}
]`)
req := MessagesRequest{}
data, status, err := c.Messages(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.Len(t, data, 2)
for _, m := range data {
assert.NotNil(t, m.Message.Dialog)
assert.Equal(t, uint64(2054), m.Message.Dialog.ID)
}
}
2018-09-13 11:38:13 +03:00
func TestMgClient_MessageSendText(t *testing.T) {
2018-08-29 02:44:06 +03:00
c := client()
2019-03-07 12:58:09 +03:00
i := uint64(1)
2018-08-29 02:44:06 +03:00
message := MessageSendRequest{
2018-09-13 11:38:13 +03:00
Type: MsgTypeText,
2018-08-29 02:44:06 +03:00
Scope: "public",
Content: "test",
ChatID: i,
}
2019-03-07 12:58:09 +03:00
defer gock.Off()
gock.New(mgURL).
Post("/api/bot/v1/messages").
JSON(message).
Reply(200).
BodyString(`{"message_id": 1, "time": "2018-01-01T00:00:00+03:00"}`)
2018-08-29 02:44:06 +03:00
data, status, err := c.MessageSend(message)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data.MessageID)
}
2018-09-20 11:41:20 +03:00
func TestMgClient_MessageSendTextWithSuggestions(t *testing.T) {
c := client()
i := uint64(1)
message := MessageSendRequest{
Type: MsgTypeText,
Scope: "public",
Content: "test message with suggestions",
ChatID: i,
TransportAttachments: &TransportAttachments{
Suggestions: []Suggestion{
{
Type: SuggestionTypeText,
Title: "text suggestion",
},
{Type: SuggestionTypeEmail},
{Type: SuggestionTypePhone},
},
},
}
defer gock.Off()
gock.New(mgURL).
Post("/api/bot/v1/messages").
JSON(message).
Reply(200).
BodyString(`{"message_id": 1, "time": "2018-01-01T00:00:00+03:00"}`)
data, status, err := c.MessageSend(message)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data.MessageID)
}
2018-09-13 11:38:13 +03:00
func TestMgClient_MessageSendProduct(t *testing.T) {
c := client()
2019-03-07 12:58:09 +03:00
message := MessageSendRequest{
2018-09-13 11:38:13 +03:00
Type: MsgTypeProduct,
ChatID: 5,
Scope: "public",
Product: &MessageProduct{
ID: 1,
Name: "Some Product",
Article: "Art-111",
Url: "https://example.com",
Img: "http://example.com/pic.jpg",
Cost: &MessageOrderCost{
Value: 29900,
Currency: "rub",
},
Quantity: &MessageOrderQuantity{
Value: 1,
},
},
2019-03-07 12:58:09 +03:00
}
defer gock.Off()
gock.New(mgURL).
Post("/api/bot/v1/messages").
JSON(message).
Reply(200).
BodyString(`{"message_id": 1, "time": "2018-01-01T00:00:00+03:00"}`)
msg, _, err := c.MessageSend(message)
2018-09-13 11:38:13 +03:00
if err != nil {
t.Errorf("%v", err)
}
assert.NoError(t, err)
t.Logf("%v", msg)
}
2018-08-29 02:44:06 +03:00
2018-09-20 11:41:20 +03:00
func TestMgClient_MessageSendOrder(t *testing.T) {
c := client()
2019-03-07 12:58:09 +03:00
message := MessageSendRequest{
2018-09-20 11:41:20 +03:00
Type: MsgTypeOrder,
ChatID: 5,
Scope: "public",
Order: &MessageOrder{
Number: RandStringBytesMaskImprSrc(7),
Cost: &MessageOrderCost{
Value: 29900,
Currency: MsgCurrencyRub,
},
Status: &MessageOrderStatus{
Code: MsgOrderStatusCodeNew,
Name: "Новый",
},
Delivery: &MessageOrderDelivery{
Name: "Курьерская доставка",
Address: "г. Москва, Проспект Мира, 9",
Price: &MessageOrderCost{
2018-09-20 11:41:20 +03:00
Value: 1100,
Currency: MsgCurrencyRub,
},
},
Items: []MessageOrderItem{
{
Name: "iPhone 6",
Url: "https://example.com/product.html",
Img: "https://example.com/picture.png",
2018-09-20 11:41:20 +03:00
Price: &MessageOrderCost{
Value: 29900,
Currency: MsgCurrencyRub,
},
Quantity: &MessageOrderQuantity{
Value: 1,
},
},
},
},
2019-03-07 12:58:09 +03:00
}
defer gock.Off()
gock.New(mgURL).
Post("/api/bot/v1/messages").
JSON(message).
Reply(200).
BodyString(`{"message_id": 1, "time": "2018-01-01T00:00:00+03:00"}`)
msg, _, err := c.MessageSend(message)
2018-09-20 11:41:20 +03:00
if err != nil {
t.Errorf("%v", err)
}
assert.NoError(t, err)
t.Logf("%v", msg)
}
func TestMgClient_RandomStringGenerator(t *testing.T) {
rnd := RandStringBytesMaskImprSrc(7)
assert.NotEmpty(t, rnd)
t.Logf("%v", rnd)
}
2018-08-29 02:44:06 +03:00
func TestMgClient_MessageEdit(t *testing.T) {
c := client()
2019-03-07 12:58:09 +03:00
message := MessageEditRequest{
ID: uint64(1),
2018-08-29 02:44:06 +03:00
Content: "test",
}
2019-03-07 12:58:09 +03:00
defer gock.Off()
2018-08-29 02:44:06 +03:00
2019-03-07 12:58:09 +03:00
gock.New(mgURL).
Patch("/api/bot/v1/messages/1").
JSON(message).
Reply(200).
BodyString(`{"message_id": 1, "time": "2018-01-01T00:00:00+03:00"}`)
2018-08-29 02:44:06 +03:00
2019-03-07 12:58:09 +03:00
e, status, err := c.MessageEdit(message)
2018-08-29 02:44:06 +03:00
if err != nil {
t.Errorf("%d %v", status, err)
}
t.Logf("Message edit: %v", e)
}
func TestMgClient_MessageDelete(t *testing.T) {
c := client()
2019-03-07 12:58:09 +03:00
defer gock.Off()
2018-08-29 02:44:06 +03:00
2019-03-07 12:58:09 +03:00
gock.New(mgURL).
Delete("/api/bot/v1/messages/1").
Reply(200).
BodyString(`{}`)
2018-08-29 02:44:06 +03:00
2019-03-07 12:58:09 +03:00
d, status, err := c.MessageDelete(1)
2018-08-29 02:44:06 +03:00
if err != nil {
t.Errorf("%d %v", status, err)
}
t.Logf("Message delete: %v", d)
}
func TestMgClient_Info(t *testing.T) {
c := client()
2019-03-07 12:58:09 +03:00
req := InfoRequest{Name: "AWESOME", Avatar: "https://test.com/awesome_bot_avatar"}
defer gock.Off()
gock.New(mgURL).
Patch("/api/bot/v1/my/info").
JSON(req).
Reply(200).
BodyString(`{}`)
2018-08-29 02:44:06 +03:00
_, status, err := c.Info(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
}
func TestMgClient_Commands(t *testing.T) {
c := client()
2019-03-07 12:58:09 +03:00
defer gock.Off()
gock.New(mgURL).
Get("/api/bot/v1/my/commands").
Reply(200).
BodyString(`[{"id": 1, "name": "command_name", "description": "Command description", "created_at": "2018-01-01T00:00:00.000000Z"}]`)
2018-08-29 02:44:06 +03:00
req := CommandsRequest{}
data, status, err := c.Commands(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data)
for _, command := range data {
assert.NotEmpty(t, command.Description)
}
}
func TestMgClient_CommandEditDelete(t *testing.T) {
c := client()
req := CommandEditRequest{
2019-03-07 12:58:09 +03:00
Name: "test_command",
Description: "Test command",
2018-08-29 02:44:06 +03:00
}
2019-03-07 12:58:09 +03:00
defer gock.Off()
gock.New(mgURL).
Put("/api/bot/v1/my/commands/test_command").
JSON(req).
Reply(200).
BodyString(`{"id": 1, "name": "test_command", "description": "Test description"}`)
2018-08-29 02:44:06 +03:00
n, status, err := c.CommandEdit(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, n.ID)
2019-03-07 12:58:09 +03:00
gock.New(mgURL).
Delete("/api/bot/v1/my/commands/test_command").
Reply(200).
BodyString(`{}`)
2018-08-29 02:44:06 +03:00
d, status, err := c.CommandDelete(n.Name)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
t.Logf("%v", d)
}
2018-09-01 00:41:29 +03:00
2024-06-28 18:04:49 +03:00
func TestMgClient_WsMeta_With_Options(t *testing.T) {
c := client()
events := []string{"user_updated", "user_join_chat"}
2024-07-11 14:02:42 +03:00
params := []WsParams{WsOptionIncludeMassCommunication}
2024-06-28 18:04:49 +03:00
2024-07-11 14:02:42 +03:00
url, headers, err := c.WsMeta(events, params...)
2024-06-28 18:04:49 +03:00
if err != nil {
t.Errorf("%v", err)
}
2024-07-11 13:49:29 +03:00
resURL := "wss://api.example.com/api/bot/v1/ws?events=user_updated,user_join_chat&options=include_mass_communication"
2024-06-28 18:04:49 +03:00
resToken := c.Token
2024-07-11 13:49:29 +03:00
assert.Equal(t, resURL, url)
2024-06-28 18:04:49 +03:00
assert.Equal(t, resToken, headers["X-Bot-Token"][0])
}
2018-09-01 00:41:29 +03:00
func TestMgClient_WsMeta(t *testing.T) {
c := client()
events := []string{"user_updated", "user_join_chat"}
url, headers, err := c.WsMeta(events)
if err != nil {
t.Errorf("%v", err)
}
2024-07-11 13:49:29 +03:00
resURL := fmt.Sprintf("%s%s%s%s", strings.Replace(c.URL, "https", "wss", 1), prefix, "/ws?events=", strings.Join(events[:], ","))
2018-09-01 00:41:29 +03:00
resToken := c.Token
2024-07-11 13:49:29 +03:00
assert.Equal(t, resURL, url)
2018-09-01 00:41:29 +03:00
assert.Equal(t, resToken, headers["X-Bot-Token"][0])
}
2018-09-20 11:41:20 +03:00
2018-12-26 17:38:41 +03:00
func TestMgClient_UploadFile(t *testing.T) {
c := client()
resp, err := http.Get("https://via.placeholder.com/300")
if err != nil {
t.Errorf("%v", err)
}
defer resp.Body.Close()
2019-03-07 12:58:09 +03:00
defer gock.Off()
gock.New(mgURL).
Post("/api/bot/v1/files/upload").
Reply(200).
BodyString(`{"created_at": "2018-01-01T00:00:00.000000Z", "hash": "hash", "id": "1"}`)
2018-12-26 17:38:41 +03:00
data, status, err := c.UploadFile(resp.Body)
if status != http.StatusOK {
t.Errorf("%v", err)
}
t.Logf("File %+v is upload", data)
}
2019-03-07 12:58:09 +03:00
func TestMgClient_UploadFileByUrl(t *testing.T) {
2018-12-26 17:38:41 +03:00
c := client()
2019-03-07 12:58:09 +03:00
file := UploadFileByUrlRequest{
2018-12-26 17:38:41 +03:00
Url: "https://via.placeholder.com/300",
2019-03-07 12:58:09 +03:00
}
defer gock.Off()
gock.New(mgURL).
Post("/api/bot/v1/files/upload_by_url").
JSON(file).
Reply(200).
BodyString(`{"created_at": "2018-01-01T00:00:00.000000Z", "hash": "hash", "id": "1"}`)
uploadFileResponse, st, err := c.UploadFileByURL(file)
2018-12-26 17:38:41 +03:00
if st != http.StatusOK {
t.Errorf("%v", err)
}
t.Logf("File %+v is upload", uploadFileResponse.ID)
assert.NoError(t, err)
}
2018-09-20 11:41:20 +03:00
func RandStringBytesMaskImprSrc(n int) string {
b := make([]byte, n)
// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = src.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
b[i] = letterBytes[idx]
i--
}
cache >>= letterIdxBits
remain--
}
return string(b)
}
2021-11-25 12:51:29 +03:00
func TestMgClient_DebugNoLogger(t *testing.T) {
c := client()
c.Debug = true
var buf bytes.Buffer
log.SetOutput(&buf)
defer func() {
log.SetOutput(os.Stderr)
}()
c.writeLog("Test log string")
assert.Contains(t, buf.String(), "Test log string")
}
func TestMgClient_DebugWithLogger(t *testing.T) {
var buf bytes.Buffer
logger := log.New(&buf, "Custom log prefix ", 0)
2024-02-09 09:44:36 +03:00
c := client(OptionDebug(), OptionLogger(logger))
2021-11-25 12:51:29 +03:00
c.writeLog("Test log string")
assert.Contains(t, buf.String(), "Custom log prefix Test log string")
}
2022-11-16 15:27:37 +03:00
func TestMgClient_SuccessChatsByCustomerId(t *testing.T) {
defer gock.Off()
customerID := uint64(191140)
gock.New(mgURL).
Path("/api/bot/v1/chats").
MatchParam("customer_id", fmt.Sprintf("%d", customerID)).
MatchHeader("X-Bot-Token", mgToken).
Reply(http.StatusOK).
JSON(getJSONResponseChats())
apiClient := client()
chatsRequest := ChatsRequest{
CustomerID: customerID,
}
resp, statusCode, err := apiClient.Chats(chatsRequest)
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, statusCode)
assert.Equal(t, 1, len(resp))
assert.Equal(t, uint64(9000), resp[0].ID)
assert.Equal(t, uint64(8000), resp[0].Channel.ID)
assert.Equal(t, customerID, resp[0].Customer.ID)
assert.Equal(t, "Имя Фамилия", resp[0].Customer.Name)
assert.Equal(t, "Имя", resp[0].Customer.FirstName)
assert.Equal(t, "Фамилия", resp[0].Customer.LastName)
}
func getJSONResponseChats() string {
return `[
{
"id": 9000,
"channel": {
"id": 8000,
"avatar": "",
"transport_id": 555,
"type": "transport",
"settings": {
"status": {
"delivered": "send"
},
"text": {
"creating": "both",
"editing": "both",
"quoting": "both",
"deleting": "receive",
"max_chars_count": 4096
},
"product": {
"creating": "receive",
"editing": "receive"
},
"order": {
"creating": "receive",
"editing": "receive"
},
"image": {
"creating": "both",
"editing": "both",
"quoting": "both",
"deleting": "receive",
"max_items_count": 10
},
"file": {
"creating": "both",
"editing": "both",
"quoting": "both",
"deleting": "receive",
"max_items_count": 1
},
"audio": {
"creating": "both",
"quoting": "both",
"deleting": "receive",
"max_items_count": 1
},
"suggestions": {
"text": "both",
"email": "both",
"phone": "both"
}
},
"name": "@test_bot123",
"is_active": false
},
"customer": {
"id": 191140,
"external_id": "",
"type": "customer",
"avatar": "",
"name": "Имя Фамилия",
"username": "Имя",
"first_name": "Имя",
"last_name": "Фамилия"
},
"last_activity": "2022-10-28T13:17:38+03:00",
"created_at": "2022-10-07T14:00:24.795382Z",
"updated_at": "2022-10-28T12:19:04.834592Z"
}
]`
}