Skip to content

[#670] Added XML schema and feed validation to 'XmlTrait'.#680

Merged
AlexSkrypnyk merged 2 commits into
mainfrom
feature/670-xml-schema-feed
Jul 6, 2026
Merged

[#670] Added XML schema and feed validation to 'XmlTrait'.#680
AlexSkrypnyk merged 2 commits into
mainfrom
feature/670-xml-schema-feed

Conversation

@AlexSkrypnyk

@AlexSkrypnyk AlexSkrypnyk commented Jul 6, 2026

Copy link
Copy Markdown
Member

Closes #670

Summary

Extends XmlTrait with whole-document schema validation (XSD, DTD, and RelaxNG, each usable inline via a PyString or loaded from a fixture file) and structural validity assertions for RSS 2.0 and Atom feeds, so a response body can be checked against a formal schema or a feed's required elements instead of only individual elements, attributes, or namespaces. All validation runs through native libxml/DOM APIs (DOMDocument::schemaValidateSource(), relaxNGValidateSource(), and LIBXML_DTDVALID), so no new Composer dependency is introduced.

Changes

  • Added six step definitions to src/XmlTrait.php: xmlAssertMatchesXsd/xmlAssertMatchesXsdFromFile for XSD, xmlAssertMatchesDtd/xmlAssertMatchesDtdFromFile for DTD, and xmlAssertMatchesRelaxNg/xmlAssertMatchesRelaxNgFromFile for RelaxNG, plus xmlAssertValidRssFeed and xmlAssertValidAtomFeed for feed structure.
  • Added the protected validation helpers backing those steps: xmlValidateXsd and xmlValidateRelaxNg delegate to DOMDocument::schemaValidateSource()/relaxNGValidateSource(); xmlValidateDtd embeds the DTD as an internal subset and reloads the document with LIBXML_DTDVALID so a file-based and an inline DTD share one code path; xmlValidateRssFeed and xmlValidateAtomFeed walk the DOM to check the required elements for each feed format; xmlDirectChildElements is a namespace-aware direct-child lookup shared by both feed validators.
  • Extracted xmlReadFile() from the existing xmlSetResponseContentFromFile step so the new "from file" schema assertions reuse the same fixture-reading logic.
  • Documented inline, next to xmlValidateDtd and the DTD step definitions, that DTDs are namespace-unaware: a namespaced response must declare its xmlns attributes and prefixed element names directly in the DTD.
  • Added fixtures tests/behat/fixtures/xml_schema.xsd, xml_schema.dtd, and xml_schema.rng describing the same "library of books" shape, plus rss_valid.xml and atom_valid.xml as valid feed samples.
  • Added 20 scenarios to tests/behat/features/xml.feature covering positive matches and negative/error paths (invalid documents, missing schema files, malformed feed structure) for every new assertion.
  • Regenerated STEPS.md to document the eight new step definitions.

Before / After

┌──────────────────────────────────────┐
│ BEFORE: XmlTrait assertion surface   │
├──────────────────────────────────────┤
│ - element exists / contains text     │
│ - attribute exists / equals value    │
│ - namespace declared on the document │
└──────────────────────────────────────┘
                    │
                    ▼  extended by this PR
┌─────────────────────────────────────────────┐
│ AFTER: XmlTrait assertion surface           │
├─────────────────────────────────────────────┤
│ - element exists / contains text            │
│ - attribute exists / equals value           │
│ - namespace declared on the document        │
│ - matches an XSD schema (inline or file)    │
│ - matches a DTD (inline or file)            │
│ - matches a RelaxNG schema (inline or file) │
│ - is a structurally valid RSS 2.0 feed      │
│ - is a structurally valid Atom feed         │
└─────────────────────────────────────────────┘

Added full-document XML validation to XmlTrait, including native XSD, DTD, and Relax NG checks from either inline schema text or fixture files.

Also added structural assertions for valid RSS 2.0 and Atom feeds, with clearer validation failures surfaced from the first libxml/DOM error.

Documentation and coverage were updated accordingly:

  • new/expanded Behat scenarios for valid and invalid XML validation cases
  • new XML, DTD, Relax NG, RSS, and Atom fixtures
  • regenerated STEPS.md
  • extracted shared fixture-reading logic in XmlTrait

No CONTRIBUTING.md step-definition rule violations were identified.

Added steps to validate the XML response against XSD, DTD and RelaxNG
schemas (inline or from a file) and to assert that a response is a
structurally valid RSS 2.0 or Atom feed. Schema and feed validation use
native libxml, with no new runtime dependency.

Claude-Session: https://claude.ai/code/session_01VetNPTaUe3wyaCR3k9rw7p
DTD validation treats namespace declarations as ordinary attributes, so
a namespaced response must declare its 'xmlns' attributes in the DTD.
This matches native DTD validation semantics.

Claude-Session: https://claude.ai/code/session_01VetNPTaUe3wyaCR3k9rw7p
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f566a9f6-9b43-4c26-b263-32d259b8bd2c

📥 Commits

Reviewing files that changed from the base of the PR and between fbaa2b2 and 9335bce.

📒 Files selected for processing (8)
  • STEPS.md
  • src/XmlTrait.php
  • tests/behat/features/xml.feature
  • tests/behat/fixtures/atom_valid.xml
  • tests/behat/fixtures/rss_valid.xml
  • tests/behat/fixtures/xml_schema.dtd
  • tests/behat/fixtures/xml_schema.rng
  • tests/behat/fixtures/xml_schema.xsd

Walkthrough

Adds XSD, DTD, and RelaxNG schema validation steps plus RSS 2.0 and Atom feed validation steps to XmlTrait, backed by new protected validation helpers and a shared fixture-reading helper. Includes new schema/feed fixtures, expanded Behat feature scenarios, and regenerated STEPS.md documentation.

Changes

XML schema and feed validation

Layer / File(s) Summary
Shared fixture-reading helper
src/XmlTrait.php
Adds xmlReadFile() to resolve and read fixture files; xmlSetResponseContentFromFile() refactored to use it.
Schema validation steps (XSD/DTD/RelaxNG)
src/XmlTrait.php
Adds xmlAssertMatchesXsd(FromFile), xmlAssertMatchesDtd(FromFile), xmlAssertMatchesRelaxNg(FromFile) steps and protected xmlValidateXsd, xmlValidateDtd, xmlValidateRelaxNg helpers throwing ExpectationException with formatted libxml errors.
Feed validation steps (RSS/Atom)
src/XmlTrait.php
Adds xmlAssertValidRssFeed() and xmlAssertValidAtomFeed() steps plus protected xmlValidateRssFeed, xmlValidateAtomFeed, and xmlDirectChildElements helpers enforcing structural requirements.
Schema and feed fixtures
tests/behat/fixtures/xml_schema.xsd, ...dtd, ...rng, rss_valid.xml, atom_valid.xml
Adds XSD, DTD, RelaxNG schemas for a library/book structure, plus valid RSS 2.0 and Atom feed fixtures.
Behat scenarios and docs
tests/behat/features/xml.feature, STEPS.md
Adds positive/negative scenarios covering all new validation steps and documents them in STEPS.md.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Scenario
  participant XmlTrait
  participant libxml

  Scenario->>XmlTrait: xmlAssertMatchesXsd / Dtd / RelaxNg
  XmlTrait->>XmlTrait: xmlReadFile(filename) (if file-based)
  XmlTrait->>libxml: validate document against schema
  libxml-->>XmlTrait: errors or success
  XmlTrait-->>Scenario: pass or throw ExpectationException

  Scenario->>XmlTrait: xmlAssertValidRssFeed / xmlAssertValidAtomFeed
  XmlTrait->>XmlTrait: xmlDirectChildElements(node, name)
  XmlTrait-->>Scenario: pass or throw ExpectationException
Loading

Suggested labels: Needs review

Poem

A rabbit hops through tags and schema trees,
Checking feeds and DTDs with practiced ease,
XSD, RelaxNG, all in a row,
RSS and Atom now validated so,
🐇✨ Thump-thump — the fixtures all agree!

🚥 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 is concise and directly describes the added XML schema and feed validation.
Linked Issues check ✅ Passed The PR adds XSD, DTD, and RelaxNG validation, RSS/Atom checks, inline/file support, BDD coverage, and docs updates as requested.
Out of Scope Changes check ✅ Passed No unrelated code changes are evident; the additions stay within XML validation, fixtures, tests, and documentation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/670-xml-schema-feed

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 PHPStan (2.2.2)

Composer install failed: the lock file is not up to date with the latest changes in composer.json. Run composer update and commit the updated composer.lock.


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

@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.01%. Comparing base (fbaa2b2) to head (9335bce).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #680      +/-   ##
==========================================
+ Coverage   96.95%   97.01%   +0.05%     
==========================================
  Files          47       47              
  Lines        3946     4020      +74     
==========================================
+ Hits         3826     3900      +74     
  Misses        120      120              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@AlexSkrypnyk AlexSkrypnyk merged commit 0de21d0 into main Jul 6, 2026
15 checks passed
@AlexSkrypnyk AlexSkrypnyk deleted the feature/670-xml-schema-feed branch July 6, 2026 12:27
@AlexSkrypnyk AlexSkrypnyk added the Needs review Pull request needs a review from assigned developers label Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs review Pull request needs a review from assigned developers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add XML schema and feed (RSS/Atom) validation to XmlTrait

1 participant