feat: Implement user preferences (saved cities, search history) with Redis storage and API handlers
This commit is contained in:
@@ -233,3 +233,107 @@ func TestProcessStation_Reactivation_AfterClosure(t *testing.T) {
|
||||
t.Errorf("expected zero days 0 after reactivation, got %d", zeroDays)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TestAutoClosureChronology verifies the chronology of auto-closure detection.
|
||||
// It tests that a station closes after exactly N=3 consecutive zero-trip days,
|
||||
// and that it reactivates when trips resume.
|
||||
func TestAutoClosureChronology(t *testing.T) {
|
||||
t.Helper()
|
||||
rc := redis.NewClient(&redis.Options{Addr: "localhost:6379"})
|
||||
defer rc.Close()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// Flush Redis database for test isolation
|
||||
rc.FlushDB(ctx)
|
||||
|
||||
// Monitor that returns 0 trips
|
||||
monitor := newMockMonitor("test-cha", 0, nil)
|
||||
|
||||
// Day 1: 0 trips - err declared with :=
|
||||
err := ProcessStation(ctx, monitor)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error day 1: %v", err)
|
||||
}
|
||||
|
||||
var zeroDays1 int
|
||||
zeroDaysData, _ := monitor.Cache.Get(ctx, zeroDaysKey("test-cha"))
|
||||
_, err = fmt.Sscanf(string(zeroDaysData), "%d", &zeroDays1)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse zero days: %v", err)
|
||||
}
|
||||
if zeroDays1 != 1 {
|
||||
t.Errorf("day 1: expected zero days 1, got %d", zeroDays1)
|
||||
}
|
||||
|
||||
// Day 2: 0 trips - assign to err (already declared)
|
||||
err = ProcessStation(ctx, monitor)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error day 2: %v", err)
|
||||
}
|
||||
|
||||
var zeroDays2 int
|
||||
zeroDaysData, _ = monitor.Cache.Get(ctx, zeroDaysKey("test-cha"))
|
||||
_, err = fmt.Sscanf(string(zeroDaysData), "%d", &zeroDays2)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse zero days: %v", err)
|
||||
}
|
||||
if zeroDays2 != 2 {
|
||||
t.Errorf("day 2: expected zero days 2, got %d", zeroDays2)
|
||||
}
|
||||
|
||||
// Day 3: 0 trips - assign to err (already declared), station closes
|
||||
err = ProcessStation(ctx, monitor)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error day 3: %v", err)
|
||||
}
|
||||
|
||||
var zeroDays3 int
|
||||
zeroDaysData, _ = monitor.Cache.Get(ctx, zeroDaysKey("test-cha"))
|
||||
_, err = fmt.Sscanf(string(zeroDaysData), "%d", &zeroDays3)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse zero days: %v", err)
|
||||
}
|
||||
if zeroDays3 != 3 {
|
||||
t.Errorf("day 3: expected zero days 3, got %d", zeroDays3)
|
||||
}
|
||||
|
||||
// Status should be closed
|
||||
statusData, err := monitor.Cache.Get(ctx, stationStatusKey("test-cha"))
|
||||
if err != nil {
|
||||
t.Fatalf("cache get status error: %v", err)
|
||||
}
|
||||
if string(statusData) != string(StatusClosed) {
|
||||
t.Errorf("expected status closed, got %s", string(statusData))
|
||||
}
|
||||
|
||||
// Day 4: trips resume - should reactivate
|
||||
monitor.ScheduleFunc = func(ctx context.Context, stationID string) (int, error) {
|
||||
return 1, nil
|
||||
}
|
||||
err = ProcessStation(ctx, monitor)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error reactivation: %v", err)
|
||||
}
|
||||
|
||||
// Status should be active again
|
||||
statusData, err = monitor.Cache.Get(ctx, stationStatusKey("test-cha"))
|
||||
if err != nil {
|
||||
t.Fatalf("cache get status error: %v", err)
|
||||
}
|
||||
if string(statusData) != string(StatusActive) {
|
||||
t.Errorf("expected status active after reactivation, got %s", string(statusData))
|
||||
}
|
||||
|
||||
var zeroDays4 int
|
||||
zeroDaysData, _ = monitor.Cache.Get(ctx, zeroDaysKey("test-cha"))
|
||||
_, err = fmt.Sscanf(string(zeroDaysData), "%d", &zeroDays4)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse zero days: %v", err)
|
||||
}
|
||||
if zeroDays4 != 0 {
|
||||
t.Errorf("expected zero days 0 after reactivation, got %d", zeroDays4)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user