Skip to main content

pact

Official Pact consumer-driven contract testing for Epoch service boundaries. Use when writing or verifying Pact contracts, HTTP client/provider integration tests, gossip/Community API contracts, or when the user says "pact", "contract test", "consumer driven contract", "CDC", "provider verification", or /pact. Follows https://docs.pact.io/ and @pact-foundation/pact (PactV3 + Verifier).

Datos de origen

Repositorio
Tyler-R-Kendrick/epoch
Última actividad en el origen
1 de agosto de 2026 a las 04:27
Idioma detectado de SKILL.md
inglés
Estrellas
0
Forks
0

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
pact
description
Official Pact consumer-driven contract testing for Epoch service boundaries. Use when writing or verifying Pact contracts, HTTP client/provider integration tests, gossip/Community API contracts, or when the user says "pact", "contract test", "consumer driven contract", "CDC", "provider verification", or /pact. Follows https://docs.pact.io/ and @pact-foundation/pact (PactV3 + Verifier).
# Pact Contract Testing (Epoch) Use **official** Pact tooling only: `@pact-foundation/pact` (already in this repo). Do not invent ad-hoc HTTP snapshot assertions when a service boundary exists. ## When to use Pact Add/update a Pact **whenever** an integration boundary is HTTP (or message) based: | Consumer | Provider | Boundary | |---|---|---| | `Epoch.Community.Core` HTTP client | `Epoch.Community.API` | `/workflows`, `/repositories`, issues, changes | | `Epoch.Core` `HttpGossipPeer` | `Epoch.Core.GossipHttp` | `POST /epoch/gossip` | **Do not** use Pact for pure in-process unit logic (CRDT merge, Ed25519 verify). Those stay as unit tests. ## Official process ([docs.pact.io](https://docs.pact.io/)) 1. **Consumer test** — real client code against Pact mock server; generates contract JSON. 2. **Share** — write contracts to durable `pacts/` (this repo) or publish to a Pact Broker. 3. **Provider verification** — `Verifier` replays requests against a **running** local provider. 4. **CI** — fail the build if consumer or provider verification fails. ## Repo layout ```text pacts/ # generated consumer contracts (durable) test/pact/helpers.ts # PactV3 factory + HTTP adapter helpers test/pact/consumer/ # additional consumer suites test/pact/provider/ # Verifier suites test/unit/community-contract.test.ts test/pact/run-pact-tests.ts # consumer then provider ``` ## Commands ```bash npm run test:pact # consumers → write pacts → provider verification npm run test:pact:consumer # consumer contracts only npm run test:pact:provider # provider verification (requires pacts/) ``` ## Writing a consumer test (PactV3) ```ts import { MatchersV3 } from "@pact-foundation/pact"; import { createConsumerPact, PactConsumers, PactProviders } from "../pact/helpers"; import { createHttpCommunityClient } from "@epoch/community-core"; // real client const pact = createConsumerPact({ consumer: PactConsumers.communityCore, provider: PactProviders.communityApi, }); pact .given("community repositories exist") .uponReceiving("a request to list community repositories") .withRequest({ method: "GET", path: "/repositories", headers: { Accept: "application/json" } }) .willRespondWith({ status: 200, headers: { "Content-Type": "application/json" }, body: MatchersV3.eachLike({ slug: "epoch/epoch" }, 1), }); await pact.executeTest(async (mockServer) => { const client = createHttpCommunityClient({ baseUrl: mockServer.url }); // MUST exercise real client code, not raw fetch-only probes await client.listRepositories(); }); ``` Rules from official docs: - Test the **collaborating client**, not raw HTTP only. - Use matchers (`MatchersV3.like`, `eachLike`, `regex`) for flexible fields. - Provider state names in `given(...)` must match provider `stateHandlers`. - Interaction `given` + `uponReceiving` pairs must be unique within a pact. ## Writing provider verification ```ts import { Verifier } from "@pact-foundation/pact"; await new Verifier({ provider: "Epoch.Community.API", providerBaseUrl: runningServer.url, pactUrls: ["pacts/Epoch.Community.Core-Epoch.Community.API.json"], stateHandlers: { "community repositories exist": async () => { /* seed provider */ }, }, }).verifyProvider(); ``` - Start the **real** provider (or thin adapter over real domain code). - Stub external deps only; do not reimplement the provider inside the test. - Prefer local `pactUrls` in unit CI; optional broker publish is CI-only. ## Adding a new service boundary 1. Name consumer + provider in `test/pact/helpers.ts` (`PactConsumers` / `PactProviders`). 2. Add consumer test under `test/pact/consumer/` (or extend unit contract suite). 3. Implement/extend HTTP provider surface if missing. 4. Add provider verification with `stateHandlers` for every `given`. 5. Wire into `test/pact/run-pact-tests.ts` and run `npm run test:pact`. 6. Update `docs/pact-contracts.md` boundary table. ## Broker (optional) Publish only from CI when broker env is configured: ```bash # requires @pact-foundation/pact-cli and PACT_BROKER_BASE_URL (+ token) npx pact-broker publish ./pacts --consumer-app-version="$GIT_SHA" --broker-base-url="$PACT_BROKER_BASE_URL" ``` Do not hard-code broker secrets in the repo. ## References - https://docs.pact.io/ - https://docs.pact.io/implementation_guides/javascript/docs/consumer - https://docs.pact.io/getting_started/verifying_pacts - https://github.com/pact-foundation/pact-js - Repo guide: `docs/pact-contracts.md`
Ver en GitHub