FixtureManipulatorTest.php
Namespace
Drupal\Tests\package_manager\KernelFile
-
core/
modules/ package_manager/ tests/ src/ Kernel/ FixtureManipulatorTest.php
View source
<?php
declare (strict_types=1);
namespace Drupal\Tests\package_manager\Kernel;
use Drupal\fixture_manipulator\ActiveFixtureManipulator;
use Drupal\fixture_manipulator\FixtureManipulator;
use Drupal\package_manager\ComposerInspector;
use Drupal\package_manager\InstalledPackagesList;
use Drupal\Tests\package_manager\Traits\InstalledPackagesListTrait;
use Drupal\package_manager\PathLocator;
/**
* @coversDefaultClass \Drupal\fixture_manipulator\FixtureManipulator
*
* @group package_manager
*/
class FixtureManipulatorTest extends PackageManagerKernelTestBase {
use InstalledPackagesListTrait;
/**
* The root directory of the test project.
*
* @var string
*/
private string $dir;
/**
* The exception expected in ::tearDown() of this test.
*
* @var \Exception
*/
private \Exception $expectedTearDownException;
/**
* The Composer inspector service.
*
* @var \Drupal\package_manager\ComposerInspector
*/
private ComposerInspector $inspector;
/**
* The original fixture package list at the start of the test.
*
* @var \Drupal\package_manager\InstalledPackagesList
*/
private InstalledPackagesList $originalFixturePackages;
/**
* {@inheritdoc}
*/
protected function setUp() : void {
parent::setUp();
$this->dir = $this->container
->get(PathLocator::class)
->getProjectRoot();
$this->inspector = $this->container
->get(ComposerInspector::class);
$manipulator = new ActiveFixtureManipulator();
$manipulator->addPackage([
'name' => 'my/package',
'type' => 'library',
'version' => '1.2.3',
])
->addPackage([
'name' => 'my/dev-package',
'version' => '2.1.0',
'type' => 'library',
], TRUE)
->commitChanges();
$this->originalFixturePackages = $this->inspector
->getInstalledPackagesList($this->dir);
}
/**
* @covers ::addPackage
*/
public function testAddPackage() : void {
// Packages cannot be added without a name.
foreach ([
'name',
'type',
] as $require_key) {
// Make a package that is missing the required key.
$package = array_diff_key([
'name' => 'Any old name',
'type' => 'Any old type',
], [
$require_key => '',
]);
try {
$manipulator = new ActiveFixtureManipulator();
$manipulator->addPackage($package)
->commitChanges();
$this->fail("Adding a package without the '{$require_key}' should raise an error.");
} catch (\UnexpectedValueException $e) {
$this->assertSame("The '{$require_key}' is required when calling ::addPackage().", $e->getMessage());
}
}
// We should get a helpful error if the name is not a valid package name.
try {
$manipulator = new ActiveFixtureManipulator();
$manipulator->addPackage([
'name' => 'my_drupal_module',
'type' => 'drupal-module',
])
->commitChanges();
$this->fail('Trying to add a package with an invalid name should raise an error.');
} catch (\UnexpectedValueException $e) {
$this->assertSame("'my_drupal_module' is not a valid package name.", $e->getMessage());
}
// We should not be able to add an existing package.
try {
$manipulator = new ActiveFixtureManipulator();
$manipulator->addPackage([
'name' => 'my/package',
'type' => 'library',
])
->commitChanges();
$this->fail('Trying to add an existing package should raise an error.');
} catch (\LogicException $e) {
$this->assertStringContainsString("Expected package 'my/package' to not be installed, but it was.", $e->getMessage());
}
// Ensure that none of the failed calls to ::addPackage() changed the installed
// packages.
$this->assertPackageListsEqual($this->originalFixturePackages, $this->inspector
->getInstalledPackagesList($this->dir));
$root_info = $this->inspector
->getRootPackageInfo($this->dir);
$this->assertSame([
'drupal/core-dev',
'my/dev-package',
], array_keys($root_info['devRequires']));
}
/**
* @covers ::modifyPackageConfig
*/
public function testModifyPackageConfig() : void {
// Assert ::modifyPackage() works with a package in an existing fixture not
// created by ::addPackage().
$decode_packages_json = function () : array {
return json_decode(file_get_contents($this->dir . "/packages.json"), TRUE, flags: JSON_THROW_ON_ERROR);
};
$original_packages_json = $decode_packages_json();
(new ActiveFixtureManipulator())->modifyPackageConfig('my/dev-package', '2.1.0', [
'description' => 'something else',
], TRUE)
->commitChanges();
// Verify that the package is indeed properly installed.
$this->assertSame('2.1.0', $this->inspector
->getInstalledPackagesList($this->dir)['my/dev-package']?->version);
// Verify that the original exists, but has no description.
$this->assertSame('my/dev-package', $original_packages_json['packages']['my/dev-package']['2.1.0']['name']);
$this->assertArrayNotHasKey('description', $original_packages_json);
// Verify that the description was updated.
$this->assertSame('something else', $decode_packages_json()['packages']['my/dev-package']['2.1.0']['description']);
(new ActiveFixtureManipulator())->modifyPackageConfig('my/package', '1.2.3', [
'extra' => [
'foo' => 'bar',
],
])
->setVersion('my/dev-package', '3.2.1', TRUE)
->commitChanges();
$this->assertSame([
'foo' => 'bar',
], $decode_packages_json()['packages']['my/package']['1.2.3']['extra']);
$this->assertSame('3.2.1', $this->inspector
->getInstalledPackagesList($this->dir)['my/dev-package']?->version);
}
/**
* @covers ::removePackage
*/
public function testRemovePackage() : void {
// We should not be able to remove a package that's not installed.
try {
(new ActiveFixtureManipulator())->removePackage('junk/drawer')
->commitChanges();
$this->fail('Removing a non-existent package should raise an error.');
} catch (\LogicException $e) {
$this->assertStringContainsString('junk/drawer is not required in your composer.json and has not been remove', $e->getMessage());
}
// Remove the 2 packages that were added in ::setUp().
(new ActiveFixtureManipulator())->removePackage('my/package')
->removePackage('my/dev-package', TRUE)
->commitChanges();
$expected_packages = $this->originalFixturePackages
->getArrayCopy();
unset($expected_packages['my/package'], $expected_packages['my/dev-package']);
$expected_list = new InstalledPackagesList($expected_packages);
$this->assertPackageListsEqual($expected_list, $this->inspector
->getInstalledPackagesList($this->dir));
$root_info = $this->inspector
->getRootPackageInfo($this->dir);
$this->assertSame([
'drupal/core-dev',
], array_keys($root_info['devRequires']));
}
/**
* Test that an exception is thrown if ::commitChanges() is not called.
*/
public function testActiveManipulatorNoCommitError() : void {
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('commitChanges() must be called.');
(new ActiveFixtureManipulator())->setVersion('drupal/core', '1.2.3');
}
/**
* @covers ::addDotGitFolder
*/
public function testAddDotGitFolder() : void {
$path_locator = $this->container
->get(PathLocator::class);
$project_root = $path_locator->getProjectRoot();
$this->assertFalse(is_dir($project_root . "/relative/path/.git"));
// We should not be able to add a git folder to a non-existing directory.
try {
(new FixtureManipulator())->addDotGitFolder($project_root . "/relative/path")
->commitChanges($project_root);
$this->fail('Trying to create a .git directory that already exists should raise an error.');
} catch (\LogicException $e) {
$this->assertSame('No directory exists at ' . $project_root . '/relative/path.', $e->getMessage());
}
mkdir($project_root . "/relative/path", 0777, TRUE);
$fixture_manipulator = (new FixtureManipulator())->addPackage([
'name' => 'relative/project_path',
'type' => 'drupal-module',
])
->addDotGitFolder($path_locator->getVendorDirectory() . "/relative/project_path")
->addDotGitFolder($project_root . "/relative/path");
$this->assertTrue(!is_dir($project_root . "/relative/project_path/.git"));
$fixture_manipulator->commitChanges($project_root);
$this->assertTrue(is_dir($project_root . "/relative/path/.git"));
// We should not be able to create already existing directory.
try {
(new FixtureManipulator())->addDotGitFolder($project_root . "/relative/path")
->commitChanges($project_root);
$this->fail('Trying to create a .git directory that already exists should raise an error.');
} catch (\LogicException $e) {
$this->assertStringContainsString("A .git directory already exists at " . $project_root, $e->getMessage());
}
}
/**
* Tests that the stage manipulator throws an exception if not committed.
*/
public function testStagedFixtureNotCommitted() : void {
$this->expectedTearDownException = new \LogicException('The StageFixtureManipulator has arguments that were not cleared. This likely means that the PostCreateEvent was never fired.');
$this->getStageFixtureManipulator()
->setVersion('any-org/any-package', '3.2.1');
}
/**
* {@inheritdoc}
*
* @todo Remove the line below when https://github.com/phpstan/phpstan-phpunit/issues/187 is fixed.
* @phpstan-ignore-next-line
*/
protected function tearDown() : void {
try {
parent::tearDown();
} catch (\Exception $exception) {
if (!(get_class($exception) === get_class($this->expectedTearDownException) && $exception->getMessage() === $this->expectedTearDownException
->getMessage())) {
throw $exception;
}
}
}
}
Classes
Title | Deprecated | Summary |
---|---|---|
FixtureManipulatorTest | @coversDefaultClass \Drupal\fixture_manipulator\FixtureManipulator |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.