Source profileQuality 93/100

event4u-app/agent-config/src/skills/api-testing/SKILL.md

api-testing

Use when writing API endpoint tests — integration tests, contract validation, response assertions, mocked external services — even when the user says 'test this route' without naming API testing.

Source repository stars
7
Declared platforms
0
Static risk flags
0
Last source update
2026-07-28
Source checked
2026-07-28

Decision brief

What it does—and where it fits

Use when writing API endpoint tests — integration tests, contract validation, response assertions, mocked external services — even when the user says 'test this route' without naming API testing.

Best for

  • Use this skill when writing or reviewing API endpoint tests — integration tests, contract validation, response structure checks, or external service mocking.

Not for

  • Tasks that require unconfirmed production actions or broad system permissions.
  • Environments where the pinned source and install steps cannot be inspected.

Compatibility matrix

Platform support, with evidence labels

PlatformStatusEvidenceWhat to check
CodexNot declaredNo explicit evidencePortability before use
Claude CodeNot declaredNo explicit evidencePortability before use
CursorNot declaredNo explicit evidencePortability before use
Gemini CLINot declaredNo explicit evidencePortability before use
Open the compatibility checker

Installation

Inspect first. Install second.

The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

Source-detected install commandSource
npx skills add https://github.com/event4u-app/agent-config --skill "src/skills/api-testing"
Safe inspection promptEditorial

Inspect the Agent Skill "api-testing" from https://github.com/event4u-app/agent-config/blob/0adf49a8ae84b0ff6e2de8759eea43257e020eff/src/skills/api-testing/SKILL.md at commit 0adf49a8ae84b0ff6e2de8759eea43257e020eff. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

Workflow

