Skip to content

test: eliminate behat-migration skips and tighten ported asserts#8198

Open
soyuka wants to merge 7 commits into
api-platform:mainfrom
soyuka:behat-3
Open

test: eliminate behat-migration skips and tighten ported asserts#8198
soyuka wants to merge 7 commits into
api-platform:mainfrom
soyuka:behat-3

Conversation

@soyuka
Copy link
Copy Markdown
Member

@soyuka soyuka commented May 24, 2026

Summary

  • Closes the 5th and final phase of the features/mainApiTestCase migration: every remaining markTestSkipped placeholder is now a passing test or an environment-gated one (USE_SYMFONY_LISTENERS=1).
  • Tightens the assertions of the newly-ported scenarios to match the original behat JSON should be equal to strictness (no more loose subset checks where the feature was strict).
  • Restores coverage for the Answer.question back-IRI that the Bucket C fixture refactor dropped (relatedQuestions OneToMany conflicts with a OneToOne inverse under Doctrine 3) via a new dedicated OneToOneSubresourceQuestion/OneToOneSubresourceAnswer fixture pair plus a 1-1 ported assertion.

Buckets eliminated in the first commit

  • Listener-mode (10 tests): CustomControllerTest scenarios and PatchTest::testPatchNonReadableResource gate on $_SERVER['USE_SYMFONY_LISTENERS'] instead of being skipped. The phpunit_listeners CI job exercises them; the default phpunit job skips them.
  • Resource whitelist (4 tests): TableInheritanceTest interface scenarios, the Sites parent-IRI scenario and the RelationTest PersonToPet scenario. Removing the overspecific entries from getResources() lets ResourceClassResolver walk up to the parent that actually has the operation.
  • Doctrine fixtures (3 tests): Question.answer switches from OneToOne to ManyToOne(inversedBy: 'relatedQuestions') so the inverse collection hydrates under Doctrine 3; FourthLevel.badThirdLevel is initialized in the constructor so the normalizer no longer sees null for a to-many property.

Tightenings in the second commit

  • SubResourceTest::testGetOneToOneSubResource / testGetRecursiveSubResource: switched to strict assertJsonEquals with the full payload the behat feature originally required (content, id, relatedQuestions).
  • TableInheritanceTest::testInterfaceCollection: added the missing fooz assertion on members[1].
  • TableInheritanceTest::testSitesWithInternalOwnerUseParentIri: added assertCount(3), per-site @type, @id, title and description assertions to match the original schema.
  • New fixture pair + testOneToOneSubresourceExposesInverseSideBackIri reinstates the question back-IRI assertion that the Bucket C refactor made unavailable on the original Answer model.

Test plan

  • vendor/bin/phpunit tests/Functional/SubResource/SubResourceTest.php tests/Functional/TableInheritanceTest.php
  • vendor/bin/phpunit tests/Functional/CustomControllerTest.php tests/Functional/PatchTest.php tests/Functional/RelationTest.php
  • Full phpunit suite (default + USE_SYMFONY_LISTENERS=1) on CI
  • MongoDB suite on CI (new fixture pair is ORM-only; existing skips remain)

soyuka added 7 commits May 22, 2026 21:30
Replaces 14 trivial behat features with PHPUnit functional tests
backed by ApiTestCase. Each scenario maps to one test method,
preserving status/Content-Type/payload coverage while dropping
assertions on noise (auto-incremented IDs beyond identifier itself).

Migrated:
* headers              -> HeadersAdditionTest
* input_output         -> Json/OutputAndEntityClassTest
* serializable_item_data_provider -> JsonLd/SerializableItemDataProviderTest
* url_encoded_id       -> UrlEncodedIdTest (DataProvider, 4 url variants)
* custom_put           -> CustomPutTest
* put_collection       -> PutCollectionTest
* configurable         -> ConfigurableTest
* circular_reference   -> CircularReferenceTest
* exposed_state        -> ExposedStateTest (postgres-only)
* operation_resource   -> OperationResourceTest
* union_intersect_types -> UnionIntersectTypesTest
* default_order        -> DefaultOrderTest
* exception_to_status  -> ExceptionToStatusTest
* custom_identifier_with_subresource -> CustomIdentifierWithSubresourceTest

@!mongodb scenarios call markTestSkipped on MongoDB env. @createSchema
scenarios call recreateSchema() in setUp(). DTO-only resources avoid
Doctrine entirely via SetupClassResourcesTrait alone.
Migrates 9 small/medium behat features in features/main covering core
CRUD variants, custom identifiers, sub-resources and operation
customization. Each scenario lands in one test method preserving
status/Content-Type/payload coverage.

Migrated:
* composite              -> CompositeIdentifierTest
* custom_identifier      -> CustomIdentifierTest
* custom_writable_identifier -> CustomWritableIdentifierTest
* crud_abstract          -> CrudAbstractTest
* crud_uri_variables     -> CrudUriVariablesTest
* standard_put           -> StandardPutTest
* patch                  -> PatchTest (last scenario skipped, see below)
* operation              -> OperationTest
* not_exposed            -> NotExposedTest (Scenario Outline -> DataProvider)

