# Consumer-Driven Contract Testing (CDC)

socialseed-e2e provides built-in support for contract testing. This ensures that microservices stay compatible even when they evolve independently.

## How it works

1.  **Consumer** defines a **Contract**: Specifies exactly what requests it will send and what responses it expects from a Provider.
2.  **Contract is shared**: The contract file (JSON) is published to a registry.
3.  **Provider** verifies the **Contract**: The provider runs the contract interactions against its real implementation to ensure it still meets the consumer's expectations.

## Step 1: Defining a Contract (Consumer side)

Create a script to generate your contract:

```python
from socialseed_e2e.contract_testing import ConsumerContract

# 1. Define expectations
contract = ConsumerContract(consumer_name="web-app", provider_name="orders-service")

contract.given("an existing order with ID 123") \
    .upon_receiving("a request for order details") \
    .with_request(method="GET", path="/orders/123") \
    .will_respond_with(
        status=200,
        body={"id": 123, "status": "shipped", "total": 99.99}
    )

# 2. Save locally or publish to registry
contract.save()
```

## Step 2: Verifying a Contract (Provider side)

In the provider's CI/CD pipeline, run the verification:

```python
from socialseed_e2e.contract_testing import ProviderVerifier

# Specify the base URL of the running provider service
verifier = ProviderVerifier(provider_url="http://localhost:8080")

# Verify the contract generated by the consumer
success = verifier.verify_contract(".e2e/contracts/web-app-orders-service.json")

if not success:
    print("Contract verification failed! Breaking changes detected.")
    exit(1)
```

## Contract Registry

You can manage multiple versions of contracts using the `LocalContractRegistry`:

```python
from socialseed_e2e.contract_testing import LocalContractRegistry

registry = LocalContractRegistry()

# Publish a new version
registry.publish(contract.to_json(), consumer="web-app", provider="orders-service", version="v1.2.0")

# Detect breaking changes against the latest version
breaking_changes = registry.detect_breaking_changes(
    contract.to_json(), 
    consumer="web-app", 
    provider="orders-service"
)

for change in breaking_changes:
    print(f"⚠️ {change}")
```

## Why use Contract Testing?

- **Decoupled Deployments**: Deploy consumers and providers independently with confidence.
- **Fast Feedback**: Find integration issues before they reach production.
- **Improved Documentation**: Contracts serve as executable documentation of how services interact.
- **Reduced Flakiness**: Contract tests are faster and more stable than full end-to-end integration tests.
