660 lines
20 KiB
Plaintext
660 lines
20 KiB
Plaintext
package service
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"testing"
|
|
|
|
"github.com/gochat/gochat/internal/model"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// ========== Create ==========
|
|
|
|
func TestDashboardAppService_Create_成功(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
|
|
req := &CreateDashboardAppRequest{
|
|
Title: "销售仪表盘",
|
|
Description: "销售数据看板",
|
|
Kind: "frame",
|
|
Content: json.RawMessage(`[{"type":"frame","url":"https://example.com/widget"}]`),
|
|
}
|
|
|
|
app, err := svc.Create(context.Background(), account.ID, nil, req)
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, app.ID)
|
|
assert.Equal(t, account.ID, app.AccountID)
|
|
assert.Nil(t, app.UserID)
|
|
assert.Equal(t, "销售仪表盘", app.Title)
|
|
assert.Equal(t, "销售数据看板", app.Description)
|
|
assert.Equal(t, "frame", app.Kind)
|
|
assert.True(t, *app.Active)
|
|
assert.Equal(t, json.RawMessage(`[{"type":"frame","url":"https://example.com/widget"}]`), app.Content)
|
|
}
|
|
|
|
func TestDashboardAppService_Create_带UserID(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
user := createTestUser(t, db, account.ID)
|
|
|
|
userID := user.ID
|
|
req := &CreateDashboardAppRequest{
|
|
Title: "个人仪表盘",
|
|
Content: json.RawMessage(`[{"type":"frame","url":"https://example.com/personal"}]`),
|
|
}
|
|
|
|
app, err := svc.Create(context.Background(), account.ID, &userID, req)
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, app.ID)
|
|
assert.Equal(t, account.ID, app.AccountID)
|
|
assert.NotNil(t, app.UserID)
|
|
assert.Equal(t, user.ID, *app.UserID)
|
|
}
|
|
|
|
func TestDashboardAppService_Create_空Content(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
|
|
req := &CreateDashboardAppRequest{
|
|
Title: "空内容仪表盘",
|
|
Content: json.RawMessage(""),
|
|
}
|
|
|
|
app, err := svc.Create(context.Background(), account.ID, nil, req)
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, app.ID)
|
|
assert.Equal(t, "空内容仪表盘", app.Title)
|
|
// Content should default to []
|
|
assert.Equal(t, json.RawMessage("[]"), app.Content)
|
|
}
|
|
|
|
func TestDashboardAppService_Create_设置ActiveFalse(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
|
|
active := false
|
|
req := &CreateDashboardAppRequest{
|
|
Title: "禁用仪表盘",
|
|
Active: &active,
|
|
}
|
|
|
|
app, err := svc.Create(context.Background(), account.ID, nil, req)
|
|
require.NoError(t, err)
|
|
assert.False(t, *app.Active)
|
|
}
|
|
|
|
func TestDashboardAppService_Create_无效Content(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
|
|
req := &CreateDashboardAppRequest{
|
|
Title: "无效内容",
|
|
Content: json.RawMessage(`{"not_array":true}`),
|
|
}
|
|
|
|
app, err := svc.Create(context.Background(), account.ID, nil, req)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, app)
|
|
// Error should mention "must be a JSON array"
|
|
assert.Contains(t, err.Error(), "JSON array")
|
|
}
|
|
|
|
func TestDashboardAppService_Create_无效WidgetURL(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
|
|
req := &CreateDashboardAppRequest{
|
|
Title: "无效URL",
|
|
Content: json.RawMessage(`[{"type":"frame","url":"ftp://bad.com"}]`),
|
|
}
|
|
|
|
app, err := svc.Create(context.Background(), account.ID, nil, req)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, app)
|
|
assert.Contains(t, err.Error(), "http/https")
|
|
}
|
|
|
|
func TestDashboardAppService_Create_无效WidgetType(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
|
|
req := &CreateDashboardAppRequest{
|
|
Title: "无效类型",
|
|
Content: json.RawMessage(`[{"type":"link","url":"https://example.com"}]`),
|
|
}
|
|
|
|
app, err := svc.Create(context.Background(), account.ID, nil, req)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, app)
|
|
assert.Contains(t, err.Error(), "must be 'frame'")
|
|
}
|
|
|
|
// ========== GetByID ==========
|
|
|
|
func TestDashboardAppService_GetByID_成功(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
|
|
created := createTestDashboardApp(t, db, account.ID)
|
|
|
|
app, err := svc.GetByID(context.Background(), created.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, created.ID, app.ID)
|
|
assert.Equal(t, created.Title, app.Title)
|
|
assert.Equal(t, created.AccountID, app.AccountID)
|
|
assert.Equal(t, "frame", app.Kind)
|
|
assert.True(t, *app.Active)
|
|
}
|
|
|
|
func TestDashboardAppService_GetByID_不存在(t *testing.T) {
|
|
_, _, svc := setupDashboardAppService(t)
|
|
|
|
app, err := svc.GetByID(context.Background(), 99999)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, app)
|
|
}
|
|
|
|
// ========== Update ==========
|
|
|
|
func TestDashboardAppService_Update_修改Title(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
created := createTestDashboardApp(t, db, account.ID)
|
|
|
|
req := &UpdateDashboardAppRequest{
|
|
Title: "更新后的标题",
|
|
Content: json.RawMessage(""),
|
|
}
|
|
|
|
app, err := svc.Update(context.Background(), created.ID, req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "更新后的标题", app.Title)
|
|
// Content unchanged because req.Content is ""
|
|
assert.Equal(t, created.Content, app.Content)
|
|
}
|
|
|
|
func TestDashboardAppService_Update_修改Content(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
created := createTestDashboardApp(t, db, account.ID)
|
|
|
|
req := &UpdateDashboardAppRequest{
|
|
Title: "",
|
|
Content: json.RawMessage(`[{"type":"frame","url":"https://example.com/kpi"}]`),
|
|
}
|
|
|
|
app, err := svc.Update(context.Background(), created.ID, req)
|
|
require.NoError(t, err)
|
|
// Title unchanged because req.Title is ""
|
|
assert.Equal(t, created.Title, app.Title)
|
|
assert.Equal(t, json.RawMessage(`[{"type":"frame","url":"https://example.com/kpi"}]`), app.Content)
|
|
}
|
|
|
|
func TestDashboardAppService_Update_修改Description和Active(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
created := createTestDashboardApp(t, db, account.ID)
|
|
|
|
active := false
|
|
req := &UpdateDashboardAppRequest{
|
|
Description: "新描述",
|
|
Active: &active,
|
|
}
|
|
|
|
app, err := svc.Update(context.Background(), created.ID, req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "新描述", app.Description)
|
|
assert.False(t, *app.Active)
|
|
// Title unchanged
|
|
assert.Equal(t, created.Title, app.Title)
|
|
}
|
|
|
|
func TestDashboardAppService_Update_不存在(t *testing.T) {
|
|
_, _, svc := setupDashboardAppService(t)
|
|
|
|
req := &UpdateDashboardAppRequest{
|
|
Title: "不存在",
|
|
Content: json.RawMessage(""),
|
|
}
|
|
|
|
app, err := svc.Update(context.Background(), 99999, req)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, app)
|
|
}
|
|
|
|
// ========== Patch (partial update via Update) ==========
|
|
|
|
func TestDashboardAppService_Patch_只修改Active(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
created := createTestDashboardApp(t, db, account.ID)
|
|
|
|
active := false
|
|
req := &UpdateDashboardAppRequest{
|
|
Active: &active,
|
|
}
|
|
|
|
app, err := svc.Update(context.Background(), created.ID, req)
|
|
require.NoError(t, err)
|
|
assert.False(t, *app.Active)
|
|
// All other fields unchanged
|
|
assert.Equal(t, created.Title, app.Title)
|
|
assert.Equal(t, created.Content, app.Content)
|
|
assert.Equal(t, created.Description, app.Description)
|
|
}
|
|
|
|
// ========== Delete ==========
|
|
|
|
func TestDashboardAppService_Delete_成功(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
created := createTestDashboardApp(t, db, account.ID)
|
|
|
|
err := svc.Delete(context.Background(), created.ID)
|
|
require.NoError(t, err)
|
|
|
|
// Verify deletion — GetByID should fail
|
|
app, err := svc.GetByID(context.Background(), created.ID)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, app)
|
|
}
|
|
|
|
func TestDashboardAppService_Delete_不存在(t *testing.T) {
|
|
_, _, svc := setupDashboardAppService(t)
|
|
|
|
// Deleting non-existent ID should not error (gorm soft-delete with non-existent ID is OK)
|
|
err := svc.Delete(context.Background(), 99999)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
// ========== ListByAccount ==========
|
|
|
|
func TestDashboardAppService_ListByAccount_成功(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
|
|
// Create 3 dashboard apps for the same account
|
|
for i := 0; i < 3; i++ {
|
|
createTestDashboardApp(t, db, account.ID, func(app *model.DashboardApp) {
|
|
app.Title = "仪表盘-" + string(rune('A'+i))
|
|
})
|
|
}
|
|
|
|
apps, count, err := svc.ListByAccount(context.Background(), account.ID, 1, 10)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(3), count)
|
|
assert.Len(t, apps, 3)
|
|
}
|
|
|
|
func TestDashboardAppService_ListByAccount_分页(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
|
|
// Create 5 dashboard apps
|
|
for i := 0; i < 5; i++ {
|
|
createTestDashboardApp(t, db, account.ID)
|
|
}
|
|
|
|
// Page 1: perPage=2 → 2 items, total count=5
|
|
apps, count, err := svc.ListByAccount(context.Background(), account.ID, 1, 2)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(5), count)
|
|
assert.Len(t, apps, 2)
|
|
|
|
// Page 2: perPage=2 → 2 items
|
|
apps, count, err = svc.ListByAccount(context.Background(), account.ID, 2, 2)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(5), count)
|
|
assert.Len(t, apps, 2)
|
|
|
|
// Page 3: perPage=2 → 1 item
|
|
apps, count, err = svc.ListByAccount(context.Background(), account.ID, 3, 2)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(5), count)
|
|
assert.Len(t, apps, 1)
|
|
}
|
|
|
|
func TestDashboardAppService_ListByAccount_空列表(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
|
|
apps, count, err := svc.ListByAccount(context.Background(), account.ID, 1, 10)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(0), count)
|
|
assert.Len(t, apps, 0)
|
|
}
|
|
|
|
func TestDashboardAppService_ListByAccount_不同账户隔离(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account1 := createTestAccount(t, db)
|
|
account2 := createTestAccount(t, db)
|
|
|
|
createTestDashboardApp(t, db, account1.ID)
|
|
createTestDashboardApp(t, db, account1.ID)
|
|
createTestDashboardApp(t, db, account2.ID)
|
|
|
|
// account1 should have 2
|
|
apps, count, err := svc.ListByAccount(context.Background(), account1.ID, 1, 10)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(2), count)
|
|
assert.Len(t, apps, 2)
|
|
|
|
// account2 should have 1
|
|
apps, count, err = svc.ListByAccount(context.Background(), account2.ID, 1, 10)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(1), count)
|
|
assert.Len(t, apps, 1)
|
|
}
|
|
|
|
// ========== ListActiveByAccount ==========
|
|
|
|
func TestDashboardAppService_ListActiveByAccount_只返回Active(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
|
|
// Create 2 active apps
|
|
createTestDashboardApp(t, db, account.ID)
|
|
createTestDashboardApp(t, db, account.ID)
|
|
// Create 1 inactive app
|
|
createTestDashboardApp(t, db, account.ID, func(app *model.DashboardApp) {
|
|
app.Active = model.BoolPtr(false)
|
|
})
|
|
|
|
apps, count, err := svc.ListActiveByAccount(context.Background(), account.ID, 1, 10)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(2), count)
|
|
assert.Len(t, apps, 2)
|
|
for _, a := range apps {
|
|
assert.True(t, *a.Active)
|
|
}
|
|
}
|
|
|
|
// ========== Search ==========
|
|
|
|
func TestDashboardAppService_Search_按标题搜索(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
|
|
// Create apps with different titles
|
|
createTestDashboardApp(t, db, account.ID, func(app *model.DashboardApp) {
|
|
app.Title = "销售仪表盘"
|
|
})
|
|
createTestDashboardApp(t, db, account.ID, func(app *model.DashboardApp) {
|
|
app.Title = "客服监控面板"
|
|
})
|
|
createTestDashboardApp(t, db, account.ID, func(app *model.DashboardApp) {
|
|
app.Title = "运营数据看板"
|
|
})
|
|
|
|
apps, count, err := svc.Search(context.Background(), account.ID, "仪表盘", 1, 10)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(1), count)
|
|
assert.Len(t, apps, 1)
|
|
assert.Equal(t, "销售仪表盘", apps[0].Title)
|
|
}
|
|
|
|
func TestDashboardAppService_Search_空结果(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
|
|
createTestDashboardApp(t, db, account.ID, func(app *model.DashboardApp) {
|
|
app.Title = "客服监控"
|
|
})
|
|
|
|
apps, count, err := svc.Search(context.Background(), account.ID, "不存在", 1, 10)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(0), count)
|
|
assert.Len(t, apps, 0)
|
|
}
|
|
|
|
func TestDashboardAppService_Search_账户隔离(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account1 := createTestAccount(t, db)
|
|
account2 := createTestAccount(t, db)
|
|
|
|
createTestDashboardApp(t, db, account1.ID, func(app *model.DashboardApp) {
|
|
app.Title = "仪表盘A"
|
|
})
|
|
createTestDashboardApp(t, db, account2.ID, func(app *model.DashboardApp) {
|
|
app.Title = "仪表盘B"
|
|
})
|
|
|
|
// Search in account1 should only find account1's apps
|
|
apps, count, err := svc.Search(context.Background(), account1.ID, "仪表盘", 1, 10)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(1), count)
|
|
assert.Len(t, apps, 1)
|
|
assert.Equal(t, "仪表盘A", apps[0].Title)
|
|
}
|
|
|
|
// ========== Widget Management ==========
|
|
|
|
func TestDashboardAppService_AddWidget_成功(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
created := createTestDashboardApp(t, db, account.ID)
|
|
|
|
req := &AddWidgetRequest{
|
|
Type: "frame",
|
|
URL: "https://example.com/new-widget",
|
|
Name: "新Widget",
|
|
}
|
|
|
|
app, err := svc.AddWidget(context.Background(), created.ID, req)
|
|
require.NoError(t, err)
|
|
|
|
var widgets []model.DashboardWidget
|
|
err = json.Unmarshal(app.Content, &widgets)
|
|
require.NoError(t, err)
|
|
// Should have original widget + new widget
|
|
assert.Len(t, widgets, 2)
|
|
lastWidget := widgets[len(widgets)-1]
|
|
assert.Equal(t, "frame", lastWidget.Type)
|
|
assert.Equal(t, "https://example.com/new-widget", lastWidget.URL)
|
|
assert.Equal(t, "新Widget", lastWidget.Name)
|
|
}
|
|
|
|
func TestDashboardAppService_AddWidget_到空Content(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
// Create app with empty content
|
|
created := createTestDashboardApp(t, db, account.ID, func(app *model.DashboardApp) {
|
|
app.Content = json.RawMessage(`[]`)
|
|
})
|
|
|
|
req := &AddWidgetRequest{
|
|
Type: "frame",
|
|
URL: "https://example.com/widget",
|
|
}
|
|
|
|
app, err := svc.AddWidget(context.Background(), created.ID, req)
|
|
require.NoError(t, err)
|
|
|
|
var widgets []model.DashboardWidget
|
|
err = json.Unmarshal(app.Content, &widgets)
|
|
require.NoError(t, err)
|
|
assert.Len(t, widgets, 1)
|
|
assert.Equal(t, "https://example.com/widget", widgets[0].URL)
|
|
}
|
|
|
|
func TestDashboardAppService_AddWidget_无效Type(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
created := createTestDashboardApp(t, db, account.ID)
|
|
|
|
req := &AddWidgetRequest{
|
|
Type: "link",
|
|
URL: "https://example.com/widget",
|
|
}
|
|
|
|
app, err := svc.AddWidget(context.Background(), created.ID, req)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, app)
|
|
assert.Contains(t, err.Error(), "must be 'frame'")
|
|
}
|
|
|
|
func TestDashboardAppService_AddWidget_无效URL(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
created := createTestDashboardApp(t, db, account.ID)
|
|
|
|
req := &AddWidgetRequest{
|
|
Type: "frame",
|
|
URL: "ftp://bad.com",
|
|
}
|
|
|
|
app, err := svc.AddWidget(context.Background(), created.ID, req)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, app)
|
|
assert.Contains(t, err.Error(), "http/https")
|
|
}
|
|
|
|
func TestDashboardAppService_GetWidgets_成功(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
created := createTestDashboardApp(t, db, account.ID)
|
|
|
|
widgets, err := svc.GetWidgets(context.Background(), created.ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, widgets, 1)
|
|
assert.Equal(t, "frame", widgets[0].Type)
|
|
}
|
|
|
|
func TestDashboardAppService_GetWidgets_空Content(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
created := createTestDashboardApp(t, db, account.ID, func(app *model.DashboardApp) {
|
|
app.Content = json.RawMessage(`[]`)
|
|
})
|
|
|
|
widgets, err := svc.GetWidgets(context.Background(), created.ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, widgets, 0)
|
|
}
|
|
|
|
func TestDashboardAppService_GetWidgets_不存在(t *testing.T) {
|
|
_, _, svc := setupDashboardAppService(t)
|
|
|
|
widgets, err := svc.GetWidgets(context.Background(), 99999)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, widgets)
|
|
}
|
|
|
|
func TestDashboardAppService_UpdateWidget_成功(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
// Create app with 2 widgets
|
|
created := createTestDashboardApp(t, db, account.ID, func(app *model.DashboardApp) {
|
|
app.Content = json.RawMessage(`[{"type":"frame","url":"https://a.com"},{"type":"frame","url":"https://b.com"}]`)
|
|
})
|
|
|
|
req := &UpdateWidgetRequest{
|
|
URL: "https://updated.com",
|
|
Name: "更新名称",
|
|
}
|
|
|
|
app, err := svc.UpdateWidget(context.Background(), created.ID, 0, req)
|
|
require.NoError(t, err)
|
|
|
|
var widgets []model.DashboardWidget
|
|
err = json.Unmarshal(app.Content, &widgets)
|
|
require.NoError(t, err)
|
|
assert.Len(t, widgets, 2)
|
|
assert.Equal(t, "https://updated.com", widgets[0].URL)
|
|
assert.Equal(t, "更新名称", widgets[0].Name)
|
|
// Second widget unchanged
|
|
assert.Equal(t, "https://b.com", widgets[1].URL)
|
|
}
|
|
|
|
func TestDashboardAppService_UpdateWidget_越界(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
created := createTestDashboardApp(t, db, account.ID)
|
|
|
|
req := &UpdateWidgetRequest{
|
|
URL: "https://updated.com",
|
|
}
|
|
|
|
app, err := svc.UpdateWidget(context.Background(), created.ID, 5, req)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, app)
|
|
assert.Contains(t, err.Error(), "out of range")
|
|
}
|
|
|
|
func TestDashboardAppService_RemoveWidget_成功(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
// Create app with 2 widgets
|
|
created := createTestDashboardApp(t, db, account.ID, func(app *model.DashboardApp) {
|
|
app.Content = json.RawMessage(`[{"type":"frame","url":"https://a.com"},{"type":"frame","url":"https://b.com"}]`)
|
|
})
|
|
|
|
app, err := svc.RemoveWidget(context.Background(), created.ID, 0)
|
|
require.NoError(t, err)
|
|
|
|
var widgets []model.DashboardWidget
|
|
err = json.Unmarshal(app.Content, &widgets)
|
|
require.NoError(t, err)
|
|
assert.Len(t, widgets, 1)
|
|
// Only second widget remains
|
|
assert.Equal(t, "https://b.com", widgets[0].URL)
|
|
}
|
|
|
|
func TestDashboardAppService_RemoveWidget_越界(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
created := createTestDashboardApp(t, db, account.ID)
|
|
|
|
app, err := svc.RemoveWidget(context.Background(), created.ID, 5)
|
|
assert.Error(t, err)
|
|
assert.Nil(t, app)
|
|
assert.Contains(t, err.Error(), "out of range")
|
|
}
|
|
|
|
func TestDashboardAppService_RemoveWidget_最后一个(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
created := createTestDashboardApp(t, db, account.ID)
|
|
|
|
app, err := svc.RemoveWidget(context.Background(), created.ID, 0)
|
|
require.NoError(t, err)
|
|
|
|
var widgets []model.DashboardWidget
|
|
err = json.Unmarshal(app.Content, &widgets)
|
|
require.NoError(t, err)
|
|
assert.Len(t, widgets, 0)
|
|
}
|
|
|
|
// ========== ValidateContent (model-level) ==========
|
|
|
|
func TestDashboardAppService_Create_验证ValidContent(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
|
|
// Valid: array of frame widgets with http URLs
|
|
req := &CreateDashboardAppRequest{
|
|
Title: "验证通过",
|
|
Content: json.RawMessage(`[{"type":"frame","url":"https://example.com"},{"type":"frame","url":"http://other.com"}]`),
|
|
}
|
|
|
|
app, err := svc.Create(context.Background(), account.ID, nil, req)
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, app.ID)
|
|
}
|
|
|
|
func TestDashboardAppService_Create_验证空数组(t *testing.T) {
|
|
db, _, svc := setupDashboardAppService(t)
|
|
account := createTestAccount(t, db)
|
|
|
|
req := &CreateDashboardAppRequest{
|
|
Title: "空数组",
|
|
Content: json.RawMessage(`[]`),
|
|
}
|
|
|
|
app, err := svc.Create(context.Background(), account.ID, nil, req)
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, app.ID)
|
|
} |