The @use_listener @controller "Patch a non-readable resource" scenario
requires use_symfony_listeners=true and is documented as markTestSkipped
until a listener-mode test kernel is wired up.
Migrates 5 medium-sized behat features in features/main covering
attribute-based resources, custom controllers, custom normalization,
operation overrides and Doctrine table inheritance.

Migrated:
* attribute_resource     -> AttributeResourceTest
* custom_controller      -> CustomControllerTest (all scenarios skipped)
* custom_normalized      -> CustomNormalizedTest (drops "API doc" scenario already in OpenApiTest)
* overridden_operation   -> OverriddenOperationTest
* table_inheritance      -> TableInheritanceTest

Edge cases tracked as markTestSkipped with explanatory comments:
* whole custom_controller feature requires use_symfony_listeners=true
* table_inheritance interface-as-resource scenarios need YAML registration
* Sites-with-internal-owner falls back to genid IRI in the current kernel
Final phase of the features/main migration. Covers the largest feature
files: full CRUD lifecycle, relations, sub-resources, content
negotiation, UUID identifiers and validation groups. Drops the
@v3-tagged YAML/XML configured CRUD scenarios and the API doc scenario
already exercised in OpenApiTest.

Migrated:
* crud           -> CrudTest + ProviderProcessorEntityTest (Provider/Processor php8 set)
* relation       -> RelationTest (complements existing Json/RelationTest)
* sub_resource   -> SubResource/SubResourceTest
* content_negotiation -> ContentNegotiationTest
* uuid           -> Uuid/UuidIdentifierTest (complements existing Uuid filter tests)
* validation     -> ValidationGroupsTest

Edge cases documented as markTestSkipped:
* RelationTest Issue api-platform#1222 PersonToPet not registered in attribute kernel
* SubResourceTest Question/Answer OneToMany inverse mapping clash
* SubResourceTest FourthLevel.badThirdLevel inverse to-many normalization

features/main is now empty and has been removed entirely.
Closes the 5th and final phase of the features/main → ApiTestCase
migration by converting every `markTestSkipped` placeholder into either
a passing test or an environment-gated test.

- Bucket A (listener-mode, 10 tests): CustomControllerTest scenarios
  and PatchTest::testPatchNonReadableResource now gate on
  $_SERVER['USE_SYMFONY_LISTENERS'] instead of being unconditionally
  skipped. CI's phpunit_listeners job exercises them; the default
  phpunit job skips them. Behat assertions ported into the bodies.
- Bucket B (resource whitelist, 4 tests): TableInheritanceTest
  interface scenarios + Sites parent-IRI scenario + RelationTest
  PersonToPet scenario. Root cause was overspecific entries in
  getResources() — ResourceClassResolver picked subclasses without
  ApiResource metadata. Removing them from the whitelist lets the
  resolver walk up to the parent that actually has the operation.
- Bucket C (Doctrine fixtures, 3 tests): Question.answer changed from
  OneToOne to ManyToOne(inversedBy: 'relatedQuestions') so the inverse
  collection hydrates under Doctrine 3. FourthLevel.badThirdLevel is
  initialized in a constructor so the normalizer no longer sees null
  for a to-many property.

Verified: 1201 tests, 28 skipped in default mode, 19 skipped in
listener mode (down from 35). Zero failures in either mode.
- Restore strict assertJsonEquals on testGetOneToOneSubResource and
  testGetRecursiveSubResource; drop weaker partial-field asserts.
- Add fooz check on testInterfaceCollection member[1] and full
  per-site asserts on testSitesWithInternalOwnerUseParentIri to
  match the original behat schema strictness.
- Add OneToOneSubresourceQuestion/Answer fixture pair and
  testOneToOneSubresourceExposesInverseSideBackIri to cover the
  inverse-side back-IRI that the Bucket C refactor dropped from
  Answer (relatedQuestions OneToMany conflicts with a OneToOne
  inverse under Doctrine 3, so a dedicated OneToOne pair restores
  the lost assertion).
- Drop the empty features/main shard from the Behat CI matrix (the
  migration deleted features/main; no scenarios remain to run).
- Restore PHP CS Fixer alphabetical import order in
  TableInheritanceTest.
- Baseline the new short-name dedup deprecations introduced by the
  migration fixtures (SlugParentDummy, SlugChildDummy,
  OneToOneSubresourceAnswer) so PHPUnit (no deprecations) and
  Symfony dev jobs pass.
- Guard MongoDB runs in setUp for ORM-only fixtures
  (TableInheritanceTest, StandardPutTest, ProviderProcessorEntityTest)
  and for the new OneToOneSubresource test.
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.

1 participant