preview_site-1.1.2/tests/src/Kernel/PreviewSiteBuildEntityTest.php

tests/src/Kernel/PreviewSiteBuildEntityTest.php
<?php

namespace Drupal\Tests\preview_site\Kernel;

use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Url;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\file\FileInterface;
use Drupal\preview_site\Entity\PreviewSiteBuild;
use Drupal\preview_site\Entity\PreviewSiteBuildInterface;
use Drupal\preview_site\Generate\GenerationInProgressException;
use Drupal\preview_site_test\Plugin\PreviewSite\Deploy\TestDeploy;
use Drupal\preview_site_test\Plugin\PreviewSite\Generate\TestGenerate;
use Drupal\Tests\taxonomy\Traits\TaxonomyTestTrait;
use Prophecy\PhpUnit\ProphecyTrait;

/**
 * Defines a class for testing the PreviewSite entity.
 *
 * @covers \Drupal\preview_site\Entity\PreviewSiteBuild
 * @covers \Drupal\preview_site\Entity\PreviewStrategy
 * @covers \Drupal\preview_site\Plugin\Derivative\PreviewSiteBuildQueueWorkerDeriver
 * @covers \Drupal\preview_site\Plugin\QueueWorker\Generate
 * @covers \Drupal\preview_site\Plugin\QueueWorker\GenerateAssets
 * @covers \Drupal\preview_site\Plugin\QueueWorker\Deploy
 * @covers \Drupal\preview_site\Generate\GeneratePluginBase
 *
 * @group preview_site
 */
class PreviewSiteBuildEntityTest extends PreviewSiteKernelTestBase {

