Ctrl K
ComunidadGuías…

internal/app/help/service_freeze_test.go

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

Archivo original ↗Preguntar a KiBot
package help

import (
	"context"
	"encoding/json"
	"testing"
	"time"

	"telesrv/internal/domain"
)

func TestAccountAppConfigFreezeOverlayIsUserScopedAndHashAware(t *testing.T) {
	since := time.Date(2026, 7, 15, 1, 2, 3, 0, time.UTC)
	until := since.Add(7 * 24 * time.Hour)
	provider := &fakeAccountFreezeProvider{items: map[int64]domain.AccountFreeze{
		1001: {UserID: 1001, Frozen: true, Since: since, Until: until, AppealURL: "https://appeals.example.test/1001"},
	}}
	svc := NewService(nil, nil, WithAccountFreezeProvider(provider))

	normal, notModified, err := svc.GetAppConfig(context.Background(), 1002, 0)
	if err != nil || notModified {
		t.Fatalf("normal GetAppConfig = %+v notModified=%v err=%v", normal, notModified, err)
	}
	frozen, notModified, err := svc.GetAppConfig(context.Background(), 1001, normal.Hash)
	if err != nil || notModified || frozen.Hash == normal.Hash {
		t.Fatalf("frozen GetAppConfig = hash:%d normal:%d notModified=%v err=%v", frozen.Hash, normal.Hash, notModified, err)
	}
	assertFreezeConfig(t, frozen.JSON, since.Unix(), until.Unix(), "https://appeals.example.test/1001")

	if _, notModified, err := svc.GetAppConfig(context.Background(), 1001, frozen.Hash); err != nil || !notModified {
		t.Fatalf("frozen hash replay = notModified:%v err:%v", notModified, err)
	}
	provider.items[1001] = domain.AccountFreeze{
		UserID:    1001,
		Frozen:    true,
		Since:     since,
		Until:     until.Add(24 * time.Hour),
		AppealURL: "https://appeals.example.test/1001/review",
	}
	updated, notModified, err := svc.GetAppConfig(context.Background(), 1001, frozen.Hash)
	if err != nil || notModified || updated.Hash == frozen.Hash {
		t.Fatalf("updated freeze config = hash:%d old:%d notModified=%v err=%v", updated.Hash, frozen.Hash, notModified, err)
	}
	assertFreezeConfig(t, updated.JSON, since.Unix(), until.Add(24*time.Hour).Unix(), "https://appeals.example.test/1001/review")
	other, notModified, err := svc.GetAppConfig(context.Background(), 1002, frozen.Hash)
	if err != nil || notModified || other.Hash != normal.Hash {
		t.Fatalf("other user = hash:%d notModified:%v err:%v", other.Hash, notModified, err)
	}
	assertNoFreezeConfig(t, other.JSON)
	unauthorized, _, err := svc.GetAppConfig(context.Background(), 0, 0)
	if err != nil {
		t.Fatal(err)
	}
	assertNoFreezeConfig(t, unauthorized.JSON)

	provider.items[1001] = domain.AccountFreeze{UserID: 1001}
	unfrozen, notModified, err := svc.GetAppConfig(context.Background(), 1001, updated.Hash)
	if err != nil || notModified || unfrozen.Hash != normal.Hash {
		t.Fatalf("unfreeze refresh = hash:%d notModified:%v err:%v", unfrozen.Hash, notModified, err)
	}
	assertNoFreezeConfig(t, unfrozen.JSON)
}

func TestAuthenticatedNonFrozenAppConfigOmitsFreezeFieldsAndReusesBaseHash(t *testing.T) {
	svc := NewService(nil, nil)
	unauthorized, _, err := svc.GetAppConfig(context.Background(), 0, 0)
	if err != nil {
		t.Fatal(err)
	}
	assertNoFreezeConfig(t, unauthorized.JSON)
	authenticated, notModified, err := svc.GetAppConfig(context.Background(), 1001, 0)
	if err != nil || notModified || authenticated.Hash != unauthorized.Hash {
		t.Fatalf("authenticated config = hash:%d base:%d notModified:%v err:%v", authenticated.Hash, unauthorized.Hash, notModified, err)
	}
	assertNoFreezeConfig(t, authenticated.JSON)
	if _, notModified, err := svc.GetAppConfig(context.Background(), 1001, authenticated.Hash); err != nil || !notModified {
		t.Fatalf("authenticated hash replay = notModified:%v err:%v", notModified, err)
	}
}

func TestAccountAppConfigStripsGlobalFreezeFields(t *testing.T) {
	svc := NewService(nil, nil)
	base := domain.AppConfig{Client: "tdesktop", Hash: 9, JSON: []byte(`{"quote_length_max":1024,"freeze_since_date":1,"freeze_until_date":2,"freeze_appeal_url":"https://wrong.example"}`)}
	cfg, err := svc.accountAppConfig(context.Background(), 0, base)
	if err != nil {
		t.Fatal(err)
	}
	if cfg.Hash == base.Hash {
		t.Fatal("stripped config reused base hash")
	}
	assertNoFreezeConfig(t, cfg.JSON)
}

func assertFreezeConfig(t *testing.T, body []byte, since, until int64, appealURL string) {
	t.Helper()
	var values map[string]any
	if err := json.Unmarshal(body, &values); err != nil {
		t.Fatal(err)
	}
	if values["freeze_since_date"] != float64(since) || values["freeze_until_date"] != float64(until) || values["freeze_appeal_url"] != appealURL {
		t.Fatalf("freeze config = %#v", values)
	}
}

func assertNoFreezeConfig(t *testing.T, body []byte) {
	t.Helper()
	var values map[string]any
	if err := json.Unmarshal(body, &values); err != nil {
		t.Fatal(err)
	}
	for _, key := range []string{"freeze_since_date", "freeze_until_date", "freeze_appeal_url"} {
		if _, exists := values[key]; exists {
			t.Fatalf("unexpected %s in config", key)
		}
	}
}

type fakeAccountFreezeProvider struct {
	items map[int64]domain.AccountFreeze
}

func (f *fakeAccountFreezeProvider) AccountFreeze(_ context.Context, userID int64) (domain.AccountFreeze, bool, error) {
	freeze, found := f.items[userID]
	return freeze, found, nil
}