Ctrl K
ComunidadGuías…

internal/app/systemidentity/systemidentity_test.go

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

Archivo original ↗Preguntar a KiBot
package systemidentity

import (
	"bytes"
	"context"
	"testing"
	"time"

	"telesrv/internal/domain"
	"telesrv/internal/identity"
)

func resetOfficialDisplayName(t *testing.T) {
	t.Helper()
	t.Cleanup(func() { domain.SetOfficialSystemUserDisplayName("") })
}

func TestApplyProjectsStoredIdentityOntoOfficialSystemUser(t *testing.T) {
	resetOfficialDisplayName(t)

	store := identity.NewStore(t.TempDir())
	if err := store.SetText("Acme Corp", "customer support"); err != nil {
		t.Fatalf("SetText: %v", err)
	}
	iconBytes := []byte("custom-icon-bytes")
	if err := store.SetIcon(iconBytes, ".png"); err != nil {
		t.Fatalf("SetIcon: %v", err)
	}

	var seededIcon []byte
	var seededAt int64
	seeder := func(_ context.Context, icon []byte, now int64) (bool, error) {
		seededIcon = append([]byte(nil), icon...)
		seededAt = now
		return true, nil
	}

	info, err := Apply(context.Background(), store, seeder, 1234)
	if err != nil {
		t.Fatalf("Apply: %v", err)
	}
	if info.Name != "Acme Corp" {
		t.Fatalf("Apply info.Name = %q, want Acme Corp", info.Name)
	}
	if got := domain.OfficialSystemUser().FirstName; got != "Acme Corp" {
		t.Fatalf("official system user FirstName = %q, want Acme Corp", got)
	}
	if !bytes.Equal(seededIcon, iconBytes) {
		t.Fatalf("seeder icon = %q, want the stored icon %q", seededIcon, iconBytes)
	}
	if seededAt != 1234 {
		t.Fatalf("seeder now = %d, want 1234", seededAt)
	}
}

func TestApplyFallsBackToBrandNameWithoutIdentity(t *testing.T) {
	resetOfficialDisplayName(t)

	store := identity.NewStore(t.TempDir())
	if _, err := Apply(context.Background(), store, nil, 0); err != nil {
		t.Fatalf("Apply: %v", err)
	}
	if got := domain.OfficialSystemUser().FirstName; got != "Telesrv" {
		t.Fatalf("official system user FirstName = %q, want branded default Telesrv", got)
	}
}

func TestWatcherAppliesNameWithoutTouchingAvatar(t *testing.T) {
	resetOfficialDisplayName(t)

	store := identity.NewStore(t.TempDir())
	if err := store.SetText("First", ""); err != nil {
		t.Fatalf("SetText: %v", err)
	}

	avatarCalls := make(chan struct{}, 8)
	seeder := func(_ context.Context, _ []byte, _ int64) (bool, error) {
		avatarCalls <- struct{}{}
		return false, nil
	}

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	go (&Watcher{Store: store, SeedAvatar: seeder, Interval: 10 * time.Millisecond}).Run(ctx)

	// Let Run take its initial snapshot ("First") before changing the store,
	// so the change is guaranteed to be seen as a change.
	time.Sleep(30 * time.Millisecond)
	if err := store.SetText("Second", ""); err != nil {
		t.Fatalf("SetText: %v", err)
	}
	waitForName(t, "Second")

	select {
	case <-avatarCalls:
		t.Fatal("a name-only change must not reseed the avatar")
	case <-time.After(50 * time.Millisecond):
	}
}

func TestWatcherSeedsAvatarOnIconChangeAndRevertsOnRemoval(t *testing.T) {
	resetOfficialDisplayName(t)

	store := identity.NewStore(t.TempDir())
	if err := store.SetText("Srv", ""); err != nil {
		t.Fatalf("SetText: %v", err)
	}

	avatarCalls := make(chan []byte, 8)
	seeder := func(_ context.Context, icon []byte, _ int64) (bool, error) {
		avatarCalls <- append([]byte(nil), icon...)
		return len(icon) > 0, nil
	}

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	go (&Watcher{Store: store, SeedAvatar: seeder, Interval: 10 * time.Millisecond}).Run(ctx)

	// No icon yet: the watcher must not seed anything.
	select {
	case icon := <-avatarCalls:
		t.Fatalf("watcher seeded avatar %q before an icon was set", icon)
	case <-time.After(60 * time.Millisecond):
	}

	if err := store.SetIcon([]byte("icon-a"), ".png"); err != nil {
		t.Fatalf("SetIcon: %v", err)
	}
	expectIcon(t, avatarCalls, []byte("icon-a"))

	if err := store.RemoveIcon(); err != nil {
		t.Fatalf("RemoveIcon: %v", err)
	}
	expectIcon(t, avatarCalls, nil)
}

func waitForName(t *testing.T, want string) {
	t.Helper()
	deadline := time.Now().Add(2 * time.Second)
	for time.Now().Before(deadline) {
		if domain.OfficialSystemUser().FirstName == want {
			return
		}
		time.Sleep(5 * time.Millisecond)
	}
	t.Fatalf("official system user FirstName = %q, want %q", domain.OfficialSystemUser().FirstName, want)
}

func expectIcon(t *testing.T, calls <-chan []byte, want []byte) {
	t.Helper()
	select {
	case icon := <-calls:
		if !bytes.Equal(icon, want) {
			t.Fatalf("seeded avatar icon = %q, want %q", icon, want)
		}
	case <-time.After(2 * time.Second):
		t.Fatalf("watcher did not seed avatar for icon %q", want)
	}
}