Ctrl K
ComunidadGuías…

internal/store/postgres/channel_top_message_cache_test.go

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

Archivo original ↗Preguntar a KiBot
package postgres

import (
	"context"
	"testing"

	"telesrv/internal/domain"
)

func TestChannelTopMessageCacheBatchesClonesAndInvalidates(t *testing.T) {
	cache := NewChannelTopMessageCache(8)
	if cache == nil {
		t.Fatal("NewChannelTopMessageCache returned nil")
	}
	keys := []channelMessageLookupKey{{channelID: 7, id: 11}, {channelID: 7, id: 12}, {channelID: 8, id: 21}}
	loads := 0
	load := func(_ context.Context, missing []channelMessageLookupKey) (map[channelMessageLookupKey]domain.ChannelMessage, error) {
		loads++
		out := make(map[channelMessageLookupKey]domain.ChannelMessage, len(missing))
		for _, key := range missing {
			out[key] = domain.ChannelMessage{
				ChannelID: key.channelID,
				ID:        key.id,
				Entities:  []domain.MessageEntity{{Offset: 1, Length: 2}},
				Action:    &domain.ChannelMessageAction{UserIDs: []int64{3}},
				RichMessage: &domain.MessageRichMessage{
					Blocks: []byte{4, 5},
				},
			}
		}
		return out, nil
	}

	first, err := cache.getOrLoadBatch(context.Background(), keys, load)
	if err != nil {
		t.Fatal(err)
	}
	if loads != 1 {
		t.Fatalf("cold batch loads = %d, want 1", loads)
	}
	first[keys[0]].Entities[0].Offset = 99
	first[keys[0]].Action.UserIDs[0] = 99
	first[keys[0]].RichMessage.Blocks[0] = 99

	second, err := cache.getOrLoadBatch(context.Background(), keys, load)
	if err != nil {
		t.Fatal(err)
	}
	if loads != 1 {
		t.Fatalf("warm batch loads = %d, want 1", loads)
	}
	if got := second[keys[0]]; got.Entities[0].Offset != 1 || got.Action.UserIDs[0] != 3 || got.RichMessage.Blocks[0] != 4 {
		t.Fatalf("cached message alias-mutated: %+v", got)
	}

	listener := NewReadModelChangeListener("", ReadModelCacheSet{ChannelTopMessages: cache}, nil)
	cache.reactionPresence.Store(keys[0], channelTopReactionPresence{Normal: true})
	listener.handlePayload(`{"model":"channel_base","owner_user_id":0,"peer_type":"channel","peer_id":7}`)
	if _, ok := cache.reactionPresence.Peek(keys[0]); ok {
		t.Fatal("channel_base did not invalidate top reaction presence")
	}
	if _, err := cache.getOrLoadBatch(context.Background(), keys, load); err != nil {
		t.Fatal(err)
	}
	if loads != 2 {
		t.Fatalf("channel invalidation loads = %d, want 2", loads)
	}
}

func TestChannelTopMessageCacheNegativeResultIsCached(t *testing.T) {
	cache := NewChannelTopMessageCache(4)
	key := channelMessageLookupKey{channelID: 9, id: 1}
	loads := 0
	load := func(context.Context, []channelMessageLookupKey) (map[channelMessageLookupKey]domain.ChannelMessage, error) {
		loads++
		return map[channelMessageLookupKey]domain.ChannelMessage{}, nil
	}
	for i := 0; i < 2; i++ {
		got, err := cache.getOrLoadBatch(context.Background(), []channelMessageLookupKey{key}, load)
		if err != nil {
			t.Fatal(err)
		}
		if got[key].ID != 0 {
			t.Fatalf("negative result = %+v", got[key])
		}
	}
	if loads != 1 {
		t.Fatalf("negative cache loads = %d, want 1", loads)
	}
}