Fix #106: Add URL format validation to SEO diagnostics job queue #125
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "typosaurus/ticket-106"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Resolves #106.
Plan
Implementation Plan: URL Format Validation for SEO Diagnostics Job Queue
1. Problem Summary
The
SeoRunFormPydantic model (inmodels.py) accepts URLs with invalid schemes (e.g.,"ahttps://...",/relative/path) and passes them to the background job queue. Downstream validation inguard_public_urlcatches these only after enqueue, wasting resources and generating failed jobs. The analogousIsslopRunFormmodel already applies proper URL validation — we will adapt that pattern.2. Scope of Changes
Two files need modification:
app/core/models.py– Add URL scheme validation to theSeoRunForm.urlfield.tests/api/tools/seo.py– Add test cases covering malformed, relative, and scheme-less URLs.No other source files require changes. The existing
IsslopRunFormvalidation functions and constants (ISSLOP_SCHEME_PATTERN,ISSLOP_URL_PATTERN) are inmodels.pyand can be reused partially.3. Detailed Changes
3.1
app/core/models.pyCurrent state (lines ~462–473):
Required changes:
At the top of the file, ensure the regex patterns used by
IsslopRunFormare accessible (they are already defined as module-level constants). We will define a new, stricter constant for SEO-only validation:(This is a subset of
ISSLOP_URL_PATTERNthat only acceptshttp://andhttps://.)Add a Pydantic
@field_validator("url", mode="before")toSeoRunFormthat:://scheme indicator, prependshttps://.httporhttps, raises aValueErrorwith a clear message.SEO_URL_PATTERN; if no match, raises aValueError.The logic should not import or mutate anything outside the model. It should be self-contained and reusable.
Draft code (to be placed inside
SeoRunFormclass):3.2
tests/api/tools/seo.pyAdd a new test class or individual test functions. The existing tests are async; new tests should also be async and use the test client.
Test cases to add:
test_run_rejects_malformed_scheme"ahttps://example.com"test_run_rejects_relative_path"/feed"test_run_accepts_missing_scheme"example.com"https://example.com)test_run_rejects_non_http_scheme"ftp://example.com"Note on relative paths: The investigation findings note that relative paths like
"/feed"currently gethttps://prepended, becoming"https:///feed", which is invalid and would fail later. To maintain consistency, we should reject them as invalid (since they are not absolute URLs). The validator above will catch them becauseSEO_URL_PATTERNrequires a hostname after the scheme. The test should therefore expect 422.Pseudo-code for test:
4. Avoiding Past Failures
python -m pytest {test_files}; we must only run the SEO-related test file to avoid side effects. Thetest_commandin the prompt refers to a specific test file – we must respect that.rufforflake8) and fix any new violations. The previous lint failure was from hidden.venvfiles being committed; this is likely a merge conflict issue, not a style issue. We must ensure we do not introduce new violations in the source code..venvwas tracked. We must ensure our branch is based on the correct base and does not include.venvfiles. The plan itself assumes a clean checkout.5. Definition of Done
app/core/models.py, add theSEO_URL_PATTERNconstant and thefield_validatortoSeoRunFormas described.tests/api/tools/seo.py, add the four test functions listed above.pip install -e '.[dev]' -q && python -m pytest tests/api/tools/seo.py– all tests pass, including the new ones and the existing five.ruff check app/ tests/or similar as defined inMakefileorpyproject.toml) – no new lint violations are introduced..venvor other unintended artifacts are in the branch diff."ahttps://devplace.net/sitem"with a 422 response in the test run.Opened automatically by Typosaurus.