Add failing tests for #652: purchase CORS violation & mock API in production#666
Add failing tests for #652: purchase CORS violation & mock API in production#666prompt-driven-github[bot] wants to merge 1 commit intomainfrom
Conversation
…ion (#652) Tests detect two root causes of the purchase failure: - CORS: configure_cors() only allows localhost origins, missing https://promptdriven.ai - Endpoint registry: CLOUD_ENDPOINTS missing processPddcPurchase entry 5 tests fail on current code, 4 pass as guardrails. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| """ | ||
| url = CloudConfig.get_endpoint_url("processPddcPurchase") | ||
|
|
||
| assert "us-central1-prompt-driven-development.cloudfunctions.net" in url, ( |
Check failure
Code scanning / CodeQL
Incomplete URL substring sanitization High test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 1 month ago
General fix: instead of checking that the production hostname appears as a substring of the full URL, parse the URL and assert on its hostname (and, if desired, scheme/path). This follows the guidance to operate on structured URL components rather than raw substrings.
Best concrete fix here:
- In
tests/core/test_cloud.py, importurlparse(fromurllib.parse) alongside existing imports. - In
test_purchase_endpoint_url_resolves_to_production, after obtainingurl, parse it withurlparse(url)and assert thatparsed.hostnameequals the expected production hostname. - Optionally, we can also assert that the scheme is
httpsto preserve the intent that this is a production Cloud Functions URL, but the minimal change needed to address the CodeQL warning is to replace the substring check with a hostname equality check usingurlparse.
Specific changes:
-
Add
from urllib.parse import urlparseafter the other imports at the top oftests/core/test_cloud.py. -
Replace:
url = CloudConfig.get_endpoint_url("processPddcPurchase") assert "us-central1-prompt-driven-development.cloudfunctions.net" in url, ( f"Purchase endpoint must resolve to production cloud functions URL. Got: {url}" )
with:
url = CloudConfig.get_endpoint_url("processPddcPurchase") parsed = urlparse(url) assert parsed.hostname == "us-central1-prompt-driven-development.cloudfunctions.net", ( f"Purchase endpoint must resolve to production cloud functions hostname. Got: {parsed.hostname} (URL: {url})" )
leaving the subsequent checks about
processPddcPurchasein the path and absence of “mock/local” substrings unchanged.
No other files or logic need to be modified.
| @@ -39,6 +39,7 @@ | ||
| import asyncio | ||
| from unittest.mock import patch, MagicMock, AsyncMock | ||
| from z3 import Solver, Bool, And, Not | ||
| from urllib.parse import urlparse | ||
|
|
||
| # Import the code under test | ||
| from pdd.core.cloud import ( | ||
| @@ -597,9 +598,11 @@ | ||
| https://us-central1-prompt-driven-development.cloudfunctions.net/processPddcPurchase | ||
| """ | ||
| url = CloudConfig.get_endpoint_url("processPddcPurchase") | ||
| parsed = urlparse(url) | ||
|
|
||
| assert "us-central1-prompt-driven-development.cloudfunctions.net" in url, ( | ||
| f"Purchase endpoint must resolve to production cloud functions URL. Got: {url}" | ||
| assert parsed.hostname == "us-central1-prompt-driven-development.cloudfunctions.net", ( | ||
| f"Purchase endpoint must resolve to production cloud functions hostname. " | ||
| f"Got: {parsed.hostname} (URL: {url})" | ||
| ) | ||
| assert "processPddcPurchase" in url, ( | ||
| f"Purchase endpoint URL must contain 'processPddcPurchase'. Got: {url}" |
| call_args = app.add_middleware.call_args | ||
| kwargs = call_args[1] | ||
| origins = kwargs["allow_origins"] | ||
|
|
Check failure
Code scanning / CodeQL
Incomplete URL substring sanitization High test
Copilot Autofix
AI about 1 month ago
Copilot could not generate an autofix suggestion
Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.
| f"Purchase endpoint URL must not contain '{indicator}'. Got: {url}" | ||
| ) | ||
|
|
||
| assert "us-central1-prompt-driven-development.cloudfunctions.net" in url |
Check failure
Code scanning / CodeQL
Incomplete URL substring sanitization High test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 1 month ago
In general, to avoid incomplete URL substring sanitization, do not treat the URL as an opaque string when checking for allowed or disallowed hosts. Instead, parse it with a proper URL parser (such as urllib.parse.urlparse in Python) and inspect the hostname (and potentially scheme/port) fields, then compare those fields against an allowlist (or explicit expected values) using exact or well-defined suffix checks.
For this specific test, we should replace the substring assertion:
assert "us-central1-prompt-driven-development.cloudfunctions.net" in urlwith a host-based assertion that parses url and verifies that its hostname matches the expected production hostname. This keeps the functional intent (“must point to the Cloud Functions production host”) while avoiding substring-based checks. Concretely:
- Import
urlparse(orurllib.parse) at the top of this test file (we’re allowed to add well-known standard-library imports). - Parse
urlviaurlparse(url)and extracthostname. - Assert that
hostnameequals"us-central1-prompt-driven-development.cloudfunctions.net"(or, if you want to be tolerant of schemes/paths but strict about host,assert parsed.hostname == EXPECTED_HOST).
No other tests or logic need to change.
| @@ -16,6 +16,7 @@ | ||
| import os | ||
| import pytest | ||
| from unittest.mock import patch | ||
| from urllib.parse import urlparse | ||
|
|
||
| from fastapi import FastAPI | ||
| from fastapi.testclient import TestClient | ||
| @@ -207,7 +208,11 @@ | ||
| f"Purchase endpoint URL must not contain '{indicator}'. Got: {url}" | ||
| ) | ||
|
|
||
| assert "us-central1-prompt-driven-development.cloudfunctions.net" in url | ||
| parsed = urlparse(url) | ||
| assert ( | ||
| parsed.hostname | ||
| == "us-central1-prompt-driven-development.cloudfunctions.net" | ||
| ), f"Purchase endpoint host must be the production Cloud Functions host. Got: {parsed.hostname!r} in URL: {url}" | ||
|
|
||
| def test_purchase_endpoint_registered_not_fallback(self, clean_env): | ||
| """Verify processPddcPurchase is explicitly registered, not using fallback. |
Summary
Adds failing tests that detect the bug reported in promptdriven/pdd_cloud#678 — purchase in settings dashboard fails with CORS violation and mock API handlers active in production.
Test Files
tests/server/test_security.py,tests/core/test_cloud.pytests/test_e2e_issue_652_purchase_cors.pyWhat This PR Contains
configure_cors()only allows localhost origins, missinghttps://promptdriven.aiCLOUD_ENDPOINTSmissingprocessPddcPurchaseentryRoot Cause
Two independent bugs in the web application:
configure_cors()inpdd/server/security.pyonly configures localhost origins, missing production originhttps://promptdriven.aiCLOUD_ENDPOINTSinpdd/core/cloud.pyis missingprocessPddcPurchase, causing fallback to mock handlersNext Steps
Fixes promptdriven/pdd_cloud#678
Generated by PDD agentic bug workflow