Skip to content
Snippets Groups Projects
Commit d8384b58 authored by Adam G-H's avatar Adam G-H Committed by Ted Bowman
Browse files

Issue #3230510 by phenaproxima, tedbow: Turn ExclusionsTest into a functional test

parent fcbb50e6
No related branches found
No related tags found
1 merge request!23Issue #3230510: Turn ExclusionsTest into a functional test
Showing
with 151 additions and 49 deletions
......@@ -72,6 +72,6 @@ services:
class: Drupal\automatic_updates\ComposerStager\ProcessFactory
automatic_updates.excluded_paths_subscriber:
class: Drupal\automatic_updates\Event\ExcludedPathsSubscriber
arguments: ['%app.root%', '%site.path%', '@file_system']
arguments: ['%app.root%', '%site.path%', '@file_system', '@stream_wrapper_manager']
tags:
- { name: event_subscriber }
......@@ -4,6 +4,8 @@ namespace Drupal\automatic_updates\Event;
use Drupal\automatic_updates\AutomaticUpdatesEvents;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\StreamWrapper\LocalStream;
use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
......@@ -32,6 +34,13 @@ class ExcludedPathsSubscriber implements EventSubscriberInterface {
*/
protected $fileSystem;
/**
* The stream wrapper manager service.
*
* @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface
*/
protected $streamWrapperManager;
/**
* Constructs an UpdateSubscriber.
*
......@@ -41,11 +50,14 @@ class ExcludedPathsSubscriber implements EventSubscriberInterface {
* The current site path, relative to the Drupal root.
* @param \Drupal\Core\File\FileSystemInterface $file_system
* The file system service.
* @param \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $stream_wrapper_manager
* The stream wrapper manager service.
*/
public function __construct(string $app_root, string $site_path, FileSystemInterface $file_system) {
public function __construct(string $app_root, string $site_path, FileSystemInterface $file_system, StreamWrapperManagerInterface $stream_wrapper_manager) {
$this->appRoot = $app_root;
$this->sitePath = $site_path;
$this->fileSystem = $file_system;
$this->streamWrapperManager = $stream_wrapper_manager;
}
/**
......@@ -55,10 +67,13 @@ class ExcludedPathsSubscriber implements EventSubscriberInterface {
* The event object.
*/
public function preStart(PreStartEvent $event): void {
if ($public = $this->fileSystem->realpath('public://')) {
// Automated test site directories should never be staged.
$event->excludePath('sites/simpletest');
if ($public = $this->getFilesPath('public')) {
$event->excludePath($public);
}
if ($private = $this->fileSystem->realpath('private://')) {
if ($private = $this->getFilesPath('private')) {
$event->excludePath($private);
}
// If this module is a git clone, exclude it.
......@@ -92,6 +107,29 @@ class ExcludedPathsSubscriber implements EventSubscriberInterface {
}
}
/**
* Returns the storage path for a stream wrapper.
*
* This will only work for stream wrappers that extend
* \Drupal\Core\StreamWrapper\LocalStream, which includes the stream wrappers
* for public and private files.
*
* @param string $scheme
* The stream wrapper scheme.
*
* @return string|null
* The storage path for files using the given scheme, relative to the Drupal
* root, or NULL if the stream wrapper does not extend
* \Drupal\Core\StreamWrapper\LocalStream.
*/
private function getFilesPath(string $scheme): ?string {
$wrapper = $this->streamWrapperManager->getViaScheme($scheme);
if ($wrapper instanceof LocalStream) {
return $wrapper->getDirectoryPath();
}
return NULL;
}
/**
* {@inheritdoc}
*/
......
This private file should never be staged.
This public file should never be staged.
This file should be staged.
# A fake services file that should never be staged.
services: {}
<?php
/**
* @file
* A fake local settings file that should never be staged.
*/
<?php
/**
* @file
* A fake settings file that should never be staged.
*/
This file should be staged.
This file should not be staged.
<?php
namespace Drupal\automatic_updates_test;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase;
/**
* Modifies service definitions for testing purposes.
*/
class AutomaticUpdatesTestServiceProvider extends ServiceProviderBase {
/**
* {@inheritdoc}
*/
public function alter(ContainerBuilder $container) {
parent::alter($container);
$service = 'automatic_updates.updater';
if ($container->hasDefinition($service)) {
$container->getDefinition($service)->setClass(TestUpdater::class);
}
}
}
<?php
namespace Drupal\automatic_updates_test;
use Drupal\automatic_updates\Updater;
/**
* A testing updater that allows arbitrary active and stage directories.
*/
class TestUpdater extends Updater {
/**
* The active directory to use, if different from the default.
*
* @var string
*/
public $activeDirectory;
/**
* The stage directory to use, if different from the default.
*
* @var string
*/
public $stageDirectory;
/**
* {@inheritdoc}
*/
public function getActiveDirectory(): string {
return $this->activeDirectory ?: parent::getActiveDirectory();
}
/**
* {@inheritdoc}
*/
public function getStageDirectory(): string {
return $this->stageDirectory ?: parent::getStageDirectory();
}
}
......@@ -2,7 +2,7 @@
namespace Drupal\Tests\automatic_updates\Functional;
use Drupal\automatic_updates\Event\PreStartEvent;
use Drupal\Core\Site\Settings;
use Drupal\Tests\BrowserTestBase;
/**
......@@ -15,64 +15,44 @@ class ExclusionsTest extends BrowserTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = ['automatic_updates'];
protected static $modules = ['automatic_updates_test'];
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* The names of site-specific settings files to mock.
*
* @var string[]
*/
private const SETTINGS_FILES = [
'settings.php',
'settings.local.php',
'services.yml',
];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
foreach (static::SETTINGS_FILES as $settings_file) {
$settings_file = "$this->siteDirectory/$settings_file";
touch($settings_file);
$this->assertFileExists($settings_file);
}
}
/**
* Tests that certain files and directories are not staged.
*
* @covers \Drupal\automatic_updates\Updater::getExclusions
*/
public function testExclusions(): void {
$event = new PreStartEvent();
$this->container->get('automatic_updates.excluded_paths_subscriber')
->preStart($event);
$stage_dir = "$this->siteDirectory/stage";
/** @var \Drupal\automatic_updates\Updater $updater */
/** @var \Drupal\automatic_updates_test\TestUpdater $updater */
$updater = $this->container->get('automatic_updates.updater');
$reflector = new \ReflectionObject($updater);
$method = $reflector->getMethod('getExclusions');
$method->setAccessible(TRUE);
$exclusions = $method->invoke($updater, $event);
$this->assertContains("$this->siteDirectory/files", $exclusions);
$this->assertContains("$this->siteDirectory/private", $exclusions);
foreach (static::SETTINGS_FILES as $settings_file) {
$this->assertContains("$this->siteDirectory/$settings_file", $exclusions);
}
if (is_dir(__DIR__ . '/../../../.git')) {
$module_path = $this->container->get('extension.list.module')
->getPath('automatic_updates');
$this->assertContains($module_path, $exclusions);
}
$updater->activeDirectory = __DIR__ . '/../../fixtures/fake-site';
$updater->stageDirectory = $stage_dir;
$settings = Settings::getAll();
$settings['file_public_path'] = 'files/public';
$settings['file_private_path'] = 'files/private';
new Settings($settings);
$updater->begin();
$this->assertFileDoesNotExist("$stage_dir/sites/default/settings.php");
$this->assertFileDoesNotExist("$stage_dir/sites/default/settings.local.php");
$this->assertFileDoesNotExist("$stage_dir/sites/default/services.yml");
// A file in sites/default, that isn't one of the site-specific settings
// files, should be staged.
$this->assertFileExists("$stage_dir/sites/default/staged.txt");
$this->assertDirectoryDoesNotExist("$stage_dir/sites/simpletest");
$this->assertDirectoryDoesNotExist("$stage_dir/files/public");
$this->assertDirectoryDoesNotExist("$stage_dir/files/private");
// A file that's in the general files directory, but not in the public or
// private directories, should be staged.
$this->assertFileExists("$stage_dir/files/staged.txt");
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment