Skip to content

Endpoint test depth: fuzz/adversarial ORM at trust boundary#154

Merged
wpak-ai merged 2 commits into
cppalliance:developfrom
whisper67265:fix/endpoint-test-depth
Jul 2, 2026
Merged

Endpoint test depth: fuzz/adversarial ORM at trust boundary#154
wpak-ai merged 2 commits into
cppalliance:developfrom
whisper67265:fix/endpoint-test-depth

Conversation

@whisper67265

@whisper67265 whisper67265 commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Close #152.

Summary by CodeRabbit

  • Bug Fixes

    • Strengthened add/update request validation for repo version, language codes, and repo segment lengths.
    • Normalized and validated extensions input (including whitespace-only entries and non-string values).
    • Enforced per-language submodule limits and improved structured error reporting for invalid language codes and submodule list issues.
    • Hardened endpoint behavior against malformed, oversized, and injection-like inputs.
  • Tests

    • Added extensive validation and adversarial/trust-boundary coverage, including denial of unsafe payloads and ensuring rejected requests don’t enqueue background work.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 39fd19ff-ac5e-400f-8742-66b90973341e

📥 Commits

Reviewing files that changed from the base of the PR and between d38a19e and 2c4c408.

📒 Files selected for processing (3)
  • src/boost_weblate/endpoint/serializers.py
  • src/boost_weblate/endpoint/validators.py
  • tests/endpoint/test_views.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/boost_weblate/endpoint/validators.py
  • src/boost_weblate/endpoint/serializers.py
  • tests/endpoint/test_views.py

📝 Walkthrough

Walkthrough

This PR adds shared length and language-code validation, updates add-or-update serializer checks for version, extensions, language counts, and submodule counts, and expands serializer and endpoint tests for invalid inputs and trust-boundary behavior.

Changes

Validation hardening and adversarial testing

Layer / File(s) Summary
Validator constants and helpers
src/boost_weblate/endpoint/validators.py
Adds size-limit constants, centralizes segment validation, extends repo-segment validation, and adds language-code validation.
Serializer validation rules
src/boost_weblate/endpoint/serializers.py
Adds version validation, rewrites extensions normalization, and enforces language-count and submodule-count limits in add-or-update validation.
Serializer validation tests
tests/endpoint/test_serializers.py
Adds tests for invalid version, unsafe language keys, non-string submodules, oversized organization, language and submodule limits, and invalid extensions input.
Adversarial endpoint and ORM tests
tests/endpoint/test_views.py
Adds shared adversarial payload fixtures, endpoint rejection tests, Celery enqueue guards, and ORM trust-boundary checks for literal request values.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested reviewers: henry0816191, wpak-ai

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: hardening endpoint trust-boundary validation with fuzz/adversarial tests.
Linked Issues check ✅ Passed The serializer, validator, and test changes match #152 by rejecting unsafe inputs, enforcing limits, and keeping rejected payloads out of Celery and ORM.
Out of Scope Changes check ✅ Passed The added validators and tests stay focused on endpoint trust-boundary hardening and do not introduce unrelated feature work.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
tests/endpoint/test_views.py (2)

630-638: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate throttle fixture across two classes.

_high_throttle_limits is defined identically in TestAddOrUpdateAdversarial and TestOrmTrustBoundary. Consider hoisting to a module-level fixture or shared base class to avoid drift.

Also applies to: 847-855

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/endpoint/test_views.py` around lines 630 - 638, The autouse fixture
_high_throttle_limits is duplicated in both TestAddOrUpdateAdversarial and
TestOrmTrustBoundary, so move the shared throttle setup into one reusable place
such as a module-level pytest fixture or a common base class and have both test
classes use it. Keep the existing _throttle_rest_framework and
_isolated_throttle_rates behavior unchanged, but reference the shared fixture
from both classes to avoid drift and keep the throttle configuration consistent.

654-844: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract repeated delay_mock/monkeypatch boilerplate into a fixture.

The same 5-line block (create MagicMock, monkeypatch.setattr("boost_weblate.endpoint.views.boost_add_or_update_task.delay", delay_mock)) is repeated in nearly every test in this class. A shared fixture would remove this duplication.

♻️ Proposed fixture
+    `@pytest.fixture`
+    def delay_mock(self, monkeypatch: pytest.MonkeyPatch) -> MagicMock:
+        mock = MagicMock()
+        monkeypatch.setattr(
+            "boost_weblate.endpoint.views.boost_add_or_update_task.delay", mock
+        )
+        return mock
+
-    def test_non_json_body_rejected_without_enqueue(
-        self, monkeypatch: pytest.MonkeyPatch
-    ) -> None:
-        delay_mock = MagicMock()
-        monkeypatch.setattr(
-            "boost_weblate.endpoint.views.boost_add_or_update_task.delay",
-            delay_mock,
-        )
+    def test_non_json_body_rejected_without_enqueue(self, delay_mock: MagicMock) -> None:
         request, _ = self._authenticated_post(
             None, content_type="application/json", data="not-json"
         )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/endpoint/test_views.py` around lines 654 - 844, Repeated
