diff --git a/.travis.yml b/.travis.yml index c179abd..d017f16 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,4 +7,5 @@ go: before_install: - go get -v github.com/google/go-querystring/query - go get -v github.com/h2non/gock + - go get -v github.com/stretchr/testify/assert script: go test -v ./... diff --git a/v1/client_test.go b/v1/client_test.go index 7f102d1..0cfc4b5 100644 --- a/v1/client_test.go +++ b/v1/client_test.go @@ -187,8 +187,8 @@ func TestMgClient_TextMessages(t *testing.T) { Type: MsgTypeText, Text: "hello!", }, - Originator: "user", - User: User{ + Originator: OriginatorCustomer, + Customer: Customer{ ExternalID: "6", Nickname: "octopus", Firstname: "Joe", @@ -228,8 +228,8 @@ func TestMgClient_ImageMessages(t *testing.T) { Type: MsgTypeImage, Items: []Item{{ID: uploadFileResponse.ID}}, }, - Originator: "user", - User: User{ + Originator: OriginatorCustomer, + Customer: Customer{ ExternalID: "6", Nickname: "octopus", Firstname: "Joe", diff --git a/v1/types.go b/v1/types.go index 43cfb56..646a463 100644 --- a/v1/types.go +++ b/v1/types.go @@ -1,6 +1,7 @@ package v1 import ( + "errors" "net/http" "time" ) @@ -47,6 +48,13 @@ const ( FileSizeLimit = 20 * 1024 * 1024 ) +const ( + // OriginatorCustomer means message was created by customer + OriginatorCustomer Originator = iota + 1 + // OriginatorChannel means message was created by channel, for example via messenger mobile application + OriginatorChannel +) + // MgClient type type MgClient struct { URL string `json:"url"` @@ -189,8 +197,8 @@ type Channels struct { Limit int `url:"limit,omitempty" json:"limit,omitempty"` } -// User struct -type User struct { +// Customer struct +type Customer struct { ExternalID string `json:"external_id"` Nickname string `json:"nickname"` Firstname string `json:"first_name,omitempty"` @@ -233,8 +241,8 @@ type EditMessageRequestMessage struct { // SendData struct type SendData struct { Message Message `json:"message"` - Originator string `json:"originator,omitempty"` - User User `json:"user"` + Originator Originator `json:"originator,omitempty"` + Customer Customer `json:"customer"` Channel uint64 `json:"channel"` ExternalChatID string `json:"external_chat_id"` Quote *SendMessageRequestQuote `json:"quote,omitempty"` @@ -399,3 +407,20 @@ type TransportRequestMeta struct { ID uint64 `json:"id"` Timestamp int64 `json:"timestamp"` } + +var ErrInvalidOriginator = errors.New("invalid originator") + +// Originator of message +type Originator byte + +// MarshalText marshals originator to text +func (o Originator) MarshalText() ([]byte, error) { + switch o { + case OriginatorCustomer: + return []byte("customer"), nil + case OriginatorChannel: + return []byte("channel"), nil + } + + return nil, ErrInvalidOriginator +} diff --git a/v1/types_test.go b/v1/types_test.go new file mode 100644 index 0000000..bb205fe --- /dev/null +++ b/v1/types_test.go @@ -0,0 +1,104 @@ +package v1 + +import ( + "encoding/json" + "fmt" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestSendData_MarshalJSON(t *testing.T) { + t.Run("WithoutOriginator", func(t *testing.T) { + data, err := json.Marshal(SendData{}) + + assert.NoError(t, err) + + expected := `{ + "channel": 0, + "customer": { + "external_id": "", + "nickname": "" + }, + "external_chat_id": "", + "message": { + "external_id": "" + } + }` + assert.JSONEq(t, expected, string(data)) + }) + + t.Run("WithOriginator", func(t *testing.T) { + cases := []struct { + originator Originator + string string + }{ + { + OriginatorCustomer, + "customer", + }, + { + OriginatorChannel, + "channel", + }, + } + + pattern := `{ + "originator": "%s", + "channel": 0, + "customer": { + "external_id": "", + "nickname": "" + }, + "external_chat_id": "", + "message": { + "external_id": "" + } + }` + + for _, c := range cases { + data, err := json.Marshal(SendData{ + Originator: c.originator, + }) + + assert.NoError(t, err) + assert.JSONEq(t, fmt.Sprintf(pattern, c.string), string(data)) + } + }) +} + +func TestOriginator(t *testing.T) { + b, err := OriginatorCustomer.MarshalText() + assert.NoError(t, err) + assert.Equal(t, "customer", string(b)) + + b, err = OriginatorChannel.MarshalText() + assert.NoError(t, err) + assert.Equal(t, "channel", string(b)) + + t.Run("MarshalText_Valid", func(t *testing.T) { + cases := []struct { + byte byte + expected string + }{ + {1, "customer"}, + {2, "channel"}, + } + for _, c := range cases { + result, err := Originator(c.byte).MarshalText() + assert.NoError(t, err) + assert.Equal(t, c.expected, string(result)) + } + }) + + t.Run("MarshalText_Invalid", func(t *testing.T) { + data, err := Originator(0).MarshalText() + assert.Nil(t, data) + assert.Equal(t, err, ErrInvalidOriginator) + }) + + t.Run("MarshalJSON_Invalid", func(t *testing.T) { + data, err := json.Marshal(Originator(3)) + assert.Nil(t, data) + assert.EqualError(t, err, "json: error calling MarshalJSON for type v1.Originator: invalid originator") + }) +}