在 fast-forward 到 origin/main 后解决 music logic/repo 冲突,SQL 与模型统一 t_* 表名;Makefile 修正 golangci-lint 变量并令 test/deploy 依赖 lint;补齐 admin/transport 等 lint 修复与 music logic 单测以满足覆盖率门禁。 Co-authored-by: Cursor <cursoragent@cursor.com>
100 lines
3.5 KiB
Go
100 lines
3.5 KiB
Go
package logic
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"spark-server/internal/infrastructure/id"
|
|
friendlogic "spark-server/internal/module/friend/logic"
|
|
friendmodel "spark-server/internal/module/friend/model"
|
|
momentlogic "spark-server/internal/module/moment/logic"
|
|
momentmodel "spark-server/internal/module/moment/model"
|
|
smslogic "spark-server/internal/module/sms/logic"
|
|
smsmodel "spark-server/internal/module/sms/model"
|
|
"spark-server/internal/module/user/entity"
|
|
"spark-server/internal/module/user/model"
|
|
"spark-server/internal/pkg/errs"
|
|
"spark-server/internal/pkg/reqctx"
|
|
)
|
|
|
|
func TestDeleteAccountArchivesAndAllowsReregister(t *testing.T) {
|
|
svc, repo, _ := testService(t)
|
|
ctx := reqctx.With(t.Context(), &reqctx.RequestContext{RealIP: "203.0.113.10", Language: "zh-CN"})
|
|
device := &entity.LoginDevice{DeviceID: 7, DeviceType: entity.DeviceIOS}
|
|
u, err := svc.AuthenticateEmail(ctx, "test01@spark.com", "1", device)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := svc.DeleteAccount(ctx, u.ID, DeleteAccountInput{}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := repo.GetByID(ctx, u.ID); !errors.Is(err, errs.ErrNotFound) {
|
|
t.Fatalf("live user %v", err)
|
|
}
|
|
if _, err := repo.GetByEmail(ctx, "test01@spark.com"); !errors.Is(err, errs.ErrNotFound) {
|
|
t.Fatalf("email still bound %v", err)
|
|
}
|
|
archived, err := repo.GetDeleted(ctx, u.ID)
|
|
if err != nil || archived.Email != "test01@spark.com" || archived.SparkID != u.SparkID {
|
|
t.Fatalf("archive %+v %v", archived, err)
|
|
}
|
|
again, err := svc.AuthenticateEmail(ctx, "test01@spark.com", "1", device)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if again.ID == u.ID {
|
|
t.Fatal("uid reused")
|
|
}
|
|
}
|
|
|
|
func TestDeleteAccountPurgesFriendsAndMoments(t *testing.T) {
|
|
ids, err := id.New(1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
repo := model.NewMemoryRepo()
|
|
store := smsmodel.NewMemoryStore()
|
|
smsSvc := smslogic.NewService(store, nil, nil, nil)
|
|
users := NewService(repo, smsSvc, ids, nil)
|
|
friends := friendlogic.NewService(friendmodel.NewMemoryRepo(), users, ids, nil)
|
|
moments := momentlogic.NewService(momentmodel.NewMemoryRepo(), friends, users, nil, ids)
|
|
users.BindAccountCleanup(nil, nil, friends, moments)
|
|
ctx := reqctx.With(t.Context(), &reqctx.RequestContext{RealIP: "10.0.0.1", Language: "zh-CN"})
|
|
a, err := users.AuthenticateEmail(ctx, "test01@spark.com", "1", &entity.LoginDevice{DeviceID: 1, DeviceType: entity.DeviceIOS})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
b, err := users.AuthenticateEmail(ctx, "test02@spark.com", "1", &entity.LoginDevice{DeviceID: 2, DeviceType: entity.DeviceWeb})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
applied, err := friends.Apply(ctx, a.ID, &friendlogic.ApplyInput{Email: "test02@spark.com"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := friends.Accept(ctx, b.ID, friendlogic.AcceptInput{RequestID: applied.RequestID}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ctxA := reqctx.With(ctx, &reqctx.RequestContext{UserID: a.ID, RealIP: "10.0.0.1", Language: "zh-CN"})
|
|
pub, err := moments.Publish(ctxA, a.ID, &momentlogic.PublishInput{Text: "bye"})
|
|
if err != nil || pub == nil {
|
|
t.Fatalf("publish %+v %v", pub, err)
|
|
}
|
|
if err := users.DeleteAccount(ctx, a.ID, DeleteAccountInput{}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ok, err := friends.AreFriends(ctx, a.ID, b.ID)
|
|
if err != nil || ok {
|
|
t.Fatalf("friends after cancel %v %v", ok, err)
|
|
}
|
|
if _, err := moments.Get(ctx, b.ID, pub.ID); !errors.Is(err, errs.ErrNotFound) {
|
|
t.Fatalf("moment still visible %v", err)
|
|
}
|
|
}
|
|
|
|
func (m *memObjects) Delete(_ context.Context, key string) error {
|
|
delete(m.kv, key)
|
|
return nil
|
|
}
|