Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
3.7 kB · 122 lines
Go
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123package viewlog
import ( "sync" "testing" "time"
"github.com/stretchr/testify/require")
// memSaltStorage is the in-memory SaltStorage used by tests so they// don't need a real localdb.type memSaltStorage struct { mu sync.Mutex salts map[string][]byte getErr error putErr error getHits int putHits int}
func newMemSaltStorage() *memSaltStorage { return &memSaltStorage{salts: make(map[string][]byte)}}
func (m *memSaltStorage) GetViewLogSalt(date string) ([]byte, error) { m.mu.Lock() defer m.mu.Unlock() m.getHits++ if m.getErr != nil { return nil, m.getErr } return m.salts[date], nil}
func (m *memSaltStorage) PutViewLogSalt(date string, salt []byte) error { m.mu.Lock() defer m.mu.Unlock() m.putHits++ if m.putErr != nil { return m.putErr } m.salts[date] = append([]byte(nil), salt...) return nil}
func TestSaltManagerMintsAndCachesPerDay(t *testing.T) { storage := newMemSaltStorage() mgr := NewSaltManager(storage)
day1 := time.Date(2026, 5, 17, 12, 0, 0, 0, time.UTC) salt1, err := mgr.Salt(day1) require.NoError(t, err) require.Len(t, salt1, 32) require.Equal(t, 1, storage.getHits, "first call reads storage") require.Equal(t, 1, storage.putHits, "first call persists the minted salt")
// Second call same day, same UTC day → cached, no storage hits. salt1b, err := mgr.Salt(day1.Add(3 * time.Hour)) require.NoError(t, err) require.Equal(t, salt1, salt1b) require.Equal(t, 1, storage.getHits, "subsequent same-day calls don't re-read storage") require.Equal(t, 1, storage.putHits, "subsequent same-day calls don't re-write storage")
// Different day → new salt, new storage hit. day2 := day1.Add(24 * time.Hour) salt2, err := mgr.Salt(day2) require.NoError(t, err) require.NotEqual(t, salt1, salt2, "salt must change across days") require.Equal(t, 2, storage.getHits) require.Equal(t, 2, storage.putHits)}
func TestSaltManagerReusesPersistedSalt(t *testing.T) { // Simulates a process restart: pre-populated storage, new manager // instance, same day → same salt comes back. storage := newMemSaltStorage() preset := []byte("00112233445566778899aabbccddeeff") require.NoError(t, storage.PutViewLogSalt("2026-05-17", preset)) storage.putHits = 0 // reset to count subsequent writes only
mgr := NewSaltManager(storage) day := time.Date(2026, 5, 17, 0, 0, 0, 0, time.UTC) got, err := mgr.Salt(day) require.NoError(t, err) require.Equal(t, preset, got) require.Equal(t, 0, storage.putHits, "no write when storage already has the salt")}
func TestHashIPSameIPSameDayCollides(t *testing.T) { mgr := NewSaltManager(newMemSaltStorage()) now := time.Date(2026, 5, 17, 12, 0, 0, 0, time.UTC)
h1, err := mgr.HashIP("203.0.113.7", now) require.NoError(t, err) h2, err := mgr.HashIP("203.0.113.7", now.Add(2*time.Hour)) require.NoError(t, err) require.Equal(t, h1, h2, "same IP within UTC day collides")
other, err := mgr.HashIP("198.51.100.42", now) require.NoError(t, err) require.NotEqual(t, h1, other, "different IPs differ within a day")}
func TestHashIPDifferentDayDecorrelates(t *testing.T) { mgr := NewSaltManager(newMemSaltStorage()) day1 := time.Date(2026, 5, 17, 23, 30, 0, 0, time.UTC) day2 := day1.Add(2 * time.Hour) // crosses UTC midnight
h1, err := mgr.HashIP("203.0.113.7", day1) require.NoError(t, err) h2, err := mgr.HashIP("203.0.113.7", day2) require.NoError(t, err) require.NotEqual(t, h1, h2, "same IP across days must produce different hashes")}
func TestHashIPEmptyIPYieldsEmpty(t *testing.T) { mgr := NewSaltManager(newMemSaltStorage()) got, err := mgr.HashIP("", time.Now()) require.NoError(t, err) require.Empty(t, got, "no IP → no hash; callers can pass c.RealIP() straight through")}