Skip to content

Commit 0fa6e81

Browse files
cevianclaude
andcommitted
Add comprehensive integration tests for CLI lifecycle
- Added integration_test.go with full authentication and service lifecycle testing - Made psql command testable by using cmd.OutOrStdout() instead of os.Stdout - Fixed global config caching issue preventing --output json flag from working - Enhanced password storage testing with keychain integration - Updated CLAUDE.md with environment variable loading patterns and integration testing docs - Fixed service deletion verification and password authentication in tests 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent dae3f7b commit 0fa6e81

File tree

5 files changed

+557
-14
lines changed

5 files changed

+557
-14
lines changed

CLAUDE.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ go test ./...
2020

2121
# Run tests with verbose output
2222
go test -v ./...
23+
24+
# Load environment variables from .env file (note: source .env doesn't work)
25+
export $(cat .env | xargs)
26+
27+
# Run integration tests with environment variables from .env file
28+
export $(cat .env | xargs) && go test ./internal/tiger/cmd -v -run TestServiceLifecycleIntegration
2329
```
2430

2531
### Running Locally
@@ -31,6 +37,26 @@ go test -v ./...
3137
go run ./cmd/tiger --help
3238
```
3339

40+
### Integration Testing
41+
```bash
42+
# Run all tests (integration tests will skip without credentials)
43+
go test ./...
44+
45+
# Run only integration tests
46+
go test ./internal/tiger/cmd -run Integration
47+
48+
# To run integration tests with real API calls, set environment variables:
49+
export TIGER_PUBLIC_KEY_INTEGRATION=your-public-key
50+
export TIGER_SECRET_KEY_INTEGRATION=your-secret-key
51+
export TIGER_PROJECT_ID_INTEGRATION=your-project-id
52+
53+
# Optional: Set this to test database commands with existing service
54+
export TIGER_EXISTING_SERVICE_ID_INTEGRATION=existing-service-id
55+
56+
# Then run tests normally
57+
go test ./internal/tiger/cmd -v -run Integration
58+
```
59+
3460
### Code Generation
3561
```bash
3662
# Generate OpenAPI client code and mocks from openapi.yaml

TODO.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
TODO items:
1+
TODO items
2+
3+
Blocked:
24
- we should get a Project ID from the API when we login (need to add a new endpoint to the API)
35
- need to add JWT/OATH2 support so that users don't handle API keys
4-
- the api key stuff right now is messy. we require setting the api key from the public key and private key as public_key:private_key. should be a single string instead.
56

7+
Active List:
8+
- update exit codes for authentication and permission errors
9+
- test the --password-storage flag with none option and PGPASSWORD env var
610

7-
spec updates needed:
11+
Done:
12+
- ✅ api key stuff right now is messy. we require setting the api key from the public key and private key as public_key:private_key. should be a single string instead.
813
- ✅ change service operations to use --wait-timeout instead of --timeout
914
- ✅ implement --wait-timeout flag to accept time.ParseDuration format (e.g., "30m", "1h30m", "90s")
1015
- ✅ update --timeout flag for db test-connection to accept time.ParseDuration format
@@ -14,7 +19,4 @@ spec updates needed:
1419
- ✅ change from "tiger services" to "tiger service" with aliases for "services" and "svc"
1520
- ✅ add --password-storage flag to all commands that save passwords (keyring|pgpass|none)
1621
- ✅ update create-service and update-password commands to respect global --password-storage flag (keyring|pgpass|none)
17-
- update exit codes for authentication and permission errors
18-
19-
small things:
20-
- make sure create makes the service the default service (with option to not do this)
22+
- ✅ make sure create makes the service the default service (with option to not do this)

internal/tiger/cmd/db.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -352,20 +352,22 @@ func separateServiceAndPsqlArgs(cmd ArgsLenAtDashProvider, args []string) ([]str
352352

353353
// launchPsqlWithConnectionString launches psql using the connection string and additional flags
354354
func launchPsqlWithConnectionString(connectionString, psqlPath string, additionalFlags []string, service api.Service, cmd *cobra.Command) error {
355-
psqlCmd := buildPsqlCommand(connectionString, psqlPath, additionalFlags, service)
355+
psqlCmd := buildPsqlCommand(connectionString, psqlPath, additionalFlags, service, cmd)
356356
return psqlCmd.Run()
357357
}
358358

359359
// buildPsqlCommand creates the psql command with proper environment setup
360-
func buildPsqlCommand(connectionString, psqlPath string, additionalFlags []string, service api.Service) *exec.Cmd {
360+
func buildPsqlCommand(connectionString, psqlPath string, additionalFlags []string, service api.Service, cmd *cobra.Command) *exec.Cmd {
361361
// Build command arguments: connection string first, then additional flags
362362
args := []string{connectionString}
363363
args = append(args, additionalFlags...)
364364

365365
psqlCmd := exec.Command(psqlPath, args...)
366-
psqlCmd.Stdin = os.Stdin
367-
psqlCmd.Stdout = os.Stdout
368-
psqlCmd.Stderr = os.Stderr
366+
367+
// Use cmd's input/output streams for testability while maintaining CLI behavior
368+
psqlCmd.Stdin = cmd.InOrStdin()
369+
psqlCmd.Stdout = cmd.OutOrStdout()
370+
psqlCmd.Stderr = cmd.ErrOrStderr()
369371

370372
// Only set PGPASSWORD for keyring storage method
371373
// pgpass storage relies on psql automatically reading ~/.pgpass file

internal/tiger/cmd/db_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,8 +361,11 @@ func TestBuildPsqlCommand_KeyringPasswordEnvVar(t *testing.T) {
361361
psqlPath := "/usr/bin/psql"
362362
additionalFlags := []string{"--quiet"}
363363

364+
// Create a mock command for testing
365+
testCmd := &cobra.Command{}
366+
364367
// Call the actual production function that builds the command
365-
psqlCmd := buildPsqlCommand(connectionString, psqlPath, additionalFlags, service)
368+
psqlCmd := buildPsqlCommand(connectionString, psqlPath, additionalFlags, service, testCmd)
366369

367370
if psqlCmd == nil {
368371
t.Fatal("buildPsqlCommand returned nil")
@@ -400,8 +403,11 @@ func TestBuildPsqlCommand_PgpassStorage_NoEnvVar(t *testing.T) {
400403
connectionString := "postgresql://testuser@testhost:5432/testdb?sslmode=require"
401404
psqlPath := "/usr/bin/psql"
402405

406+
// Create a mock command for testing
407+
testCmd := &cobra.Command{}
408+
403409
// Call the actual production function that builds the command
404-
psqlCmd := buildPsqlCommand(connectionString, psqlPath, []string{}, service)
410+
psqlCmd := buildPsqlCommand(connectionString, psqlPath, []string{}, service, testCmd)
405411

406412
if psqlCmd == nil {
407413
t.Fatal("buildPsqlCommand returned nil")

0 commit comments

Comments
 (0)