Skip to content

IBX-12530: Built IbexaKernelTestTrait schema from SchemaBuilderEvent - #823

Open
Steveb-p wants to merge 3 commits into
4.6from
feature/kernel-test-trait-schema-builder
Open

IBX-12530: Built IbexaKernelTestTrait schema from SchemaBuilderEvent#823
Steveb-p wants to merge 3 commits into
4.6from
feature/kernel-test-trait-schema-builder

Conversation

@Steveb-p

@Steveb-p Steveb-p commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Warning

This branch includes a temporary commit (dependencies.json) that points CI at
ibexa/doctrine-schema#49 so tests can run before that PR merges. Must be removed before
merging this PR.

🎫 Issue IBX-12530

Related PRs:

Description:

IbexaKernelTestTrait::loadSchema() pushed raw schema.yaml files — listed by
getSchemaFiles() — through LegacySchemaImporter, which never dispatches SchemaBuilderEvent.
Since ibexa/test-core#43 moved DatabaseSchemaHook onto the event, that left two different
schema-building paths
in the test stack, and it is the only remaining reason a package has to
keep a getSchemaFiles() override alive.

loadSchema() now builds through SchemaBuilderInterface and applies the result with
doctrine-schema's new SchemaApplier, keeping the drop-then-create ordering LegacySchemaImporter
had — it runs per test case, so the tables are normally already there.

Three things worth flagging for review:

  • IbexaTestKernel gains DoctrineSchemaBundle + IbexaRepositoryInstallerBundle. Without
    them the event isn't reachable. Note this is core's own Ibexa\Contracts\Core\Test\IbexaTestKernel,
    which does not extend ibexa/test-core's same-named-but-different-namespace kernel, so it does
    not inherit them from Merge IBX-1182: Added cache invalidation to liip:imagine:cache:remove command #43. It is the kernel phpunit-integration-legacy.xml boots, and therefore
    the one TokenServiceTest — the only loadSchema() caller in this repo — actually runs on.
  • SchemaApplier is constructed, not fetched from the container. Its service is private and
    unreferenced in a plain test kernel, so the compiler removes it and TestContainer cannot
    resolve it. It is a stateless helper over a Connection, so constructing it is simpler than
    making a production service public for tests' sake.
  • LegacySchemaImporter stays. SetupFactory\Legacy and Persistence\Legacy\TestCase still
    use it directly; only the trait stops.

getSchemaFiles() is deprecated on both IbexaTestKernelInterface and the trait. It is not
removed — ibexa/test-core's DefaultSchemaFilesProvider and every downstream override still
implement it, and the interface is @internal/@experimental but widely implemented. Removal is
a 6.0 job.

One phpstan-baseline.neon entry is dropped: it ignored Cannot call method importSchema() on object|null, and that call no longer exists. The replacement call is narrowed with an assert()
rather than baselined, matching how getServiceByClassName() already does it.

For QA:

All against this branch with doctrine-schema#49 symlinked in:

Suite Result
phpunit-integration-legacy.xml integration_core (includes TokenServiceTest) 11438 tests / 22917 assertions / 5516 skipped
TokenServiceTest alone — the only loadSchema() caller 13 / 43, unchanged
phpunit-integration.xml 78 / 140 / 23 skipped, unchanged
phpunit.xml (unit) 7643 / 17285 / 27 skipped
PHPStan no errors

loadSchema() pushed raw schema.yaml files listed by getSchemaFiles() through
LegacySchemaImporter, which never dispatches SchemaBuilderEvent. That left two different
schema-building paths in the test stack once ibexa/test-core#43 moved DatabaseSchemaHook onto
the event, and it is the only reason a package still has to keep a getSchemaFiles() override
alive.

It now builds through SchemaBuilderInterface and applies the result with doctrine-schema's new
SchemaApplier, keeping the drop-then-create ordering LegacySchemaImporter had, since loadSchema()
runs per test case.

IbexaTestKernel gains DoctrineSchemaBundle and IbexaRepositoryInstallerBundle, without which the
event is not reachable — core's own kernel does not extend ibexa/test-core's, so it does not
inherit them.

