feat(inboxes): bind chatwoot channel settings
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
@@ -109,6 +110,104 @@ func TestInboxHandler_ChatwootSerializerParity(t *testing.T) {
|
||||
require.Equal(t, "Your inbox deletion request will be processed in some time.", inboxParityObject(t, destroy)["message"])
|
||||
}
|
||||
|
||||
func TestInboxHandler_ChatwootCreateUpdateRequestBinding(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
db, err := gorm.Open(sqlite.Open("file:inbox_handler_binding?mode=memory&cache=shared"), &gorm.Config{
|
||||
Logger: logger.Default.LogMode(logger.Silent),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
sqlDB, dbErr := db.DB()
|
||||
if dbErr == nil {
|
||||
_ = sqlDB.Close()
|
||||
}
|
||||
})
|
||||
require.NoError(t, db.AutoMigrate(&model.Account{}, &model.Inbox{}))
|
||||
|
||||
account := &model.Account{Name: "Inbox Binding", Locale: "en", Active: true}
|
||||
require.NoError(t, db.Create(account).Error)
|
||||
router := setupInboxParityRouter(db)
|
||||
|
||||
websiteCreate := inboxParityMultipartRequest(t, router, http.MethodPost, fmt.Sprintf("/api/v1/accounts/%d/inboxes/", account.ID), map[string][]string{
|
||||
"name": {"Website"},
|
||||
"greeting_enabled": {"true"},
|
||||
"greeting_message": {"Hello from Chatwoot"},
|
||||
"enable_email_collect": {"false"},
|
||||
"allow_messages_after_resolved": {"true"},
|
||||
"sender_name_type": {"business_name"},
|
||||
"business_name": {"Acme Support"},
|
||||
"channel[type]": {"web_widget"},
|
||||
"channel[website_url]": {"https://acme.example"},
|
||||
"channel[widget_color]": {"#f97316"},
|
||||
"channel[welcome_title]": {"Hi there"},
|
||||
"channel[welcome_tagline]": {"We reply quickly"},
|
||||
"channel[selected_feature_flags][]": {"attachments", "emoji_picker"},
|
||||
})
|
||||
require.Equal(t, http.StatusOK, websiteCreate.Code, websiteCreate.Body.String())
|
||||
websiteData := inboxParityObject(t, websiteCreate)
|
||||
require.Equal(t, "Channel::WebWidget", websiteData["channel_type"])
|
||||
require.Equal(t, "https://acme.example", websiteData["website_url"])
|
||||
require.Equal(t, "#f97316", websiteData["widget_color"])
|
||||
require.Equal(t, "Hi there", websiteData["welcome_title"])
|
||||
require.NotEmpty(t, websiteData["website_token"])
|
||||
require.NotEmpty(t, websiteData["hmac_token"])
|
||||
require.Equal(t, false, websiteData["enable_email_collect"])
|
||||
require.Equal(t, "business_name", websiteData["sender_name_type"])
|
||||
require.Equal(t, "Acme Support", websiteData["business_name"])
|
||||
require.ElementsMatch(t, []any{"attachments", "emoji_picker"}, websiteData["selected_feature_flags"].([]any))
|
||||
|
||||
apiCreate := inboxParityRequest(t, router, http.MethodPost, fmt.Sprintf("/api/v1/accounts/%d/inboxes/", account.ID), map[string]any{
|
||||
"name": "API",
|
||||
"channel": map[string]any{
|
||||
"type": "api",
|
||||
"webhook_url": "https://hooks.example/chatwoot",
|
||||
},
|
||||
})
|
||||
require.Equal(t, http.StatusOK, apiCreate.Code, apiCreate.Body.String())
|
||||
apiData := inboxParityObject(t, apiCreate)
|
||||
require.Equal(t, "Channel::Api", apiData["channel_type"])
|
||||
require.Equal(t, "https://hooks.example/chatwoot", apiData["webhook_url"])
|
||||
require.NotEmpty(t, apiData["secret"])
|
||||
require.NotEmpty(t, apiData["hmac_token"])
|
||||
require.NotEmpty(t, apiData["inbox_identifier"])
|
||||
|
||||
telegramCreate := inboxParityRequest(t, router, http.MethodPost, fmt.Sprintf("/api/v1/accounts/%d/inboxes/", account.ID), map[string]any{
|
||||
"channel": map[string]any{
|
||||
"type": "telegram",
|
||||
"bot_token": "123:telegram-token",
|
||||
},
|
||||
})
|
||||
require.Equal(t, http.StatusOK, telegramCreate.Code, telegramCreate.Body.String())
|
||||
telegramData := inboxParityObject(t, telegramCreate)
|
||||
require.Equal(t, "Telegram", telegramData["name"])
|
||||
require.Equal(t, "Channel::Telegram", telegramData["channel_type"])
|
||||
|
||||
websiteID := uint(websiteData["id"].(float64))
|
||||
update := inboxParityMultipartRequest(t, router, http.MethodPatch, fmt.Sprintf("/api/v1/accounts/%d/inboxes/%d", account.ID, websiteID), map[string][]string{
|
||||
"name": {"Website Updated"},
|
||||
"enable_auto_assignment": {"true"},
|
||||
"csat_survey_enabled": {"true"},
|
||||
"csat_config[display_type]": {"emoji"},
|
||||
"csat_config[message]": {"Rate this conversation"},
|
||||
"csat_config[survey_rules][operator]": {"contains"},
|
||||
"csat_config[survey_rules][values][]": {"vip", "priority"},
|
||||
"channel[website_url]": {"https://updated.example"},
|
||||
"channel[welcome_tagline]": {"Updated tagline"},
|
||||
})
|
||||
require.Equal(t, http.StatusOK, update.Code, update.Body.String())
|
||||
updateData := inboxParityObject(t, update)
|
||||
require.Equal(t, "Website Updated", updateData["name"])
|
||||
require.Equal(t, true, updateData["enable_auto_assignment"])
|
||||
require.Equal(t, true, updateData["csat_survey_enabled"])
|
||||
require.Equal(t, "https://updated.example", updateData["website_url"])
|
||||
require.Equal(t, "Updated tagline", updateData["welcome_tagline"])
|
||||
csatConfig := updateData["csat_config"].(map[string]any)
|
||||
require.Equal(t, "Rate this conversation", csatConfig["message"])
|
||||
require.Equal(t, "Please rate us", csatConfig["button_text"])
|
||||
require.ElementsMatch(t, []any{"vip", "priority"}, csatConfig["survey_rules"].(map[string]any)["values"].([]any))
|
||||
}
|
||||
|
||||
func setupInboxParityRouter(db *gorm.DB) *gin.Engine {
|
||||
inboxSvc := service.NewInboxService(repository.NewInboxRepo(db), nil, nil, nil, nil, nil, nil)
|
||||
handler := NewInboxHandler(inboxSvc)
|
||||
@@ -143,6 +242,23 @@ func inboxParityRequest(t *testing.T, router *gin.Engine, method string, path st
|
||||
return w
|
||||
}
|
||||
|
||||
func inboxParityMultipartRequest(t *testing.T, router *gin.Engine, method string, path string, fields map[string][]string) *httptest.ResponseRecorder {
|
||||
t.Helper()
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
for key, values := range fields {
|
||||
for _, value := range values {
|
||||
require.NoError(t, writer.WriteField(key, value))
|
||||
}
|
||||
}
|
||||
require.NoError(t, writer.Close())
|
||||
req := httptest.NewRequest(method, path, body)
|
||||
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
return w
|
||||
}
|
||||
|
||||
func inboxParityObject(t *testing.T, response *httptest.ResponseRecorder) map[string]any {
|
||||
t.Helper()
|
||||
var data map[string]any
|
||||
|
||||
Reference in New Issue
Block a user