cypress-8.x-1.x-dev/tests/Unit/CachedInstallationTest.php

tests/Unit/CachedInstallationTest.php
<?php

namespace Drupal\Tests\cypress\Unit;

use Drupal\cypress\CachedInstallation;
use Drupal\Tests\UnitTestCase;
use org\bovigo\vfs\vfsStream;
use Symfony\Component\Filesystem\Filesystem;

interface Procedure {
  public function __invoke(): void;
}

class CachedInstallationTest extends UnitTestCase {

  /**
   * @var callable
   */
  protected $installer;

  /**
   * @var \Prophecy\Prophecy\MethodProphecy
   */
  protected $installProcedure;

  /**
   * @var callable
   */
  protected $updater;

  /**
   * @var \Prophecy\Prophecy\MethodProphecy
   */
  protected $updateProcedure;

  /**
   * The Drupal root directory.
   *
   * @var string
   */
  protected $appRoot;

  /**
   * @var \Drupal\cypress\CachedInstallation
   */
  protected $cachedInstall;

  protected function setUp(): void {
    $vfs = vfsStream::setup('app');
    $this->appRoot = vfsStream::create([
      'config' => [
        'a' => [
          'foo.yml' => 'foo',
        ],
        'b' => [
          'bar.yml' => 'bar',
        ],
      ],
      'drupal' => [
        'core' => [],
        'themes' => [
          'y' => [
            'y.theme' => 'foo',
            'y.libraries.yml' => 'foo',
          ],
        ],
        'modules' => [
          'x' => [
            'x.module' => 'foo',
            'x.install' => 'foo',
            'x.post_update.php' => 'foo',
            'x.routing.yml' => 'foo',
          ],
        ],
        'sites' => [
        ],
      ],
    ], $vfs)->url();

    $appRoot = $this->appRoot;

    $installer = $this->prophesize(Procedure::class);
    $this->installProcedure = $installer->__invoke()->will(function () use ($appRoot) {
      $fs = new Filesystem();
      $fs->mkdir($appRoot . '/drupal/sites/simpletest/123/files');
      $fs->mkdir($appRoot . '/drupal/sites/default/files');

      file_put_contents(
        $appRoot . '/drupal/sites/simpletest/123/settings.php',
        '123 ' . $appRoot . '/drupal'
      );

      file_put_contents(
        $appRoot . '/drupal/sites/default/files/.sqlite-test123',
        'foo'
      );
    });
    $this->installer = $installer->reveal();

    $updater = $this->prophesize(Procedure::class);
    $this->updateProcedure = $updater->__invoke();
    $this->updater = $updater->reveal();

    $this->cachedInstall = new class(
      $this->appRoot . '/drupal',
      'sites/simpletest/123',
      '123',
      'sqlite://localhost/sites/default/files/.sqlite',
      'test123'
    ) extends CachedInstallation {

      protected function zippyCompress($files, $destination): void {
        file_put_contents(
          $this->appRoot . '/' . $this->installCache,
          'bar'
        );
      }

      protected function zippyExtract($archive, $destination): void {
        file_put_contents(
          $destination . '/settings.php',
          'LOCK_ID APP_ROOT'
        );

        (new Filesystem())->mkdir($destination  . '/files');

        file_put_contents(
          $destination . '/files/.sqlite',
          'foo'
        );
      }

    };
    $this->cachedInstall->setCacheDir($this->appRoot . '/cache');
    $this->cachedInstall->setConfigDir($this->appRoot . '/config/a');
    parent::setUp();
  }

  protected function assertSiteInstalled(): void {
    $this->assertStringEqualsFile(
      $this->appRoot . '/drupal/sites/default/files/.sqlite-test123',
      'foo'
    );

    $this->assertStringEqualsFile(
      $this->appRoot . '/drupal/sites/simpletest/123/settings.php',
      '123 ' . $this->appRoot . '/drupal'
    );
  }

  protected function assertSiteCached(string $cacheId): void {
    $cacheDir = $this->appRoot . '/cache/' . $cacheId;
    $this->assertStringEqualsFile(
      $cacheDir . '/files/.sqlite',
      'foo'
    );

    $this->assertStringEqualsFile(
      $cacheDir . '/settings.php',
      'LOCK_ID APP_ROOT'
    );
  }

  protected function assertSiteNotCached(string $cacheId): void {
    $this->assertDirectoryNotExists(
      $this->appRoot . '/cache/' . $cacheId
    );
  }

  /**
   * Installation should not fail if no cache directory is set.
   */
  public function testNoCacheDir(): void {
    $this->installProcedure->shouldBeCalledOnce();
    $this->updateProcedure->shouldNotBeCalled();
    $this->cachedInstall
      ->setCacheDir('')
      ->install($this->installer, $this->updater);

    $this->assertSiteInstalled();
    $this->assertSiteNotCached($this->cachedInstall->getInstallCacheId());
    $this->assertSiteNotCached($this->cachedInstall->getUpdateCacheId());
  }

