Skip to content

Epic: Integration Testing & Regression Pipeline — OpenSID ↔ OpenDK #1678

Description

@analisopendesa

Epic ini mengumpulkan pekerjaan untuk memastikan integrasi antara OpenSID (consumer) dan OpenDK (provider) — khususnya alur API-key yang dipasang di OpenSID dan digunakan untuk mengirim data ke OpenDK — terlindungi dari regresi fungsional dan performa. Epic ini menuntun dari pembuatan OpenAPI spec sampai E2E + CI gating.

Linked issues (yang sudah dibuat)

Summary / tujuan

  • Jadikan openapi/openapi.yaml sumber kebenaran (source of truth) untuk integrasi OpenSID → OpenDK.
  • Hindari breaking changes: consumer (OpenSID) harus gagal build jika kontrak API berubah tidak kompatibel.
  • Pastikan OpenDK menegakkan keamanan API-key (pembuatan, validasi, revocation, scope).
  • Otomatiskan pipeline test di CI: lint → unit → generate/openapi → contract → integration → gated E2E.
  • Tambahkan E2E happy-path (konfigurasi API-key di OpenSID → kirim data → verifikasi di OpenDK) dan ringan perf tests (k6) untuk memantau regressi performa.

Target hasil akhir (Definition of Done epic)

  • openapi/openapi.yaml tersedia & tervalidasi di CI.
  • OpenSID memiliki job contract-test yang memvalidasi contoh request/responses terhadap spec.
  • OpenDK memiliki unit & integration tests untuk API-key lifecycle yang berjalan di CI.
  • CI pipeline menghalangi merge ketika contract/integration tests gagal (PR gating).
  • E2E happy-path dan perf test dibuat, terdokumentasi dan dijalankan di CI (gated/optional sesuai runtime).

Context & why (singkat)

  • Saat ini OpenSID akan menyimpan API key OpenDK (setting di UI). OpenSID men-submit data khusus ke OpenDK menggunakan API key. Tanpa contract tests dan provider-side tests, perubahan kecil di payload/headers dapat memutus integrasi di lapangan. Epic ini menutup celah tersebut.

Bagaimana berbagai masalah tersebut saling berkaitan (urutan ketergantungan):

  1. Issue Generate & publish OpenAPI spec untuk OpenDK + dokumentasi runbook integrasi #1674 — Generate & publish OpenAPI spec + runbook (OpenDK)
    • Menghasilkan spec yang menjadi dasar contract tests.
  2. Issue Tests untuk API Key lifecycle + integration tests (provider-side) di OpenDK #1675 — Provider tests: API-key lifecycle (OpenDK)
    • Pastikan provider behavior (security, audit) benar.
    • Bisa dikerjakan paralel dengan Issue 1674, tapi finalisasi contract sync diperlukan.
  3. Issue Contract tests consumer-driven antara OpenSID (consumer) dan OpenDK (provider) #1673 — Contract tests (OpenSID consumer)
    • Konsumen memvalidasi request/response contoh terhadap spec dari Issue 1674.
  4. Issue CI workflow integrasi untuk regression (unit → contract → integration → E2E) + test metrics/coverage gating #1676 — CI pipeline integration-regression.yml (OpenDK + OpenSID)
    • Menggabungkan artifact/spec dari OpenDK dan menjalankan contract/integration jobs.
  5. Issue End-to-end user flow + performance/regression tests: configure API key in OpenSID UI, submit data to OpenDK, rate-limit & perf checks #1677 — E2E & perf (OpenSID + OpenDK)
    • Menjalankan full flow di lingkungan ephemeral atau menggunakan mock provider; perf tests nightly/after-merge.

Panduan terperinci untuk pemrogram (langkah demi langkah, berdasarkan peran)

Common assumptions & repo locations

  • Provider repo: https://github.com/OpenSID/OpenDK
  • Consumer repo: https://github.com/OpenSID/premium (atau repo OpenSID yang relevan)
  • Spec path on provider: openapi/openapi.yaml
  • Runbook path: docs/integration-testing.md
  • CI workflows: .github/workflows/integration-regression.yml (provider) and consumer job that downloads spec artifact

--- ISSUE #1674 (OpenAPI spec + runbook) — Implementation steps
Goal: generate a trustworthy OpenAPI spec and doc how to run integration tests.

