From 4f4a66c902da14a4b3b9e18c1cbcd7fcaf34438c Mon Sep 17 00:00:00 2001
From: phenaproxima <phenaproxima@205645.no-reply.drupal.org>
Date: Thu, 14 Apr 2022 15:37:17 +0000
Subject: [PATCH] Issue #3275282 by phenaproxima:
 PackageManagerKernelTestBase::createTestProject() should mirror a real
 directory

---
 .../tests/fixtures/fake_site/.gitignore       |   1 +
 .../tests/fixtures/fake_site/_git/ignore.txt  |   4 +
 .../tests/fixtures/fake_site/composer.json    |   1 +
 .../tests/fixtures/fake_site/composer.lock    |   1 +
 .../fake_site/modules/example/_git/ignore.txt |   4 +
 .../modules/example/example.info.yml          |   3 +
 .../fixtures/fake_site/private/ignore.txt     |   1 +
 .../fake_site/sites/default/services.yml      |   2 +
 .../sites/default/settings.local.php          |   6 +
 .../fake_site/sites/default/settings.php      |   6 +
 .../fake_site/sites/default/stage.txt         |   1 +
 .../fake_site/sites/example.com/db.sqlite     |   1 +
 .../fake_site/sites/example.com/db.sqlite-shm |   1 +
 .../fake_site/sites/example.com/db.sqlite-wal |   1 +
 .../sites/example.com/files/ignore.txt        |   1 +
 .../fake_site/sites/example.com/services.yml  |   2 +
 .../sites/example.com/settings.local.php      |   6 +
 .../fake_site/sites/example.com/settings.php  |   6 +
 .../fake_site/sites/simpletest/ignore.txt     |   1 +
 .../tests/fixtures/fake_site/vendor/.htaccess |   1 +
 .../fixtures/fake_site/vendor/web.config      |   1 +
 .../Kernel/PackageManagerKernelTestBase.php   | 118 ++++++------------
 .../tests/src/Kernel/StageOwnershipTest.php   |  25 ++--
 23 files changed, 100 insertions(+), 94 deletions(-)
 create mode 100644 package_manager/tests/fixtures/fake_site/.gitignore
 create mode 100644 package_manager/tests/fixtures/fake_site/_git/ignore.txt
 create mode 100644 package_manager/tests/fixtures/fake_site/composer.json
 create mode 100644 package_manager/tests/fixtures/fake_site/composer.lock
 create mode 100644 package_manager/tests/fixtures/fake_site/modules/example/_git/ignore.txt
 create mode 100644 package_manager/tests/fixtures/fake_site/modules/example/example.info.yml
 create mode 100644 package_manager/tests/fixtures/fake_site/private/ignore.txt
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/default/services.yml
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/default/settings.local.php
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/default/settings.php
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/default/stage.txt
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/example.com/db.sqlite
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/example.com/db.sqlite-shm
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/example.com/db.sqlite-wal
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/example.com/files/ignore.txt
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/example.com/services.yml
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/example.com/settings.local.php
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/example.com/settings.php
 create mode 100644 package_manager/tests/fixtures/fake_site/sites/simpletest/ignore.txt
 create mode 100644 package_manager/tests/fixtures/fake_site/vendor/.htaccess
 create mode 100644 package_manager/tests/fixtures/fake_site/vendor/web.config

diff --git a/package_manager/tests/fixtures/fake_site/.gitignore b/package_manager/tests/fixtures/fake_site/.gitignore
new file mode 100644
index 0000000000..e11552b41d
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/.gitignore
@@ -0,0 +1 @@
+# This file should never be staged.
diff --git a/package_manager/tests/fixtures/fake_site/_git/ignore.txt b/package_manager/tests/fixtures/fake_site/_git/ignore.txt
new file mode 100644
index 0000000000..b70fb51506
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/_git/ignore.txt
@@ -0,0 +1,4 @@
+This file should never be staged.
+
+The parent directory will be renamed to .git.
+@see \Drupal\Tests\package_manager\Kernel\PackageManagerKernelTestBase::createTestProject()
diff --git a/package_manager/tests/fixtures/fake_site/composer.json b/package_manager/tests/fixtures/fake_site/composer.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/composer.json
@@ -0,0 +1 @@
+{}
diff --git a/package_manager/tests/fixtures/fake_site/composer.lock b/package_manager/tests/fixtures/fake_site/composer.lock
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/composer.lock
@@ -0,0 +1 @@
+{}
diff --git a/package_manager/tests/fixtures/fake_site/modules/example/_git/ignore.txt b/package_manager/tests/fixtures/fake_site/modules/example/_git/ignore.txt
new file mode 100644
index 0000000000..b70fb51506
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/modules/example/_git/ignore.txt
@@ -0,0 +1,4 @@
+This file should never be staged.
+
+The parent directory will be renamed to .git.
+@see \Drupal\Tests\package_manager\Kernel\PackageManagerKernelTestBase::createTestProject()
diff --git a/package_manager/tests/fixtures/fake_site/modules/example/example.info.yml b/package_manager/tests/fixtures/fake_site/modules/example/example.info.yml
new file mode 100644
index 0000000000..046fc058cf
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/modules/example/example.info.yml
@@ -0,0 +1,3 @@
+# This file should be staged.
+name: Example
+type: module
diff --git a/package_manager/tests/fixtures/fake_site/private/ignore.txt b/package_manager/tests/fixtures/fake_site/private/ignore.txt
new file mode 100644
index 0000000000..08874eba8b
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/private/ignore.txt
@@ -0,0 +1 @@
+This file should never be staged.
diff --git a/package_manager/tests/fixtures/fake_site/sites/default/services.yml b/package_manager/tests/fixtures/fake_site/sites/default/services.yml
new file mode 100644
index 0000000000..cbc4434e8f
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/default/services.yml
@@ -0,0 +1,2 @@
+# This file should never be staged.
+must_not_be: 'empty'
diff --git a/package_manager/tests/fixtures/fake_site/sites/default/settings.local.php b/package_manager/tests/fixtures/fake_site/sites/default/settings.local.php
new file mode 100644
index 0000000000..15b43d2812
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/default/settings.local.php
@@ -0,0 +1,6 @@
+<?php
+
+/**
+ * @file
+ * This file should never be staged.
+ */
diff --git a/package_manager/tests/fixtures/fake_site/sites/default/settings.php b/package_manager/tests/fixtures/fake_site/sites/default/settings.php
new file mode 100644
index 0000000000..15b43d2812
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/default/settings.php
@@ -0,0 +1,6 @@
+<?php
+
+/**
+ * @file
+ * This file should never be staged.
+ */
diff --git a/package_manager/tests/fixtures/fake_site/sites/default/stage.txt b/package_manager/tests/fixtures/fake_site/sites/default/stage.txt
new file mode 100644
index 0000000000..0087269e33
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/default/stage.txt
@@ -0,0 +1 @@
+This file should be staged.
diff --git a/package_manager/tests/fixtures/fake_site/sites/example.com/db.sqlite b/package_manager/tests/fixtures/fake_site/sites/example.com/db.sqlite
new file mode 100644
index 0000000000..08874eba8b
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/example.com/db.sqlite
@@ -0,0 +1 @@
+This file should never be staged.
diff --git a/package_manager/tests/fixtures/fake_site/sites/example.com/db.sqlite-shm b/package_manager/tests/fixtures/fake_site/sites/example.com/db.sqlite-shm
new file mode 100644
index 0000000000..08874eba8b
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/example.com/db.sqlite-shm
@@ -0,0 +1 @@
+This file should never be staged.
diff --git a/package_manager/tests/fixtures/fake_site/sites/example.com/db.sqlite-wal b/package_manager/tests/fixtures/fake_site/sites/example.com/db.sqlite-wal
new file mode 100644
index 0000000000..08874eba8b
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/example.com/db.sqlite-wal
@@ -0,0 +1 @@
+This file should never be staged.
diff --git a/package_manager/tests/fixtures/fake_site/sites/example.com/files/ignore.txt b/package_manager/tests/fixtures/fake_site/sites/example.com/files/ignore.txt
new file mode 100644
index 0000000000..08874eba8b
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/example.com/files/ignore.txt
@@ -0,0 +1 @@
+This file should never be staged.
diff --git a/package_manager/tests/fixtures/fake_site/sites/example.com/services.yml b/package_manager/tests/fixtures/fake_site/sites/example.com/services.yml
new file mode 100644
index 0000000000..f408d89e28
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/example.com/services.yml
@@ -0,0 +1,2 @@
+# This file should never be staged.
+key: "value"
diff --git a/package_manager/tests/fixtures/fake_site/sites/example.com/settings.local.php b/package_manager/tests/fixtures/fake_site/sites/example.com/settings.local.php
new file mode 100644
index 0000000000..15b43d2812
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/example.com/settings.local.php
@@ -0,0 +1,6 @@
+<?php
+
+/**
+ * @file
+ * This file should never be staged.
+ */
diff --git a/package_manager/tests/fixtures/fake_site/sites/example.com/settings.php b/package_manager/tests/fixtures/fake_site/sites/example.com/settings.php
new file mode 100644
index 0000000000..15b43d2812
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/example.com/settings.php
@@ -0,0 +1,6 @@
+<?php
+
+/**
+ * @file
+ * This file should never be staged.
+ */
diff --git a/package_manager/tests/fixtures/fake_site/sites/simpletest/ignore.txt b/package_manager/tests/fixtures/fake_site/sites/simpletest/ignore.txt
new file mode 100644
index 0000000000..08874eba8b
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/sites/simpletest/ignore.txt
@@ -0,0 +1 @@
+This file should never be staged.
diff --git a/package_manager/tests/fixtures/fake_site/vendor/.htaccess b/package_manager/tests/fixtures/fake_site/vendor/.htaccess
new file mode 100644
index 0000000000..e11552b41d
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/vendor/.htaccess
@@ -0,0 +1 @@
+# This file should never be staged.
diff --git a/package_manager/tests/fixtures/fake_site/vendor/web.config b/package_manager/tests/fixtures/fake_site/vendor/web.config
new file mode 100644
index 0000000000..08874eba8b
--- /dev/null
+++ b/package_manager/tests/fixtures/fake_site/vendor/web.config
@@ -0,0 +1 @@
+This file should never be staged.
diff --git a/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php b/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php
index 5b636ff355..6a929245f0 100644
--- a/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php
+++ b/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php
@@ -12,6 +12,9 @@ use Drupal\package_manager\PathLocator;
 use Drupal\package_manager\Stage;
 use Drupal\Tests\package_manager\Traits\ValidationTestTrait;
 use org\bovigo\vfs\vfsStream;