  /**
   * Test uncacheable install.
   *
   * If the setup is not cacheable the whole procedure is execute and no
   * cache directory is created.
   */
  public function testUncacheableInstall(): void {
    $this->installProcedure->shouldBeCalledOnce();
    $this->updateProcedure->shouldNotBeCalled();

    $this->cachedInstall = new CachedInstallation(
      $this->appRoot . '/drupal',
      'sites/default',
      'LOCK',
      'mysql://localhost:3306#drupal',
      'PREFIX'
    );
    $this->cachedInstall->setCacheDir($this->appRoot . '/cache');
    $this->cachedInstall->setConfigDir($this->appRoot . '/config');

    $this->cachedInstall->install($this->installer, $this->updater);

    $this->assertSiteInstalled();
    $this->assertSiteNotCached($this->cachedInstall->getInstallCacheId());
    $this->assertSiteNotCached($this->cachedInstall->getUpdateCacheId());
  }

  /**
   * Test install without configuration.
   *
   * If there is no config directory, only execute the install procedure and
   * cache it accordingly.
   */
  public function testCacheableInstallWithoutConfig(): void {
    $this->installProcedure->shouldBeCalledOnce();
    $this->updateProcedure->shouldNotBeCalled();

    $this->cachedInstall
      ->setConfigDir('')
      ->install($this->installer, $this->updater);
    $this->cachedInstall->install($this->installer, $this->updater);

    $this->assertSiteInstalled();
    $this->assertSiteCached($this->cachedInstall->getInstallCacheId());
    $this->assertSiteNotCached($this->cachedInstall->getUpdateCacheId());
  }

  /**
   * Test install with configuration.
   *
   * Should effectively create two cached directories. One for the installation
   * and one for the update.
   *
   */
  public function testCacheableInstallWithConfig(): void {
    $this->installProcedure->shouldBeCalledOnce();
    $this->updateProcedure->shouldNotBeCalled();

    $this->cachedInstall->install($this->installer, $this->updater);
    $this->cachedInstall->install($this->installer, $this->updater);

    $this->assertSiteInstalled();
    $this->assertSiteCached($this->cachedInstall->getInstallCacheId());
    $this->assertSiteCached($this->cachedInstall->getUpdateCacheId());
  }

  /**
   * Test writing of the persistent cache.
   */
  public function testWriteToPersistentCache(): void {
    $this->installProcedure->shouldBeCalledOnce();
    $this->updateProcedure->shouldNotBeCalled();

    $this->cachedInstall
      ->setInstallCache('../install-cache.zip')
      ->install($this->installer, $this->updater);

    $this->assertSiteInstalled();
    $this->assertSiteCached($this->cachedInstall->getInstallCacheId());
    $this->assertSiteCached($this->cachedInstall->getUpdateCacheId());
    $this->assertFileExists($this->appRoot . '/install-cache.zip');
  }

  /**
   * Test loading from the persistent cache.
   */
  public function testRestoreFromPersistentCache(): void {
    $this->installProcedure->shouldNotBeCalled();
    $this->updateProcedure->shouldBeCalledOnce();

    file_put_contents($this->appRoot . '/install-cache.zip', 'foo');
    $this->cachedInstall
      ->setInstallCache('../install-cache.zip')
      ->install($this->installer, $this->updater);

    $this->assertSiteInstalled();
    $this->assertSiteCached($this->cachedInstall->getInstallCacheId());
    $this->assertSiteCached($this->cachedInstall->getUpdateCacheId());
  }

  /**
   * Test profile change.
   *
   * If the install profile is different, a entirely new site install should
   * be invoked.
   */
  public function testProfileChange(): void {
    $this->installProcedure->shouldBeCalledTimes(2);
    $this->updateProcedure->shouldNotBeCalled();

    $this->cachedInstall->install($this->installer, $this->updater);
    $this->cachedInstall->setProfile('standard');
    $this->cachedInstall->install($this->installer, $this->updater);

    $this->assertSiteInstalled();
    $this->assertSiteCached($this->cachedInstall->getInstallCacheId());
    $this->assertSiteCached($this->cachedInstall->getUpdateCacheId());
  }

  /**
   * Test config directory change.
   *
   * If the config directory is different, a entirely new site install should
   * be invoked.
   */
  public function testConfigDirChange(): void {
    $this->installProcedure->shouldBeCalledTimes(2);
    $this->updateProcedure->shouldNotBeCalled();

    $this->cachedInstall->install($this->installer, $this->updater);
    $this->cachedInstall->setConfigDir($this->appRoot . '/config/b');
    $this->cachedInstall->install($this->installer, $this->updater);

    $this->assertSiteInstalled();
    $this->assertSiteCached($this->cachedInstall->getInstallCacheId());
    $this->assertSiteCached($this->cachedInstall->getUpdateCacheId());
  }