  use ProphecyTrait;
  use TaxonomyTestTrait;

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'taxonomy',
    'entity_test',
  ];

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();
    $this->installEntitySchema('entity_test');
    $this->installEntitySchema('taxonomy_term');
  }

  /**
   * Tests build entity functionality.
   */
  public function testBasicCrudOperations(): void {
    $strategy_label = $this->randomMachineName();
    $label = $this->randomMachineName();
    $user = $this->createUser();
    $vocabulary = $this->createVocabulary();
    $term = $this->createTerm($vocabulary);
    $entity_test = EntityTest::create();
    $prefix = $this->randomMachineName();
    $strategy = $this->createStrategy($strategy_label, $this->randomMachineName(), $prefix);
    /** @var \Drupal\Core\Queue\QueueWorkerManagerInterface $queue_manager */
    $queue_manager = \Drupal::service('plugin.manager.queue_worker');
    $this->assertCount(0, array_filter(array_keys($queue_manager->getDefinitions()), function (string $key) {
      return strpos($key, 'preview_site') === 0 && $key !== 'preview_site_decommission';
    }));
    $file = $this->getTestFile();
    $build = $this->createPreviewSiteBuild([
      'strategy' => $strategy->id(),
      'label' => $label,
      'contents' => [
        $entity_test,
        $term,
        $user,
      ],
      'artifacts' => $file->id(),
      'log' => 'stuff',
      'processed_paths' => ['/some/path'],
    ]);
    $this->assertEquals(3, $build->getItemCount());
    $this->assertEquals(PreviewSiteBuildInterface::STATUS_PENDING, $build->getStatus());
    $this->assertEquals($strategy_label, $build->getStrategyLabel());

    // Saving a build should create three queues for each item.
    $this->assertTrue($queue_manager->hasDefinition('preview_site_generate:' . $build->id()));
    $this->assertTrue($queue_manager->hasDefinition('preview_site_deploy:' . $build->id()));
    $this->assertTrue($queue_manager->hasDefinition('preview_site_assets:' . $build->id()));
    $build = \Drupal::entityTypeManager()->getStorage('preview_site_build')
      ->loadUnchanged($build->id());
    $contents = $build->get('contents')->getValue();
    $this->assertEquals([
      $entity_test->id(),
      $term->id(),
      $user->id(),
    ], array_column($contents, 'target_id'));
    $this->assertEquals([
      $entity_test->getEntityTypeId(),
      $term->getEntityTypeId(),
      $user->getEntityTypeId(),
    ], array_column($contents, 'target_type'));
    $this->assertEquals($label, $build->label());
    $this->assertEquals($strategy->label(), $build->strategy->entity->label());
    $this->assertEquals('stuff', $build->log->value);
    $this->assertEquals($file->id(), $build->artifacts->target_id);
    $this->assertEquals('/some/path', $build->processed_paths->value);
    $this->assertInstanceOf(TestGenerate::class, $build->getGeneratePlugin());

    $build->delete();

    // The queues should now be deleted.
    $this->assertCount(0, array_filter(array_keys($queue_manager->getDefinitions()), function (string $key) {
      return strpos($key, 'preview_site') === 0 && $key !== 'preview_site_decommission';
    }));
  }

  /**
   * Tests to ensure a built preview site build enters a stale state.
   */
  public function testStaleStatus(): void {
    $strategy_label = $this->randomMachineName();
    $label = $this->randomMachineName();
    $prefix = $this->randomMachineName();
    $strategy = $this->createStrategy($strategy_label, $this->randomMachineName(), $prefix);
    $entity_test = EntityTest::create();
    $file = $this->getTestFile();
    // Create a preview site build and set the status to built.
    $build = $this->createPreviewSiteBuild([
      'strategy' => $strategy->id(),
      'label' => $label,
      'contents' => [
        $entity_test,
      ],
      'artifacts' => $file->id(),
      'log' => 'stuff',
      'processed_paths' => ['/some/path'],
      'status' => PreviewSiteBuildInterface::STATUS_BUILT,
    ]);
    $this->assertEquals(PreviewSiteBuildInterface::STATUS_BUILT, $build->getStatus());

    // Create an additional entity and add it to the preview site build.
    $entity_test_1 = EntityTest::create();
    $build->get('contents')->appendItem($entity_test_1);
    $build->save();
    // The preview site build status should now be 'stale'.
    $this->assertEquals(PreviewSiteBuildInterface::STATUS_STALE, $build->getStatus());
    // Reset the preview site build status to 'built'.
    $build->set('status', PreviewSiteBuildInterface::STATUS_BUILT);
    $build->save();
    // Change the additional entity's title.
    $entity_test_1_title = $this->randomMachineName();
    $entity_test_1->set('name', $entity_test_1_title);
    $entity_test_1->save();
    // The preview site build status should still be 'built'.
    $this->assertNotEquals(PreviewSiteBuildInterface::STATUS_STALE, $build->getStatus());
    // Turn on preview_site.settings.proactive_stale_check.
    $this->config('preview_site.settings')->set('proactive_stale_check', 1)->save();
    // Change the additional entity's title.
    $entity_test_1_title = $this->randomMachineName();
    $entity_test_1->set('name', $entity_test_1_title);
    $entity_test_1->save();
    // The preview site build status should now be 'stale'.
    // It requires a reload.
    $this->assertEquals(PreviewSiteBuildInterface::STATUS_STALE, $build::load($build->id())->getStatus());
  }

  /**
   * Tests generate and deployment queues.
   */
  public function testGenerationAndDeploymentQueue(): void {
    $user = $this->createUser();
    $vocabulary = $this->createVocabulary();
    $term = $this->createTerm($vocabulary);
    $entity_test = EntityTest::create();
    $build = $this->createPreviewSiteBuild([
      'contents' => [
        $entity_test,
        $term,
        $user,
      ],
    ]);
    $generate_queue = \Drupal::queue('preview_site_generate:' . $build->id());
    $this->assertEquals(0, $generate_queue->numberOfItems());
    $build->queueGeneration($generate_queue);
    $this->assertEquals(3, $generate_queue->numberOfItems());

    $state = \Drupal::state();
    $deployment_queue = \Drupal::queue('preview_site_deploy:' . $build->id());
    $this->assertEquals(0, $deployment_queue->numberOfItems());
    $this->assertNull($state->get(TestGenerate::COMPLETE_STEP));
    $build->queueDeployment($deployment_queue);
    $this->assertTrue($state->get(TestGenerate::COMPLETE_STEP));
    $this->assertEquals(1, $deployment_queue->numberOfItems());
  }

  /**
   * Tests starting deployment.
   */
  public function testStartingDeployment(): void {
    $build = $this->createPreviewSiteBuild();
    $state = \Drupal::state();

    $this->assertNull($state->get(PreviewSiteBuildInterface::BUILDING_STATE_KEY));
    $this->assertNull($state->get(TestGenerate::PREPARE_STEP));
    $build->startDeployment($state);
    $this->assertTrue($build->get('artifacts')->isEmpty());
    $this->assertTrue($build->get('processed_paths')->isEmpty());
    $this->assertEquals('Starting deployment', $build->log->value);
    $this->assertEquals(PreviewSiteBuildInterface::STATUS_BUILDING, $build->getStatus());
    $this->assertEquals($build->uuid(), $state->get(PreviewSiteBuildInterface::BUILDING_STATE_KEY));
    $this->assertTrue($state->get(TestGenerate::PREPARE_STEP));
    $this->expectException(GenerationInProgressException::class);
    $build->startDeployment($state);
  }

  /**
   * Tests finishing deployment.
   */
  public function testFinishDeployment(): void {
    $state = \Drupal::state();
    $file = $this->getTestFile();
    $build = $this->createPreviewSiteBuild([
      'artifacts' => $file->id(),
    ]);
    $time = $this->prophesize(TimeInterface::class);
    $now = time();
    $time->getCurrentTime()->willReturn($now);
    $time->getRequestTime()->willReturn($now);
    $this->container->set('datetime.time', $time->reveal());
    $return = $build->finishDeployment($state)->getArtifactIds();
    $this->assertEquals([$file->id()], $return);
    $this->assertNull($state->get(PreviewSiteBuildInterface::BUILDING_STATE_KEY));
    $this->assertEquals(PreviewSiteBuildInterface::STATUS_BUILT, $build->getStatus());
    $this->assertEquals($now, $build->deployed->value);
    $log_entries = array_column($build->get('log')->getValue(), 'value');
    $this->assertEquals('Finishing deployment', end($log_entries));
  }

  /**
   * Tests finishing deployment that previously failed.
   */
  public function testFinishingDeploymentWhilstFailed(): void {
    $state = \Drupal::state();
    $build = $this->createPreviewSiteBuild();
    $build->status = PreviewSiteBuildInterface::STATUS_FAILED;
    $build->finishDeployment($state);
    $this->assertEquals(PreviewSiteBuildInterface::STATUS_FAILED, $build->getStatus());
  }

  /**
   * Tests deployment failed.
   */
  public function testDeploymentFailed(): void {
    $state = \Drupal::state();
    $build = $this->createPreviewSiteBuild();
    $build->startDeployment($state);
    $this->assertEquals($build->uuid(), $state->get(PreviewSiteBuildInterface::BUILDING_STATE_KEY));
    $build->deploymentFailed($state, TRUE);
    $log_entries = array_column($build->get('log')->getValue(), 'value');
    $this->assertNull($state->get(PreviewSiteBuildInterface::BUILDING_STATE_KEY));
    $this->assertEquals('Deployment failed', end($log_entries));
    $this->assertTrue($build->isFailed());
  }

  /**
   * Tests build contents.
   */
  public function testBuildContents(): void {
    $vocabulary = $this->createVocabulary();
    $term = $this->createTerm($vocabulary);
    $build = $this->createPreviewSiteBuild([
      'contents' => [$term],
    ]);
    $this->assertEquals([$term->id()], $build->getMatchingContents([$term->id()], 'taxonomy_term'));
    $this->assertEquals([$term->id()], $build->getContentsOfType('taxonomy_term'));
    $this->assertEquals([], $build->getMatchingContents([
      -3,
      -2,
      -1,
    ], 'taxonomy_term'));
  }

  /**
   * Tests build artifacts.
   */
  public function testAddingArtifacts(): void {
    $file = $this->getTestFile('html', 1);
    $build = $this->createPreviewSiteBuild(['artifacts' => NULL]);
    $build->addArtifact($file);
    $this->assertEquals($file->id(), $build->artifacts->target_id);
  }

  /**
   * Tests keeping track of processed paths.
   */
  public function testProcessedPaths(): void {
    $build = $this->createPreviewSiteBuild();
    $path = 'some/path';
    $this->assertFalse($build->hasPathBeenProcessed($path));
    $build->markPathAsProcessed($path);
    $this->assertTrue($build->hasPathBeenProcessed($path));
  }

  /**
   * Tests get artifact base-path.
   */
  public function testGetArtifactBasePath(): void {
    $build = $this->createPreviewSiteBuild();
    $this->assertEquals('public://', $build->getArtifactBasePath());
  }

  /**
   * Tests getExpiryDate.
   */
  public function testGetExpiryDate(): void {
    $time = new \DateTime('now', new \DateTimeZone('UTC'));
    $build = $this->createPreviewSiteBuild([
      'expiry_date' => $time->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT),
    ]);
    $this->assertEquals($time->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT), $build->getExpiryDate()->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT));
  }

  /**
   * Tests decommissioning a preview site build.
   */
  public function testDecomission(): void {
    $build = $this->createPreviewSiteBuild();
    $state = \Drupal::state();
    $this->assertNull($state->get(TestDeploy::DECOMISSION_STEP));
    $build->decomission();
    $this->assertEquals(PreviewSiteBuildInterface::STATUS_DECOMMISSIONED, $build->getStatus());
    $this->assertTrue($state->get(TestDeploy::DECOMISSION_STEP));
  }

  /**
   * Tests deleting a preview site build.
   */
  public function testDelete(): void {
    $build = $this->createPreviewSiteBuild();
    $state = \Drupal::state();
    $this->assertNull($state->get(TestDeploy::DELETE_STEP));
    $build->delete();
    $this->assertTrue($state->get(TestDeploy::DELETE_STEP));
    $this->assertNull(PreviewSiteBuild::load($build->id()));
  }

  /**
   * Tests ::getArtifacts.
   */
  public function testGetArtifacts(): void {
    $files = [
      $this->getTestFile(),
      $this->getTestFile('html', 1),
    ];
    $build = $this->createPreviewSiteBuild([
      'artifacts' => $files,
    ]);
    $artifacts = iterator_to_array($build->getArtifacts());
    $this->assertCount(2, $artifacts);
    $get_uuids = function (FileInterface $file) {
      return $file->uuid();
    };
    $this->assertEquals(array_map($get_uuids, $files), array_map($get_uuids, $artifacts));
  }

  /**
   * Tests ::getItemLinks.
   */
  public function testGetItemLinks(): void {
    $entity = $this->createTerm($this->createVocabulary());
    $build = $this->createPreviewSiteBuild([
      'contents' => $entity,
      'status' => PreviewSiteBuildInterface::STATUS_BUILT,
    ]);
    $this->assertEquals([
      'item_0' => [
        'title' => $entity->label(),
        'weight' => 0,
        'url' => Url::fromUri($build->getDeploymentBaseUri() . $build->uuid() . $entity->toUrl()->toString() . '/index.html'),
      ],
    ], $build->getItemLinks());
  }

}

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

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