# Testing

This guide covers testing KayakNet during development and for quality assurance.

## Test Types

### Unit Tests

Test individual functions and components:

```bash
# Run all unit tests
go test ./...

# With verbose output
go test -v ./...

# Specific package
go test ./internal/chat/...

# With coverage
go test -cover ./...
```

### Integration Tests

Test component interactions:

```bash
# Run integration tests
go test -tags=integration ./...
```

### End-to-End Tests

Test complete user flows (manual):

1. Start bootstrap node
2. Start test nodes
3. Perform actions
4. Verify results

## Running Tests

### Quick Test

```bash
go test ./...
```

### Full Test Suite

```bash
# With race detection
go test -race ./...

# With coverage report
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
```

### Specific Tests

```bash
# Single test function
go test -run TestChatSendMessage ./internal/chat/...

# Test pattern
go test -run "TestChat.*" ./internal/chat/...
```

## Test Coverage

### Generate Report

```bash
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
open coverage.html
```

### Coverage Goals

| Package | Target |
| ------- | ------ |
| crypto  | 90%+   |
| e2e     | 85%+   |
| chat    | 80%+   |
| market  | 80%+   |
| escrow  | 85%+   |

## Writing Tests

### Test Structure

```go
func TestFunctionName(t *testing.T) {
    // Arrange
    input := setupTestData()
    
    // Act
    result, err := FunctionUnderTest(input)
    
    // Assert
    if err != nil {
        t.Errorf("unexpected error: %v", err)
    }
    if result != expected {
        t.Errorf("got %v, want %v", result, expected)
    }
}
```

### Table-Driven Tests

```go
func TestEncrypt(t *testing.T) {
    tests := []struct {
        name      string
        plaintext string
        key       []byte
        wantErr   bool
    }{
        {"valid input", "hello", validKey, false},
        {"empty input", "", validKey, false},
        {"nil key", "hello", nil, true},
        {"short key", "hello", shortKey, true},
    }
    
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            _, err := Encrypt([]byte(tt.plaintext), tt.key)
            if (err != nil) != tt.wantErr {
                t.Errorf("Encrypt() error = %v, wantErr %v", err, tt.wantErr)
            }
        })
    }
}
```

### Mocking

```go
type MockPeerStore struct {
    peers map[string]*Peer
}

func (m *MockPeerStore) GetPeer(id string) *Peer {
    return m.peers[id]
}

func TestWithMock(t *testing.T) {
    mock := &MockPeerStore{
        peers: map[string]*Peer{
            "peer1": {ID: "peer1", Name: "Test"},
        },
    }
    
    // Use mock in tests...
}
```

## Manual Testing

### Local Network Setup

```bash
# Terminal 1: Bootstrap
./kayakd --listen 0.0.0.0:4242 --name bootstrap

# Terminal 2: Node A
./kayakd --bootstrap 127.0.0.1:4242 --proxy --name nodeA --listen 0.0.0.0:4243

# Terminal 3: Node B  
./kayakd --bootstrap 127.0.0.1:4242 --name nodeB --listen 0.0.0.0:4244
```

### Test Scenarios

#### Chat Test

1. Node A joins room `#test`
2. Node B joins room `#test`
3. Node A sends message
4. Verify Node B receives message

#### Marketplace Test

1. Node A creates listing
2. Node B searches for listing
3. Verify listing appears
4. Node B creates order
5. Verify escrow created

#### Domain Test

1. Node A registers `test.kyk`
2. Node B looks up `test.kyk`
3. Verify resolution

## Browser Testing

### Setup

1. Start node with `--proxy`
2. Configure browser proxy to `127.0.0.1:8118`
3. Navigate to `http://home.kyk`

### Test Cases

| Feature     | Test                  |
| ----------- | --------------------- |
| Homepage    | Loads correctly       |
| Chat        | Send/receive messages |
| Marketplace | Browse listings       |
| Domains     | Search works          |
| Escrow      | Create order          |

## Performance Testing

### Load Test

```bash
# Using hey (install: go install github.com/rakyll/hey@latest)
hey -n 1000 -c 50 http://127.0.0.1:8080/api/network/info
```

### Benchmark Tests

```go
func BenchmarkEncrypt(b *testing.B) {
    key := generateKey()
    data := make([]byte, 1024)
    
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        Encrypt(data, key)
    }
}
```

Run benchmarks:

```bash
go test -bench=. ./internal/crypto/...
```

## CI/CD Integration

### GitHub Actions

```yaml
name: Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: '1.21'
      - run: go test -race -coverprofile=coverage.out ./...
      - uses: codecov/codecov-action@v4
        with:
          files: coverage.out
```

## Debugging Tests

### Verbose Output

```bash
go test -v ./...
```

### With Logging

```go
func TestWithLogging(t *testing.T) {
    t.Log("Starting test")
    // ...
    t.Logf("Result: %v", result)
}
```

### Debugging Failures

```bash
# Run specific failing test
go test -v -run TestFailingFunction ./path/to/package

# With debug output
KAYAKNET_DEBUG=1 go test -v ./...
```
