feat: change email, export my data, delete account (with data anonymization)
This commit is contained in:
1 parent
bb191c389a
commit
10a66cd979
123 files changed
+10789
-76
No files matched your search
@@ -0,0 +1,81 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"RenewCMS/internal/domain/user"
|
||||
entity "RenewCMS/internal/infrastructure/persistence/models"
|
||||
persistence "RenewCMS/internal/infrastructure/persistence/repositories"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func failAccountDeleteKeyRemoval(t *testing.T, db *gorm.DB, name string, failure error) {
|
||||
t.Helper()
|
||||
err := db.Callback().Delete().Before("gorm:delete").Register(name, func(tx *gorm.DB) {
|
||||
if tx.Statement.Table == "api_keys" {
|
||||
_ = tx.AddError(failure)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { _ = db.Callback().Delete().Remove(name) })
|
||||
}
|
||||
|
||||
func TestAccountDeleteContentionMapping(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
failure string
|
||||
guards []uint32
|
||||
notDeletable bool
|
||||
}{
|
||||
{"locked database with a guard role", "database is locked", []uint32{8}, true},
|
||||
{"sqlite busy with a guard role", "SQLITE_BUSY: x", []uint32{8}, true},
|
||||
{"deadlock with a guard role", "Deadlock found when trying to get lock", []uint32{8}, true},
|
||||
{"serialization failure with a guard role", "could not serialize access", []uint32{8}, true},
|
||||
{"locked database without a guard role", "database is locked", nil, false},
|
||||
{"unrelated failure with a guard role", "disk exploded", []uint32{8}, false},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
db := openContractSQLite(t)
|
||||
seedDeleteAccountRows(t, db, true)
|
||||
failure := errors.New(tc.failure)
|
||||
failAccountDeleteKeyRemoval(t, db, "test:account_delete_contention", failure)
|
||||
|
||||
err := persistence.NewAccountEraser(db).Erase(user.Erasure{UserID: 7, GuardRoleIDs: tc.guards})
|
||||
|
||||
if errors.Is(err, user.ErrAccountNotDeletable) != tc.notDeletable {
|
||||
t.Errorf("ErrAccountNotDeletable = %v, want %v (err %v)", !tc.notDeletable, tc.notDeletable, err)
|
||||
}
|
||||
if !tc.notDeletable && !errors.Is(err, failure) {
|
||||
t.Errorf("expected the original failure, got %v", err)
|
||||
}
|
||||
if deleteAccountRowCount(t, db, &entity.User{}, "id = ?", 7) != 1 {
|
||||
t.Error("the user must still exist after a failed erasure")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccountDeleteSQLiteTakesTheWriteLockBeforeCounting(t *testing.T) {
|
||||
db := openContractSQLite(t)
|
||||
seedDeleteAccountRows(t, db, true)
|
||||
roleWrites := 0
|
||||
err := db.Callback().Update().Before("gorm:update").Register("test:account_delete_role_writes", func(tx *gorm.DB) {
|
||||
if tx.Statement.Table == "roles" {
|
||||
roleWrites++
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { _ = db.Callback().Update().Remove("test:account_delete_role_writes") })
|
||||
|
||||
err = persistence.NewAccountEraser(db).Erase(user.Erasure{UserID: 7, GuardRoleIDs: []uint32{8}})
|
||||
|
||||
if err != nil || roleWrites != 1 {
|
||||
t.Errorf("expected one lock write on the guard roles and no error, got %d writes and %v", roleWrites, err)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user