Apa yang harus dilakukan

  • Configure Scribe (already in composer.json) or other generator:
    • Add/adjust config/scribe.php to output to openapi/openapi.yaml.
    • Add composer script: "generate:openapi": "php artisan scribe:generate --format=openapi".
  • Generate initial spec and commit openapi/openapi.yaml. Alternatively generate in CI and upload as artifact; but keep a committed representative spec for development.
  • Add validation step in CI: example command:
    • (Node) npx @redocly/openapi-cli lint openapi/openapi.yaml or
    • openapi-cli validate openapi/openapi.yaml (tool choice is team decision).
  • Write docs/integration-testing.md with:
    • How to generate the spec locally
    • How to run provider tests locally (docker-compose + php artisan migrate --env=testing)
    • Which env vars / GH Secrets are required (suggested names below)
    • How to use the spec in consumer project (URL or artifact)
  • Verify in browser: open public/swagger-ui or https://raw.githubusercontent.com/.../openapi/openapi.yaml in Swagger UI.

Files to edit/create

  • config/scribe.php
  • composer.json (scripts)
  • openapi/openapi.yaml (generated)
  • docs/integration-testing.md

Commands (dev)

  • composer install
  • cp .env.example .env
  • php artisan key:generate
  • php artisan scribe:generate
  • npx @redocly/openapi-cli lint openapi/openapi.yaml

