acceptance

package
v1.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 21, 2025 License: Apache-2.0 Imports: 11 Imported by: 0

README

Hookdeck CLI Acceptance Tests

This directory contains Go-based acceptance tests for the Hookdeck CLI. These tests verify end-to-end functionality by executing the CLI and validating outputs.

Test Categories

Tests are divided into two categories:

1. Automated Tests (CI-Compatible)

These tests run automatically in CI using API keys from hookdeck ci. They don't require human interaction.

Files: All test files without build tags (e.g., basic_test.go, connection_test.go, project_use_test.go)

2. Manual Tests (Require Human Interaction)

These tests require browser-based authentication via hookdeck login and must be run manually by developers.

Files: Test files with //go:build manual tag (e.g., project_use_manual_test.go)

Why Manual? These tests access endpoints (like /teams) that require CLI authentication keys obtained through interactive browser login, which aren't available to CI service accounts.

Setup

Local Development

For local testing, create a .env file in this directory:

# test/acceptance/.env
HOOKDECK_CLI_TESTING_API_KEY=your_api_key_here

The .env file is automatically loaded when tests run. This file is git-ignored and should never be committed.

CI/CD

In CI environments (GitHub Actions), set the HOOKDECK_CLI_TESTING_API_KEY environment variable directly in your workflow configuration or repository secrets.

Running Tests

Run all automated (CI) tests:
go test ./test/acceptance/... -v
Run manual tests (requires human authentication):
go test -tags=manual -v ./test/acceptance/
Run specific manual test:
go test -tags=manual -run TestProjectUseLocalCreatesConfig -v ./test/acceptance/
Skip acceptance tests (short mode):
go test ./test/acceptance/... -short

All acceptance tests are skipped when -short flag is used, allowing fast unit test runs.

Manual Test Workflow

When you run manual tests, here's what happens:

Example Session
$ go test -tags=manual -v ./test/acceptance/

=== RUN   TestProjectUseLocalCreatesConfig

🔐 Fresh Authentication Required
=================================
These tests require fresh CLI authentication with project access.

Step 1: Clearing existing authentication...
✅ Authentication cleared

Step 2: Starting login process...
Running: hookdeck login

[Browser opens for authentication - complete the login process]

Please complete the browser authentication if not already done.
Press Enter when you've successfully logged in and are ready to continue...

[User presses Enter]

Verifying authentication...
✅ Authenticated successfully: Logged in as user@example.com on project my-project in organization Acme Inc

--- PASS: TestProjectUseLocalCreatesConfig (15.34s)

=== RUN   TestProjectUseSmartDefault
✅ Already authenticated (from previous test)
--- PASS: TestProjectUseSmartDefault (1.12s)

...
What the Helper Does

The RequireCLIAuthenticationOnce(t) helper function:

  1. Clears existing authentication by running hookdeck logout and deleting config files
  2. Runs hookdeck login which opens a browser for authentication
  3. Waits for you to press Enter after completing browser authentication (gives you full control)
  4. Verifies authentication by running hookdeck whoami
  5. Fails the test if authentication doesn't succeed
  6. Runs only once per test session - subsequent tests in the same run reuse the authentication
Which Tests Require Manual Authentication

Automated Tests (project_use_test.go):

  • TestProjectUseLocalAndConfigFlagConflict - Flag validation only, no API calls
  • TestLocalConfigHelpers - Helper function tests, no API calls

Manual Tests (project_use_manual_test.go):

  • 🔐 TestProjectUseLocalCreatesConfig - Requires /teams endpoint access
  • 🔐 TestProjectUseSmartDefault - Requires /teams endpoint access
  • 🔐 TestProjectUseLocalCreateDirectory - Requires /teams endpoint access
  • 🔐 TestProjectUseLocalSecurityWarning - Requires /teams endpoint access
Tips for Running Manual Tests
  • Run all manual tests together to authenticate only once:

    go test -tags=manual -v ./test/acceptance/
    
  • Authentication persists across tests in the same run (handled by RequireCLIAuthenticationOnce)

  • Fresh authentication each run - existing auth is always cleared at the start

  • Be ready to authenticate - the browser will open automatically when you run the tests

Test Structure