  /**
   * Test language change.
   *
   * If the install language is different, a entirely new site install should
   * be invoked.
   */
  public function testLangCodeChange(): void {
    $this->installProcedure->shouldBeCalledTimes(2);
    $this->updateProcedure->shouldNotBeCalled();

    $this->cachedInstall->install($this->installer, $this->updater);
    $this->cachedInstall->setLangCode('de');
    $this->cachedInstall->install($this->installer, $this->updater);

    $this->assertSiteInstalled();
    $this->assertSiteCached($this->cachedInstall->getInstallCacheId());
    $this->assertSiteCached($this->cachedInstall->getUpdateCacheId());
  }

  /**
   * Test setup class change.
   *
   * If the setup class is different, a entirely new site install should
   * be invoked.
   */
  public function testSetupClassChange(): void {
    $this->installProcedure->shouldBeCalledTimes(2);
    $this->updateProcedure->shouldNotBeCalled();

    $this->cachedInstall->install($this->installer, $this->updater);
    $this->cachedInstall->setSetupClass('bar');
    $this->cachedInstall->install($this->installer, $this->updater);

    $this->assertSiteInstalled();
    $this->assertSiteCached($this->cachedInstall->getInstallCacheId());
    $this->assertSiteCached($this->cachedInstall->getUpdateCacheId());
  }

  /**
   * Test config change.
   *
   * If the contents of the configuration directory change, an update should be
   * invoked.
   */
  public function testConfigChange(): void {
    $this->installProcedure->shouldBeCalledOnce();
    $this->updateProcedure->shouldBeCalledOnce();

    $this->cachedInstall->install($this->installer, $this->updater);
    file_put_contents($this->appRoot . '/config/a/foo.yml', 'bar');
    $this->cachedInstall->install($this->installer, $this->updater);

    $this->assertSiteInstalled();
    $this->assertSiteCached($this->cachedInstall->getInstallCacheId());
    $this->assertSiteCached($this->cachedInstall->getUpdateCacheId());
  }

  /**
   * Test update hook changes.
   *
   * If the contents of a *.install, *.post_update.php or *.yml files change,
   * an update should be invoked.
   */
  public function testInstallFileChanges(): void {
    $this->installProcedure->shouldBeCalledOnce();
    $this->updateProcedure->shouldBeCalledOnce();

    $this->cachedInstall->install($this->installer, $this->updater);
    file_put_contents($this->appRoot . '/drupal/modules/x/x.install', 'bar');
    $this->cachedInstall->install($this->installer, $this->updater);

    $this->assertSiteInstalled();
    $this->assertSiteCached($this->cachedInstall->getInstallCacheId());
    $this->assertSiteCached($this->cachedInstall->getUpdateCacheId());
  }

  /**
   * Test update hook changes.
   *
   * If the contents of a *.install, *.post_update.php or *.yml files change,
   * an update should be invoked.
   */
  public function testUpdateFileChanges(): void {
    $this->installProcedure->shouldBeCalledOnce();
    $this->updateProcedure->shouldBeCalledOnce();

    $this->cachedInstall->install($this->installer, $this->updater);
    file_put_contents($this->appRoot . '/drupal/modules/x/x.post_update.php', 'bar');
    $this->cachedInstall->install($this->installer, $this->updater);

    $this->assertSiteInstalled();
    $this->assertSiteCached($this->cachedInstall->getInstallCacheId());
    $this->assertSiteCached($this->cachedInstall->getUpdateCacheId());
  }

  /**
   * Test *.yml changes.
   *
   * If the contents of a *.install, *.post_update.php or *.yml files change,
   * an update should be invoked.
   */
  public function testYmlFileChanges(): void {
    $this->installProcedure->shouldBeCalledOnce();
    $this->updateProcedure->shouldBeCalledOnce();

    $this->cachedInstall->install($this->installer, $this->updater);
    file_put_contents($this->appRoot . '/drupal/modules/x/x.routing.yml', 'bar');
    $this->cachedInstall->install($this->installer, $this->updater);

    $this->assertSiteInstalled();
    $this->assertSiteCached($this->cachedInstall->getInstallCacheId());
    $this->assertSiteCached($this->cachedInstall->getUpdateCacheId());
  }

  /**
   * Test code changes changes.
   *
   * If any other
   */
  public function testCodeChanges(): void {
    $this->installProcedure->shouldBeCalledOnce();
    $this->updateProcedure->shouldBeCalledOnce();

    $this->cachedInstall->install($this->installer, $this->updater);
    file_put_contents($this->appRoot . '/config/a/foo.yml', 'bar');
    $this->cachedInstall->install($this->installer, $this->updater);

    $this->assertSiteInstalled();
    $this->assertSiteCached($this->cachedInstall->getInstallCacheId());
    $this->assertSiteCached($this->cachedInstall->getUpdateCacheId());
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc