Files
sub2api/backend/internal/service/user_service_update_fields_test.go
T

84 lines
2.7 KiB
Go
Raw Normal View History

//go:build unit
package service
import (
"context"
"testing"
"github.com/stretchr/testify/require"
)
// 这些用例锁死"每个入口只声明自己真正要改的列":
// 任何退回整行回写的改动都会让并发写入被陈旧快照覆盖,并在这里变红。
func TestUpdateProfile_OnlyDeclaresRequestedColumns(t *testing.T) {
username := "renamed"
tests := []struct {
name string
req UpdateProfileRequest
want UserUpdateFields
}{
{
name: "username only",
req: UpdateProfileRequest{Username: &username},
want: UserUpdateFields{Username: true},
},
{
name: "notify settings only",
req: UpdateProfileRequest{BalanceNotifyEnabled: boolPtr(true)},
want: UserUpdateFields{BalanceNotifySettings: true},
},
{
name: "username and notify threshold",
req: UpdateProfileRequest{Username: &username, BalanceNotifyThreshold: float64Ptr(1.5)},
want: UserUpdateFields{Username: true, BalanceNotifySettings: true},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
repo := &mockUserRepo{getByIDUser: &User{ID: 7, Balance: 0.30, Status: StatusActive}}
svc := NewUserService(repo, nil, nil, nil)
_, err := svc.UpdateProfile(context.Background(), 7, tt.req)
require.NoError(t, err)
require.Equal(t, []UserUpdateFields{tt.want}, repo.updateFields)
})
}
}
// 只改头像时用户行没有任何列要写,不应产生一次整行更新。
func TestUpdateProfile_AvatarOnlySkipsUserRowWrite(t *testing.T) {
repo := &mockUserRepo{getByIDUser: &User{ID: 7, Balance: 0.30}}
svc := NewUserService(repo, nil, nil, nil)
avatar := "https://cdn.example.com/a.png"
_, err := svc.UpdateProfile(context.Background(), 7, UpdateProfileRequest{AvatarURL: &avatar})
require.NoError(t, err)
require.Len(t, repo.upsertAvatarArgs, 1, "avatar must still be stored")
require.Equal(t, []UserUpdateFields{{}}, repo.updateFields, "no user column should be declared")
}
func TestChangePassword_OnlyDeclaresPasswordHash(t *testing.T) {
user := &User{ID: 7, Balance: 0.30}
require.NoError(t, user.SetPassword("old-password"))
repo := &mockUserRepo{getByIDUser: user}
svc := NewUserService(repo, nil, nil, nil)
err := svc.ChangePassword(context.Background(), 7, ChangePasswordRequest{
CurrentPassword: "old-password",
NewPassword: "new-password",
})
require.NoError(t, err)
require.Equal(t, []UserUpdateFields{{PasswordHash: true}}, repo.updateFields)
}
func TestUpdateStatus_OnlyDeclaresStatus(t *testing.T) {
repo := &mockUserRepo{getByIDUser: &User{ID: 7, Balance: 0.30, Status: StatusActive}}
svc := NewUserService(repo, nil, nil, nil)
require.NoError(t, svc.UpdateStatus(context.Background(), 7, StatusDisabled))
require.Equal(t, []UserUpdateFields{{Status: true}}, repo.updateFields)
}