* feat(cli): improve agent ergonomics * fix(cli): address code review findings - Fix nil pointer dereference in confirmDestructive when flags is nil - Deduplicate dry-run logic by delegating to dryRunExit - Remove deprecated net.Error.Temporary() call (dead since Go 1.18) - Add unit tests for resolveTasklistID and resolveCalendarID Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: resolve PR #201 conflicts and follow-ups (#201) (thanks @salmonumbrella) * fix: resolve rebase fallout for PR #201 landing (#201) (thanks @salmonumbrella) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Peter Steinberger <steipete@gmail.com>
102 lines
3.1 KiB
Go
102 lines
3.1 KiB
Go
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/99designs/keyring"
|
|
ggoogleapi "google.golang.org/api/googleapi"
|
|
|
|
"github.com/steipete/gogcli/internal/config"
|
|
gogapi "github.com/steipete/gogcli/internal/googleapi"
|
|
)
|
|
|
|
func TestStableExitCode_PreservesExistingExitError(t *testing.T) {
|
|
in := &ExitError{Code: 3, Err: errors.New("no results")}
|
|
out := stableExitCode(in)
|
|
if !errors.Is(out, in) {
|
|
t.Fatalf("expected same error instance")
|
|
}
|
|
if got := ExitCode(out); got != 3 {
|
|
t.Fatalf("expected exit code 3, got %d", got)
|
|
}
|
|
}
|
|
|
|
func TestStableExitCode_AuthRequired(t *testing.T) {
|
|
in := &gogapi.AuthRequiredError{Service: "gmail", Email: "a@b.com", Cause: keyring.ErrKeyNotFound}
|
|
out := stableExitCode(in)
|
|
if got := ExitCode(out); got != exitCodeAuthRequired {
|
|
t.Fatalf("expected exit code %d, got %d", exitCodeAuthRequired, got)
|
|
}
|
|
}
|
|
|
|
func TestStableExitCode_CredentialsMissing(t *testing.T) {
|
|
in := &config.CredentialsMissingError{Path: "/tmp/credentials.json", Cause: errors.New("missing")}
|
|
out := stableExitCode(in)
|
|
if got := ExitCode(out); got != exitCodeConfig {
|
|
t.Fatalf("expected exit code %d, got %d", exitCodeConfig, got)
|
|
}
|
|
}
|
|
|
|
func TestStableExitCode_GoogleAPINotFound(t *testing.T) {
|
|
in := &ggoogleapi.Error{Code: 404, Message: "not found"}
|
|
out := stableExitCode(in)
|
|
if got := ExitCode(out); got != exitCodeNotFound {
|
|
t.Fatalf("expected exit code %d, got %d", exitCodeNotFound, got)
|
|
}
|
|
}
|
|
|
|
func TestStableExitCode_GoogleAPIRateLimited(t *testing.T) {
|
|
in := &ggoogleapi.Error{Code: 429, Message: "too many requests"}
|
|
out := stableExitCode(in)
|
|
if got := ExitCode(out); got != exitCodeRateLimited {
|
|
t.Fatalf("expected exit code %d, got %d", exitCodeRateLimited, got)
|
|
}
|
|
}
|
|
|
|
func TestStableExitCode_GoogleAPIQuotaExceeded(t *testing.T) {
|
|
in := &ggoogleapi.Error{
|
|
Code: 403,
|
|
Message: "quota exceeded",
|
|
Errors: []ggoogleapi.ErrorItem{{Reason: "quotaExceeded"}},
|
|
}
|
|
out := stableExitCode(in)
|
|
if got := ExitCode(out); got != exitCodeRateLimited {
|
|
t.Fatalf("expected exit code %d, got %d", exitCodeRateLimited, got)
|
|
}
|
|
}
|
|
|
|
func TestStableExitCode_GoogleAPIRetryable(t *testing.T) {
|
|
in := &ggoogleapi.Error{Code: 503, Message: "backend error"}
|
|
out := stableExitCode(in)
|
|
if got := ExitCode(out); got != exitCodeRetryable {
|
|
t.Fatalf("expected exit code %d, got %d", exitCodeRetryable, got)
|
|
}
|
|
}
|
|
|
|
func TestStableExitCode_Cancelled(t *testing.T) {
|
|
out := stableExitCode(context.Canceled)
|
|
if got := ExitCode(out); got != exitCodeCancelled {
|
|
t.Fatalf("expected exit code %d, got %d", exitCodeCancelled, got)
|
|
}
|
|
}
|
|
|
|
func TestStableExitCode_DeadlineExceeded(t *testing.T) {
|
|
out := stableExitCode(context.DeadlineExceeded)
|
|
if got := ExitCode(out); got != exitCodeRetryable {
|
|
t.Fatalf("expected exit code %d, got %d", exitCodeRetryable, got)
|
|
}
|
|
}
|
|
|
|
func TestStableExitCode_GenericErrorUnchanged(t *testing.T) {
|
|
in := errors.New("boom")
|
|
out := stableExitCode(in)
|
|
if !errors.Is(out, in) {
|
|
t.Fatalf("expected stableExitCode to return original error for generic errors")
|
|
}
|
|
if got := ExitCode(out); got != 1 {
|
|
t.Fatalf("expected exit code 1, got %d", got)
|
|
}
|
|
}
|