Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.

fix(integrations): pass Tier-2 constructor args in calendar/email/tasks DI factories + log provider boot failures#1869

Merged
rubenvdlinde merged 1 commit into
developmentfrom
fix/integration-provider-di-factories
May 25, 2026
Merged

fix(integrations): pass Tier-2 constructor args in calendar/email/tasks DI factories + log provider boot failures#1869
rubenvdlinde merged 1 commit into
developmentfrom
fix/integration-provider-di-factories

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Summary

A live-NC E2E surfaced that three integration providers — calendar, email, tasks — were missing in production. Their OCS registry tabs 404'd and the registered-provider count was 22 instead of 25.

Root cause

The DI factory closures in Application::registerBuiltinIntegrationProviders() were not updated when these providers gained Tier-2 constructor args:

Provider Tier-2 arg(s) the factory failed to pass
CalendarProvider $calendarLinkService
EmailProvider $emailLinkService
TasksProvider $registerMapper, $schemaMapper, $objectService

The closures still passed the old arg lists, so each provider threw ArgumentCountError on construction. bootBuiltinIntegrationProviders()'s try/catch silently swallowed the Throwable, dropping the three providers from the IntegrationRegistry. Existing tests instantiate providers directly with mocks, so they were blind to the factory-wiring bug — only the live E2E caught it.

Changes

  • The 3 factory fixes — resolve and pass the Tier-2 dependencies, matching the already-correct contacts/deck/forms factories.
  • Harden the swallowbootBuiltinIntegrationProviders() now logs a warning (provider class + exception message) when a provider fails to construct, so a mis-wired factory is diagnosable in the logs instead of a silently-missing tab. Graceful degradation is preserved (boot does not crash on one bad provider).
  • Label consistency (cosmetic) — align the maps/time-tracker OCS labels (Location/Time) with the in-page registry pills from the nc-vue descriptors (Locations/Time tracker). OR getLabel() is the smaller change, so no nc-vue PR is needed.
  • Regression testBuiltinProviderDiFactoryTest invokes the actual factory closures (via a captured IRegistrationContext + a mocking container) and asserts every provider constructs without throwing. This closes the direct-instantiation blind spot. It fails on the pre-fix code (3 ArgumentCountErrors for calendar/email/tasks).

Verification

Note: PHPCS/PHPUnit could not be run in the local dev container due to a pre-existing incomplete bind-mount vendor/ (missing sabre/uri, unrelated to this change). CI runs both in a clean-vendor container.

Refs ADR-019, ADR-022.

Test plan

  • CI: PHPUnit (incl. new BuiltinProviderDiFactoryTest) + PHPCS/PHPMD/Psalm/PHPStan green
  • OCS capabilities.openregister.integrations.registered length is 25 incl. calendar/email/tasks
  • Calendar/email/tasks tabs render in the registry sidebar
  • maps/time-tracker pill labels match OCS labels

…ks DI factories + log provider boot failures

The DI factory closures in Application::registerBuiltinIntegrationProviders()
were not updated when three providers gained Tier-2 constructor args:

- CalendarProvider gained $calendarLinkService
- EmailProvider gained $emailLinkService
- TasksProvider gained $registerMapper + $schemaMapper + $objectService

The closures still passed the old arg lists, so the providers threw
ArgumentCountError on construction. bootBuiltinIntegrationProviders()'s
try/catch silently swallowed the Throwable, dropping the calendar, email
and tasks providers from the IntegrationRegistry. Their tabs 404'd on the
OCS registry and the registered-provider count was 22 instead of 25. The
regression was invisible to the existing tests (they instantiate providers
directly with mocks) and only surfaced in a live-NC E2E.

Changes:
- Update the three factory closures to resolve and pass the Tier-2
  dependencies, matching the already-correct contacts/deck/etc. factories.
- Harden bootBuiltinIntegrationProviders(): log a warning (provider class +
  exception) when a provider fails to construct, so a mis-wired factory is
  diagnosable instead of silently swallowed. Graceful degradation is kept —
  the boot does not crash on one bad provider.
- Align the maps/time-tracker OCS labels ("Location"/"Time") with the in-page
  registry pills from the nc-vue descriptors ("Locations"/"Time tracker").
- Add BuiltinProviderDiFactoryTest, a DI-container regression test that
  invokes the actual factory closures and asserts every provider constructs
  without throwing. It fails on the pre-fix code (3 ArgumentCountErrors),
  closing the direct-instantiation blind spot in the existing provider tests.

Refs ADR-019, ADR-022.
@rubenvdlinde rubenvdlinde merged commit f4ed21e into development May 25, 2026
14 of 19 checks passed
@rubenvdlinde rubenvdlinde deleted the fix/integration-provider-di-factories branch May 25, 2026 09:42
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openregister @ b67864f

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
composer ✅ 165/165
npm ✅ 532/532
PHPUnit ⏭️
Newman ⏭️
Playwright ⏭️

Quality workflow — 2026-05-25 09:45 UTC

Download the full PDF report from the workflow artifacts.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant