package status import ( "encoding/json" "errors" "testing" "time" ) var quotaCheckedAt = time.Date(2026, 7, 25, 8, 0, 0, 0, time.UTC) func TestNormalizeQuotaSnapshotExhaustedWinsMissing(t *testing.T) { snapshot := NormalizeQuotaSnapshot("agy", "Gemini", []string{"overall", "model:missing"}, quotaCheckedAt, &UsageStatus{DailyLimit: "0%"}, nil) if got := snapshot.Targets[0].Status; got != "exhausted" { t.Fatalf("status = %q, want exhausted", got) } if snapshot.RequiredCaps[1].Status != "unknown" { t.Fatalf("missing model status = %q, want unknown", snapshot.RequiredCaps[1].Status) } } func TestNormalizeQuotaSnapshotAvailableWhenAllPositive(t *testing.T) { snapshot := NormalizeQuotaSnapshot("agy", "Gemini", []string{"overall", "model:Flash"}, quotaCheckedAt, &UsageStatus{ DailyLimit: "70%", Metadata: map[string]string{ "model_usage_count": "1", "model_usage_0_name": "flash", "model_usage_0_used_percent": "20%", }, }, nil) if got := snapshot.Targets[0].Status; got != "available" { t.Fatalf("status = %q, want available", got) } for _, cap := range snapshot.RequiredCaps { if cap.Status != "available" || cap.RemainingPercent == nil || *cap.RemainingPercent <= 0 { t.Fatalf("cap = %#v, want positive available evidence", cap) } } } func TestNormalizeQuotaSnapshotUnknownForMissingConflictAndParseFailure(t *testing.T) { for name, tc := range map[string]struct { requiredCaps []string usage *UsageStatus }{ "missing": { requiredCaps: []string{"overall", "model:missing"}, usage: &UsageStatus{DailyLimit: "50%"}, }, "conflict": { requiredCaps: []string{"model:flash"}, usage: &UsageStatus{Metadata: map[string]string{ "model_usage_count": "2", "model_usage_0_name": "Flash", "model_usage_0_used_percent": "10%", "model_usage_1_name": "flash", "model_usage_1_used_percent": "20%", }}, }, "parse": { requiredCaps: []string{"overall"}, usage: &UsageStatus{DailyLimit: "not-a-percent"}, }, } { t.Run(name, func(t *testing.T) { snapshot := NormalizeQuotaSnapshot("agy", "Gemini", tc.requiredCaps, quotaCheckedAt, tc.usage, nil) if got := snapshot.Targets[0].Status; got != "unknown" { t.Fatalf("status = %q, want unknown", got) } }) } snapshot := NormalizeQuotaSnapshot("agy", "Gemini", []string{"overall"}, quotaCheckedAt, nil, errors.New("provider output must not escape")) if got := snapshot.Targets[0].Status; got != "unknown" { t.Fatalf("checker error status = %q, want unknown", got) } if len(snapshot.ReasonCodes) != 1 || snapshot.ReasonCodes[0] != "checker_error" { t.Fatalf("reason codes = %#v", snapshot.ReasonCodes) } } func TestNormalizeQuotaSnapshotUnknownForNonFinitePercent(t *testing.T) { for _, value := range []string{"NaN%", "Inf%", "-Inf%"} { t.Run("overall_"+value, func(t *testing.T) { snapshot := NormalizeQuotaSnapshot("agy", "Gemini", []string{"overall"}, quotaCheckedAt, &UsageStatus{DailyLimit: value}, nil) if got := snapshot.Targets[0].Status; got != "unknown" { t.Fatalf("status = %q, want unknown", got) } if _, err := json.Marshal(snapshot); err != nil { t.Fatalf("snapshot must be JSON encodable: %v", err) } }) t.Run("model_"+value, func(t *testing.T) { snapshot := NormalizeQuotaSnapshot("agy", "Gemini", []string{"model:flash"}, quotaCheckedAt, &UsageStatus{Metadata: map[string]string{ "model_usage_count": "1", "model_usage_0_name": "flash", "model_usage_0_used_percent": value, }}, nil) if got := snapshot.Targets[0].Status; got != "unknown" { t.Fatalf("status = %q, want unknown", got) } if _, err := json.Marshal(snapshot); err != nil { t.Fatalf("snapshot must be JSON encodable: %v", err) } }) } } func TestNormalizeQuotaSnapshotUsesAntigravityModelMetadata(t *testing.T) { usage, err := ParseStatusOutput("Auto (Antigravity) quota\n0% used (Limit resets in 24h)\nModel usage\nFlash ▬▬▬ 2% Resets: tomorrow\n(Press Esc to close)\n") if err != nil { t.Fatalf("parse status: %v", err) } snapshot := NormalizeQuotaSnapshot("agy", "Gemini", []string{"overall", "model:FLASH"}, quotaCheckedAt, usage, nil) if got := snapshot.Targets[0].Status; got != "available" { t.Fatalf("status = %q, want available", got) } }