MagicMock/monkeypatch setup for boost_add_or_update_task.delay is duplicated
across the AddOrUpdateView tests. Add a shared fixture in test_views.py that
creates the mock and applies monkeypatch.setattr to
boost_weblate.endpoint.views.boost_add_or_update_task.delay, then inject that
fixture into the affected test methods and use its returned mock for the
assert_not_called checks.
src/boost_weblate/endpoint/validators.py (1)

35-58: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Minor duplication between validate_repo_segment and validate_language_code.

Both functions repeat the same non-empty → length → regex → raise pattern, differing only in the regex and error text. Could be consolidated into a single generic helper taking the pattern, field name, and "allowed chars" description, reducing future drift between the two validators.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/boost_weblate/endpoint/validators.py` around lines 35 - 58, Both
validate_repo_segment and validate_language_code duplicate the same validation
flow, so factor the shared non-empty, length, and regex checks into a single
generic helper. Update the helper to accept the input value, field name, regex
pattern, and allowed-characters text, then have validate_repo_segment and
validate_language_code delegate to it while preserving their current error
messages and behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/boost_weblate/endpoint/serializers.py`:
- Around line 233-247: The validate_add_or_update method should short-circuit
immediately when the MAX_ADD_OR_UPDATE_LANGS limit is exceeded instead of only
appending an error and continuing into the per-language loop. Add an early
return (or equivalent guard) right after recording the invalid language-count
error in validate_add_or_update so oversized payloads do not reach the
validate_language_code and submodule validation work. Keep the existing error
accumulation shape consistent with the rest of validate_add_or_update and
preserve the RequestField.ADD_OR_UPDATE context.

---

Nitpick comments:
In `@src/boost_weblate/endpoint/validators.py`:
- Around line 35-58: Both validate_repo_segment and validate_language_code
duplicate the same validation flow, so factor the shared non-empty, length, and
regex checks into a single generic helper. Update the helper to accept the input
value, field name, regex pattern, and allowed-characters text, then have
validate_repo_segment and validate_language_code delegate to it while preserving
their current error messages and behavior.

In `@tests/endpoint/test_views.py`:
- Around line 630-638: The autouse fixture _high_throttle_limits is duplicated
in both TestAddOrUpdateAdversarial and TestOrmTrustBoundary, so move the shared
throttle setup into one reusable place such as a module-level pytest fixture or
a common base class and have both test classes use it. Keep the existing
_throttle_rest_framework and _isolated_throttle_rates behavior unchanged, but
reference the shared fixture from both classes to avoid drift and keep the
throttle configuration consistent.
- Around line 654-844: Repeated MagicMock/monkeypatch setup for
boost_add_or_update_task.delay is duplicated across the AddOrUpdateView tests.
Add a shared fixture in test_views.py that creates the mock and applies
monkeypatch.setattr to
boost_weblate.endpoint.views.boost_add_or_update_task.delay, then inject that
fixture into the affected test methods and use its returned mock for the
assert_not_called checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 609e6958-7758-4393-9e44-b40105a783c1

📥 Commits

Reviewing files that changed from the base of the PR and between ed65097 and d38a19e.

📒 Files selected for processing (4)
  • src/boost_weblate/endpoint/serializers.py
  • src/boost_weblate/endpoint/validators.py
  • tests/endpoint/test_serializers.py
  • tests/endpoint/test_views.py

Comment thread src/boost_weblate/endpoint/serializers.py
@whisper67265 whisper67265 requested a review from henry0816191 July 2, 2026 17:02
@henry0816191 henry0816191 requested a review from wpak-ai July 2, 2026 17:40
@wpak-ai wpak-ai merged commit bc71235 into cppalliance:develop Jul 2, 2026
22 of 23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Endpoint test depth: fuzz/adversarial ORM at trust boundary

3 participants