What the source asks the agent to do

  1. 01

    Procedure: Write API tests

    1. Understand the endpoint — Read the controller, form request, and existing tests. Understand expected behavior, edge cases, and auth requirements before writing anything. 2. Set up test data — Use seeders (preferred) or factories. Mock external services with Http::fake(). 3. E…

    Understand the endpoint — Read the controller, form request, and existing tests. Understand expected behavior, edge cases, and auth requirements before writing anything.Set up test data — Use seeders (preferred) or factories. Mock external services with Http::fake().Enumerate test cases — Run the test-case-discovery funnel first; cover success, validation errors, authorization failures, and edge cases — floor per behavior: 1 happy + 1 boundary + 1 error (+1 abuse case; on data-retu…
  2. 02

    Bridge to UI verification

    API tests cover the contract layer. When an endpoint feeds a UI surface (Livewire component, Blade-rendered page, SPA route), complement the API test with a thin UI probe: a livewire test for wired components, or a Playwright spec / browser screenshot for the rendered shell. Nev…

    API tests cover the contract layer. When an endpoint feeds a UI surface (Livewire component, Blade-rendered page, SPA route), complement the API test with a thin UI probe: a livewire test for wired components, or a Play…
  3. 03

    When to use

    Use this skill when writing or reviewing API endpoint tests — integration tests, contract validation, response structure checks, or external service mocking.

    Use this skill when writing or reviewing API endpoint tests — integration tests, contract validation, response structure checks, or external service mocking.
  4. 04

    Example

    Review the “Example” section in the pinned source before continuing.

    Review and apply the “Example” source section.
  5. 05

    Test categories

    Test the expected success scenario with valid input:

    Test the expected success scenario with valid input:Test that invalid input is rejected with correct error messages:Test that unauthorized access is blocked:

Permission review

Static risk signals and limitations

No configured static risk pattern was detected

This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.

Evidence record

Why each signal appears

EvidenceSourceComputedTestedEditorial
SignalValueEvidence typeMeaning
Quality score93/100ComputedDocumentation, specificity, maintenance, and trust rules
Repository stars7SourceRepository attention, not individual Skill quality
Compatibility0 platformsSourceDeclared in the catalog source record
Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

Pinned source

Provenance and original SKILL.md

Repository
event4u-app/agent-config
Skill path
src/skills/api-testing/SKILL.md
Commit
0adf49a8ae84b0ff6e2de8759eea43257e020eff
License
MIT
Collected
2026-07-28
Default branch
main
View the original SKILL.md

api-testing

When to use

Use this skill when writing or reviewing API endpoint tests — integration tests, contract validation, response structure checks, or external service mocking.

Procedure: Write API tests

  1. Understand the endpoint — Read the controller, form request, and existing tests. Understand expected behavior, edge cases, and auth requirements before writing anything.
  2. Set up test data — Use seeders (preferred) or factories. Mock external services with Http::fake().
  3. Enumerate test cases — Run the test-case-discovery funnel first; cover success, validation errors, authorization failures, and edge cases — floor per behavior: 1 happy + 1 boundary + 1 error (+1 abuse case; on data-returning endpoints the three broken-access-control negative tests are mandatory).
  4. Assert response — Check status code, JSON structure, data values. Use assertJsonStructure().
  5. Verify — Run the test. Must pass. Check no flaky assertions (no time-dependent, no random ordering).

Example

describe('GET /api/v1/projects', function () {
    it('returns paginated projects for authenticated user', function () {
        $user = loginAsTestUser();

        $response = $this->getJson('/api/v1/projects');

        $response->assertOk()
            ->assertJsonStructure([
                'data' => [['id', 'title', 'status']],
                'meta' => ['current_page', 'per_page', 'total'],
            ]);
    });

    it('returns 401 for unauthenticated request', function () {
        $this->getJson('/api/v1/projects')
            ->assertUnauthorized();
    });

    it('returns 403 when user lacks permission', function () {
        loginAsRestrictedUser();

        $this->getJson('/api/v1/projects')
            ->assertForbidden();
    });
});

Test categories

Happy path

Test the expected success scenario with valid input:

it('creates a project', function () {
    loginAsTestUser();

    $this->postJson('/api/v1/projects', [
        'title' => 'New Project',
        'customer_id' => $customerId,
    ])
        ->assertCreated()
        ->assertJsonPath('data.title', 'New Project');

    $this->assertDatabaseHas('projects', ['title' => 'New Project']);
});

Validation

Test that invalid input is rejected with correct error messages:

it('rejects project without title', function () {
    loginAsTestUser();

    $this->postJson('/api/v1/projects', [
        'customer_id' => $customerId,
    ])
        ->assertUnprocessable()
        ->assertJsonValidationErrors(['title']);
});

Authorization

Test that unauthorized access is blocked:

it('prevents non-owner from updating project', function () {
    $otherUser = loginAsOtherUser();

    $this->putJson("/api/v1/projects/{$project->id}", [
        'title' => 'Hijacked',
    ])
        ->assertForbidden();
});

Edge cases

Test boundary conditions:

it('handles empty collection', function () {
    loginAsTestUser();

    $this->getJson('/api/v1/projects')
        ->assertOk()
        ->assertJsonCount(0, 'data');
});

it('paginates large result sets', function () {
    loginAsTestUser();

    $this->getJson('/api/v1/projects?per_page=5')
        ->assertOk()
        ->assertJsonPath('meta.per_page', 5);
});

Response contract validation

Assert JSON structure

// Verify response shape (keys exist)
$response->assertJsonStructure([
    'data' => ['id', 'title', 'status', 'created_at'],
]);

// Verify exact values
$response->assertJsonPath('data.status', 'active');

// Verify collection count
$response->assertJsonCount(3, 'data');

Assert response types

// When strict typing matters
$data = $response->json('data');
expect($data['id'])->toBeInt();
expect($data['title'])->toBeString();
expect($data['total'])->toBeString(); // Money as string, not float

Filter noisy responses

When a failing test dumps the full JSON body, narrow the diagnosis with jq or grep instead of scrolling the whole payload:

# Extract only the failing assertion path
echo "$RESPONSE_JSON" | jq '.data.status, .errors'

# Targeted log scan
rg --json 'API call failed' storage/logs/laravel.log | jq -r '.data.lines.text'

External service mocking

it('handles external API failure gracefully', function () {
    Http::fake([
        'external-api.com/*' => Http::response(null, 500),
    ]);

    loginAsTestUser();

    $this->postJson('/api/v1/sync')
        ->assertStatus(502)
        ->assertJsonPath('message', 'External service unavailable');
});

Test checklist per endpoint

CategoryTests needed
AuthUnauthenticated (401), unauthorized (403)
ValidationMissing fields, wrong types, boundary values
Happy pathSuccess with valid input, correct status code
ResponseJSON structure, field types, pagination meta
Side effectsDatabase changes, events dispatched, jobs queued
Edge casesEmpty results, large payloads, concurrent access

Bridge to UI verification

API tests cover the contract layer. When an endpoint feeds a UI surface (Livewire component, Blade-rendered page, SPA route), complement the API test with a thin UI probe: a livewire test for wired components, or a Playwright spec / browser screenshot for the rendered shell. Never assume the UI works just because the API test is green.

Output format

  1. Test file in the project’s test framework (Pest, Jest, pytest) covering happy path, validation, auth, and edge cases
  2. Test names as readable sentences describing expected behavior
  3. Mocked external services where applicable

Auto-trigger keywords

  • API test
  • endpoint test
  • integration test
  • response validation
  • contract testing

Gotcha

  • Don't test framework internals (e.g., "does Laravel return 422 on validation error") — test YOUR validation rules.
  • Always seed test data explicitly — don't rely on data from other tests (parallel execution).
  • Mock external APIs with Http::fake() — never hit real services in tests.
  • The model forgets to assert response structure, only checking status codes — always check both.

Do NOT

  • Do not hardcode IDs or timestamps — use factories or seeders.
  • Do not skip auth tests — always test both authenticated and unauthenticated.
  • Do not assert entire JSON responses — assert only meaningful fields.
  • Do not use Http::fake() without also testing the real integration path.

Anti-bruteforce — diagnose before retry

When a test fails, do not retry blindly with tweaked assertions until something passes. Diagnose the root cause first: print the actual response shape once, compare it to the contract, then write a targeted fix. Trial-and-error retries hide real regressions.

Clarification guard — ambiguous contract → ask

If the endpoint contract is ambiguous (unclear status code, optional fields, error envelope shape), do not assume. Ask the user or check the OpenAPI spec / route definition before writing assertions — never guess the response shape from the route name.

Alternatives

Compare before choosing