Files
at-container-registry/pkg/appview/db/delete_test.go

307 lines
8.6 KiB
Go

package db
import (
"fmt"
"testing"
"time"
)
func TestDeleteUserDataFull_DeletesAllData(t *testing.T) {
db, err := InitDB(":memory:", LibsqlConfig{})
if err != nil {
t.Fatalf("Failed to init database: %v", err)
}
defer db.Close()
// Create test user
testUser := &User{
DID: "did:plc:test123",
Handle: "test.bsky.social",
PDSEndpoint: "https://bsky.social",
LastSeen: time.Now(),
}
if err := UpsertUser(db, testUser); err != nil {
t.Fatalf("Failed to create user: %v", err)
}
// Create manifest
_, err = db.Exec(`
INSERT INTO manifests (did, repository, digest, hold_endpoint, schema_version, media_type, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?)
`, testUser.DID, "myapp", "sha256:abc123", "did:web:hold.example.com", 2,
"application/vnd.oci.image.manifest.v1+json", time.Now())
if err != nil {
t.Fatalf("Failed to create manifest: %v", err)
}
// Create tag
_, err = db.Exec(`
INSERT INTO tags (did, repository, tag, digest, created_at)
VALUES (?, ?, ?, ?, ?)
`, testUser.DID, "myapp", "latest", "sha256:abc123", time.Now())
if err != nil {
t.Fatalf("Failed to create tag: %v", err)
}
// Create hold membership data (non-cascading)
_, err = db.Exec(`
INSERT INTO hold_crew_approvals (hold_did, user_did, approved_at, expires_at)
VALUES (?, ?, ?, ?)
`, "did:web:hold.example.com", testUser.DID, time.Now(), time.Now().Add(24*time.Hour))
if err != nil {
t.Fatalf("Failed to create crew approval: %v", err)
}
_, err = db.Exec(`
INSERT INTO hold_crew_members (hold_did, member_did, rkey, permissions)
VALUES (?, ?, ?, ?)
`, "did:web:hold.example.com", testUser.DID, "member1", `["blob:read","blob:write"]`)
if err != nil {
t.Fatalf("Failed to create crew member: %v", err)
}
// Create OAuth store
oauthStore := NewOAuthStore(db)
// Delete all user data
err = DeleteUserDataFull(db, oauthStore, testUser.DID)
if err != nil {
t.Fatalf("DeleteUserDataFull failed: %v", err)
}
// Verify user was deleted
var count int
err = db.QueryRow("SELECT COUNT(*) FROM users WHERE did = ?", testUser.DID).Scan(&count)
if err != nil {
t.Fatalf("Failed to query users: %v", err)
}
if count != 0 {
t.Error("Expected user to be deleted")
}
// Verify manifests were cascade deleted
err = db.QueryRow("SELECT COUNT(*) FROM manifests WHERE did = ?", testUser.DID).Scan(&count)
if err != nil {
t.Fatalf("Failed to query manifests: %v", err)
}
if count != 0 {
t.Error("Expected manifests to be cascade deleted")
}
// Verify tags were cascade deleted
err = db.QueryRow("SELECT COUNT(*) FROM tags WHERE did = ?", testUser.DID).Scan(&count)
if err != nil {
t.Fatalf("Failed to query tags: %v", err)
}
if count != 0 {
t.Error("Expected tags to be cascade deleted")
}
// Verify hold membership data was deleted
err = db.QueryRow("SELECT COUNT(*) FROM hold_crew_approvals WHERE user_did = ?", testUser.DID).Scan(&count)
if err != nil {
t.Fatalf("Failed to query crew approvals: %v", err)
}
if count != 0 {
t.Error("Expected crew approvals to be deleted")
}
err = db.QueryRow("SELECT COUNT(*) FROM hold_crew_members WHERE member_did = ?", testUser.DID).Scan(&count)
if err != nil {
t.Fatalf("Failed to query crew members: %v", err)
}
if count != 0 {
t.Error("Expected crew members to be deleted")
}
}
func TestDeleteUserDataFull_DoesNotAffectOtherUsers(t *testing.T) {
db, err := InitDB(":memory:", LibsqlConfig{})
if err != nil {
t.Fatalf("Failed to init database: %v", err)
}
defer db.Close()
// Create two users
user1 := &User{
DID: "did:plc:user1",
Handle: "user1.bsky.social",
PDSEndpoint: "https://bsky.social",
LastSeen: time.Now(),
}
user2 := &User{
DID: "did:plc:user2",
Handle: "user2.bsky.social",
PDSEndpoint: "https://bsky.social",
LastSeen: time.Now(),
}
if err := UpsertUser(db, user1); err != nil {
t.Fatalf("Failed to create user1: %v", err)
}
if err := UpsertUser(db, user2); err != nil {
t.Fatalf("Failed to create user2: %v", err)
}
// Create manifests for both users
for _, user := range []*User{user1, user2} {
_, err = db.Exec(`
INSERT INTO manifests (did, repository, digest, hold_endpoint, schema_version, media_type, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?)
`, user.DID, "myapp", "sha256:"+user.DID, "did:web:hold.example.com", 2,
"application/vnd.oci.image.manifest.v1+json", time.Now())
if err != nil {
t.Fatalf("Failed to create manifest for %s: %v", user.Handle, err)
}
}
// Create hold membership data for both users
for i, user := range []*User{user1, user2} {
_, err = db.Exec(`
INSERT INTO hold_crew_members (hold_did, member_did, rkey, permissions)
VALUES (?, ?, ?, ?)
`, "did:web:hold.example.com", user.DID, fmt.Sprintf("member%d", i+1), `["blob:read"]`)
if err != nil {
t.Fatalf("Failed to create crew member for %s: %v", user.Handle, err)
}
}
oauthStore := NewOAuthStore(db)
// Delete only user1's data
err = DeleteUserDataFull(db, oauthStore, user1.DID)
if err != nil {
t.Fatalf("DeleteUserDataFull failed: %v", err)
}
// Verify user1 was deleted
var count int
err = db.QueryRow("SELECT COUNT(*) FROM users WHERE did = ?", user1.DID).Scan(&count)
if err != nil {
t.Fatalf("Failed to query users: %v", err)
}
if count != 0 {
t.Error("Expected user1 to be deleted")
}
// Verify user2 still exists
err = db.QueryRow("SELECT COUNT(*) FROM users WHERE did = ?", user2.DID).Scan(&count)
if err != nil {
t.Fatalf("Failed to query users: %v", err)
}
if count != 1 {
t.Error("Expected user2 to still exist")
}
// Verify user2's manifests still exist
err = db.QueryRow("SELECT COUNT(*) FROM manifests WHERE did = ?", user2.DID).Scan(&count)
if err != nil {
t.Fatalf("Failed to query manifests: %v", err)
}
if count != 1 {
t.Error("Expected user2's manifest to still exist")
}
// Verify user2's crew membership still exists
err = db.QueryRow("SELECT COUNT(*) FROM hold_crew_members WHERE member_did = ?", user2.DID).Scan(&count)
if err != nil {
t.Fatalf("Failed to query crew members: %v", err)
}
if count != 1 {
t.Error("Expected user2's crew membership to still exist")
}
}
func TestDeleteUserDataFull_HandlesNonExistentUser(t *testing.T) {
db, err := InitDB(":memory:", LibsqlConfig{})
if err != nil {
t.Fatalf("Failed to init database: %v", err)
}
defer db.Close()
oauthStore := NewOAuthStore(db)
// Try to delete non-existent user - should not error
err = DeleteUserDataFull(db, oauthStore, "did:plc:nonexistent")
if err != nil {
t.Errorf("Expected no error for non-existent user, got: %v", err)
}
}
func TestDeleteUserDataFull_WithNilOAuthStore(t *testing.T) {
db, err := InitDB(":memory:", LibsqlConfig{})
if err != nil {
t.Fatalf("Failed to init database: %v", err)
}
defer db.Close()
testUser := &User{
DID: "did:plc:test123",
Handle: "test.bsky.social",
PDSEndpoint: "https://bsky.social",
LastSeen: time.Now(),
}
if err := UpsertUser(db, testUser); err != nil {
t.Fatalf("Failed to create user: %v", err)
}
// Delete with nil OAuth store - should still work
err = DeleteUserDataFull(db, nil, testUser.DID)
if err != nil {
t.Errorf("Expected no error with nil OAuth store, got: %v", err)
}
// Verify user was deleted
var count int
err = db.QueryRow("SELECT COUNT(*) FROM users WHERE did = ?", testUser.DID).Scan(&count)
if err != nil {
t.Fatalf("Failed to query users: %v", err)
}
if count != 0 {
t.Error("Expected user to be deleted")
}
}
func TestDeleteUserDataFull_DeletesDenials(t *testing.T) {
db, err := InitDB(":memory:", LibsqlConfig{})
if err != nil {
t.Fatalf("Failed to init database: %v", err)
}
defer db.Close()
testUser := &User{
DID: "did:plc:test123",
Handle: "test.bsky.social",
PDSEndpoint: "https://bsky.social",
LastSeen: time.Now(),
}
if err := UpsertUser(db, testUser); err != nil {
t.Fatalf("Failed to create user: %v", err)
}
// Create denial record
_, err = db.Exec(`
INSERT INTO hold_crew_denials (hold_did, user_did, denial_count, next_retry_at, last_denied_at)
VALUES (?, ?, ?, ?, ?)
`, "did:web:hold.example.com", testUser.DID, 1, time.Now().Add(24*time.Hour), time.Now())
if err != nil {
t.Fatalf("Failed to create crew denial: %v", err)
}
oauthStore := NewOAuthStore(db)
err = DeleteUserDataFull(db, oauthStore, testUser.DID)
if err != nil {
t.Fatalf("DeleteUserDataFull failed: %v", err)
}
// Verify denial was deleted
var count int
err = db.QueryRow("SELECT COUNT(*) FROM hold_crew_denials WHERE user_did = ?", testUser.DID).Scan(&count)
if err != nil {
t.Fatalf("Failed to query crew denials: %v", err)
}
if count != 0 {
t.Error("Expected crew denials to be deleted")
}
}