Smail/backend/services/del_email/del_email_test.go
smail f60d3b0880
Some checks are pending
Security Checks / security (push) Waiting to run
整理前后端与测试构建目录并完善配置和安全引导
统一 frontend、backend、test、test-log 和 out 目录,更新构建、部署及测试入口;纳入配置管理兼容与首次安全引导修复;排除本机配置、密钥和测试产物。
2026-09-05 19:19:52 +08:00

154 lines
3.8 KiB
Go

package del_email
import (
"path/filepath"
"testing"
"git.pcux.cn/xuans/Smail/config"
"git.pcux.cn/xuans/Smail/db"
"git.pcux.cn/xuans/Smail/models"
"git.pcux.cn/xuans/Smail/utils/context"
)
func initDeleteTestDB(t *testing.T) {
t.Helper()
config.Instance = &config.Config{DbType: config.DBTypeSQLite, DbDSN: filepath.Join(t.TempDir(), "delete.db")}
if err := db.Init(""); err != nil {
t.Fatal(err)
}
t.Cleanup(func() {
if db.Instance != nil {
_ = db.Instance.Close()
}
})
}
func insertDeleteTestEmail(t *testing.T) models.Email {
t.Helper()
email := models.Email{Subject: "security test"}
if _, err := db.Instance.Insert(&email); err != nil {
t.Fatal(err)
}
return email
}
func TestForcedDeleteDoesNotDeleteUnownedOrphanEmail(t *testing.T) {
initDeleteTestDB(t)
email := insertDeleteTestEmail(t)
if err := DelEmail(&context.Context{UserID: 1}, []int{email.Id}, true); err != nil {
t.Fatal(err)
}
found, err := db.Instance.ID(email.Id).Get(&models.Email{})
if err != nil {
t.Fatal(err)
}
if !found {
t.Fatal("unowned email was deleted")
}
}
func TestForcedDeleteKeepsSharedEmail(t *testing.T) {
initDeleteTestDB(t)
email := insertDeleteTestEmail(t)
relations := []models.UserEmail{
{UserID: 1, EmailID: email.Id},
{UserID: 2, EmailID: email.Id},
}
if _, err := db.Instance.Insert(&relations); err != nil {
t.Fatal(err)
}
if err := DelEmail(&context.Context{UserID: 1}, []int{email.Id}, true); err != nil {
t.Fatal(err)
}
found, err := db.Instance.ID(email.Id).Get(&models.Email{})
if err != nil {
t.Fatal(err)
}
if !found {
t.Fatal("shared email was deleted")
}
remaining, err := db.Instance.Where("email_id=? and user_id=?", email.Id, 2).Count(&models.UserEmail{})
if err != nil {
t.Fatal(err)
}
if remaining != 1 {
t.Fatalf("remaining relation count = %d, want 1", remaining)
}
}
func TestForcedDeleteRemovesLastOwnedEmail(t *testing.T) {
initDeleteTestDB(t)
email := insertDeleteTestEmail(t)
relation := models.UserEmail{UserID: 1, EmailID: email.Id}
if _, err := db.Instance.Insert(&relation); err != nil {
t.Fatal(err)
}
if err := DelEmail(&context.Context{UserID: 1}, []int{email.Id}, true); err != nil {
t.Fatal(err)
}
found, err := db.Instance.ID(email.Id).Get(&models.Email{})
if err != nil {
t.Fatal(err)
}
if found {
t.Fatal("unreferenced owned email was not deleted")
}
}
func TestDelByUIDRequiresDeletedFlag(t *testing.T) {
initDeleteTestDB(t)
email := insertDeleteTestEmail(t)
relation := models.UserEmail{UserID: 1, EmailID: email.Id}
if _, err := db.Instance.Insert(&relation); err != nil {
t.Fatal(err)
}
if err := DelByUID(&context.Context{UserID: 1}, []int{relation.ID}); err == nil {
t.Fatal("unmarked relation was accepted for expunge")
}
found, err := db.Instance.ID(relation.ID).Get(&models.UserEmail{})
if err != nil {
t.Fatal(err)
}
if !found {
t.Fatal("unmarked relation was deleted")
}
}
func TestDelByUIDRollsBackBatchWhenRelationIsNotMarked(t *testing.T) {
initDeleteTestDB(t)
firstEmail := insertDeleteTestEmail(t)
secondEmail := insertDeleteTestEmail(t)
firstRelation := models.UserEmail{UserID: 1, EmailID: firstEmail.Id, IsDeleted: 1}
if _, err := db.Instance.Insert(&firstRelation); err != nil {
t.Fatal(err)
}
secondRelation := models.UserEmail{UserID: 1, EmailID: secondEmail.Id}
if _, err := db.Instance.Insert(&secondRelation); err != nil {
t.Fatal(err)
}
relations := []models.UserEmail{firstRelation, secondRelation}
err := DelByUID(&context.Context{UserID: 1}, []int{relations[0].ID, relations[1].ID})
if err == nil {
t.Fatal("mixed marked and unmarked batch was accepted")
}
for _, relation := range relations {
found, loadErr := db.Instance.ID(relation.ID).Get(&models.UserEmail{})
if loadErr != nil {
t.Fatal(loadErr)
}
if !found {
t.Fatalf("relation %d was not rolled back", relation.ID)
}
}
}