2018-05-17 17:26:18 +03:00
|
|
|
package v1
|
|
|
|
|
|
|
|
import (
|
2020-04-08 13:11:46 +03:00
|
|
|
"bytes"
|
|
|
|
"encoding/base64"
|
2023-12-14 14:41:44 +03:00
|
|
|
"encoding/json"
|
2022-10-26 10:54:54 +03:00
|
|
|
"errors"
|
2020-04-08 13:11:46 +03:00
|
|
|
"fmt"
|
2023-12-14 14:41:44 +03:00
|
|
|
"io/ioutil"
|
2018-05-17 17:26:18 +03:00
|
|
|
"net/http"
|
2021-11-22 16:08:53 +03:00
|
|
|
"strings"
|
2018-05-17 17:26:18 +03:00
|
|
|
"testing"
|
2018-05-21 17:56:42 +03:00
|
|
|
"time"
|
2020-04-08 13:11:46 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
"gopkg.in/h2non/gock.v1"
|
2018-05-17 17:26:18 +03:00
|
|
|
)
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
type MGClientTest struct {
|
|
|
|
suite.Suite
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMGClient(t *testing.T) {
|
|
|
|
suite.Run(t, new(MGClientTest))
|
|
|
|
}
|
2018-05-17 17:26:18 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
func (t *MGClientTest) client() *MgClient {
|
|
|
|
c := New("https://mg-test.retailcrm.pro", "mg_token")
|
2018-12-17 14:34:15 +03:00
|
|
|
c.Debug = true
|
|
|
|
|
|
|
|
return c
|
2018-05-17 17:26:18 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
func (t *MGClientTest) gock() *gock.Request {
|
|
|
|
return gock.New("https://mg-test.retailcrm.pro").MatchHeader("x-transport-token", "mg_token")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *MGClientTest) transportURL(path string) string {
|
|
|
|
return "/api/transport/v1/" + strings.TrimLeft(path, "/")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *MGClientTest) Test_TransportChannels() {
|
|
|
|
c := t.client()
|
|
|
|
chName := "WhatsApp Channel"
|
|
|
|
createdAt := "2021-11-22T08:20:46.479979Z"
|
|
|
|
|
|
|
|
defer gock.Off()
|
|
|
|
t.gock().
|
|
|
|
Get(t.transportURL("channels")).
|
|
|
|
Reply(http.StatusOK).
|
2022-10-26 10:54:54 +03:00
|
|
|
JSON(
|
|
|
|
[]ChannelListItem{
|
|
|
|
{
|
|
|
|
ID: 1,
|
|
|
|
ExternalID: "external_id",
|
|
|
|
Type: "whatsapp",
|
|
|
|
Name: &chName,
|
|
|
|
Settings: ChannelSettings{
|
|
|
|
Status: Status{
|
|
|
|
Delivered: ChannelFeatureNone,
|
|
|
|
Read: ChannelFeatureSend,
|
|
|
|
},
|
|
|
|
Text: ChannelSettingsText{
|
|
|
|
Creating: ChannelFeatureBoth,
|
|
|
|
Editing: ChannelFeatureBoth,
|
|
|
|
Quoting: ChannelFeatureBoth,
|
|
|
|
Deleting: ChannelFeatureReceive,
|
|
|
|
MaxCharsCount: 4096,
|
|
|
|
},
|
|
|
|
Product: Product{
|
|
|
|
Creating: ChannelFeatureReceive,
|
|
|
|
Editing: ChannelFeatureReceive,
|
|
|
|
},
|
|
|
|
Order: Order{
|
|
|
|
Creating: ChannelFeatureReceive,
|
|
|
|
Editing: ChannelFeatureReceive,
|
|
|
|
},
|
|
|
|
File: ChannelSettingsFilesBase{
|
|
|
|
Creating: ChannelFeatureBoth,
|
|
|
|
Editing: ChannelFeatureBoth,
|
|
|
|
Quoting: ChannelFeatureBoth,
|
|
|
|
Deleting: ChannelFeatureReceive,
|
|
|
|
Max: 1,
|
|
|
|
},
|
|
|
|
Image: ChannelSettingsFilesBase{
|
|
|
|
Creating: ChannelFeatureBoth,
|
|
|
|
Editing: ChannelFeatureBoth,
|
|
|
|
Quoting: ChannelFeatureBoth,
|
|
|
|
Deleting: ChannelFeatureReceive,
|
|
|
|
Max: 1, // nolint:gomnd
|
|
|
|
},
|
|
|
|
Suggestions: ChannelSettingsSuggestions{
|
|
|
|
Text: ChannelFeatureBoth,
|
|
|
|
Phone: ChannelFeatureBoth,
|
|
|
|
Email: ChannelFeatureBoth,
|
|
|
|
},
|
|
|
|
CustomerExternalID: ChannelFeatureCustomerExternalIDPhone,
|
|
|
|
SendingPolicy: SendingPolicy{
|
|
|
|
NewCustomer: ChannelFeatureSendingPolicyTemplate,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
CreatedAt: createdAt,
|
|
|
|
UpdatedAt: &createdAt,
|
|
|
|
ActivatedAt: createdAt,
|
|
|
|
DeactivatedAt: nil,
|
|
|
|
IsActive: true,
|
2020-06-11 14:41:08 +03:00
|
|
|
},
|
2020-04-08 13:11:46 +03:00
|
|
|
},
|
2022-10-26 10:54:54 +03:00
|
|
|
)
|
2018-10-01 18:17:03 +03:00
|
|
|
|
|
|
|
data, status, err := c.TransportChannels(Channels{Active: true})
|
2021-11-22 16:08:53 +03:00
|
|
|
t.Require().NoError(err)
|
|
|
|
t.Assert().Equal(http.StatusOK, status)
|
2018-10-01 18:17:03 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
t.Assert().Len(data, 1)
|
2018-10-01 18:17:03 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
func (t *MGClientTest) Test_ActivateTransportChannel() {
|
|
|
|
c := t.client()
|
2018-05-17 17:26:18 +03:00
|
|
|
ch := Channel{
|
2021-11-22 16:08:53 +03:00
|
|
|
ID: 1,
|
2018-05-17 17:26:18 +03:00
|
|
|
Type: "telegram",
|
2018-09-10 12:06:57 +03:00
|
|
|
Name: "@my_shopping_bot",
|
2018-08-16 16:53:29 +03:00
|
|
|
Settings: ChannelSettings{
|
2018-08-21 13:37:49 +03:00
|
|
|
Status: Status{
|
|
|
|
Delivered: ChannelFeatureNone,
|
|
|
|
Read: ChannelFeatureReceive,
|
|
|
|
},
|
|
|
|
Text: ChannelSettingsText{
|
2018-12-05 10:57:45 +03:00
|
|
|
Creating: ChannelFeatureBoth,
|
|
|
|
Editing: ChannelFeatureSend,
|
|
|
|
Quoting: ChannelFeatureReceive,
|
|
|
|
Deleting: ChannelFeatureBoth,
|
|
|
|
MaxCharsCount: 2000,
|
2018-08-16 16:53:29 +03:00
|
|
|
},
|
2018-09-19 18:12:37 +03:00
|
|
|
Product: Product{
|
|
|
|
Creating: ChannelFeatureSend,
|
|
|
|
Deleting: ChannelFeatureSend,
|
|
|
|
},
|
|
|
|
Order: Order{
|
|
|
|
Creating: ChannelFeatureBoth,
|
|
|
|
Deleting: ChannelFeatureSend,
|
|
|
|
},
|
2018-11-13 12:52:01 +03:00
|
|
|
Image: ChannelSettingsFilesBase{
|
|
|
|
Creating: ChannelFeatureBoth,
|
|
|
|
},
|
|
|
|
File: ChannelSettingsFilesBase{
|
|
|
|
Creating: ChannelFeatureBoth,
|
|
|
|
},
|
2018-08-16 16:53:29 +03:00
|
|
|
},
|
2018-05-17 17:26:18 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
defer gock.Off()
|
|
|
|
t.gock().
|
|
|
|
Post(t.transportURL("channels")).
|
|
|
|
Reply(http.StatusCreated).
|
2022-10-26 10:54:54 +03:00
|
|
|
JSON(
|
|
|
|
ActivateResponse{
|
|
|
|
ChannelID: 1,
|
|
|
|
ExternalID: "external_id_1",
|
|
|
|
ActivatedAt: time.Now(),
|
|
|
|
},
|
|
|
|
)
|
2018-05-17 17:26:18 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
data, status, err := c.ActivateTransportChannel(ch)
|
|
|
|
t.Require().NoError(err)
|
|
|
|
t.Assert().Equal(http.StatusCreated, status)
|
2018-05-17 17:26:18 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
t.Assert().Equal(uint64(1), data.ChannelID)
|
|
|
|
t.Assert().Equal("external_id_1", data.ExternalID)
|
|
|
|
t.Assert().NotEmpty(data.ActivatedAt.String())
|
2018-05-17 17:26:18 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
func (t *MGClientTest) Test_ActivateNewTransportChannel() {
|
|
|
|
c := t.client()
|
2018-05-17 17:26:18 +03:00
|
|
|
ch := Channel{
|
|
|
|
Type: "telegram",
|
2018-09-10 12:06:57 +03:00
|
|
|
Name: "@my_shopping_bot",
|
2018-08-16 16:53:29 +03:00
|
|
|
Settings: ChannelSettings{
|
2018-08-21 13:37:49 +03:00
|
|
|
Status: Status{
|
|
|
|
Delivered: ChannelFeatureNone,
|
|
|
|
Read: ChannelFeatureBoth,
|
|
|
|
},
|
|
|
|
Text: ChannelSettingsText{
|
|
|
|
Creating: ChannelFeatureBoth,
|
|
|
|
Editing: ChannelFeatureSend,
|
|
|
|
Quoting: ChannelFeatureBoth,
|
|
|
|
Deleting: ChannelFeatureSend,
|
2018-08-16 16:53:29 +03:00
|
|
|
},
|
2018-09-19 18:12:37 +03:00
|
|
|
Product: Product{
|
|
|
|
Creating: ChannelFeatureSend,
|
|
|
|
Deleting: ChannelFeatureSend,
|
|
|
|
},
|
|
|
|
Order: Order{
|
|
|
|
Creating: ChannelFeatureBoth,
|
|
|
|
Deleting: ChannelFeatureSend,
|
|
|
|
},
|
2018-11-13 12:52:01 +03:00
|
|
|
Image: ChannelSettingsFilesBase{
|
|
|
|
Creating: ChannelFeatureBoth,
|
|
|
|
},
|
|
|
|
File: ChannelSettingsFilesBase{
|
|
|
|
Creating: ChannelFeatureBoth,
|
|
|
|
},
|
2018-08-16 16:53:29 +03:00
|
|
|
},
|
2018-05-17 17:26:18 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
defer gock.Off()
|
2018-05-17 17:26:18 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
t.gock().
|
|
|
|
Post(t.transportURL("channels")).
|
|
|
|
Reply(http.StatusCreated).
|
2022-10-26 10:54:54 +03:00
|
|
|
JSON(
|
|
|
|
ActivateResponse{
|
|
|
|
ChannelID: 1,
|
|
|
|
ExternalID: "external_id_1",
|
|
|
|
ActivatedAt: time.Now(),
|
|
|
|
},
|
|
|
|
)
|
2018-05-21 17:56:42 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
t.gock().
|
|
|
|
Delete(t.transportURL("channels/1")).
|
|
|
|
Reply(http.StatusOK).
|
2022-10-26 10:54:54 +03:00
|
|
|
JSON(
|
|
|
|
DeleteResponse{
|
|
|
|
ChannelID: 1,
|
|
|
|
DeactivatedAt: time.Now(),
|
|
|
|
},
|
|
|
|
)
|
2018-05-21 17:56:42 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
data, status, err := c.ActivateTransportChannel(ch)
|
|
|
|
t.Require().NoError(err)
|
|
|
|
t.Assert().Equal(http.StatusCreated, status)
|
2018-05-21 17:56:42 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
t.Assert().Equal(uint64(1), data.ChannelID)
|
|
|
|
t.Assert().Equal("external_id_1", data.ExternalID)
|
|
|
|
t.Assert().NotEmpty(data.ActivatedAt.String())
|
2018-05-21 17:56:42 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
deleteData, status, err := c.DeactivateTransportChannel(data.ChannelID)
|
|
|
|
t.Require().NoError(err)
|
|
|
|
t.Assert().Equal(http.StatusOK, status)
|
|
|
|
t.Assert().NotEmpty(deleteData.DeactivatedAt.String())
|
|
|
|
t.Assert().Equal(uint64(1), deleteData.ChannelID)
|
2018-05-17 17:26:18 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
func (t *MGClientTest) Test_UpdateTransportChannel() {
|
|
|
|
c := t.client()
|
2018-05-17 17:26:18 +03:00
|
|
|
ch := Channel{
|
2021-11-22 16:08:53 +03:00
|
|
|
ID: 1,
|
2018-09-10 12:06:57 +03:00
|
|
|
Name: "@my_shopping_bot_2",
|
2018-08-16 16:53:29 +03:00
|
|
|
Settings: ChannelSettings{
|
2018-08-21 13:37:49 +03:00
|
|
|
Status: Status{
|
|
|
|
Delivered: ChannelFeatureNone,
|
|
|
|
Read: ChannelFeatureBoth,
|
|
|
|
},
|
|
|
|
Text: ChannelSettingsText{
|
|
|
|
Creating: ChannelFeatureBoth,
|
|
|
|
Editing: ChannelFeatureBoth,
|
|
|
|
Quoting: ChannelFeatureBoth,
|
|
|
|
Deleting: ChannelFeatureBoth,
|
2018-08-16 16:53:29 +03:00
|
|
|
},
|
2018-09-19 18:12:37 +03:00
|
|
|
Product: Product{
|
|
|
|
Creating: ChannelFeatureSend,
|
|
|
|
Deleting: ChannelFeatureSend,
|
|
|
|
},
|
|
|
|
Order: Order{
|
|
|
|
Creating: ChannelFeatureBoth,
|
|
|
|
Deleting: ChannelFeatureSend,
|
|
|
|
},
|
2018-11-13 12:52:01 +03:00
|
|
|
Image: ChannelSettingsFilesBase{
|
|
|
|
Creating: ChannelFeatureBoth,
|
|
|
|
},
|
|
|
|
File: ChannelSettingsFilesBase{
|
|
|
|
Creating: ChannelFeatureBoth,
|
|
|
|
},
|
2018-08-16 16:53:29 +03:00
|
|
|
},
|
2018-05-17 17:26:18 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
defer gock.Off()
|
|
|
|
t.gock().
|
|
|
|
Put(t.transportURL("channels/1")).
|
|
|
|
Reply(http.StatusOK).
|
2022-10-26 10:54:54 +03:00
|
|
|
JSON(
|
|
|
|
UpdateResponse{
|
|
|
|
ChannelID: uint64(1),
|
|
|
|
ExternalID: "external_id_1",
|
|
|
|
UpdatedAt: time.Now(),
|
|
|
|
},
|
|
|
|
)
|
2018-05-17 17:26:18 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
data, status, err := c.UpdateTransportChannel(ch)
|
|
|
|
t.Require().NoError(err)
|
|
|
|
t.Assert().Equal(http.StatusOK, status)
|
|
|
|
t.Assert().Equal(uint64(1), data.ChannelID)
|
|
|
|
t.Assert().Equal("external_id_1", data.ExternalID)
|
|
|
|
t.Assert().NotEmpty(data.UpdatedAt.String())
|
2018-05-17 17:26:18 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
func (t *MGClientTest) Test_TransportTemplates() {
|
|
|
|
c := t.client()
|
|
|
|
|
|
|
|
defer gock.Off()
|
|
|
|
t.gock().
|
|
|
|
Get(t.transportURL("templates")).
|
|
|
|
Reply(http.StatusOK).
|
2022-10-26 10:54:54 +03:00
|
|
|
JSON(
|
|
|
|
[]Template{
|
2021-11-22 16:08:53 +03:00
|
|
|
{
|
2022-10-26 10:54:54 +03:00
|
|
|
Code: "tpl_code",
|
|
|
|
ChannelID: 1,
|
|
|
|
Name: "Test Template",
|
|
|
|
Enabled: true,
|
|
|
|
Type: TemplateTypeText,
|
|
|
|
Template: []TemplateItem{
|
|
|
|
{
|
|
|
|
Type: TemplateItemTypeText,
|
|
|
|
Text: "Hello, ",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: TemplateItemTypeVar,
|
|
|
|
VarType: TemplateVarFirstName,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: TemplateItemTypeText,
|
|
|
|
Text: "! We're glad to see you back in our store.",
|
|
|
|
},
|
|
|
|
},
|
2021-11-22 16:08:53 +03:00
|
|
|
},
|
|
|
|
},
|
2022-10-26 10:54:54 +03:00
|
|
|
)
|
2020-04-08 13:11:46 +03:00
|
|
|
|
|
|
|
data, status, err := c.TransportTemplates()
|
2021-11-22 16:08:53 +03:00
|
|
|
t.Assert().NoError(err, fmt.Sprintf("%d %s", status, err))
|
|
|
|
t.Assert().Equal(http.StatusOK, status)
|
|
|
|
t.Assert().Len(data, 1)
|
2020-04-08 14:17:21 +03:00
|
|
|
|
|
|
|
for _, item := range data {
|
|
|
|
for _, tpl := range item.Template {
|
|
|
|
if tpl.Type == TemplateItemTypeText {
|
2021-11-22 16:08:53 +03:00
|
|
|
t.Assert().Empty(tpl.VarType)
|
2020-04-08 14:17:21 +03:00
|
|
|
} else {
|
2021-11-22 16:08:53 +03:00
|
|
|
t.Assert().Empty(tpl.Text)
|
|
|
|
t.Assert().NotEmpty(tpl.VarType)
|
2020-04-08 14:17:21 +03:00
|
|
|
|
|
|
|
if _, ok := templateVarAssoc[tpl.VarType]; !ok {
|
2021-11-22 16:08:53 +03:00
|
|
|
t.T().Errorf("unknown TemplateVar type %s", tpl.VarType)
|
2020-04-08 14:17:21 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-04-08 13:11:46 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
func (t *MGClientTest) Test_ActivateTemplate() {
|
|
|
|
c := t.client()
|
2020-04-08 13:11:46 +03:00
|
|
|
req := ActivateTemplateRequest{
|
2021-11-22 16:08:53 +03:00
|
|
|
Code: "tplCode",
|
2020-04-08 13:11:46 +03:00
|
|
|
Type: TemplateTypeText,
|
2023-10-25 19:07:05 +03:00
|
|
|
UpdateTemplateRequest: UpdateTemplateRequest{
|
|
|
|
Name: "tplCode",
|
|
|
|
Template: []TemplateItem{
|
|
|
|
{
|
|
|
|
Type: TemplateItemTypeText,
|
|
|
|
Text: "Hello ",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: TemplateItemTypeVar,
|
|
|
|
VarType: TemplateVarFirstName,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: TemplateItemTypeText,
|
|
|
|
Text: "!",
|
|
|
|
},
|
2020-04-08 13:11:46 +03:00
|
|
|
},
|
2023-10-25 19:07:05 +03:00
|
|
|
RejectionReason: "",
|
|
|
|
VerificationStatus: TemplateStatusApproved,
|
2020-04-08 13:11:46 +03:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
defer gock.Off()
|
|
|
|
t.gock().
|
|
|
|
Post("/channels/1/templates").
|
|
|
|
Reply(http.StatusCreated).
|
|
|
|
JSON(map[string]interface{}{})
|
2020-04-08 13:11:46 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
status, err := c.ActivateTemplate(1, req)
|
|
|
|
t.Assert().NoError(err, fmt.Sprintf("%d %s", status, err))
|
|
|
|
t.Assert().Equal(http.StatusCreated, status)
|
2020-04-08 13:11:46 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
func (t *MGClientTest) Test_UpdateTemplate() {
|
|
|
|
c := t.client()
|
2023-10-25 19:07:05 +03:00
|
|
|
tpl := UpdateTemplateRequest{
|
|
|
|
Name: "updated name",
|
2020-04-08 13:11:46 +03:00
|
|
|
Template: []TemplateItem{
|
|
|
|
{
|
|
|
|
Type: TemplateItemTypeText,
|
|
|
|
Text: "Welcome ",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: TemplateItemTypeVar,
|
|
|
|
VarType: TemplateVarFirstName,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: TemplateItemTypeText,
|
|
|
|
Text: "!",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
defer gock.Off()
|
|
|
|
|
|
|
|
t.gock().
|
2022-10-26 10:54:54 +03:00
|
|
|
Filter(
|
|
|
|
func(r *http.Request) bool {
|
|
|
|
return r.Method == http.MethodPut &&
|
|
|
|
r.URL.Path == "/api/transport/v1/channels/1/templates/encodable#code"
|
|
|
|
},
|
|
|
|
).
|
2021-11-22 16:08:53 +03:00
|
|
|
Reply(http.StatusOK).
|
|
|
|
JSON(map[string]interface{}{})
|
|
|
|
|
|
|
|
t.gock().
|
|
|
|
Get(t.transportURL("templates")).
|
|
|
|
Reply(http.StatusOK).
|
2023-10-25 19:07:05 +03:00
|
|
|
JSON([]ActivateTemplateRequest{ActivateTemplateRequest{
|
|
|
|
UpdateTemplateRequest: tpl,
|
|
|
|
Code: "encodable#code",
|
|
|
|
Type: TemplateTypeText,
|
|
|
|
}})
|
2021-11-22 16:08:53 +03:00
|
|
|
|
2023-10-25 19:07:05 +03:00
|
|
|
status, err := c.UpdateTemplate(1, "encodable#code", tpl)
|
2021-11-22 16:08:53 +03:00
|
|
|
t.Assert().NoError(err, fmt.Sprintf("%d %s", status, err))
|
2020-04-08 13:11:46 +03:00
|
|
|
|
|
|
|
templates, status, err := c.TransportTemplates()
|
2021-11-22 16:08:53 +03:00
|
|
|
t.Assert().NoError(err, fmt.Sprintf("%d %s", status, err))
|
2020-04-08 13:11:46 +03:00
|
|
|
|
|
|
|
for _, template := range templates {
|
2023-10-25 19:07:05 +03:00
|
|
|
if template.Code == "encodable#code" {
|
2021-11-22 16:08:53 +03:00
|
|
|
t.Assert().Equal(tpl.Name, template.Name)
|
2020-04-08 13:11:46 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
func (t *MGClientTest) Test_UpdateTemplateFail() {
|
|
|
|
c := t.client()
|
2023-10-25 19:07:05 +03:00
|
|
|
tpl := UpdateTemplateRequest{
|
|
|
|
Name: "updated name",
|
2020-05-11 17:41:17 +03:00
|
|
|
Template: []TemplateItem{
|
|
|
|
{
|
|
|
|
Type: TemplateItemTypeText,
|
|
|
|
Text: "Welcome ",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: TemplateItemTypeVar,
|
|
|
|
VarType: TemplateVarFirstName,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Type: TemplateItemTypeText,
|
|
|
|
Text: "!",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
defer gock.Off()
|
|
|
|
t.gock().
|
|
|
|
Reply(http.StatusBadRequest).
|
2022-10-26 10:54:54 +03:00
|
|
|
JSON(
|
|
|
|
map[string][]string{
|
|
|
|
"errors": {"Some weird error message..."},
|
|
|
|
},
|
|
|
|
)
|
2021-11-22 16:08:53 +03:00
|
|
|
|
2023-10-25 19:07:05 +03:00
|
|
|
status, err := c.UpdateTemplate(1, "encodable#code", tpl)
|
2021-11-22 16:08:53 +03:00
|
|
|
t.Assert().Error(err, fmt.Sprintf("%d %s", status, err))
|
2020-05-11 17:41:17 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
func (t *MGClientTest) Test_DeactivateTemplate() {
|
|
|
|
c := t.client()
|
|
|
|
|
|
|
|
defer gock.Off()
|
|
|
|
t.gock().
|
2022-10-26 10:54:54 +03:00
|
|
|
Filter(
|
|
|
|
func(r *http.Request) bool {
|
|
|
|
return r.Method == http.MethodDelete &&
|
|
|
|
r.URL.Path == t.transportURL("channels/1/templates/test_template#code")
|
|
|
|
},
|
|
|
|
).
|
2021-11-22 16:08:53 +03:00
|
|
|
Reply(http.StatusOK).
|
|
|
|
JSON(map[string]interface{}{})
|
|
|
|
|
|
|
|
status, err := c.DeactivateTemplate(1, "test_template#code")
|
|
|
|
t.Assert().NoError(err, fmt.Sprintf("%d %s", status, err))
|
2020-04-08 13:11:46 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
func (t *MGClientTest) Test_TextMessages() {
|
|
|
|
c := t.client()
|
2018-05-17 17:26:18 +03:00
|
|
|
|
2018-05-21 17:56:42 +03:00
|
|
|
snd := SendData{
|
2018-09-10 11:33:42 +03:00
|
|
|
Message: Message{
|
2021-11-22 16:08:53 +03:00
|
|
|
ExternalID: "external_id",
|
2018-12-05 17:14:51 +03:00
|
|
|
Type: MsgTypeText,
|
2018-09-10 11:33:42 +03:00
|
|
|
Text: "hello!",
|
2023-12-14 14:41:44 +03:00
|
|
|
PageLink: "https://example.loca/catalog/1",
|
2018-05-21 17:56:42 +03:00
|
|
|
},
|
2019-03-12 14:09:54 +03:00
|
|
|
Originator: OriginatorCustomer,
|
|
|
|
Customer: Customer{
|
2018-05-21 17:56:42 +03:00
|
|
|
ExternalID: "6",
|
|
|
|
Nickname: "octopus",
|
|
|
|
Firstname: "Joe",
|
2022-11-18 16:25:50 +03:00
|
|
|
Utm: &Utm{
|
|
|
|
Source: "test-source",
|
|
|
|
Term: "",
|
|
|
|
},
|
2018-05-21 17:56:42 +03:00
|
|
|
},
|
2021-11-22 16:08:53 +03:00
|
|
|
Channel: 1,
|
2018-07-13 15:15:51 +03:00
|
|
|
ExternalChatID: "24798237492374",
|
2018-05-17 17:26:18 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
defer gock.Off()
|
|
|
|
t.gock().
|
|
|
|
Post(t.transportURL("messages")).
|
2023-12-14 14:41:44 +03:00
|
|
|
Filter(func(request *http.Request) bool {
|
|
|
|
data, err := ioutil.ReadAll(request.Body)
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
request.Body = ioutil.NopCloser(bytes.NewReader(data))
|
|
|
|
|
|
|
|
var snd SendData
|
|
|
|
t.Require().NoError(json.Unmarshal(data, &snd))
|
|
|
|
return t.Assert().Equal("https://example.loca/catalog/1", snd.Message.PageLink)
|
|
|
|
}).
|
2021-11-22 16:08:53 +03:00
|
|
|
Reply(http.StatusOK).
|
2022-10-26 10:54:54 +03:00
|
|
|
JSON(
|
|
|
|
MessagesResponse{
|
|
|
|
MessageID: 1,
|
|
|
|
Time: time.Now(),
|
|
|
|
},
|
|
|
|
)
|
2018-05-21 17:56:42 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
data, status, err := c.Messages(snd)
|
|
|
|
t.Require().NoError(err)
|
|
|
|
t.Assert().Equal(http.StatusOK, status)
|
|
|
|
t.Assert().NotEmpty(data.Time.String())
|
|
|
|
t.Assert().Equal(1, data.MessageID)
|
2018-05-17 17:26:18 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
func (t *MGClientTest) Test_ImageMessages() {
|
|
|
|
c := t.client()
|
|
|
|
|
|
|
|
defer gock.Off()
|
|
|
|
|
|
|
|
t.gock().
|
|
|
|
Post(t.transportURL("files/upload_by_url")).
|
|
|
|
Reply(http.StatusOK).
|
2022-10-26 10:54:54 +03:00
|
|
|
JSON(
|
|
|
|
UploadFileResponse{
|
|
|
|
ID: "1",
|
|
|
|
Hash: "1",
|
|
|
|
Type: "image/png",
|
|
|
|
MimeType: "",
|
|
|
|
Size: 1024,
|
|
|
|
CreatedAt: time.Now(),
|
|
|
|
},
|
|
|
|
)
|
2021-11-22 16:08:53 +03:00
|
|
|
|
|
|
|
t.gock().
|
|
|
|
Post(t.transportURL("messages")).
|
|
|
|
Reply(http.StatusOK).
|
2022-10-26 10:54:54 +03:00
|
|
|
JSON(
|
|
|
|
MessagesResponse{
|
|
|
|
MessageID: 1,
|
|
|
|
Time: time.Now(),
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
uploadFileResponse, st, err := c.UploadFileByURL(
|
|
|
|
UploadFileByUrlRequest{
|
|
|
|
Url: "https://via.placeholder.com/1",
|
|
|
|
},
|
|
|
|
)
|
2021-11-22 16:08:53 +03:00
|
|
|
t.Require().NoError(err)
|
|
|
|
t.Assert().Equal(http.StatusOK, st)
|
|
|
|
t.Assert().Equal("1", uploadFileResponse.ID)
|
2018-11-13 12:52:01 +03:00
|
|
|
|
|
|
|
snd := SendData{
|
|
|
|
Message: Message{
|
2021-11-22 16:08:53 +03:00
|
|
|
ExternalID: "file",
|
2018-11-13 12:52:01 +03:00
|
|
|
Type: MsgTypeImage,
|
|
|
|
Items: []Item{{ID: uploadFileResponse.ID}},
|
|
|
|
},
|
2019-03-12 14:09:54 +03:00
|
|
|
Originator: OriginatorCustomer,
|
|
|
|
Customer: Customer{
|
2018-11-13 12:52:01 +03:00
|
|
|
ExternalID: "6",
|
|
|
|
Nickname: "octopus",
|
|
|
|
Firstname: "Joe",
|
|
|
|
},
|
2021-11-22 16:08:53 +03:00
|
|
|
Channel: 1,
|
2018-11-13 12:52:01 +03:00
|
|
|
ExternalChatID: "24798237492374",
|
|
|
|
}
|
|
|
|
|
|
|
|
data, status, err := c.Messages(snd)
|
2021-11-22 16:08:53 +03:00
|
|
|
t.Require().NoError(err)
|
|
|
|
t.Assert().Equal(http.StatusOK, status)
|
|
|
|
t.Assert().NotEmpty(data.Time.String())
|
|
|
|
t.Assert().Equal(1, data.MessageID)
|
2018-11-13 12:52:01 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
func (t *MGClientTest) Test_UpdateMessages() {
|
|
|
|
c := t.client()
|
2018-05-17 17:26:18 +03:00
|
|
|
|
2018-10-03 09:48:07 +03:00
|
|
|
sndU := EditMessageRequest{
|
|
|
|
EditMessageRequestMessage{
|
2021-11-22 16:08:53 +03:00
|
|
|
ExternalID: "editing",
|
2018-10-03 09:48:07 +03:00
|
|
|
Text: "hello hello!",
|
2023-12-14 14:41:44 +03:00
|
|
|
PageLink: "https://example.local/1",
|
2018-05-17 17:26:18 +03:00
|
|
|
},
|
2021-11-22 16:08:53 +03:00
|
|
|
1,
|
2018-05-21 17:56:42 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
defer gock.Off()
|
|
|
|
t.gock().
|
|
|
|
Put(t.transportURL("messages")).
|
2023-12-14 14:41:44 +03:00
|
|
|
Filter(func(request *http.Request) bool {
|
|
|
|
data, err := ioutil.ReadAll(request.Body)
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
request.Body = ioutil.NopCloser(bytes.NewReader(data))
|
|
|
|
|
|
|
|
var snd SendData
|
|
|
|
t.Require().NoError(json.Unmarshal(data, &snd))
|
|
|
|
return t.Assert().Equal("https://example.local/1", snd.Message.PageLink)
|
|
|
|
}).
|
2021-11-22 16:08:53 +03:00
|
|
|
Reply(http.StatusOK).
|
2022-10-26 10:54:54 +03:00
|
|
|
JSON(
|
|
|
|
MessagesResponse{
|
|
|
|
MessageID: 1,
|
|
|
|
Time: time.Now(),
|
|
|
|
},
|
|
|
|
)
|
2018-05-21 17:56:42 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
dataU, status, err := c.UpdateMessages(sndU)
|
|
|
|
t.Require().NoError(err)
|
|
|
|
t.Assert().Equal(http.StatusOK, status)
|
|
|
|
t.Assert().NotEmpty(dataU.Time.String())
|
|
|
|
t.Assert().Equal(1, dataU.MessageID)
|
2018-05-21 17:56:42 +03:00
|
|
|
}
|
|
|
|
|
2022-11-02 17:00:13 +03:00
|
|
|
func (t *MGClientTest) Test_ReadUntil() {
|
|
|
|
c := t.client()
|
|
|
|
req := MarkMessagesReadUntilRequest{
|
|
|
|
CustomerExternalID: "customer",
|
|
|
|
ChannelID: 1,
|
|
|
|
Until: time.Unix(0, 0),
|
|
|
|
}
|
|
|
|
|
|
|
|
defer gock.Off()
|
|
|
|
t.gock().
|
|
|
|
Post("messages/read_until").
|
|
|
|
Reply(http.StatusOK).
|
|
|
|
JSON(MarkMessagesReadUntilResponse{
|
|
|
|
IDs: []int64{1},
|
|
|
|
})
|
|
|
|
|
|
|
|
resp, st, err := c.ReadUntil(req)
|
|
|
|
t.Require().NoError(err)
|
|
|
|
t.Assert().Equal(http.StatusOK, st)
|
|
|
|
t.Assert().Equal([]int64{1}, resp.IDs)
|
|
|
|
}
|
|
|
|
|
2022-11-03 17:26:48 +03:00
|
|
|
func (t *MGClientTest) Test_MessagesHistory() {
|
|
|
|
c := t.client()
|
|
|
|
|
|
|
|
snd := SendHistoryMessageRequest{
|
|
|
|
Message: SendMessageRequestMessage{
|
|
|
|
ExternalID: "external_id",
|
|
|
|
Type: MsgTypeText,
|
|
|
|
Text: "hello!",
|
|
|
|
},
|
|
|
|
Originator: OriginatorCustomer,
|
|
|
|
Customer: &Customer{
|
|
|
|
ExternalID: "6",
|
|
|
|
Nickname: "octopus",
|
|
|
|
Firstname: "Joe",
|
|
|
|
},
|
|
|
|
ChannelID: 1,
|
|
|
|
ExternalChatID: "24798237492374",
|
|
|
|
}
|
|
|
|
|
|
|
|
defer gock.Off()
|
|
|
|
t.gock().
|
|
|
|
Post(t.transportURL("messages/history")).
|
|
|
|
Reply(http.StatusOK).
|
|
|
|
JSON(
|
|
|
|
MessagesResponse{
|
|
|
|
MessageID: 1,
|
|
|
|
Time: time.Now(),
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
data, status, err := c.MessagesHistory(snd)
|
|
|
|
t.Require().NoError(err)
|
|
|
|
t.Assert().Equal(http.StatusOK, status)
|
|
|
|
t.Assert().NotEmpty(data.Time.String())
|
|
|
|
t.Assert().Equal(1, data.MessageID)
|
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
func (t *MGClientTest) Test_MarkMessageReadAndDelete() {
|
|
|
|
c := t.client()
|
2018-05-21 17:56:42 +03:00
|
|
|
|
2018-10-03 09:48:07 +03:00
|
|
|
snd := MarkMessageReadRequest{
|
|
|
|
MarkMessageReadRequestMessage{
|
2021-11-22 16:08:53 +03:00
|
|
|
ExternalID: "external_1",
|
2018-10-03 09:48:07 +03:00
|
|
|
},
|
2021-11-22 16:08:53 +03:00
|
|
|
1,
|
2018-10-03 09:48:07 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
defer gock.Off()
|
|
|
|
t.gock().
|
|
|
|
Post(t.transportURL("messages/read")).
|
|
|
|
Reply(http.StatusOK).
|
|
|
|
JSON(MarkMessageReadResponse{})
|
2018-10-03 09:48:07 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
t.gock().
|
|
|
|
Delete(t.transportURL("messages")).
|
2022-10-26 10:54:54 +03:00
|
|
|
JSON(
|
|
|
|
DeleteData{
|
|
|
|
Message: Message{
|
|
|
|
ExternalID: "deleted",
|
|
|
|
},
|
|
|
|
Channel: 1,
|
2021-11-22 16:08:53 +03:00
|
|
|
},
|
2022-10-26 10:54:54 +03:00
|
|
|
).
|
2021-11-22 16:08:53 +03:00
|
|
|
Reply(http.StatusOK).
|
2022-10-26 10:54:54 +03:00
|
|
|
JSON(
|
|
|
|
MessagesResponse{
|
|
|
|
MessageID: 2,
|
|
|
|
Time: time.Now(),
|
|
|
|
},
|
|
|
|
)
|
2018-05-21 17:56:42 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
_, status, err := c.MarkMessageRead(snd)
|
|
|
|
t.Require().NoError(err)
|
|
|
|
t.Assert().Equal(http.StatusOK, status)
|
2018-12-05 17:14:51 +03:00
|
|
|
|
2022-10-26 10:54:54 +03:00
|
|
|
previousChatMessage, status, err := c.DeleteMessage(
|
|
|
|
DeleteData{
|
|
|
|
Message{
|
|
|
|
ExternalID: "deleted",
|
|
|
|
},
|
|
|
|
1,
|
2018-12-05 17:14:51 +03:00
|
|
|
},
|
2022-10-26 10:54:54 +03:00
|
|
|
)
|
2021-11-22 16:08:53 +03:00
|
|
|
t.Require().NoError(err)
|
|
|
|
t.Assert().Equal(http.StatusOK, status)
|
|
|
|
t.Assert().Equal(2, previousChatMessage.MessageID)
|
2018-05-21 17:56:42 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
func (t *MGClientTest) Test_DeactivateTransportChannel() {
|
|
|
|
c := t.client()
|
2018-05-21 17:56:42 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
defer gock.Off()
|
|
|
|
t.gock().
|
|
|
|
Delete(t.transportURL("channels/1")).
|
|
|
|
Reply(http.StatusOK).
|
2022-10-26 10:54:54 +03:00
|
|
|
JSON(
|
|
|
|
DeleteResponse{
|
|
|
|
ChannelID: 1,
|
|
|
|
DeactivatedAt: time.Now(),
|
|
|
|
},
|
|
|
|
)
|
2018-05-21 17:56:42 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
deleteData, status, err := c.DeactivateTransportChannel(1)
|
|
|
|
t.Require().NoError(err)
|
|
|
|
t.Assert().Equal(http.StatusOK, status)
|
|
|
|
t.Assert().NotEmpty(deleteData.DeactivatedAt.String())
|
|
|
|
t.Assert().Equal(uint64(1), deleteData.ChannelID)
|
2018-05-21 17:56:42 +03:00
|
|
|
}
|
2018-12-05 17:14:51 +03:00
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
func (t *MGClientTest) Test_UploadFile() {
|
|
|
|
c := t.client()
|
2018-12-05 17:14:51 +03:00
|
|
|
|
2020-04-08 13:11:46 +03:00
|
|
|
// 1x1 png picture
|
|
|
|
img := "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAAAXRSTlPM0jRW/QAAAApJREFUeJxjYgAAAAYAAzY3fKgAAAAASUVORK5CYII="
|
|
|
|
binary, err := base64.StdEncoding.DecodeString(img)
|
2018-12-05 17:14:51 +03:00
|
|
|
if err != nil {
|
2021-11-22 16:08:53 +03:00
|
|
|
t.T().Errorf("cannot convert base64 to binary: %s", err)
|
2018-12-05 17:14:51 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
resp := UploadFileResponse{
|
|
|
|
ID: "1",
|
|
|
|
Hash: "1",
|
|
|
|
Type: "image/png",
|
|
|
|
MimeType: "",
|
|
|
|
Size: 1024,
|
|
|
|
CreatedAt: time.Now(),
|
2018-12-05 17:14:51 +03:00
|
|
|
}
|
|
|
|
|
2021-11-22 16:08:53 +03:00
|
|
|
defer gock.Off()
|
|
|
|
t.gock().
|
|
|
|
Post(t.transportURL("files/upload")).
|
|
|
|
Body(bytes.NewReader(binary)).
|
|
|
|
Reply(http.StatusOK).
|
|
|
|
JSON(resp)
|
|
|
|
|
|
|
|
data, status, err := c.UploadFile(bytes.NewReader(binary))
|
|
|
|
t.Require().NoError(err)
|
|
|
|
t.Assert().Equal(http.StatusOK, status)
|
|
|
|
|
|
|
|
resp.CreatedAt = data.CreatedAt
|
|
|
|
t.Assert().Equal(resp, data)
|
2018-12-05 17:14:51 +03:00
|
|
|
}
|
2022-10-25 10:47:02 +03:00
|
|
|
|
2022-10-26 10:54:54 +03:00
|
|
|
func (t *MGClientTest) Test_SuccessHandleError() {
|
2022-10-25 10:47:02 +03:00
|
|
|
client := t.client()
|
2022-10-26 10:54:54 +03:00
|
|
|
json := `{"errors": ["Channel not found"]}`
|
2022-10-25 12:38:51 +03:00
|
|
|
|
|
|
|
defer gock.Off()
|
|
|
|
t.gock().
|
|
|
|
Delete(t.transportURL("channels/123")).
|
|
|
|
Reply(http.StatusInternalServerError)
|
|
|
|
|
2022-10-26 10:54:54 +03:00
|
|
|
t.gock().
|
|
|
|
Delete(t.transportURL("channels/455")).
|
|
|
|
Reply(http.StatusBadRequest).
|
|
|
|
JSON(json)
|
|
|
|
|
2022-10-25 12:38:51 +03:00
|
|
|
_, statusCode, err := client.DeactivateTransportChannel(123)
|
|
|
|
|
|
|
|
t.Assert().Equal(http.StatusInternalServerError, statusCode)
|
2022-10-27 09:28:07 +03:00
|
|
|
t.Assert().IsType(new(HTTPClientError), err)
|
2022-10-26 14:58:32 +03:00
|
|
|
t.Assert().Equal(internalServerError, err.Error())
|
2022-10-27 09:28:07 +03:00
|
|
|
var serverErr *HTTPClientError
|
2022-10-26 10:54:54 +03:00
|
|
|
if errors.As(err, &serverErr) {
|
2022-10-26 18:07:04 +03:00
|
|
|
t.Assert().Nil(serverErr.Response)
|
2022-10-26 10:54:54 +03:00
|
|
|
} else {
|
|
|
|
t.Fail("Unexpected type of error")
|
|
|
|
}
|
|
|
|
|
|
|
|
_, statusCode, err = client.DeactivateTransportChannel(455)
|
|
|
|
t.Assert().Equal(http.StatusBadRequest, statusCode)
|
2022-10-27 09:28:07 +03:00
|
|
|
t.Assert().IsType(new(HTTPClientError), err)
|
2022-10-26 10:54:54 +03:00
|
|
|
t.Assert().Equal("Channel not found", err.Error())
|
2022-10-25 10:47:02 +03:00
|
|
|
}
|