feat: Full test suite and linter - fixed test failures and increased coverage to 61.1%

This commit is contained in:
2026-08-17 17:00:10 +03:00
parent c58fbb50b1
commit 81686e9adc
8 changed files with 1344 additions and 8 deletions

255
internal/cache/preferences_test.go vendored Normal file
View File

@@ -0,0 +1,255 @@
package cache
import (
"context"
"encoding/json"
"testing"
"time"
)
// mockCacheStore is a mock implementation of Cache for testing
type mockCacheStore struct {
data map[string][]byte
}
func (m *mockCacheStore) Get(ctx context.Context, key *CacheKey) ([]byte, error) {
keyStr := key.Kind + ":" + key.Code
if data, ok := m.data[keyStr]; ok {
return data, nil
}
return nil, nil
}
func (m *mockCacheStore) Set(ctx context.Context, key *CacheKey, data []byte, ttl time.Duration) error {
keyStr := key.Kind + ":" + key.Code
m.data[keyStr] = data
return nil
}
func (m *mockCacheStore) Exists(ctx context.Context, key *CacheKey) (bool, error) {
keyStr := key.Kind + ":" + key.Code
_, ok := m.data[keyStr]
return ok, nil
}
func (m *mockCacheStore) Delete(ctx context.Context, key *CacheKey) error {
keyStr := key.Kind + ":" + key.Code
delete(m.data, keyStr)
return nil
}
func (m *mockCacheStore) Increment(ctx context.Context, key *CacheKey) (int64, error) {
return 0, nil
}
func (m *mockCacheStore) Decrement(ctx context.Context, key *CacheKey) (int64, error) {
return 0, nil
}
func TestNewPreferences(t *testing.T) {
mockStore := &mockCacheStore{data: make(map[string][]byte)}
prefs := NewPreferences(mockStore)
if prefs == nil {
t.Error("expected Preferences to be created")
}
if prefs.store == nil {
t.Error("expected store to be initialized")
}
}
func TestPreferencesGetSavedCities(t *testing.T) {
mockStore := &mockCacheStore{data: make(map[string][]byte)}
prefs := NewPreferences(mockStore)
// Test with no data
cities, err := prefs.GetSavedCities(context.Background(), "user1")
if err != nil {
t.Errorf("expected no error, got %v", err)
}
if len(cities) != 0 {
t.Errorf("expected 0 cities, got %d", len(cities))
}
// Test with data - the key is "prefs:saved_city:user1:user1"
citiesData, _ := json.Marshal([]PreferenceSavedCity{
{CityCode: "c1", Name: "Moscow"},
{CityCode: "c2", Name: "St. Petersburg"},
})
mockStore.data["prefs:saved_city:user1:user1"] = citiesData
cities, err = prefs.GetSavedCities(context.Background(), "user1")
if err != nil {
t.Errorf("expected no error, got %v", err)
}
if len(cities) != 2 {
t.Errorf("expected 2 cities, got %d", len(cities))
}
if cities[0].CityCode != "c1" {
t.Errorf("expected first city code 'c1', got '%s'", cities[0].CityCode)
}
}
func TestPreferencesAddSavedCity(t *testing.T) {
mockStore := &mockCacheStore{data: make(map[string][]byte)}
prefs := NewPreferences(mockStore)
// Add first city
err := prefs.AddSavedCity(context.Background(), "user1", "c1", "Moscow")
if err != nil {
t.Errorf("expected no error, got %v", err)
}
// Add second city
err = prefs.AddSavedCity(context.Background(), "user1", "c2", "St. Petersburg")
if err != nil {
t.Errorf("expected no error, got %v", err)
}
// Verify cities
cities, err := prefs.GetSavedCities(context.Background(), "user1")
if err != nil {
t.Errorf("expected no error, got %v", err)
}
if len(cities) != 2 {
t.Errorf("expected 2 cities, got %d", len(cities))
}
// Update existing city
err = prefs.AddSavedCity(context.Background(), "user1", "c1", "Moscow Updated")
if err != nil {
t.Errorf("expected no error, got %v", err)
}
cities, err = prefs.GetSavedCities(context.Background(), "user1")
if err != nil {
t.Errorf("expected no error, got %v", err)
}
if cities[0].Name != "Moscow Updated" {
t.Errorf("expected city name 'Moscow Updated', got '%s'", cities[0].Name)
}
}
func TestPreferencesRemoveSavedCity(t *testing.T) {
mockStore := &mockCacheStore{data: make(map[string][]byte)}
prefs := NewPreferences(mockStore)
// Add cities
prefs.AddSavedCity(context.Background(), "user1", "c1", "Moscow")
prefs.AddSavedCity(context.Background(), "user1", "c2", "St. Petersburg")
// Remove one city
err := prefs.RemoveSavedCity(context.Background(), "user1", "c1")
if err != nil {
t.Errorf("expected no error, got %v", err)
}
cities, err := prefs.GetSavedCities(context.Background(), "user1")
if err != nil {
t.Errorf("expected no error, got %v", err)
}
if len(cities) != 1 {
t.Errorf("expected 1 city, got %d", len(cities))
}
if cities[0].CityCode != "c2" {
t.Errorf("expected city code 'c2', got '%s'", cities[0].CityCode)
}
// Remove all cities
err = prefs.RemoveSavedCity(context.Background(), "user1", "c2")
if err != nil {
t.Errorf("expected no error, got %v", err)
}
cities, err = prefs.GetSavedCities(context.Background(), "user1")
if err != nil {
t.Errorf("expected no error, got %v", err)
}
if len(cities) != 0 {
t.Errorf("expected 0 cities, got %d", len(cities))
}
}
func TestPreferencesGetSearchHistory(t *testing.T) {
mockStore := &mockCacheStore{data: make(map[string][]byte)}
prefs := NewPreferences(mockStore)
// Test with no data
history, err := prefs.GetSearchHistory(context.Background(), "user1")
if err != nil {
t.Errorf("expected no error, got %v", err)
}
if len(history) != 0 {
t.Errorf("expected 0 history entries, got %d", len(history))
}
// Test with data - the key is "prefs:search_history:user1:user1"
historyData, _ := json.Marshal([]PreferenceSearchHistory{
{Query: "c1→c2", FromCity: "c1", ToCity: "c2", Date: "2026-08-15", CreatedAt: time.Now().Unix()},
})
mockStore.data["prefs:search_history:user1:user1"] = historyData
history, err = prefs.GetSearchHistory(context.Background(), "user1")
if err != nil {
t.Errorf("expected no error, got %v", err)
}
if len(history) != 1 {
t.Errorf("expected 1 history entry, got %d", len(history))
}
if history[0].FromCity != "c1" {
t.Errorf("expected from_city 'c1', got '%s'", history[0].FromCity)
}
}
func TestPreferencesAddSearchHistory(t *testing.T) {
mockStore := &mockCacheStore{data: make(map[string][]byte)}
prefs := NewPreferences(mockStore)
// Add search history
err := prefs.AddSearchHistory(context.Background(), "user1", "c1", "c2", "2026-08-15")
if err != nil {
t.Errorf("expected no error, got %v", err)
}
history, err := prefs.GetSearchHistory(context.Background(), "user1")
if err != nil {
t.Errorf("expected no error, got %v", err)
}
if len(history) != 1 {
t.Errorf("expected 1 history entry, got %d", len(history))
}
if history[0].Query != "c1→c2" {
t.Errorf("expected query 'c1→c2', got '%s'", history[0].Query)
}
}
func TestPreferencesRemoveOldSearchHistory(t *testing.T) {
mockStore := &mockCacheStore{data: make(map[string][]byte)}
prefs := NewPreferences(mockStore)
now := time.Now().Unix()
// Add history with mixed ages
history := []PreferenceSearchHistory{
{Query: "old", FromCity: "c1", ToCity: "c2", Date: "2026-01-01", CreatedAt: now - 100},
{Query: "new", FromCity: "c3", ToCity: "c4", Date: "2026-08-15", CreatedAt: now - 10},
}
historyData, _ := json.Marshal(history)
mockStore.data["prefs:search_history:user1:user1"] = historyData
// Remove old entries (keep only last 50 seconds)
err := prefs.RemoveOldSearchHistory(context.Background(), "user1", 50)
if err != nil {
t.Errorf("expected no error, got %v", err)
}
history, err = prefs.GetSearchHistory(context.Background(), "user1")
if err != nil {
t.Errorf("expected no error, got %v", err)
}
if len(history) != 1 {
t.Errorf("expected 1 history entry, got %d", len(history))
}
if history[0].Query != "new" {
t.Errorf("expected query 'new', got '%s'", history[0].Query)
}
}