# Testing the Webhook Notification Plugin

This guide covers comprehensive testing strategies for the Webhook Notification Plugin at unit, integration, and end-to-end levels.

## Test Structure

```
tests/unit/mcpgateway/plugins/plugins/webhook_notification/
├── test_webhook_notification.py      # Unit tests
├── test_webhook_integration.py       # Integration tests
└── __init__.py                       # Test package init
```

## 1. Unit Tests

### Running Unit Tests
```bash
# Run all webhook plugin tests
pytest tests/unit/mcpgateway/plugins/plugins/webhook_notification/ -v

# Run specific test file
pytest tests/unit/mcpgateway/plugins/plugins/webhook_notification/test_webhook_notification.py -v

# Run with coverage
pytest tests/unit/mcpgateway/plugins/plugins/webhook_notification/ --cov=plugins.webhook_notification --cov-report=html
```

### Unit Test Coverage
- ✅ Plugin initialization and configuration
- ✅ Template rendering with context variables
- ✅ HMAC signature creation
- ✅ Webhook delivery success scenarios
- ✅ Authentication methods (Bearer, API Key, HMAC)
- ✅ Retry logic on failures
- ✅ Event type determination
- ✅ Hook execution (tool_post_invoke, prompt_post_fetch, etc.)
- ✅ Event filtering by webhook configuration
- ✅ Disabled webhook handling
- ✅ Custom payload templates
- ✅ Payload size limiting

### Key Test Cases

#### Authentication Testing
```python
# Test Bearer token authentication
config = {
    "webhooks": [{
        "authentication": {
            "type": "bearer",
            "token": "test-token-123"
        }
    }]
}

# Test API key authentication
config = {
    "webhooks": [{
        "authentication": {
            "type": "api_key",
            "api_key": "test-key",
            "api_key_header": "X-API-Key"
        }
    }]
}
```

#### Retry Logic Testing
```python
# Mock HTTP client to return 500 errors
mock_response.status_code = 500
mock_client.post.return_value = mock_response

# Verify retries (1 initial + 3 retries = 4 total calls)
assert mock_client.post.call_count == 4
```

## 2. Integration Tests

### Running Integration Tests
```bash
# Run integration tests
pytest tests/unit/mcpgateway/plugins/plugins/webhook_notification/test_webhook_integration.py -v

# Run with plugin manager setup
pytest tests/unit/mcpgateway/plugins/plugins/webhook_notification/test_webhook_integration.py::test_webhook_plugin_with_manager -v
```

### Integration Test Scenarios
- ✅ Plugin manager initialization with webhook plugin
- ✅ End-to-end hook execution through plugin manager
- ✅ Multiple webhook delivery
- ✅ Custom template usage
- ✅ Plugin interaction with other plugins (PII filter, rate limiter)

### Sample Integration Test Config
```yaml
plugins:
  - name: "WebhookNotification"
    kind: "plugins.webhook_notification.webhook_notification.WebhookNotificationPlugin"
    hooks: ["tool_post_invoke"]
    mode: "permissive"
    priority: 900
    config:
      webhooks:
        - url: "https://test.example.com/webhook"
          events: ["tool_success"]
          authentication:
            type: "bearer"
            token: "test-token"
```

## 3. Manual Testing

### Local Webhook Server Setup

#### Using Python HTTP Server
```bash
# Simple webhook receiver
cat << 'EOF' > webhook_server.py
#!/usr/bin/env python3
import json
from http.server import HTTPServer, BaseHTTPRequestHandler

class WebhookHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length)

        print(f"\n--- Webhook Received ---")
        print(f"Headers: {dict(self.headers)}")
        print(f"Body: {post_data.decode('utf-8')}")

        # Parse and pretty print JSON
        try:
            data = json.loads(post_data.decode('utf-8'))
            print(f"Parsed JSON:")
            print(json.dumps(data, indent=2))
        except:
            pass

        print("--- End Webhook ---\n")

        self.send_response(200)
        self.end_headers()
        self.wfile.write(b'OK')

if __name__ == '__main__':
    server = HTTPServer(('localhost', 3000), WebhookHandler)
    print("Webhook server running on http://localhost:3000")
    server.serve_forever()
EOF

python3 webhook_server.py
```

#### Using ngrok for Public URLs
```bash
# Install ngrok (if not installed)
# Mac: brew install ngrok
# Linux: snap install ngrok

# Expose local webhook server
ngrok http 3000

# Use the https URL from ngrok in your webhook config
```

### Manual Testing Steps

1. **Start Local Webhook Server**
   ```bash
   python3 webhook_server.py
   ```

2. **Configure Test Environment**
   ```bash
   cp plugins/webhook_notification/test_config.yaml plugins/config.yaml
   # Edit the webhook URL to point to your local server
   ```

3. **Start MCP Gateway**
   ```bash
   export PLUGINS_ENABLED=true
   export PLUGIN_CONFIG_FILE=plugins/config.yaml
   make dev
   ```

4. **Generate Test Bearer Token**
   ```bash
   export MCPGATEWAY_BEARER_TOKEN=$(python -m mcpgateway.utils.create_jwt_token --username test@example.com --exp 60 --secret test-secret)
   ```