getSchemaFiles() is deprecated on both IbexaTestKernelInterface and the trait.
LegacySchemaImporter stays: SetupFactory\Legacy and Persistence\Legacy\TestCase still use it.
…ema#49

Points CI at the branch that adds SchemaApplier, so this PR's tests can run before that PR
merges. Must be removed before merging.
…r TestKernel

It registered DoctrineSchemaBundle and IbexaRepositoryInstallerBundle itself and extends
IbexaTestKernel, which now yields both, so booting it threw "Trying to register two bundles with
the same name". Its registerBundles() override did nothing else, so it goes entirely.
@sonarqubecloud

sonarqubecloud Bot commented Sep 9, 2026

Copy link
Copy Markdown

@Steveb-p Steveb-p changed the title Built IbexaKernelTestTrait schema from SchemaBuilderEvent IBX-12530: Built IbexaKernelTestTrait schema from SchemaBuilderEvent Sep 9, 2026
@Steveb-p
Steveb-p marked this pull request as ready for review September 10, 2026 08:17
@Steveb-p

Copy link
Copy Markdown
Contributor Author

Blast-radius note for reviewers — org-wide audit of who actually calls IbexaKernelTestTrait::loadSchema(), since this PR changes what that method does.

All 483 non-archived ibexa/* repos were enumerated via the API and their 4.6 composer.json checked, giving 64 direct ibexa/test-core consumers. Grepping those for ::loadSchema() finds five callers:

Repo Test
ibexa/core TokenServiceTest (this repo — covered in the QA section)
ibexa/scheduler ScheduledHidePermissionTest
ibexa/dashboard BasicKernelTest
ibexa/image-editor ImageAssetControllerTest
ibexa/personalization ExportCommandTest

Why the four downstream ones are safe:

  • All five extend Ibexa\Contracts\Test\Core\IbexaTestKernel, so IBX-12530: Rebuilt DatabaseSchemaHook on SchemaBuilderInterface instead of a raw-file reimplementation test-core#43 gives them DoctrineSchemaBundle + IbexaRepositoryInstallerBundle and the event is reachable.
  • All five call loadSchema() immediately followed by loadFixtures(). That matters, because this PR widens the drop-and-recreate scope from "the files getSchemaFiles() listed" (in practice core's legacy schema.yaml) to "the whole event-built schema". Since fixtures are re-imported right after, nothing is left wiped.

LegacySchemaImporter is intentionally not removed — SetupFactory\Legacy, Persistence\Legacy\TestCase, and three repos still on the pre-Bootstrapper hand-rolled bootstrap (admin-ui, connect, integrated-help) all still use it directly.

@Steveb-p
Steveb-p requested a review from a team September 10, 2026 10:55
Steveb-p added a commit to ibexa/test-core that referenced this pull request Sep 10, 2026
…maApplier

DatabaseSchemaHook reimplemented the toSql()-and-execute loop that ibexa/core's
LegacySchemaImporter also has; both now use doctrine-schema's SchemaApplier. The hook needs no
dropping, since Bootstrapper always hands it a freshly created database.

DefaultSchemaFilesProvider and IbexaTestKernel::getSchemaFiles() are deprecated. Nothing in this
package reads them any more: the schema comes from SchemaBuilderEvent, so whichever bundles a
kernel registers is what the schema contains. They stay because
IbexaTestKernelInterface still mandates getSchemaFiles(), and ibexa/core's IbexaKernelTestTrait
kept reading it until ibexa/core#823.
Comment on lines -37 to +38
$schemaImporter = self::getContainer()->get(LegacySchemaImporter::class);
foreach (static::getSchemaFiles() as $schemaFile) {
$schemaImporter->importSchema($schemaFile);
}
$schemaBuilder = self::getContainer()->get(SchemaBuilderInterface::class);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Don't we have already some helper method to get service correctly typed/recognized by phpstan (based on passed class-string value)? If so, we coud use it and remove asert here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants