View source
<?php
namespace Drupal\Tests\Composer\Plugin\Scaffold\Functional;
use Composer\Util\Filesystem;
use Drupal\Tests\Composer\Plugin\Scaffold\AssertUtilsTrait;
use Drupal\Tests\Composer\Plugin\Scaffold\Fixtures;
use Drupal\Tests\Composer\Plugin\Scaffold\ScaffoldTestResult;
use PHPUnit\Framework\TestCase;
class ScaffoldTest extends TestCase {
use AssertUtilsTrait;
protected $projectRoot;
protected $fixturesDir;
protected $fileSystem;
protected $fixtures;
protected function setUp() : void {
$this->fileSystem = new Filesystem();
$this->fixtures = new Fixtures();
$this->fixtures
->createIsolatedComposerCacheDir();
$this->projectRoot = $this->fixtures
->projectRoot();
$this->fixturesDir = getenv('SCAFFOLD_FIXTURE_DIR');
if (!$this->fixturesDir) {
$this->fixturesDir = $this->fixtures
->tmpDir($this
->getName());
}
}
protected function tearDown() : void {
$this->fixtures
->tearDown();
}
protected function createSut($fixture_name, array $replacements = []) {
$sut = $this->fixturesDir . '/' . $fixture_name;
$this->fileSystem
->remove($sut);
$replacements += [
'PROJECT_ROOT' => $this->projectRoot,
];
$this->fixtures
->cloneFixtureProjects($this->fixturesDir, $replacements);
return $sut;
}
public function scaffoldSut($fixture_name, $is_link = FALSE, $relocated_docroot = TRUE) {
$sut = $this
->createSut($fixture_name, [
'SYMLINK' => $is_link ? 'true' : 'false',
]);
$this->fixtures
->runComposer("install --no-ansi --no-scripts --no-plugins", $sut);
$scaffoldOutput = $this->fixtures
->runScaffold($sut);
$docroot = $sut;
if ($relocated_docroot) {
$docroot .= '/docroot';
$this
->assertFileExists($docroot);
}
else {
$this
->assertFileDoesNotExist($sut . '/docroot');
}
return new ScaffoldTestResult($docroot, $scaffoldOutput);
}
public function scaffoldExpectedExceptionTestValues() {
return [
[
'drupal-drupal-missing-scaffold-file',
'Scaffold file assets/missing-robots-default.txt not found in package fixtures/drupal-drupal-missing-scaffold-file.',
TRUE,
],
[
'project-with-empty-scaffold-path',
'No scaffold file path given for [web-root]/my-error in package fixtures/project-with-empty-scaffold-path',
FALSE,
],
[
'project-with-illegal-dir-scaffold',
'Scaffold file assets in package fixtures/project-with-illegal-dir-scaffold is a directory; only files may be scaffolded',
FALSE,
],
];
}
public function testScaffoldWithExpectedException($fixture_name, $expected_exception_message, $is_link) {
$this
->expectException(\Exception::class);
$this
->expectExceptionMessage($expected_exception_message);
$this
->scaffoldSut($fixture_name, $is_link);
}
public function testEmptyProject() {
$fixture_name = 'empty-fixture';
$result = $this
->scaffoldSut($fixture_name, FALSE, FALSE);
$this
->assertStringContainsString('Nothing scaffolded because no packages are allowed in the top-level composer.json file', $result
->scaffoldOutput());
}
public function testProjectThatScaffoldsEmptyProject() {
$fixture_name = 'project-allowing-empty-fixture';
$result = $this
->scaffoldSut($fixture_name, FALSE, FALSE);
$this
->assertStringContainsString('The allowed package fixtures/empty-fixture does not provide a file mapping for Composer Scaffold', $result
->scaffoldOutput());
$this
->assertCommonDrupalAssetsWereScaffolded($result
->docroot(), FALSE);
$this
->assertAutoloadFileCorrect($result
->docroot());
}
public function scaffoldOverridingSettingsExcludingHtaccessValues() {
return [
[
'drupal-composer-drupal-project',
TRUE,
TRUE,
],
[
'drupal-drupal',
FALSE,
FALSE,
],
];
}
public function testScaffoldOverridingSettingsExcludingHtaccess($fixture_name, $is_link, $relocated_docroot) {
$result = $this
->scaffoldSut($fixture_name, $is_link, $relocated_docroot);
$this
->assertCommonDrupalAssetsWereScaffolded($result
->docroot(), $is_link);
$this
->assertAutoloadFileCorrect($result
->docroot(), $relocated_docroot);
$this
->assertDefaultSettingsFromScaffoldOverride($result
->docroot(), $is_link);
$this
->assertHtaccessExcluded($result
->docroot());
}
public function testDrupalDrupalFileWasReplaced() {
$fixture_name = 'drupal-drupal-test-overwrite';
$result = $this
->scaffoldSut($fixture_name, FALSE, FALSE);
$this
->assertScaffoldedFile($result
->docroot() . '/replace-me.txt', FALSE, 'from assets that replaces file');
$this
->assertScaffoldedFile($result
->docroot() . '/keep-me.txt', FALSE, 'File in drupal-drupal-test-overwrite that is not replaced');
$this
->assertScaffoldedFile($result
->docroot() . '/make-me.txt', FALSE, 'from assets that replaces file');
$this
->assertCommonDrupalAssetsWereScaffolded($result
->docroot(), FALSE);
$this
->assertAutoloadFileCorrect($result
->docroot());
$this
->assertScaffoldedFile($result
->docroot() . '/robots.txt', FALSE, $fixture_name);
}
public function scaffoldAppendTestValues() {
return array_merge($this
->scaffoldAppendTestValuesToPermute(FALSE), $this
->scaffoldAppendTestValuesToPermute(TRUE), [
[
'drupal-drupal-append-settings',
FALSE,
'sites/default/settings.php',
'<?php
// Default settings.php contents
include __DIR__ . "/settings-custom-additions.php";',
'NOTICE Creating a new file at [web-root]/sites/default/settings.php. Examine the contents and ensure that it came out correctly.',
],
]);
}
protected function scaffoldAppendTestValuesToPermute($is_link) {
return [
[
'drupal-drupal-test-append',
$is_link,
'robots.txt',
'# robots.txt fixture scaffolded from "file-mappings" in drupal-drupal-test-append composer.json fixture.
# This content is prepended to the top of the existing robots.txt fixture.
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# Test version of robots.txt from drupal/core.
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# This content is appended to the bottom of the existing robots.txt fixture.
# robots.txt fixture scaffolded from "file-mappings" in drupal-drupal-test-append composer.json fixture.
',
'Prepend to [web-root]/robots.txt from assets/prepend-to-robots.txt',
],
[
'drupal-drupal-append-to-append',
$is_link,
'robots.txt',
'# robots.txt fixture scaffolded from "file-mappings" in drupal-drupal-append-to-append composer.json fixture.
# This content is prepended to the top of the existing robots.txt fixture.
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# Test version of robots.txt from drupal/core.
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# This content is appended to the bottom of the existing robots.txt fixture.
# robots.txt fixture scaffolded from "file-mappings" in profile-with-append composer.json fixture.
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# This content is appended to the bottom of the existing robots.txt fixture.
# robots.txt fixture scaffolded from "file-mappings" in drupal-drupal-append-to-append composer.json fixture.',
'Append to [web-root]/robots.txt from assets/append-to-robots.txt',
],
];
}
public function testDrupalDrupalFileWasAppended($fixture_name, $is_link, $scaffold_file_path, $scaffold_file_contents, $scaffoldOutputContains) {
$result = $this
->scaffoldSut($fixture_name, $is_link, FALSE);
$this
->assertStringContainsString($scaffoldOutputContains, $result
->scaffoldOutput());
$this
->assertScaffoldedFile($result
->docroot() . '/' . $scaffold_file_path, FALSE, $scaffold_file_contents);
$this
->assertCommonDrupalAssetsWereScaffolded($result
->docroot(), $is_link);
$this
->assertAutoloadFileCorrect($result
->docroot());
}
protected function assertDefaultSettingsFromScaffoldOverride($docroot, $is_link) {
$this
->assertScaffoldedFile($docroot . '/sites/default/default.settings.php', $is_link, 'scaffolded from the scaffold-override-fixture');
}
protected function assertHtaccessExcluded($docroot) {
$this
->assertFileDoesNotExist($docroot . '/.htaccess');
}
protected function assertCommonDrupalAssetsWereScaffolded($docroot, $is_link) {
$this
->assertScaffoldedFile($docroot . '/.csslintrc', $is_link, 'Test version of .csslintrc from drupal/core.');
$this
->assertScaffoldedFile($docroot . '/.editorconfig', $is_link, 'Test version of .editorconfig from drupal/core.');
$this
->assertScaffoldedFile($docroot . '/.eslintignore', $is_link, 'Test version of .eslintignore from drupal/core.');
$this
->assertScaffoldedFile($docroot . '/.eslintrc.json', $is_link, 'Test version of .eslintrc.json from drupal/core.');
$this
->assertScaffoldedFile($docroot . '/.gitattributes', $is_link, 'Test version of .gitattributes from drupal/core.');
$this
->assertScaffoldedFile($docroot . '/.ht.router.php', $is_link, 'Test version of .ht.router.php from drupal/core.');
$this
->assertScaffoldedFile($docroot . '/sites/default/default.services.yml', $is_link, 'Test version of default.services.yml from drupal/core.');
$this
->assertScaffoldedFile($docroot . '/sites/example.settings.local.php', $is_link, 'Test version of example.settings.local.php from drupal/core.');
$this
->assertScaffoldedFile($docroot . '/sites/example.sites.php', $is_link, 'Test version of example.sites.php from drupal/core.');
$this
->assertScaffoldedFile($docroot . '/index.php', $is_link, 'Test version of index.php from drupal/core.');
$this
->assertScaffoldedFile($docroot . '/update.php', $is_link, 'Test version of update.php from drupal/core.');
$this
->assertScaffoldedFile($docroot . '/web.config', $is_link, 'Test version of web.config from drupal/core.');
}
protected function assertAutoloadFileCorrect($docroot, $relocated_docroot = FALSE) {
$autoload_path = $docroot . '/autoload.php';
$this
->assertFileExists($autoload_path);
$contents = file_get_contents($autoload_path);
$expected = "return require __DIR__ . '/vendor/autoload.php';";
if ($relocated_docroot) {
$expected = "return require __DIR__ . '/../vendor/autoload.php';";
}
$this
->assertStringContainsString($expected, $contents);
}
}