5. **Trigger Webhook Events**

   **Tool Success Event:**
   ```bash
   curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
        -H "Content-Type: application/json" \
        -d '{"jsonrpc":"2.0","id":1,"method":"test_tool","params":{"query":"hello world"}}' \
        http://localhost:8000/
   ```

   **PII Detection Event:**
   ```bash
   curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
        -H "Content-Type: application/json" \
        -d '{"jsonrpc":"2.0","id":2,"method":"search","params":{"query":"my email is john@example.com"}}' \
        http://localhost:8000/
   ```

   **Rate Limit Event (call rapidly):**
   ```bash
   for i in {1..10}; do
     curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
          -H "Content-Type: application/json" \
          -d '{"jsonrpc":"2.0","id":'$i',"method":"test_tool","params":{"query":"test"}}' \
          http://localhost:8000/ &
   done
   wait
   ```

## 4. External Service Testing

### Testing with Webhook.site
1. Visit https://webhook.site
2. Copy your unique URL
3. Update config with the URL:
   ```yaml
   webhooks:
     - url: "https://webhook.site/YOUR-UNIQUE-ID"
       events: ["violation", "tool_success"]
       enabled: true
   ```

### Testing with Slack
1. Create a Slack webhook in your workspace
2. Set environment variable:
   ```bash
   export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK"
   ```
3. Enable Slack webhook in config:
   ```yaml
   webhooks:
     - url: "${env.SLACK_WEBHOOK_URL}"
       events: ["violation", "pii_detected"]
       enabled: true
   ```

## 5. Performance Testing

### Load Testing Webhook Delivery
```python
# Test concurrent webhook delivery
import asyncio
import time
from plugins.webhook_notification.webhook_notification import WebhookNotificationPlugin

async def test_concurrent_webhooks():
    plugin = create_test_plugin()

    # Send 100 concurrent notifications
    tasks = []
    start_time = time.time()

    for i in range(100):
        context = create_test_context(f"user-{i}")
        task = plugin._notify_webhooks(EventType.TOOL_SUCCESS, context)
        tasks.append(task)

    await asyncio.gather(*tasks)

    end_time = time.time()
    print(f"Sent 100 webhooks in {end_time - start_time:.2f} seconds")

# Run the test
asyncio.run(test_concurrent_webhooks())
```

### Memory Usage Testing
```bash
# Monitor memory usage during webhook delivery
pip install memory_profiler

# Profile webhook plugin
python -m memory_profiler test_webhook_memory.py
```

## 6. Error Scenario Testing

### Testing Network Failures
```python
# Mock network timeouts
mock_client.post.side_effect = asyncio.TimeoutError("Request timed out")

# Mock connection errors
mock_client.post.side_effect = httpx.ConnectError("Connection failed")

# Mock HTTP errors
mock_response.status_code = 503
mock_client.post.return_value = mock_response
```

### Testing Authentication Failures
```bash
# Test with invalid bearer token
curl -X POST -H "Authorization: Bearer invalid-token" \
     -H "Content-Type: application/json" \
     -d '{"jsonrpc":"2.0","id":1,"method":"test","params":{}}' \
     http://localhost:8000/
```

## 7. Security Testing

### Testing HMAC Signatures
```python
import hmac
import hashlib

def verify_webhook_signature(payload, signature, secret):
    expected = hmac.new(
        secret.encode('utf-8'),
        payload.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    return f"sha256={expected}" == signature

# Test signature verification in your webhook receiver
```

### Testing Credential Security
- ✅ Verify tokens are not logged
- ✅ Verify environment variables are used for secrets
- ✅ Test with expired/invalid credentials

## 8. Debugging Tips

### Enable Debug Logging
```bash
export LOG_LEVEL=DEBUG
make dev
```

### View Webhook Plugin Logs
```bash
# Filter for webhook plugin logs
tail -f logs/mcpgateway.log | grep -i webhook

# Or use structured logging
export MCPGATEWAY_LOG_FORMAT=json
```

### Common Issues and Solutions

**Issue**: Webhooks not being sent
- Check `enabled: true` in webhook config
- Verify events match what's being triggered
- Check plugin priority and hooks configuration

**Issue**: Authentication failures
- Verify environment variables are set correctly
- Check token/key format and headers
- Test authentication separately

**Issue**: Template rendering errors
- Validate JSON syntax in templates
- Check variable names match available context
- Test templates with sample data

**Issue**: Network timeouts
- Increase timeout values in webhook config
- Check network connectivity to webhook URLs
- Verify firewall and proxy settings

## 9. CI/CD Integration

### GitHub Actions Test Configuration
```yaml
name: Webhook Plugin Tests
on: [push, pull_request]

jobs:
  test-webhook-plugin:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: '3.11'

      - name: Install dependencies
        run: |
          make venv install-dev

      - name: Run webhook plugin tests
        run: |
          pytest tests/unit/mcpgateway/plugins/plugins/webhook_notification/ -v --cov

      - name: Run integration tests
        run: |
          pytest tests/unit/mcpgateway/plugins/plugins/webhook_notification/test_webhook_integration.py -v
```

### Test Coverage Requirements
- Unit tests: > 95% line coverage
- Integration tests: All major user scenarios
- Error handling: All exception paths covered

## 10. Test Data and Fixtures

### Sample Test Payloads
```json
{
  "tool_success": {
    "event": "tool_success",
    "tool_name": "search",
    "user": "test@example.com",
    "timestamp": "2025-01-15T10:30:45.123Z"
  },
  "violation": {
    "event": "violation",
    "violation": {
      "reason": "Rate limit exceeded",
      "code": "RATE_LIMIT"
    }
  }
}
```

This comprehensive testing approach ensures the Webhook Notification Plugin is robust, reliable, and ready for production use.
