Ctrl K
ComunidadGuías…

internal/store/postgres/channel_delete_monoforum_integration_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package postgres

import (
	"context"
	"testing"

	"telesrv/internal/domain"
)

// TestDeleteChannelCascadesLinkedMonoforumPostgres regression Risk A: when deleting a parent broadcast
// channel with Direct Messages enabled, the linked monoforum is soft-deleted in the same transaction and returned in the result. Not cascading would leave an orphan mono pointing at the deleted parent channel.
// Gated on TELESRV_TEST_POSTGRES_DSN.
func TestDeleteChannelCascadesLinkedMonoforumPostgres(t *testing.T) {
	pool := testPool(t) // an unset DSN makes it t.Skip
	ctx := context.Background()
	suffix := randomSuffix(t)

	users := NewUserStore(pool)
	owner, err := users.Create(ctx, domain.User{AccessHash: 91, Phone: "+1778" + suffix + "31", FirstName: "DelMonoOwner"})
	if err != nil {
		t.Fatalf("create owner: %v", err)
	}
	var channelIDs []int64
	t.Cleanup(func() {
		if len(channelIDs) > 0 {
			_, _ = pool.Exec(ctx, "DELETE FROM channels WHERE id = ANY($1::bigint[])", channelIDs)
		}
		_, _ = pool.Exec(ctx, "DELETE FROM users WHERE id = $1", owner.ID)
	})

	channels := NewChannelStore(pool)
	created, err := channels.CreateChannel(ctx, domain.CreateChannelRequest{
		CreatorUserID: owner.ID, Title: "Del Mono BC " + suffix, Broadcast: true, Date: 1700000900,
	})
	if err != nil {
		t.Fatalf("create channel: %v", err)
	}
	parentID := created.Channel.ID
	channelIDs = append(channelIDs, parentID)

	enabled, err := channels.SetPaidMessagesPrice(ctx, owner.ID, parentID, 0, true)
	if err != nil {
		t.Fatalf("enable DM: %v", err)
	}
	monoID := enabled.Channel.LinkedMonoforumID
	if monoID == 0 {
		t.Fatalf("no monoforum created")
	}
	channelIDs = append(channelIDs, monoID)

	res, err := channels.DeleteChannel(ctx, domain.DeleteChannelRequest{UserID: owner.ID, ChannelID: parentID, Date: 1700001000})
	if err != nil {
		t.Fatalf("delete parent: %v", err)
	}
	if !res.Channel.Deleted {
		t.Fatalf("parent not marked deleted: %+v", res.Channel)
	}
	if res.LinkedMonoforum == nil || res.LinkedMonoforum.ID != monoID || !res.LinkedMonoforum.Deleted {
		t.Fatalf("result LinkedMonoforum = %+v, want deleted mono %d", res.LinkedMonoforum, monoID)
	}

	// Both rows must be deleted=true in the DB.
	var parentDeleted, monoDeleted bool
	if err := pool.QueryRow(ctx, "SELECT deleted FROM channels WHERE id = $1", parentID).Scan(&parentDeleted); err != nil {
		t.Fatalf("read parent deleted: %v", err)
	}
	if err := pool.QueryRow(ctx, "SELECT deleted FROM channels WHERE id = $1", monoID).Scan(&monoDeleted); err != nil {
		t.Fatalf("read mono deleted: %v", err)
	}
	if !parentDeleted || !monoDeleted {
		t.Fatalf("deleted flags parent=%v mono=%v, want both true (orphan monoforum left behind)", parentDeleted, monoDeleted)
	}

	// After the delete, getDialogs no longer returns the parent channel or the mono.
	dialogs, err := channels.ListChannelDialogs(ctx, owner.ID, domain.DialogFilter{Limit: 100})
	if err != nil {
		t.Fatalf("list dialogs after delete: %v", err)
	}
	for _, d := range dialogs.Dialogs {
		if d.Peer.ID == monoID || d.Peer.ID == parentID {
			t.Fatalf("dialogs after delete still include parent/mono: %+v", d)
		}
	}
}