# StemeDB Go SDK Integration Tests

Integration tests that run the Go SDK against a live StemeDB server.

## Quick Start

1. **Start the StemeDB API server:**

```bash
cd /path/to/stemedb
cargo run --bin stemedb-api
```

The server will start on `http://localhost:18180` by default.

2. **Run the integration tests:**

```bash
cd sdk/go/steme
STEMEDB_URL=http://localhost:18180 go test -tags=integration -v
```

## Test Coverage

The integration test suite is split across multiple files for maintainability:

### `integration_helpers_test.go` - Test Helpers & Health

- **getTestClient()** - Creates test client with auto-generated signer
- **uniqueSubject()** - Generates unique subjects for test isolation
- **TestIntegration_Health** - Verify health endpoint works

### `integration_assert_test.go` - Assert Operations

- **TestIntegration_Assert_Query_Roundtrip** - Create assertion, query it back
- **TestIntegration_Assert_AllObjectTypes** - Test all supported value types (Text, Number, Boolean, Reference)
- **TestIntegration_Assert_InvalidAssertion** - Verify invalid assertions are rejected (missing source_hash, invalid/negative confidence)
- **TestIntegration_Lifecycle** - Filter by lifecycle stage (Proposed, Approved, Deprecated)

### `integration_query_test.go` - Query Operations

- **TestIntegration_Query_WithLens** - Query with different lenses (Recency, Consensus, Authority)
- **TestIntegration_Query_NotFound** - Query for non-existent data returns empty
- **TestIntegration_Query_Limit** - Verify limit parameter works

### `integration_trace_test.go` - Audit Trail

- **TestIntegration_Trace** - Verify trace endpoint for audit trail querying
- **TestIntegration_Trace_WithPattern** - Trace with subject pattern filtering using wildcards

## Running Individual Tests

```bash
# Run a specific test
STEMEDB_URL=http://localhost:18180 go test -tags=integration -v -run TestIntegration_Health

# Run tests matching a pattern
STEMEDB_URL=http://localhost:18180 go test -tags=integration -v -run Query
```

## Test Isolation

Each test uses `uniqueSubject()` to generate unique subject IDs based on timestamps:

```go
subject := uniqueSubject("IntegrationTest_Entity")
// => "IntegrationTest_Entity_1738425600000000000"
```

This ensures tests don't interfere with each other, even when running in parallel.

## CI/CD Integration

Integration tests are **skipped by default** (build tag `integration`) so they don't break CI when no server is running.

To run integration tests in CI:

```yaml
# GitHub Actions example
- name: Start StemeDB server
  run: cargo run --bin stemedb-api &
  working-directory: /path/to/stemedb

- name: Wait for server
  run: |
    for i in {1..30}; do
      curl -f http://localhost:18180/v1/health && break
      sleep 1
    done

- name: Run integration tests
  run: STEMEDB_URL=http://localhost:18180 go test -tags=integration -v ./...
  working-directory: sdk/go/steme
```

## Troubleshooting

### Tests skip with "STEMEDB_URL not set"

Set the environment variable:

```bash
export STEMEDB_URL=http://localhost:18180
go test -tags=integration -v
```

### Tests fail with connection errors

Verify the server is running:

```bash
curl http://localhost:18180/v1/health
```

Should return:

```json
{
  "status": "healthy",
  "version": "0.1.0",
  "assertions_count": 0
}
```

### Tests fail after server restart

The server uses persistent storage. If tests fail due to stale data, clear the data directory:

```bash
# Check server logs for data directory location
rm -rf /path/to/data/stemedb_*
```

## Test File Organization

Each test file is under 400 lines for maintainability:

- **integration_helpers_test.go** (73 lines) - Shared helpers
- **integration_assert_test.go** (302 lines) - Assert/lifecycle tests
- **integration_query_test.go** (170 lines) - Query/lens tests
- **integration_trace_test.go** (203 lines) - Audit trail tests

## Adding New Tests

1. **Choose the appropriate file:**
   - Assert operations → `integration_assert_test.go`
   - Query operations → `integration_query_test.go`
   - Trace/audit → `integration_trace_test.go`
   - New category → Create new `integration_*_test.go`

2. **Use the build tag:**

```go
//go:build integration

package steme
```

3. **Get a test client:**

```go
client := getTestClient(t) // Auto-skips if STEMEDB_URL not set
```

4. **Use unique subjects:**

```go
subject := uniqueSubject("YourTest_Name")
```

5. **Add indexing delay after writes:**

```go
_, err := client.Assert(ctx, assertion)
time.Sleep(100 * time.Millisecond) // Allow indexing to complete
```

6. **Check for errors:**

```go
if err != nil {
    t.Fatalf("Assert() failed: %v", err)
}
```

## Example Test

```go
func TestIntegration_MyFeature(t *testing.T) {
    client := getTestClient(t)
    ctx := context.Background()

    subject := uniqueSubject("MyFeature_Test")

    // Create assertion
    assertion := NewAssertion(subject, "has_value").
        WithText("test").
        WithSourceHash("0000000000000000000000000000000000000000000000000000000000000000").
        Build()

    hash, err := client.Assert(ctx, assertion)
    if err != nil {
        t.Fatalf("Assert() failed: %v", err)
    }

    t.Logf("Created assertion: %s", hash)

    // Small delay for indexing
    time.Sleep(100 * time.Millisecond)

    // Query it back
    result, err := client.Query(ctx, NewQuery().WithSubject(subject).Build())
    if err != nil {
        t.Fatalf("Query() failed: %v", err)
    }

    if result.TotalCount == 0 {
        t.Fatal("Expected results, got none")
    }
}
```
