Skip to main content

prowler-test-api

Testing patterns for Prowler API: JSON:API, Celery tasks, RLS isolation, RBAC. Trigger: When writing tests for api/ (JSON:API requests/assertions, cross-tenant isolation, RBAC, Celery tasks, viewsets/serializers).

Zur Installation springen

Quellinformationen

Repository
prowler-cloud/prowler
Letzte Quellaktivität
8. Juli 2026 um 12:31
Erkannte Sprache von SKILL.md
Englisch
Sterne
14.842
Forks
2.391

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
3 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
prowler-test-api
description
Testing patterns for Prowler API: JSON:API, Celery tasks, RLS isolation, RBAC. Trigger: When writing tests for api/ (JSON:API requests/assertions, cross-tenant isolation, RBAC, Celery tasks, viewsets/serializers).
license
Apache-2.0
metadata
{"author":"prowler-cloud","version":"1.1.0","scope":["root","api"],"auto_invoke":["Writing Prowler API tests","Testing RLS tenant isolation"]}
allowed-tools
Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
## Critical Rules - ALWAYS use `response.json()["data"]` not `response.data` - ALWAYS use `content_type = "application/vnd.api+json"` for PATCH/PUT requests - ALWAYS use `format="vnd.api+json"` for POST requests - ALWAYS test cross-tenant isolation - RLS returns 404, NOT 403 - NEVER skip RLS isolation tests when adding new endpoints - NEVER use realistic-looking API keys in tests (TruffleHog will flag them) - ALWAYS mock BOTH `.delay()` AND `Task.objects.get` for async task tests --- ## 1. Fixture Dependency Chain ```text create_test_user (session) ─► tenants_fixture (function) ─► authenticated_client │ └─► aws_provider ─► scans_fixture ─► findings_fixture ``` ### Key Fixtures | Fixture | Description | |---------|-------------| | `create_test_user` | Session user (`dev@prowler.com`) | | `tenants_fixture` | 3 tenants: [0],[1] have membership, [2] isolated | | `authenticated_client` | Django test client with JWT for tenant[0] | | `authenticated_client_for_tenant_factory` | Creates a Django test client with JWT for a specific user and tenant | | `provider_factory` | Creates one validated provider with provider-specific defaults | | `aws_provider` | 1 AWS provider in tenant[0] | | `aws_provider_pair` | 2 AWS providers in tenant[0] | | `all_provider_types_fixture` | 1 provider for every supported provider type | | `tasks_fixture` | 2 Celery tasks with TaskResult | ### RBAC Fixtures | Fixture | Permissions | |---------|-------------| | `authenticated_client_rbac` | All permissions (admin) | | `authenticated_client_rbac_noroles` | Membership but NO roles | | `authenticated_client_no_permissions_rbac` | All permissions = False | Use `authenticated_client` for normal view behavior tests. It uses a cheap JWT and still runs the real request authentication path. Use serializer-generated JWTs or API-key clients only when the test is specifically about token obtain/refresh, invalid tokens, expired tokens, tenant switching by token, API keys, or unauthenticated 401 behavior. Use `authenticated_client_for_tenant_factory` when a test needs a cheap JWT client for a different user or tenant. --- ## 2. JSON:API Requests ### POST (Create) ```python response = client.post( reverse("provider-list"), data={"data": {"type": "providers", "attributes": {...}}}, format="vnd.api+json", # NOT content_type! ) ``` ### PATCH (Update) ```python response = client.patch( reverse("provider-detail", kwargs={"pk": provider.id}), data={"data": {"type": "providers", "id": str(provider.id), "attributes": {...}}}, content_type="application/vnd.api+json", # NOT format! ) ``` ### Reading Responses ```python data = response.json()["data"] attrs = data["attributes"] errors = response.json()["errors"] # For 400 responses ``` --- ## 3. RLS Isolation (Cross-Tenant) **RLS returns 404, NOT 403** - the resource is invisible, not forbidden. ```python def test_cross_tenant_access_denied(self, authenticated_client, tenants_fixture): other_tenant = tenants_fixture[2] # Isolated tenant foreign_provider = Provider.objects.create(tenant_id=other_tenant.id, ...) response = authenticated_client.get(reverse("provider-detail", args=[foreign_provider.id])) assert response.status_code == status.HTTP_404_NOT_FOUND # NOT 403! ``` --- ## 4. Celery Task Testing ### Testing Strategies | Strategy | Use For | |----------|---------| | Mock `.delay()` + `Task.objects.get` | Testing views that trigger tasks | | `task.apply()` | Synchronous task logic testing | | Mock `chain`/`group` | Testing Canvas orchestration | | Mock `connection` | Testing `@set_tenant` decorator | | Mock `apply_async` | Testing Beat scheduled tasks | ### Why NOT `task_always_eager` | Problem | Impact | |---------|--------| | No task serialization | Misses argument type errors | | No broker interaction | Hides connection issues | | Different execution context | `self.request` behaves differently | **Instead, use:** `task.apply()` for sync execution, mocking for isolation. > **Full examples:** See [assets/api_test.py](assets/api_test.py) for `TestCeleryTaskLogic`, `TestCeleryCanvas`, `TestSetTenantDecorator`, `TestBeatScheduling`. --- ## 5. Fake Secrets (TruffleHog) ```python # BAD - TruffleHog flags these: api_key = "sk-test1234567890T3BlbkFJtest1234567890" # GOOD - obviously fake: api_key = "sk-fake-test-key-for-unit-testing-only" ``` --- ## 6. Response Status Codes | Scenario | Code | |----------|------| | Successful GET | 200 | | Successful POST | 201 | | Async operation (DELETE/scan trigger) | 202 | | Sync DELETE | 204 | | Validation error | 400 | | Missing permission (RBAC) | 403 | | RLS isolation / not found | 404 | --- ## Commands ```bash cd api && uv run pytest -x --tb=short cd api && uv run pytest -k "test_provider" cd api && uv run pytest api/src/backend/api/tests/test_rbac.py ``` --- ## Resources - **Full Examples**: See [assets/api_test.py](assets/api_test.py) for complete test patterns - **Fixture Reference**: See [references/test-api-docs.md](references/test-api-docs.md) - **Fixture Source**: `api/src/backend/conftest.py`
Auf GitHub ansehen