Example 24

Consumer/provider contract testing

Provider verification needs provider states backed by data that matches the consumer's expectations.

Status
illustrative
Industry
Cross-industry
Language
TypeScript
Framework
Pact
CI
any
Fulfilment
BUILD_DATASET
Profile
retail-orders

About this example

All data is synthetic. DataNivra provisions approved test data into a customer-controlled target; it does not run these tests. Credentials for the target are never returned by DataNivra — your runner holds its own.

Why test data matters

Provider verification needs provider states backed by data that matches the consumer's expectations.

What is requested

100 everyday orders for the provider states.

Policy gates

Within the profile.

What is provisioned

A certified synthetic dataset behind the provider.

Expected output

AUTO_APPROVED.

Cleanup

Release after verification.

Files

  • request.yaml
  • provider.pact.ts

Run

  1. A tenant administrator defines and a second person approves the profile (datanivra test-data define ../../profiles/retail-orders.yaml --submit, then datanivra policies approve).
  2. datanivra test-data validate request.yaml && datanivra test-data plan request.yaml
  3. Run the example with DATANIVRA_BASE_URL and a session or workload token.

Files

Exactly as they are in the examples repository. Every value is a synthetic placeholder; nothing here is a credential.

request.yaml

# yaml-language-server: $schema=../../../../packages/contracts/schemas/v1/manifests/test-data-request.schema.json
# DataNivra test-data-request manifest (apiVersion datanivra.io/v1alpha1). Validate: datanivra test-data validate <file>
apiVersion: datanivra.io/v1alpha1
kind: TestDataRequest
metadata:
  name: provider-states
spec:
  profile: { name: retail-orders, version: 1 }
  scenarios:
    - { scenario_code: RET_EVERYDAY_SHOPPING, count: 100 }

examples/test-data-api/scenarios/24-contract-testing-pact/request.yaml

provider.pact.ts

/**
 * Consumer/provider contract testing — Pact provider verification with approved test data.
 * Illustrative: @pact-foundation/pact is not a dependency of this repository.
 */
import { readFileSync } from 'node:fs';
import { Verifier } from '@pact-foundation/pact';
import { createDataNivraClient } from '@datanivra/sdk';
import { TestDataClient } from '@datanivra/sdk/testdata';

const testData = new TestDataClient(
  createDataNivraClient({
    baseUrl: process.env.DATANIVRA_BASE_URL ?? 'https://api.example.test',
    getAccessToken: () => process.env.DATANIVRA_TOKEN,
  }),
);

await testData.withTestData(
  readFileSync(new URL('./request.yaml', import.meta.url), 'utf8'),
  async () => {
    await new Verifier({
      providerBaseUrl: process.env.PROVIDER_URL ?? 'http://localhost:8080',
      pactUrls: ['./pacts/web-orders.json'],
    }).verifyProvider();
  },
);

examples/test-data-api/scenarios/24-contract-testing-pact/provider.pact.ts

The profile it uses: retail-orders

A tenant administrator defines this profile and a second person approves it; requests can only ask for what it allows. All profiles

retail-orders.yaml

# yaml-language-server: $schema=../../../packages/contracts/schemas/v1/manifests/test-data-profile.schema.json
# DataNivra test-data-profile manifest (apiVersion datanivra.io/v1alpha1). Validate: datanivra test-data validate <file>
# Placeholder ids (00000000-0000-4000-8000-0000000000NN): replace with your ids.
# 01 = approved target environment, 11 = certified dataset, 21 = customer agent,
# 99 = workload identity trust (datanivra workload-identities list).
apiVersion: datanivra.io/v1alpha1
kind: TestDataProfile
metadata:
  name: retail-orders
  description: Synthetic customers, carts, orders, payments and returns
spec:
  fulfilment: BUILD_DATASET
  build:
    business_domain: orders and payments
    pack_id: retail-ecommerce
    dataset_kind: SYNTHETIC_ONLY
    target_environment_id: 00000000-0000-4000-8000-000000000001
    retention_days: 1
    max_total_records: 1500
    scenarios:
      - {
          pack_id: retail-ecommerce,
          scenario_code: RET_EVERYDAY_SHOPPING,
          kind: NORMAL,
          default_count: 500,
          max_count: 1000,
        }
      - {
          pack_id: retail-ecommerce,
          scenario_code: RET_RETURNS_AND_REFUNDS,
          kind: RARE,
          default_count: 50,
          max_count: 200,
        }
      - {
          pack_id: retail-ecommerce,
          scenario_code: RET_PAYMENT_DECLINES,
          kind: RARE,
          default_count: 50,
          max_count: 200,
        }
      - {
          pack_id: retail-ecommerce,
          scenario_code: RET_SPLIT_SHIPMENTS,
          kind: RARE,
          default_count: 20,
          max_count: 100,
          included_by_default: false,
        }

examples/test-data-api/profiles/retail-orders.yaml