H-418: cover widget direct upload file flow (#76)

Co-authored-by: Rogee <rogee@ipao.vip>
This commit is contained in:
Rogee
2026-08-21 14:17:03 +08:00
committed by GitHub
co-authored by rogee
parent b971b09ac7
commit e8fa7c9c2c
@@ -11,6 +11,8 @@ import (
"mime/multipart"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strconv"
"strings"
"testing"
@@ -26,6 +28,8 @@ import (
"github.com/gochat/gochat/internal/automation"
"github.com/gochat/gochat/internal/campaign"
"github.com/gochat/gochat/internal/config"
apiv1 "github.com/gochat/gochat/internal/handler/api/v1"
"github.com/gochat/gochat/internal/model"
channelmodel "github.com/gochat/gochat/internal/model/channel"
"github.com/gochat/gochat/internal/repository"
@@ -963,6 +967,13 @@ func TestWidgetHandler_ChatwootMessageReplyToContentAttributes(t *testing.T) {
func TestWidgetHandler_ChatwootMessageDirectUploadAttachment(t *testing.T) {
db, router, _ := setupWidgetHandlerTest(t)
account, _ := seedWidgetHandlerData(t, db)
tmpDir := t.TempDir()
uploadSvc := service.NewUploadService(repository.NewDirectUploadRepo(db), &config.Config{
Storage: config.StorageConfig{LocalPath: tmpDir, MaxFileSize: 50 << 20},
}).WithWidgetAuth(repository.NewInboxRepo(db), repository.NewContactInboxRepo(db))
uploadHandler := apiv1.NewUploadHandler(uploadSvc)
router.POST("/api/v1/widget/direct_uploads", uploadHandler.DirectUpload)
router.PUT("/api/v1/widget/direct_uploads/:upload_uuid", uploadHandler.CompleteWidgetDirectUpload)
wConfig := httptest.NewRecorder()
reqConfig, _ := http.NewRequest("POST", "/api/v1/widget/config?website_token=handler_ws_token_123", nil)
@@ -973,24 +984,46 @@ func TestWidgetHandler_ChatwootMessageDirectUploadAttachment(t *testing.T) {
require.NoError(t, json.Unmarshal(wConfig.Body.Bytes(), &configResp))
authToken := configResp["contact"].(map[string]interface{})["pubsub_token"].(string)
upload := &model.DirectUpload{
UploadUUID: "signed-widget-upload-1",
AccountID: account.ID,
Status: model.DirectUploadStatusPending,
Source: model.DirectUploadSourceWidget,
OriginalName: "screenshot.png",
FileType: "image",
MimeType: "image/png",
FileSize: 12,
FileURL: "/uploads/widget_direct/signed-widget-upload-1.png",
ThumbURL: "/uploads/widget_direct/signed-widget-upload-1.png",
ExpiresAt: time.Now().Add(time.Hour),
}
require.NoError(t, db.Create(upload).Error)
fileContent := []byte("hello image")
metadataBody, err := json.Marshal(map[string]interface{}{
"blob": map[string]interface{}{
"filename": "screenshot.png",
"byte_size": len(fileContent),
"checksum": "checksum-token",
"content_type": "image/png",
"metadata": map[string]interface{}{"identified": true},
},
})
require.NoError(t, err)
wCreate := httptest.NewRecorder()
reqCreate, _ := http.NewRequest("POST", "/api/v1/widget/direct_uploads?website_token=handler_ws_token_123", bytes.NewReader(metadataBody))
reqCreate.Header.Set("Content-Type", "application/json")
reqCreate.Header.Set("X-Auth-Token", authToken)
router.ServeHTTP(wCreate, reqCreate)
require.Equal(t, http.StatusOK, wCreate.Code)
var createResp map[string]interface{}
require.NoError(t, json.Unmarshal(wCreate.Body.Bytes(), &createResp))
signedID := createResp["signed_id"].(string)
uploadURL := createResp["direct_upload"].(map[string]interface{})["url"].(string)
wPut := httptest.NewRecorder()
reqPut, _ := http.NewRequest("PUT", uploadURL, bytes.NewReader(fileContent))
reqPut.Header.Set("Content-Type", "image/png")
router.ServeHTTP(wPut, reqPut)
require.Equal(t, http.StatusOK, wPut.Code)
storedBytes, err := os.ReadFile(filepath.Join(tmpDir, "widget_direct", signedID+".png"))
require.NoError(t, err)
assert.Equal(t, fileContent, storedBytes)
var upload model.DirectUpload
require.NoError(t, db.Where("upload_uuid = ?", signedID).First(&upload).Error)
require.Equal(t, model.DirectUploadStatusPending, upload.Status)
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
require.NoError(t, writer.WriteField("message[attachments][]", upload.UploadUUID))
require.NoError(t, writer.WriteField("message[attachments][]", signedID))
require.NoError(t, writer.Close())
wMessage := httptest.NewRecorder()
@@ -1008,7 +1041,7 @@ func TestWidgetHandler_ChatwootMessageDirectUploadAttachment(t *testing.T) {
require.Len(t, attachments, 1)
attachmentPayload := attachments[0].(map[string]interface{})
assertWidgetAttachmentFixtureShape(t, attachmentPayload)
assert.Equal(t, "/uploads/widget_direct/signed-widget-upload-1.png", attachmentPayload["data_url"])
assert.Equal(t, upload.FileURL, attachmentPayload["data_url"])
assert.Equal(t, "image", attachmentPayload["file_type"])
assert.Equal(t, float64(account.ID), attachmentPayload["account_id"])
assert.NotContains(t, attachmentPayload, "created_at")
@@ -1016,7 +1049,7 @@ func TestWidgetHandler_ChatwootMessageDirectUploadAttachment(t *testing.T) {
var attachment model.Attachment
require.NoError(t, db.Where("file_name = ?", "screenshot.png").First(&attachment).Error)
assert.Equal(t, upload.FileURL, attachment.FileURL)
require.NoError(t, db.First(upload, upload.ID).Error)
require.NoError(t, db.First(&upload, upload.ID).Error)
assert.Equal(t, model.DirectUploadStatusCompleted, upload.Status)
wIndex := httptest.NewRecorder()
@@ -1035,7 +1068,7 @@ func TestWidgetHandler_ChatwootMessageDirectUploadAttachment(t *testing.T) {
require.Len(t, indexedAttachments, 1)
indexedAttachment := indexedAttachments[0].(map[string]interface{})
assertWidgetAttachmentFixtureShape(t, indexedAttachment)
assert.Equal(t, "/uploads/widget_direct/signed-widget-upload-1.png", indexedAttachment["data_url"])
assert.Equal(t, upload.FileURL, indexedAttachment["data_url"])
assert.Equal(t, float64(account.ID), indexedAttachment["account_id"])
assert.NotContains(t, indexedAttachment, "created_at")
}