Unverified Commit 2a2ff0e5 authored by Alex Pott's avatar Alex Pott
Browse files

fix: #3612163 When installing themes on the Appearance page, batches added...

fix: #3612163 When installing themes on the Appearance page, batches added (eg. by locale) are never executed

By: gábor hojtsy
By: nicxvan
By: alexpott
(cherry picked from commit c35d842e)
parent 9cd9d24c
Loading
Loading
Loading
Loading
Loading
+103 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\Tests\locale\Functional;

use Drupal\Tests\BrowserTestBase;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;

/**
 * Tests that locale rewrites config langcodes after theme install.
 *
 * When a theme ships config with langcode 'en' and locale is enabled with a
 * non-English site default, locale's updateDefaultConfigLangcodes() batch
 * must rewrite those langcodes to the site default after install.
 */
#[Group('locale')]
#[RunTestsInSeparateProcesses]
class LocaleThemeInstallTest extends BrowserTestBase {

  /**
   * {@inheritdoc}
   */
  protected static $modules = ['language', 'locale'];

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * {@inheritdoc}
   */
  protected function installParameters(): array {
    $parameters = parent::installParameters();
    $parameters['parameters']['langcode'] = 'de';
    // Create a po file so we don't attempt to download one from
    // localize.drupal.org and to have a test translation that will not change.
    \Drupal::service('file_system')->mkdir($this->publicFilesDirectory . '/translations', NULL, TRUE);
    $contents = <<<PO
msgid ""
msgstr ""

PO;
    file_put_contents($this->publicFilesDirectory . '/translations/drupal-' . \Drupal::VERSION . '.de.po', $contents);
    return $parameters;
  }

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();
    $admin = $this->drupalCreateUser([
      'administer themes',
      'administer languages',
      'access administration pages',
    ]);
    $this->drupalLogin($admin);
  }

  /**
   * Tests that installing a theme via the UI updates config language.
   *
   * The olivero theme ships core.date_format.olivero_medium with langcode
   * 'en'. With locale enabled and a non-English site default, that langcode
   * should be rewritten to the site default after the install batch runs.
   */
  public function testThemeInstallRewritesConfigLangcode(): void {
    // Install olivero via the Appearance UI.
    $this->drupalGet('admin/appearance');
    $this->cssSelect('a[title="Install Olivero theme"]')[0]->click();
    // The ThemeController redirects to the batch page; follow its meta-refresh
    // chain to process all batch operations before asserting config state.
    $this->checkForMetaRefresh();
    $this->rebuildContainer();

    // core.date_format.olivero_medium ships with langcode 'en'. Locale's
    // updateDefaultConfigLangcodes() should have rewritten it to 'de'.
    $langcode = $this->config('core.date_format.olivero_medium')->get('langcode');
    $this->assertSame('de', $langcode);

    // Ensure that the theme is installed.
    $this->assertSession()->addressEquals('admin/appearance');
    $this->assertSession()->pageTextContains('The Olivero theme has been installed.');
  }

  /**
   * Tests that "install as default" also updates config language.
   */
  public function testThemeSetDefaultRewritesConfigLangcode(): void {
    $this->drupalGet('admin/appearance');
    $this->cssSelect('a[title="Install Olivero as default theme"]')[0]->click();
    $this->checkForMetaRefresh();
    $this->rebuildContainer();
    $langcode = $this->config('core.date_format.olivero_medium')->get('langcode');
    $this->assertSame('de', $langcode);
    $this->assertSession()->addressEquals('admin/appearance');
    $this->assertSession()->pageTextContains('Olivero is now the default theme.');
  }

}
+17 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
use Drupal\Core\Config\UnmetDependenciesException;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\Core\Extension\MissingDependencyException;
use Drupal\Core\Extension\ThemeExtensionList;
use Drupal\Core\Extension\ThemeHandlerInterface;
@@ -113,6 +114,14 @@ public function install(#[MapQueryParameter] string $theme) {
      $this->messenger()->addError($this->t('Unable to install @theme due to missing module dependencies.', ['@theme' => $theme]));
    }

    // Process any batch queued by hook_themes_installed (e.g. locale's
    // langcode rewrite). batch_process() redirects to the batch page and
    // then to $redirect after completion, so it is returned directly.
    $batch = &batch_get();
    if (!empty($batch)) {
      return batch_process(Url::fromRoute('system.themes_page'));
    }

    return $this->redirect('system.themes_page');
  }

@@ -200,6 +209,14 @@ public function setDefaultTheme(#[MapQueryParameter] string $theme) {
      $this->messenger()->addError($this->t('The %theme theme was not found.', ['%theme' => $theme]));
    }

    // Process any batch queued by hook_themes_installed (e.g. locale's
    // langcode rewrite). batch_process() redirects to the batch page and
    // then to $redirect after completion, so it is returned directly.
    $batch = &batch_get();
    if (!empty($batch)) {
      return batch_process(Url::fromRoute('system.themes_page'));
    }

    return $this->redirect('system.themes_page');
  }