Files
  • helpers.go - Test infrastructure and utilities

    • CLIRunner - Executes CLI commands via go run main.go
    • RequireCLIAuthentication(t) - Forces fresh CLI authentication for manual tests
    • RequireCLIAuthenticationOnce(t) - Authenticates once per test run
    • Helper functions for creating/deleting test resources
    • JSON parsing utilities
    • Data structures (Connection, etc.)
  • basic_test.go - Basic CLI functionality tests

    • Version command
    • Help command
    • Authentication (ci mode with API key)
    • Whoami verification
  • connection_test.go - Connection CRUD tests

    • List connections
    • Create and delete connections
    • Update connection metadata
    • Various source/destination types
  • listen_test.go - Listen command tests

    • Basic listen command startup and termination
    • Context-based process management
    • Background process handling
  • project_use_test.go - Project use automated tests (CI-compatible)

    • Flag validation tests
    • Helper function tests
    • Tests that don't require /teams endpoint access
  • project_use_manual_test.go - Project use manual tests (requires human auth)

    • Build tag: //go:build manual
    • Tests that require browser-based authentication
    • Tests that access /teams endpoint
  • .env - Local environment variables (git-ignored)

Key Components
CLIRunner

The CLIRunner struct provides methods to execute CLI commands:

cli := NewCLIRunner(t)

// Run command and get output
stdout, stderr, err := cli.Run("connection", "list")

// Run command expecting success
stdout := cli.RunExpectSuccess("connection", "list")

// Run command and parse JSON output
var conn Connection
err := cli.RunJSON(&conn, "connection", "get", connID)
Test Helpers
  • createTestConnection(t, cli) - Creates a basic test connection
  • deleteConnection(t, cli, id) - Deletes a connection (for cleanup)
  • generateTimestamp() - Generates unique timestamp for resource names

Writing Tests

All tests should:

  1. Skip in short mode:

    if testing.Short() {
        t.Skip("Skipping acceptance test in short mode")
    }
    
  2. Use cleanup for resources:

    t.Cleanup(func() {
        deleteConnection(t, cli, connID)
    })
    
  3. Use descriptive names:

    func TestConnectionWithStripeSource(t *testing.T) { ... }
    
  4. Log important information:

    t.Logf("Created connection: %s (ID: %s)", name, id)
    

Environment Requirements

  • Go 1.24.9+
  • Valid Hookdeck API key with appropriate permissions
  • Network access to Hookdeck API

Migration from Shell Scripts

These Go-based tests replace the shell script acceptance tests in test-scripts/test-acceptance.sh. The Go version provides:

  • Better error handling and reporting
  • Cross-platform compatibility
  • Integration with Go's testing framework
  • Easier maintenance and debugging
  • Structured test output with -v flag
Shell Script Coverage Mapping

All functionality from test-scripts/test-acceptance.sh has been successfully ported to Go tests:

Shell Script Test (Line) Go Test Location Status
Build CLI (33-34) Not needed - go run builds automatically ✅ N/A
Version command (40-41) basic_test.go:TestCLIBasics/Version ✅ Ported
Help command (43-44) basic_test.go:TestCLIBasics/Help ✅ Ported
CI auth (47) helpers.go:NewCLIRunner ✅ Ported
Whoami (49-50) basic_test.go:TestCLIBasics/Authentication ✅ Ported
Listen command (52-70) listen_test.go:TestListenCommandBasic ✅ Ported
Connection list (75-76) connection_test.go:TestConnectionListBasic ✅ Ported
Connection create - WEBHOOK (124-131) connection_test.go:TestConnectionAuthenticationTypes/WEBHOOK_Source_NoAuth ✅ Ported
Connection create - STRIPE (133-141) connection_test.go:TestConnectionAuthenticationTypes/STRIPE_Source_WebhookSecret ✅ Ported
Connection create - HTTP API key (143-152) connection_test.go:TestConnectionAuthenticationTypes/HTTP_Source_APIKey ✅ Ported
Connection create - HTTP basic auth (154-163) connection_test.go:TestConnectionAuthenticationTypes/HTTP_Source_BasicAuth ✅ Ported
Connection create - TWILIO HMAC (165-174) connection_test.go:TestConnectionAuthenticationTypes/TWILIO_Source_HMAC ✅ Ported
Connection create - HTTP dest bearer (178-187) connection_test.go:TestConnectionAuthenticationTypes/HTTP_Destination_BearerToken ✅ Ported
Connection create - HTTP dest basic (189-199) connection_test.go:TestConnectionAuthenticationTypes/HTTP_Destination_BasicAuth ✅ Ported
Connection update (201-238) connection_test.go:TestConnectionUpdate ✅ Ported
Connection bulk delete (240-246) connection_test.go:TestConnectionBulkDelete ✅ Ported
Logout (251-252) Not needed - handled automatically by test cleanup ✅ N/A

