Ctrl K
ComunidadGuías…

internal/store/postgres/bootstrap_update_job_integration_test.go

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

Archivo original ↗Preguntar a KiBot
package postgres

import (
	"context"
	"testing"
	"time"

	"telesrv/internal/domain"
)

func TestBootstrapUpdateJobPostgresSameAuthKeyReconnectTakesOverPendingSession(t *testing.T) {
	pool := testPool(t)
	ctx := context.Background()
	user := createLoginCodeDeliveryTestUser(t, ctx, pool, "bootstrap-reconnect")
	msg, err := NewMessageStore(pool).Create(ctx, domain.Message{
		OwnerUserID: user.ID,
		Peer:        domain.Peer{Type: domain.PeerTypeUser, ID: domain.OfficialSystemUserID},
		From:        domain.Peer{Type: domain.PeerTypeUser, ID: domain.OfficialSystemUserID},
		Date:        int(time.Now().Unix()),
		Body:        "Login code: 12345",
	})
	if err != nil {
		t.Fatalf("create bootstrap message: %v", err)
	}
	bootstrap := NewBootstrapUpdateJobStore(pool)
	authKeyID := [8]byte{1, 3, 5, 7}
	const (
		oldSessionID = int64(11001)
		newSessionID = int64(22002)
	)
	job, err := bootstrap.EnqueueLoginMessage(ctx, domain.BootstrapUpdateJob{
		Kind: domain.BootstrapUpdateJobLoginMessage, UserID: user.ID,
		AuthKeyID: authKeyID, SessionID: oldSessionID, MessageBoxID: msg.ID,
	})
	if err != nil {
		t.Fatalf("enqueue bootstrap: %v", err)
	}
	if ready, err := bootstrap.MarkReadyForSession(ctx, user.ID, [8]byte{9}, newSessionID); err != nil || ready != 0 {
		t.Fatalf("different-auth ready=%d err=%v, want 0/nil", ready, err)
	}
	ready, err := bootstrap.MarkReadyForSession(ctx, user.ID, authKeyID, newSessionID)
	if err != nil || ready != 1 {
		t.Fatalf("same-auth reconnect ready=%d err=%v, want 1/nil", ready, err)
	}
	var status string
	var sessionID int64
	if err := pool.QueryRow(ctx, `SELECT status, session_id FROM bootstrap_update_jobs WHERE id = $1`, job.ID).Scan(&status, &sessionID); err != nil {
		t.Fatalf("load bootstrap job: %v", err)
	}
	if status != string(domain.BootstrapUpdateJobReady) || sessionID != newSessionID {
		t.Fatalf("bootstrap status/session = %s/%d, want ready/%d", status, sessionID, newSessionID)
	}
}

func TestBootstrapUpdateJobPostgresMarksReadinessBatchByOrdinal(t *testing.T) {
	pool := testPool(t)
	ctx := context.Background()
	user := createLoginCodeDeliveryTestUser(t, ctx, pool, "bootstrap-batch")
	messages := NewMessageStore(pool)
	bootstrap := NewBootstrapUpdateJobStore(pool)
	authKeyID := [8]byte{2, 4, 6, 8}
	for index := 0; index < 2; index++ {
		msg, err := messages.Create(ctx, domain.Message{
			OwnerUserID: user.ID,
			Peer:        domain.Peer{Type: domain.PeerTypeUser, ID: domain.OfficialSystemUserID},
			From:        domain.Peer{Type: domain.PeerTypeUser, ID: domain.OfficialSystemUserID},
			Date:        int(time.Now().Unix()) + index,
			Body:        "Login code batch",
		})
		if err != nil {
			t.Fatalf("create bootstrap message %d: %v", index, err)
		}
		if _, err := bootstrap.EnqueueLoginMessage(ctx, domain.BootstrapUpdateJob{
			Kind: domain.BootstrapUpdateJobLoginMessage, UserID: user.ID,
			AuthKeyID: authKeyID, SessionID: int64(100 + index), MessageBoxID: msg.ID,
		}); err != nil {
			t.Fatalf("enqueue bootstrap %d: %v", index, err)
		}
	}

	results, err := bootstrap.markReadyForSessions(ctx, []bootstrapReadyBatchRequest{
		{userID: user.ID + 1, authKeyID: authKeyID, sessionID: 700},
		{userID: user.ID, authKeyID: [8]byte{9}, sessionID: 701},
		{userID: user.ID, authKeyID: authKeyID, sessionID: 702},
	})
	if err != nil {
		t.Fatal(err)
	}
	if len(results) != 3 || results[0] != 0 || results[1] != 0 || results[2] != 2 {
		t.Fatalf("batch results = %#v, want [0 0 2]", results)
	}
	var count int
	if err := pool.QueryRow(ctx, `
SELECT count(*)
FROM bootstrap_update_jobs
WHERE user_id = $1 AND auth_key_id = $2 AND status = 'ready' AND session_id = $3`,
		user.ID, authKeyIDToInt64(authKeyID), int64(702)).Scan(&count); err != nil {
		t.Fatal(err)
	}
	if count != 2 {
		t.Fatalf("ready jobs = %d, want 2", count)
	}

	if _, err := bootstrap.markReadyForSessions(ctx, []bootstrapReadyBatchRequest{
		{userID: user.ID, authKeyID: authKeyID, sessionID: 1},
		{userID: user.ID, authKeyID: authKeyID, sessionID: 2},
	}); err == nil {
		t.Fatal("duplicate fence accepted in one batch")
	}
}