flarum / flarum/framework

`Extend\Locales` translations never register in integration tests (1.x + 2.x)

Open
#4,600 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
PHP
Stars
6.7k
Forks
883
Avg merge
15h 16m
Merged PRs (30d)
73

Description

### What's happening

When writing an integration test for an extension that ships with locale files via `Extend\Locales`, translation keys from the extension's own `resources/locale/*.yml` are never loaded into the catalogue. Calls like `$translator->get('my-ext.some.key')` just echo the key back.

### Reproduction

In an extension's integration test:

```php
public function setUp(): void
{
parent::setUp();
$this->extension('my-vendor-myext');
}

/** @test */
public function extension_translations_are_loaded()
{
$translator = $this->app()->getContainer()->make(
\Illuminate\Contracts\Translation\Translator::class
);
// Fails: returns 'my-vendor-myext.some.key' instead of the translated value
$this->assertNotEquals(
'my-vendor-myext.some.key',
$translator->get('my-vendor-myext.some.key')
);
}
```

Core translations (`flarum.*`, `validation.*`) work fine because they're registered directly by `LocaleServiceProvider` at the time `LocaleManager` is constructed.

### Root cause

`Extend\Locales::extend()` registers translation loading via `$container->resolving(LocaleManager::class, …)` — a callback that only fires when the container *resolves* the `LocaleManager` singleton. Because `LocaleManager` is a singleton, it is resolved exactly once.

The test harness calls `ExtensionManager::enable($id)` before `ExtensionManager::extend($container)` (see [`OverrideExtensionManagerForTests`](https://github.com/flarum/framework/blob/2.x/php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php#L34-L44)):

```php
foreach ($this->extensions as $extension) {
$extensionManager->enable($extension); // fires Locales::onEnable → make(LocaleManager::class) → singleton resolved NOW
}

$extensionManager->booted = true;
$extensionManager->extend($container); // only now is Locales::extend() called, but the resolving() callback arrives too late
```

`Locales::onEnable()` calls `$container->make(LocaleManager::class)->clearCache()`, which triggers the first resolution of the singleton — *before* `Locales::extend()` has had a chance to register its `resolving()` callback. From that point on, the callback can never fire.

In production, this ordering is not a problem because `LocaleManager` is resolved lazily at HTTP request time — well after all extenders have registered their `resolving()` hooks during the normal boot flow.

### Impact

- Any integration test that exercises code which calls into the extension's translator returns raw translation keys
- Silently produces misleading test output (e.g. a `Subject:` in a sent email containing `my-ext.email.default_subject` instead of the translated string) rather than failing noisily
- Affects both 1.x and 2.x — identical ordering in both `OverrideExtensionManagerForTests` implementations

### Current workaround in test

```php
$locales = $this->app()->getContainer()->make(\Flarum\Locale\LocaleManager::class);
$locales->addTranslations('en', __DIR__.'/../../resources/locale/en.yml');
$locales->clearCache();
```

### Suggested fix

Simplest surgical change: swap the two calls in `OverrideExtensionManagerForTests::extend()`:

```php
$extensionManager->booted = true;
$extensionManager->extend($container); // apply extenders first — Locales registers its resolving() callback

foreach ($this->extensions as $extension) {
$extensionManager->enable($extension); // now safe — when onEnable resolves LocaleManager, the callback fires
}
```

Need to verify this doesn't break other lifecycle assumptions (e.g. migrations running before extenders are applied), but given the current order already leads to broken locale loading, the extender-first approach aligns better with production boot sequencing.

### Environment

- Reproduced on Flarum 1.8 (testing 1.8)
- Same ordering confirmed present in [2.x](https://github.com/flarum/framework/blob/2.x/php-packages/testing/src/integration/Extend/OverrideExtensionManagerForTests.php#L34-L44)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.