Migration Notes:

  • Build step is unnecessary in Go tests as go run compiles on-the-fly
  • Authentication is handled centrally in NewCLIRunner() helper
  • Logout is not required as each test gets a fresh runner instance
  • Go tests provide better isolation with t.Cleanup() for resource management
  • All authentication types and edge cases are covered with more granular tests

Troubleshooting

API Key Not Set
Error: HOOKDECK_CLI_TESTING_API_KEY environment variable must be set

Solution: Create a .env file in test/acceptance/ with your API key.

Command Execution Failures

If commands fail to execute, ensure you're running from the project root or that the working directory is set correctly.

Resource Cleanup

Tests use t.Cleanup() to ensure resources are deleted even if tests fail. If you see orphaned resources, check the cleanup logic in your test.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetCurrentOrgAndProject added in v1.3.0

func GetCurrentOrgAndProject(t *testing.T) (org, project string)

GetCurrentOrgAndProject returns the current organization and project from whoami. This is useful for tests that need to know which project they're working with.

func ParseOrgAndProjectFromWhoami added in v1.3.0

func ParseOrgAndProjectFromWhoami(t *testing.T, whoamiOutput string) (org, project string)

ParseOrgAndProjectFromWhoami extracts organization and project names from whoami output. Expected format: "Logged in as ... on project PROJECT_NAME in organization ORG_NAME"

func RequireCLIAuthentication added in v1.3.0

func RequireCLIAuthentication(t *testing.T) string

RequireCLIAuthentication forces fresh CLI authentication for tests that need human interaction. This helper: 1. Clears any existing authentication 2. Runs `hookdeck login` for the user 3. Prompts user to complete browser authentication 4. Waits for user confirmation (Enter key) 5. Verifies authentication succeeded via `hookdeck whoami` 6. Fails the test if authentication doesn't succeed

This ensures tests always run with fresh human-interactive CLI login.

func RequireCLIAuthenticationOnce added in v1.3.0

func RequireCLIAuthenticationOnce(t *testing.T) string

Types

type CLIRunner

type CLIRunner struct {
	// contains filtered or unexported fields
}

CLIRunner provides utilities for running CLI commands in tests

func NewCLIRunner

func NewCLIRunner(t *testing.T) *CLIRunner

NewCLIRunner creates a new CLI runner for tests It requires HOOKDECK_CLI_TESTING_API_KEY environment variable to be set

func NewManualCLIRunner added in v1.3.0

func NewManualCLIRunner(t *testing.T) *CLIRunner

NewManualCLIRunner creates a CLI runner for manual tests that use human authentication. Unlike NewCLIRunner, this does NOT run `hookdeck ci` and relies on existing CLI credentials from `hookdeck login`.

func (*CLIRunner) Run

func (r *CLIRunner) Run(args ...string) (stdout, stderr string, err error)

Run executes the CLI with the given arguments and returns stdout, stderr, and error The CLI is executed via `go run main.go` from the project root

func (*CLIRunner) RunExpectSuccess

func (r *CLIRunner) RunExpectSuccess(args ...string) string

RunExpectSuccess runs the CLI command and fails the test if it returns an error Returns only stdout for convenience

func (*CLIRunner) RunFromCwd added in v1.3.0

func (r *CLIRunner) RunFromCwd(args ...string) (stdout, stderr string, err error)

RunFromCwd executes the CLI from the current working directory. This is useful for tests that need to test --local flag behavior, which creates config in the current directory.

This builds a temporary binary in the project root, then runs it from the current working directory.

func (*CLIRunner) RunJSON

func (r *CLIRunner) RunJSON(result interface{}, args ...string) error

RunJSON runs the CLI command with --output json flag and unmarshals the result Automatically adds --output json to the arguments

type Connection

type Connection struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	Description string `json:"description"`
	Source      struct {
		Name string `json:"name"`
		Type string `json:"type"`
	} `json:"source"`
	Destination struct {
		Name   string      `json:"name"`
		Type   string      `json:"type"`
		Config interface{} `json:"config"`
	} `json:"destination"`
	Rules []map[string]interface{} `json:"rules"`
}

Connection represents a Hookdeck connection for testing

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL