gogcli/internal/cmd/gmail_autoforward_test.go
salmonumbrella d2be673d10
feat: add retry logic, concurrent fetching, and extended commands
Resilience:
- RetryTransport with circuit breaker for 429/5xx resilience
- Exponential backoff with jitter, respects Retry-After headers
- Circuit breaker auto-resets after 30s of successful requests

Performance:
- Concurrent gmail thread fetching (fixes N+1 query pattern)
- Bounded concurrency with semaphore (max 10 parallel)

New calendar commands:
- colors: list available event/calendar colors
- conflicts: check availability across calendars
- search: find events by text query
- time: show current time in multiple timezones

New gmail commands:
- autoforward: get/enable/disable auto-forwarding
- delegates: list/add/remove mail delegation
- filters: list/create/delete inbox filters
- forwarding: manage forwarding addresses
- sendas: manage send-as aliases
- vacation: get/enable/disable vacation responder
- batch: bulk operations (mark-read, archive, label, delete)
- watch: Pub/Sub push with webhook forwarding

New services:
- Sheets: read/write/append spreadsheet data
- Tasks: manage tasklists and tasks

Developer experience:
- Shell completion (bash, zsh, fish, powershell)
- version command with build info
- --debug flag for verbose logging
- lefthook for pre-commit hooks

Documentation:
- Expanded README with examples
- Gmail watch/Pub/Sub guide (docs/watch.md)
- Architecture spec (docs/spec.md)
- Release process (docs/RELEASING.md)
2025-12-24 17:51:21 -08:00

69 lines
1.3 KiB
Go

package cmd
import (
"testing"
)
func TestAutoForwardCommandExists(t *testing.T) {
// Unit tests for the actual API call live in integration; here we just ensure
// the command exists and is properly structured. (Compile-time coverage.)
_ = newGmailAutoForwardCmd
_ = newGmailAutoForwardGetCmd
_ = newGmailAutoForwardUpdateCmd
}
func TestValidateDisposition(t *testing.T) {
tests := []struct {
name string
value string
isValid bool
}{
{
name: "leaveInInbox is valid",
value: "leaveInInbox",
isValid: true,
},
{
name: "archive is valid",
value: "archive",
isValid: true,
},
{
name: "trash is valid",
value: "trash",
isValid: true,
},
{
name: "markRead is valid",
value: "markRead",
isValid: true,
},
{
name: "invalid value",
value: "deleteForever",
isValid: false,
},
{
name: "empty string",
value: "",
isValid: false,
},
}
validDispositions := map[string]bool{
"leaveInInbox": true,
"archive": true,
"trash": true,
"markRead": true,
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := validDispositions[tt.value]
if got != tt.isValid {
t.Errorf("disposition %q: got valid=%v, want valid=%v", tt.value, got, tt.isValid)
}
})
}
}