Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
UpdaterTest.php 4.17 KiB
<?php

namespace Drupal\Tests\automatic_updates\Kernel;

use Drupal\package_manager\PathLocator;
use Drupal\Tests\user\Traits\UserCreationTrait;

/**
 * @coversDefaultClass \Drupal\automatic_updates\Updater
 *
 * @group automatic_updates
 */
class UpdaterTest extends AutomaticUpdatesKernelTestBase {

  use UserCreationTrait;

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'automatic_updates',
    'automatic_updates_test',
    'package_manager',
    'package_manager_bypass',
    'system',
    'user',
  ];

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();
    $this->installEntitySchema('user');
  }

  /**
   * Tests that correct versions are staged after calling ::begin().
   */
  public function testCorrectVersionsStaged() {
    $this->setReleaseMetadata(__DIR__ . '/../../fixtures/release-history/drupal.9.8.1-security.xml');

    // Create a user who will own the stage even after the container is rebuilt.
    $user = $this->createUser([], NULL, TRUE, ['uid' => 2]);
    $this->setCurrentUser($user);

    // Point to a fake site which requires Drupal core via a distribution. The
    // lock file should be scanned to determine the core packages, which should
    // result in drupal/core-recommended being updated.
    $fixture_dir = __DIR__ . '/../../fixtures/fake-site';
    $locator = $this->prophesize(PathLocator::class);
    $locator->getActiveDirectory()->willReturn($fixture_dir);
    $locator->getProjectRoot()->willReturn($fixture_dir);
    $locator->getVendorDirectory()->willReturn($fixture_dir);
    $this->container->set('package_manager.path_locator', $locator->reveal());

    $id = $this->container->get('automatic_updates.updater')->begin([
      'drupal' => '9.8.1',
    ]);
    // Rebuild the container to ensure the project versions are kept in state.
    /** @var \Drupal\Core\DrupalKernel $kernel */
    $kernel = $this->container->get('kernel');
    $kernel->rebuildContainer();
    $this->container = $kernel->getContainer();
    // Keep using the mocked path locator and current user.
    $this->container->set('package_manager.path_locator', $locator->reveal());
    $this->setCurrentUser($user);

    // When we call Updater::stage(), the stored project versions should be
    // read from state and passed to Composer Stager's Stager service, in the
    // form of a Composer command. This is done using package_manager_bypass's
    // invocation recorder, rather than a regular mock, in order to test that
    // the invocation recorder itself works.
    // The production dependencies should be updated first...
    $expected_require_arguments = [
      'require',
      'drupal/core-recommended:9.8.1',
      '--update-with-all-dependencies',
    ];
    // ...followed by the dev dependencies.
    $expected_require_dev_arguments = [
      'require',
      'drupal/core-dev:9.8.1',
      '--update-with-all-dependencies',
      '--dev',
    ];
    $this->container->get('automatic_updates.updater')->claim($id)->stage();

    /** @var \Drupal\package_manager_bypass\InvocationRecorderBase $stager */
    $stager = $this->container->get('package_manager.stager');
    [
      $actual_require_arguments,
      $actual_require_dev_arguments,
    ] = $stager->getInvocationArguments();
    $this->assertSame($expected_require_arguments, $actual_require_arguments[0]);
    $this->assertSame($expected_require_dev_arguments, $actual_require_dev_arguments[0]);
  }

  /**
   * @covers ::begin
   *
   * @dataProvider providerInvalidProjectVersions
   */
  public function testInvalidProjectVersions(array $project_versions): void {
    $this->expectException(\InvalidArgumentException::class);
    $this->expectExceptionMessage('Currently only updates to Drupal core are supported.');
    $this->container->get('automatic_updates.updater')->begin($project_versions);
  }

  /**
   * Data provider for testInvalidProjectVersions().
   *
   * @return array
   *   The test cases for testInvalidProjectVersions().
   */
  public function providerInvalidProjectVersions(): array {
    return [
      'only not drupal' => [['not_drupal' => '1.1.3']],
      'not drupal and drupal' => [['drupal' => '9.8.0', 'not_drupal' => '1.2.3']],
      'empty' => [[]],
    ];
  }

}