+use org\bovigo\vfs\vfsStreamDirectory;
+use org\bovigo\vfs\vfsStreamFile;
+use org\bovigo\vfs\visitor\vfsStreamAbstractVisitor;
 
 /**
  * Base class for kernel tests of Package Manager's functionality.
@@ -140,92 +143,41 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase {
    * locator service will also be mocked so that it points to the test project.
    */
   protected function createTestProject(): void {
-    $tree = [
-      'active' => [
-        'composer.json' => '{}',
-        'composer.lock' => '{}',
-        '.git' => [
-          'ignore.txt' => 'This file should never be staged.',
-        ],
-        '.gitignore' => 'This file should be staged.',
-        'private' => [
-          'ignore.txt' => 'This file should never be staged.',
-        ],
-        'modules' => [
-          'example' => [
-            'example.info.yml' => 'This file should be staged.',
-            '.git' => [
-              'ignore.txt' => 'This file should never be staged.',
-            ],
-          ],
-        ],
-        'sites' => [
-          'default' => [
-            'services.yml' => <<<END
-# This file should never be staged.
-must_not_be: 'empty'
-END,
-            'settings.local.php' => <<<END
-<?php
-
-/**
- * @file
- * This file should never be staged.
- */
-END,
-            'settings.php' => <<<END
-<?php
-
-/**
- * @file
- * This file should never be staged.
- */
-END,
-            'stage.txt' => 'This file should be staged.',
-          ],
-          'example.com' => [
-            'files' => [
-              'ignore.txt' => 'This file should never be staged.',
-            ],
-            'db.sqlite' => 'This file should never be staged.',
-            'db.sqlite-shm' => 'This file should never be staged.',
-            'db.sqlite-wal' => 'This file should never be staged.',
-            'services.yml' => <<<END
-# This file should never be staged.
-key: "value"
-END,
-            'settings.local.php' => <<<END
-<?php
+    // Create the active directory and copy its contents from a fixture.
+    $active_dir = vfsStream::newDirectory('active');
+    $this->vfsRoot->addChild($active_dir);
+    vfsStream::copyFromFileSystem(__DIR__ . '/../../fixtures/fake_site', $active_dir);
+
+    // Because we can't commit physical `.git` directories into the fixture, use
+    // a visitor to traverse the virtual file system and rename all `_git`
+    // directories to `.git`.
+    vfsStream::inspect(new class () extends vfsStreamAbstractVisitor {
+
+      /**
+       * {@inheritdoc}
+       */
+      public function visitFile(vfsStreamFile $file) {}
+
+      /**
+       * {@inheritdoc}
+       */
+      public function visitDirectory(vfsStreamDirectory $dir) {
+        if ($dir->getName() === '_git') {
+          $dir->rename('.git');
+        }
+        foreach ($dir->getChildren() as $child) {
+          $this->visit($child);
+        }
+      }
 
-/**
- * @file
- * This file should never be staged.
- */
-END,
-            'settings.php' => <<<END
-<?php
+    });
 
-/**
- * @file
- * This file should never be staged.
- */
-END,
-          ],
-          'simpletest' => [
-            'ignore.txt' => 'This file should never be staged.',
-          ],
-        ],
-        'vendor' => [
-          '.htaccess' => '# This file should never be staged.',
-          'web.config' => 'This file should never be staged.',
-        ],
-      ],
-      'stage' => [],
-    ];
-    $root = vfsStream::create($tree, $this->vfsRoot)->url();
-    TestStage::$stagingRoot = "$root/stage";
+    // Create a staging root directory alongside the active directory.
+    $stage_dir = vfsStream::newDirectory('stage');
+    $this->vfsRoot->addChild($stage_dir);
+    TestStage::$stagingRoot = $stage_dir->url();
 
-    $path_locator = $this->mockPathLocator("$root/active");
+    $path_locator = $this->mockPathLocator($active_dir->url());
 
     // Since the path locator now points to a virtual file system, we need to
     // replace the disk space validator with a test-only version that bypasses
diff --git a/package_manager/tests/src/Kernel/StageOwnershipTest.php b/package_manager/tests/src/Kernel/StageOwnershipTest.php
index d3f73d5c6d..c5f3bdac9b 100644
--- a/package_manager/tests/src/Kernel/StageOwnershipTest.php
+++ b/package_manager/tests/src/Kernel/StageOwnershipTest.php
@@ -10,8 +10,7 @@ use Drupal\package_manager\Exception\StageException;
 use Drupal\package_manager\Exception\StageOwnershipException;
 use Drupal\package_manager_test_validation\EventSubscriber\TestSubscriber;
 use Drupal\Tests\user\Traits\UserCreationTrait;
-use Prophecy\Argument;
-use Psr\Log\LoggerInterface;
+use Psr\Log\Test\TestLogger;
 
 /**
  * Tests that ownership of the stage is enforced.
@@ -272,15 +271,8 @@ class StageOwnershipTest extends PackageManagerKernelTestBase {
     chmod($dir, 0400);
     $this->assertDirectoryIsNotWritable($dir);
 
-    // Mock a logger to prove that a file system error was raised while trying
-    // to delete the stage directory.
-    $logger = $this->prophesize(LoggerInterface::class);
-    $logger->log(
-      RfcLogLevel::ERROR,
-      "Failed to unlink file '%path'.",
-      Argument::withEntry('%path', "$dir/composer.json")
-    )->shouldBeCalled();
-    $logger_channel->addLogger($logger->reveal());
+    $logger = new TestLogger();
+    $logger_channel->addLogger($logger);
 
     // Listen to the post-destroy event so we can confirm that it was fired, and
     // the stage was made available, despite the file system error.
@@ -291,6 +283,17 @@ class StageOwnershipTest extends PackageManagerKernelTestBase {
       });
     $stage->destroy();
     $this->assertTrue($stage_available);
+
+    // A file system error should have been logged while trying to delete the
+    // stage directory.
+    $predicate = function (array $record) use ($dir): bool {
+      return (
+        $record['message'] === "Failed to unlink file '%path'." &&
+        isset($record['context']['%path']) &&
+        str_contains($record['context']['%path'], $dir)
+      );
+    };
+    $this->assertTrue($logger->hasRecordThatPasses($predicate, RfcLogLevel::ERROR));
   }
 
 }
-- 
GitLab