iop/apps/node/internal/adapters/cli/status/gemini_test.go

283 lines
8.1 KiB
Go

package status
import (
"context"
"os"
"path/filepath"
"testing"
"time"
)
func TestGeminiCheckerRequestsStatsModel(t *testing.T) {
dir := t.TempDir()
fakeGemini := filepath.Join(dir, "gemini")
script := `#!/usr/bin/env sh
printf 'Gemini CLI v0.42.0\n'
printf '? for shortcuts\n'
sleep 0.1
IFS= read -r command
cmd="${command#?}"
if [ "$cmd" != "/stats model" ] && [ "$command" != "/stats model" ]; then
printf 'unexpected command: %s\n' "$command"
exit 3
fi
printf 'Auto (Gemini 3) Stats For Nerds\n'
printf '0%% used (Limit resets in 24h)\n'
printf 'Usage limit: 200\n'
printf 'Usage limits span all sessions and reset daily.\n'
IFS= read -r model_command
model_cmd="${model_command#?}"
if [ "$model_cmd" != "/model" ] && [ "$model_command" != "/model" ]; then
printf 'unexpected command: %s\n' "$model_command"
exit 3
fi
printf 'Select Model\n'
printf 'Model usage\n'
printf 'Flash ▬▬▬ 0%% Resets: 2:15 PM (24h)\n'
printf 'Pro ▬▬▬ 2%% Resets: 2:15 PM (24h)\n'
printf '(Press Esc to close)\n'
IFS= read -r exit_command
pkill -P $$ 2>/dev/null || true
exit 0
`
if err := os.WriteFile(fakeGemini, []byte(script), 0o755); err != nil {
t.Fatalf("write fake gemini: %v", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
checker := NewGeminiChecker(fakeGemini)
status, err := checker.Check(ctx)
if err != nil {
t.Fatalf("Check failed: %v", err)
}
if status.DailyLimit != "100%" {
t.Errorf("DailyLimit: got %q want %q", status.DailyLimit, "100%")
}
if status.DailyResetTime != "24h" {
t.Errorf("DailyResetTime: got %q want %q", status.DailyResetTime, "24h")
}
if status.Metadata["usage_limit"] != "200" {
t.Errorf("usage_limit: got %q want %q", status.Metadata["usage_limit"], "200")
}
if status.Metadata["used_percent"] != "0%" {
t.Errorf("used_percent: got %q want %q", status.Metadata["used_percent"], "0%")
}
if status.Metadata["daily_label"] != "Daily quota" {
t.Errorf("daily_label: got %q want %q", status.Metadata["daily_label"], "Daily quota")
}
if status.Metadata["model_usage_count"] != "2" {
t.Errorf("model_usage_count: got %q want %q", status.Metadata["model_usage_count"], "2")
}
if status.Metadata["model_usage_0_name"] != "Flash" {
t.Errorf("model_usage_0_name: got %q want %q", status.Metadata["model_usage_0_name"], "Flash")
}
if status.Metadata["model_usage_1_used_percent"] != "2%" {
t.Errorf("model_usage_1_used_percent: got %q want %q", status.Metadata["model_usage_1_used_percent"], "2%")
}
}
func TestGeminiCheckerWaitsForInputReady(t *testing.T) {
dir := t.TempDir()
fakeGemini := filepath.Join(dir, "gemini")
// Print the banner and non-input-ready workspace line first, then watch
// stdin for 0.5s. If anything is received before the prompt is rendered,
// exit 4. Only after the gap do we print the prompt and accept the real
// /stats model command.
script := `#!/usr/bin/env bash
printf 'Gemini CLI v0.42.0\n'
printf 'Tips for getting started\n'
printf 'workspace (/directory)\n'
if IFS= read -r -t 0.5 early; then
printf 'early input before prompt: %s\n' "$early"
exit 4
fi
printf '? for shortcuts\n'
IFS= read -r command
cmd="${command#?}"
if [ "$cmd" != "/stats model" ] && [ "$command" != "/stats model" ]; then
printf 'unexpected command: %s\n' "$command"
exit 3
fi
printf 'Auto (Gemini 3) Stats For Nerds\n'
printf '0%% used (Limit resets in 24h)\n'
printf 'Usage limit: 200\n'
IFS= read -r model_command
model_cmd="${model_command#?}"
if [ "$model_cmd" != "/model" ] && [ "$model_command" != "/model" ]; then
printf 'unexpected command: %s\n' "$model_command"
exit 3
fi
printf 'Select Model\n'
printf 'Model usage\n'
printf 'Flash ▬▬▬ 0%% Resets: 2:15 PM (24h)\n'
printf '(Press Esc to close)\n'
IFS= read -r exit_command
pkill -P $$ 2>/dev/null || true
exit 0
`
if err := os.WriteFile(fakeGemini, []byte(script), 0o755); err != nil {
t.Fatalf("write fake gemini: %v", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
checker := NewGeminiChecker(fakeGemini)
status, err := checker.Check(ctx)
if err != nil {
t.Fatalf("Check failed: %v", err)
}
if status.DailyLimit != "100%" {
t.Errorf("DailyLimit: got %q want %q", status.DailyLimit, "100%")
}
if status.DailyResetTime != "24h" {
t.Errorf("DailyResetTime: got %q want %q", status.DailyResetTime, "24h")
}
if status.Metadata["usage_limit"] != "200" {
t.Errorf("usage_limit: got %q want %q", status.Metadata["usage_limit"], "200")
}
if status.Metadata["model_usage_count"] != "1" {
t.Errorf("model_usage_count: got %q want %q", status.Metadata["model_usage_count"], "1")
}
}
func TestGeminiCheckerNoAPICallsReturnsRawUnparsed(t *testing.T) {
dir := t.TempDir()
fakeGemini := filepath.Join(dir, "gemini")
script := `#!/usr/bin/env sh
printf 'Gemini CLI v0.42.0\n'
printf '? for shortcuts\n'
sleep 0.1
IFS= read -r command
cmd="${command#?}"
if [ "$cmd" != "/stats model" ] && [ "$command" != "/stats model" ]; then
printf 'unexpected command: %s\n' "$command"
exit 3
fi
printf 'Auto (Gemini 3) Stats For Nerds\n'
printf 'No API calls have been made in this session.\n'
IFS= read -r model_command
model_cmd="${model_command#?}"
if [ "$model_cmd" != "/model" ] && [ "$model_command" != "/model" ]; then
printf 'unexpected command: %s\n' "$model_command"
exit 3
fi
printf 'Select Model\n'
printf 'Model usage\n'
printf 'Flash ▬▬▬ 0%% Resets: 2:15 PM (24h)\n'
printf '(Press Esc to close)\n'
IFS= read -r exit_command
pkill -P $$ 2>/dev/null || true
exit 0
`
if err := os.WriteFile(fakeGemini, []byte(script), 0o755); err != nil {
t.Fatalf("write fake gemini: %v", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
checker := NewGeminiChecker(fakeGemini)
status, err := checker.Check(ctx)
if err != nil {
t.Fatalf("Check failed: %v", err)
}
if status.DailyLimit != "" {
t.Errorf("DailyLimit should be empty, got %q", status.DailyLimit)
}
if status.WeeklyLimit != "" {
t.Errorf("WeeklyLimit should be empty, got %q", status.WeeklyLimit)
}
if status.RawOutput == "" {
t.Error("RawOutput should not be empty")
}
if status.Metadata["model_usage_count"] != "1" {
t.Errorf("model_usage_count: got %q want %q", status.Metadata["model_usage_count"], "1")
}
}
func TestGeminiCheckerParsesScreenReaderQuotaWithNoAPICalls(t *testing.T) {
dir := t.TempDir()
fakeGemini := filepath.Join(dir, "gemini")
script := `#!/usr/bin/env sh
printf 'Gemini CLI v0.42.0\n'
printf 'workspace (/directory)\n'
printf 'Auto (Gemini 3) quota\n'
printf '0%% used\n'
printf '? for shortcuts\n'
sleep 0.1
IFS= read -r command
cmd="${command#?}"
if [ "$cmd" != "/stats model" ] && [ "$command" != "/stats model" ]; then
printf 'unexpected command: %s\n' "$command"
exit 3
fi
printf 'No API calls have been made in this session.\n'
IFS= read -r model_command
model_cmd="${model_command#?}"
if [ "$model_cmd" != "/model" ] && [ "$model_command" != "/model" ]; then
printf 'unexpected command: %s\n' "$model_command"
exit 3
fi
printf 'Select Model\n'
printf 'Model usage\n'
printf 'Flash ▬▬▬ 0%% Resets: 2:15 PM (24h)\n'
printf '(Press Esc to close)\n'
IFS= read -r exit_command
pkill -P $$ 2>/dev/null || true
exit 0
`
if err := os.WriteFile(fakeGemini, []byte(script), 0o755); err != nil {
t.Fatalf("write fake gemini: %v", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
checker := NewGeminiChecker(fakeGemini)
status, err := checker.Check(ctx)
if err != nil {
t.Fatalf("Check failed: %v", err)
}
if status.DailyLimit != "100%" {
t.Errorf("DailyLimit: got %q want %q", status.DailyLimit, "100%")
}
if status.DailyResetTime != "" {
t.Errorf("DailyResetTime should be empty, got %q", status.DailyResetTime)
}
if status.Metadata["used_percent"] != "0%" {
t.Errorf("used_percent: got %q want %q", status.Metadata["used_percent"], "0%")
}
if status.Metadata["usage_limit"] != "" {
t.Errorf("usage_limit should be empty, got %q", status.Metadata["usage_limit"])
}
if status.Metadata["model_usage_count"] != "1" {
t.Errorf("model_usage_count: got %q want %q", status.Metadata["model_usage_count"], "1")
}
}