Acceptance (issue #1674)

  • openapi/openapi.yaml exists & validated by CI
  • docs/integration-testing.md explains local + CI steps

--- ISSUE #1675 (API Key lifecycle tests, provider-side)
Goal: ensure OpenDK enforces API-key rules and logs requests; add factories/seeders for deterministic tests.

Apa yang harus dilakukan :

  • Add factories:
    • database/factories/ApiKeyFactory.php
    • database/factories/UserFactory.php (if missing)
  • Add tests:
    • Unit tests for ApiKeyService (create, hash, revoke, scope)
    • Integration (Feature) tests that exercise controller + middleware + DB:
      • Valid key → 2xx
      • Missing key → 401
      • Invalid key → 401/403
      • Revoked key → 403
      • Insufficient scope → 403
      • Audit log created per request
  • Use Pest or PHPUnit; in-memory sqlite recommended for CI speed:
    • set env for tests: DB_CONNECTION=sqlite DB_DATABASE=:memory:
  • Ensure tests clean up state (use RefreshDatabase trait).

Files to create/modify

  • tests/Unit/ApiKeyServiceTest.php
  • tests/Feature/ApiKeyMiddlewareTest.php
  • database/factories/ApiKeyFactory.php
  • database/seeders/TestApiKeySeeder.php (optional)

Commands (dev)

  • vendor/bin/pest
  • vendor/bin/phpunit --filter ApiKey

Acceptance (issue #1675)

  • Tests cover API-key lifecycle; module coverage >= 80% (module-specific)
  • Tests reliable on CI

--- ISSUE #1673 (Contract tests, consumer-driven)
Goal: ensure OpenSID (consumer) validates outgoing requests against provider spec.

What to do (consumer-side)

  • Choose validator approach:
    • Quick approach: validate JSON examples against OpenAPI schema using openapi-cli or ajv.
    • Longer-term: Pact (consumer-driven contract) to capture interactions and verify provider.
  • Add tests/Contract in consumer repo:
    • Example requests/responses in tests/fixtures/contract/
    • Tests that download openapi.yaml from provider (or fetch artifact) and validate examples.
  • Add CI job contract-test in consumer repo:
    • Step: curl -sL https://raw.githubusercontent.com/OpenSID/OpenDK/master/openapi/openapi.yaml -o openapi.yaml
    • Run validator against example JSONs.
  • Coordinate with provider: if consumer tests fail due to spec mismatch, open a PR linking to provider issue.

Files & places

  • On consumer repo tests/Contract/ValidateAgainstOpenApiTest.*
  • CI job in .github/workflows/contract-test.yml or include in main CI.

Commands (dev)

  • node ./tools/validate-contracts.js openapi.yaml tests/fixtures/contract/*.json
  • or npx @redocly/openapi-cli validate openapi.yaml

Acceptance (issue #1673)

  • Consumer CI fails on contract mismatch
  • At least 5 example flows validated (happy path, validation error, auth error, duplicate/idempotency, revoked key)

--- ISSUE #1676 (CI workflow integration-regression.yml)
Goal: create CI pipeline that runs unit → generate-openapi → contract → integration → E2E (gated/optional) and enforces coverage gates.

What to do

  • Add workflow file: .github/workflows/integration-regression.yml
  • Jobs design (suggested):
    • job: lint (pint/phpcs)
    • job: unit-tests (fast)
    • job: generate-openapi (artifact openapi.yaml)
    • job: integration-tests (provider) — depends on unit-tests
    • job: contract-test (consumer) — can be run in separate repo that downloads artifact
    • job: e2e (optional; gated) — spins ephemeral services using docker-compose
  • Upload coverage to Codecov; gate PRs with coverage threshold (configurable, e.g., min 70%).
  • Make sure jobs cache composer & node_modules where possible.
  • Add matrix/parallelization for speed if tests grow.

CI secrets & artifacts

  • Secrets: CODECOV_TOKEN, TEST_API_KEY, DOCKERHUB_USERNAME / DOCKERHUB_TOKEN (if using images)
  • Artifact: openapi.yaml uploaded after generate job (actions/upload-artifact)

Commands (example steps)

  • php composer install --prefer-dist --no-progress
  • php artisan scribe:generate
  • npx @redocly/openapi-cli lint openapi/openapi.yaml
  • vendor/bin/pest --coverage
  • upload artifact openapi.yaml

Acceptance (issue #1676)

  • Workflow runs on PR and main; unit/integration/contract tests must pass before merge
  • Coverage uploaded; PR blocked if coverage drops below configured threshold

--- ISSUE #1677 (E2E & perf)
Goal: implement E2E happy-path and basic perf checks for the API-key integration.

What to do

  • E2E test (Playwright recommended or Pest Browser):
    • Steps:
      1. Login to OpenSID admin
      2. Go to integration settings, set TEST_API_KEY (from GH Secret)
      3. Trigger send-data action
      4. Verify provider received the payload — via:
        • a) Mock server that records request, or
        • b) ephemeral OpenDK instance + check DB record
    • Include negative cases: invalid key, revoked key
  • Perf test (k6):
    • Add scripts/perf/send-data-k6.js that simulates small load and asserts p95 threshold and error rate
    • Optional scheduled GitHub Action to run nightly and store metrics
  • E2E in CI:
    • Option A: gated job (long running) — run on merge or nightly
    • Option B: optional job — run on request or as part of nightly run

Acceptance (issue #1677)

  • E2E passes in CI (or documented gated behavior)
  • Perf script fails if p95 > 500ms or error rate > 0.1%

Developer notes — practical checklist for each PR

  • Branch naming: feature/integration-<short-desc> or test/<what>
  • PR title: prefix with issue id: ISSUE-#1674: generate openapi spec + scribe config
  • PR description must include:
    • Which issue it closes (e.g., Closes #1674)
    • Acceptance criteria checklist (mark done in PR)
    • How to run tests locally (commands + env)
  • Labels: type/feature or type/test, priority/high, area/ci as appropriate
  • Require code review + green CI before merge

Env vars & GH Secrets (recommended names)

  • TEST_API_KEY — test API key for E2E
  • CODECOV_TOKEN — for coverage upload
  • DB_CONNECTION_TEST, DB_DATABASE_TEST, DB_USERNAME_TEST, DB_PASSWORD_TEST — if needed for ephemeral DB in CI
  • OPENAPI_ARTIFACT_URL — optional pointer for consumer tests if hosted as artifact

Local dev quick-start (developer)

  1. Clone repo
  2. composer install
  3. cp .env.example .env
  4. composer run generate:openapi (or php artisan scribe:generate)
  5. php artisan migrate --env=testing
  6. vendor/bin/pest or vendor/bin/phpunit
  7. For E2E:
    • npm install
    • npx playwright test (or vendor/bin/pest --tests=tests/Browser)

Coordination & communication

  • If a change to API is necessary (breaking change), open a PR in OpenDK and:
    • update openapi/openapi.yaml
    • bump spec version and tag release
    • notify OpenSID maintainers and update consumer contract tests accordingly
  • For any failing contract test, coordinate via issue/PR referencing both repos and the failing example.

Sprint & estimate (recommended)

Appendix — useful commands & tools

  • Generate openapi: php artisan scribe:generate
  • Validate openapi: npx @redocly/openapi-cli lint openapi/openapi.yaml
  • Run unit tests: vendor/bin/pest or vendor/bin/phpunit
  • Run Playwright: npx playwright test
  • k6 run: k6 run scripts/perf/send-data-k6.js
  • Start ephemeral stack: docker-compose -f docker-compose.yml up --build -d

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions