package service import ( "context" "testing" "github.com/gochat/gochat/internal/model" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // ========== GetByID 测试 ========== func TestAttachmentService_GetByID_成功(t *testing.T) { db, _, svc := setupAttachmentService(t) account := createTestAccount(t, db) inbox := createTestInbox(t, db, account.ID, "web_widget") contact := createTestContact(t, db, account.ID) conv := createTestConversation(t, db, account.ID, inbox.ID, contact.ID) msg := createTestMessage(t, db, account.ID, inbox.ID, conv.ID) att := createTestAttachment(t, db, msg.ID, account.ID) result, err := svc.GetByID(context.Background(), att.ID) require.NoError(t, err) assert.Equal(t, att.ID, result.ID) assert.Equal(t, msg.ID, result.MessageID) assert.Equal(t, "image", result.FileType) assert.Equal(t, "https://example.com/test.png", result.FileURL) assert.Equal(t, "test.png", result.FileName) assert.Equal(t, 1024, result.FileSize) } func TestAttachmentService_GetByID_不存在(t *testing.T) { _, _, svc := setupAttachmentService(t) result, err := svc.GetByID(context.Background(), 9999) assert.Error(t, err) assert.Nil(t, result) } // ========== ListByMessage 测试 ========== func TestAttachmentService_ListByMessage_成功(t *testing.T) { db, _, svc := setupAttachmentService(t) account := createTestAccount(t, db) inbox := createTestInbox(t, db, account.ID, "web_widget") contact := createTestContact(t, db, account.ID) conv := createTestConversation(t, db, account.ID, inbox.ID, contact.ID) msg := createTestMessage(t, db, account.ID, inbox.ID, conv.ID) // 为同一消息创建多个附件 att1 := &model.Attachment{ MessageID: msg.ID, AccountID: account.ID, FileType: "image", FileURL: "https://example.com/img1.png", FileName: "img1.png", FileSize: 1024, } att2 := &model.Attachment{ MessageID: msg.ID, AccountID: account.ID, FileType: "file", FileURL: "https://example.com/doc1.pdf", FileName: "doc1.pdf", FileSize: 2048, } require.NoError(t, db.Create(att1).Error) require.NoError(t, db.Create(att2).Error) attachments, err := svc.ListByMessage(context.Background(), msg.ID) require.NoError(t, err) require.Len(t, attachments, 2) assert.Equal(t, att1.ID, attachments[0].ID) assert.Equal(t, att2.ID, attachments[1].ID) } func TestAttachmentService_ListByMessage_无附件(t *testing.T) { db, _, svc := setupAttachmentService(t) account := createTestAccount(t, db) inbox := createTestInbox(t, db, account.ID, "web_widget") contact := createTestContact(t, db, account.ID) conv := createTestConversation(t, db, account.ID, inbox.ID, contact.ID) msg := createTestMessage(t, db, account.ID, inbox.ID, conv.ID) attachments, err := svc.ListByMessage(context.Background(), msg.ID) require.NoError(t, err) assert.Empty(t, attachments) } func TestAttachmentService_ListByMessage_不存在的消息(t *testing.T) { _, _, svc := setupAttachmentService(t) attachments, err := svc.ListByMessage(context.Background(), 9999) require.NoError(t, err) assert.Empty(t, attachments) } // ========== Create 测试 ========== func TestAttachmentService_Create_成功(t *testing.T) { db, _, svc := setupAttachmentService(t) account := createTestAccount(t, db) inbox := createTestInbox(t, db, account.ID, "web_widget") contact := createTestContact(t, db, account.ID) conv := createTestConversation(t, db, account.ID, inbox.ID, contact.ID) msg := createTestMessage(t, db, account.ID, inbox.ID, conv.ID) req := CreateAttachmentRequest{ MessageID: msg.ID, FileType: "image", ExternalURL: "https://external.example.com/img", FileURL: "https://example.com/created.png", ThumbURL: "https://example.com/thumb.png", FileSize: 512, FileName: "created.png", Width: 800, Height: 600, AltText: "测试图片", Metadata: "", } result, err := svc.Create(context.Background(), req) require.NoError(t, err) assert.NotZero(t, result.ID) assert.Equal(t, msg.ID, result.MessageID) assert.Equal(t, "image", result.FileType) assert.Equal(t, "https://external.example.com/img", result.ExternalURL) assert.Equal(t, "https://example.com/created.png", result.FileURL) assert.Equal(t, "https://example.com/thumb.png", result.ThumbURL) assert.Equal(t, 512, result.FileSize) assert.Equal(t, "created.png", result.FileName) assert.Equal(t, 800, result.Width) assert.Equal(t, 600, result.Height) assert.Equal(t, "测试图片", result.AltText) } func TestAttachmentService_Create_不同文件类型(t *testing.T) { db, _, svc := setupAttachmentService(t) account := createTestAccount(t, db) inbox := createTestInbox(t, db, account.ID, "web_widget") contact := createTestContact(t, db, account.ID) conv := createTestConversation(t, db, account.ID, inbox.ID, contact.ID) msg := createTestMessage(t, db, account.ID, inbox.ID, conv.ID) fileTypes := []string{"image", "audio", "video", "file", "location", "emoji", "contact"} for i, ft := range fileTypes { req := CreateAttachmentRequest{ MessageID: msg.ID, FileType: ft, FileURL: "https://example.com/" + ft, FileName: ft + ".ext", FileSize: 100 * (i + 1), } result, err := svc.Create(context.Background(), req) require.NoError(t, err) assert.Equal(t, ft, result.FileType) } } // ========== Delete 测试 ========== func TestAttachmentService_Delete_成功(t *testing.T) { db, _, svc := setupAttachmentService(t) account := createTestAccount(t, db) inbox := createTestInbox(t, db, account.ID, "web_widget") contact := createTestContact(t, db, account.ID) conv := createTestConversation(t, db, account.ID, inbox.ID, contact.ID) msg := createTestMessage(t, db, account.ID, inbox.ID, conv.ID) att := createTestAttachment(t, db, msg.ID, account.ID) err := svc.Delete(context.Background(), att.ID) require.NoError(t, err) // 验证删除后无法再查询到 result, err := svc.GetByID(context.Background(), att.ID) assert.Error(t, err) assert.Nil(t, result) } func TestAttachmentService_Delete_不存在(t *testing.T) { _, _, svc := setupAttachmentService(t) // 删除不存在的附件不应返回错误(GORM Delete 对不存在的记录不报错) err := svc.Delete(context.Background(), 9999) assert.NoError(t, err) } // ========== DeleteByMessage 测试 ========== func TestAttachmentService_DeleteByMessage_成功(t *testing.T) { db, _, svc := setupAttachmentService(t) account := createTestAccount(t, db) inbox := createTestInbox(t, db, account.ID, "web_widget") contact := createTestContact(t, db, account.ID) conv := createTestConversation(t, db, account.ID, inbox.ID, contact.ID) msg := createTestMessage(t, db, account.ID, inbox.ID, conv.ID) // 创建多个附件 att1 := &model.Attachment{ MessageID: msg.ID, AccountID: account.ID, FileType: "image", FileURL: "https://example.com/img1.png", FileName: "img1.png", FileSize: 1024, } att2 := &model.Attachment{ MessageID: msg.ID, AccountID: account.ID, FileType: "file", FileURL: "https://example.com/doc1.pdf", FileName: "doc1.pdf", FileSize: 2048, } require.NoError(t, db.Create(att1).Error) require.NoError(t, db.Create(att2).Error) err := svc.DeleteByMessage(context.Background(), msg.ID) require.NoError(t, err) // 验证该消息的所有附件都被删除 attachments, err := svc.ListByMessage(context.Background(), msg.ID) require.NoError(t, err) assert.Empty(t, attachments) } func TestAttachmentService_DeleteByMessage_不影响其他消息(t *testing.T) { db, _, svc := setupAttachmentService(t) account := createTestAccount(t, db) inbox := createTestInbox(t, db, account.ID, "web_widget") contact := createTestContact(t, db, account.ID) conv := createTestConversation(t, db, account.ID, inbox.ID, contact.ID) msg1 := createTestMessage(t, db, account.ID, inbox.ID, conv.ID) msg2 := createTestMessage(t, db, account.ID, inbox.ID, conv.ID) // 为两个不同消息创建附件 att1 := &model.Attachment{ MessageID: msg1.ID, AccountID: account.ID, FileType: "image", FileURL: "https://example.com/img1.png", FileName: "img1.png", FileSize: 1024, } att2 := &model.Attachment{ MessageID: msg2.ID, AccountID: account.ID, FileType: "file", FileURL: "https://example.com/doc1.pdf", FileName: "doc1.pdf", FileSize: 2048, } require.NoError(t, db.Create(att1).Error) require.NoError(t, db.Create(att2).Error) // 只删除 msg1 的附件 err := svc.DeleteByMessage(context.Background(), msg1.ID) require.NoError(t, err) // msg1 的附件应该被清空 attachments1, err := svc.ListByMessage(context.Background(), msg1.ID) require.NoError(t, err) assert.Empty(t, attachments1) // msg2 的附件应该保留 attachments2, err := svc.ListByMessage(context.Background(), msg2.ID) require.NoError(t, err) require.Len(t, attachments2, 1) assert.Equal(t, att2.ID, attachments2[0].ID) } func TestAttachmentService_DeleteByMessage_不存在的消息(t *testing.T) { _, _, svc := setupAttachmentService(t) // 删除不存在消息的附件不应返回错误 err := svc.DeleteByMessage(context.Background(), 9999) assert.NoError(t, err) }