View source
<?php
namespace Drupal\Tests\minisite\Functional;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\Random;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\file\Entity\File;
use Drupal\file\FileInterface;
use Drupal\minisite\Asset;
use Drupal\minisite\LegacyWrapper;
use Drupal\minisite\Minisite;
use Drupal\node\Entity\Node;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\field_ui\Traits\FieldUiTestTrait;
use Drupal\Tests\minisite\Traits\FixtureTrait;
abstract class MinisiteTestBase extends BrowserTestBase {
use FixtureTrait;
use FieldCreationTrait;
use FieldUiTestTrait;
use StringTranslationTrait;
protected static $modules = [
'node',
'file',
'field',
'field_ui',
'path',
'minisite',
];
protected $defaultTheme = 'stark';
protected $adminUser;
protected $contentType = 'article';
protected $adminUserPermissions = [
'access content',
'access administration pages',
'administer site configuration',
'administer users',
'administer permissions',
'administer content types',
'administer node fields',
'administer node display',
'administer nodes',
'bypass node access',
'administer url aliases',
];
protected function setUp() {
parent::setUp();
$this
->fixtureSetUp();
$this->adminUser = $this
->drupalCreateUser($this->adminUserPermissions);
$this
->drupalLogin($this->adminUser);
$this
->drupalCreateContentType([
'type' => $this->contentType,
'name' => 'Article',
]);
}
protected function tearDown() {
parent::tearDown();
$this
->fixtureTearDown();
}
protected function screenshot() {
$base_directory = '/sites/simpletest/browser_output';
$directory = DRUPAL_ROOT . $base_directory;
if (!is_dir($directory)) {
mkdir($directory, 0777, TRUE);
}
$current_url = substr(Html::cleanCssIdentifier($this
->getSession()
->getCurrentUrl()), 100);
$filename = uniqid() . '_' . $current_url . '.html';
$full_filename = file_create_filename($filename, $directory);
$screenshot = $this
->getSession()
->getPage()
->getContent();
file_put_contents($full_filename, $screenshot);
$url = $GLOBALS['base_url'] . $base_directory . '/' . $filename;
$this
->fail($url);
}
public function uploadNodeFile(FileInterface $file, $field_name, $nid_or_type, $new_revision = TRUE, array $extras = []) {
return $this
->uploadNodeFiles([
$file,
], $field_name, $nid_or_type, $new_revision, $extras);
}
public function uploadNodeFiles(array $files, $field_name, $nid_or_type, $new_revision = TRUE, array $extras = []) {
$edit = [
'title[0][value]' => $this
->randomMachineName(),
'revision' => (string) (int) $new_revision,
];
$node_storage = $this->container
->get('entity_type.manager')
->getStorage('node');
if (is_numeric($nid_or_type)) {
$nid = $nid_or_type;
$node_storage
->resetCache([
$nid,
]);
$node = $node_storage
->load($nid);
}
else {
$extras['type'] = $nid_or_type;
$node = $this
->drupalCreateNode($extras);
$nid = $node
->id();
$node
->setNewRevision();
$node
->save();
$node_storage
->resetCache([
$nid,
]);
$node = $node_storage
->load($nid);
$this
->assertNotEqual($nid, $node
->getRevisionId(), 'Node revision exists.');
}
$this
->drupalGet("node/{$nid}/edit");
$page = $this
->getSession()
->getPage();
$field_storage = FieldStorageConfig::loadByName('node', $field_name);
$field_num = count($node->{$field_name});
foreach ($files as $i => $file) {
$delta = $field_num + $i;
$file_path = $this->container
->get('file_system')
->realpath($file
->getFileUri());
$name = 'files[' . $field_name . '_' . $delta . ']';
if ($field_storage
->getCardinality() != 1) {
$name .= '[]';
}
if (count($files) == 1) {
$edit[$name] = $file_path;
}
else {
$page
->attachFileToField($name, $file_path);
$this
->drupalPostForm(NULL, [], $this
->t('Upload'));
}
}
$this
->drupalPostForm(NULL, $edit, $this
->t('Save'));
return $nid;
}
public static function assertFileUriExists($filename, $message = '') {
$message = isset($message) ? $message : new FormattableMarkup('File %file exists on the disk.', [
'%file' => $filename
->getFileUri(),
]);
$filename = $filename instanceof FileInterface ? $filename
->getFileUri() : $filename;
parent::assertFileExists($filename, $message);
}
public function assertFileEntryExists($file, $message = NULL) {
$this->container
->get('entity_type.manager')
->getStorage('file')
->resetCache();
$db_file = File::load($file
->id());
$message = isset($message) ? $message : new FormattableMarkup('File %file exists in database at the correct path.', [
'%file' => $file
->getFileUri(),
]);
$this
->assertEqual($db_file
->getFileUri(), $file
->getFileUri(), $message);
}
public function assertFileEntryNotExists($file, $message = NULL) {
$this->container
->get('entity_type.manager')
->getStorage('file')
->resetCache();
$db_file = File::load($file
->id());
$message = isset($message) ? $message : new FormattableMarkup('File %file does not exists in database at the correct path.', [
'%file' => $file
->getFileUri(),
]);
$this
->assertNull($db_file, $message);
}
protected function convertToFileEntity($absolute_file_path) {
$archive_file = basename($absolute_file_path);
$file = new \stdClass();
$file->uri = $absolute_file_path;
$file->filename = $archive_file;
$file->name = pathinfo($archive_file, PATHINFO_FILENAME);
$file->filesize = filesize($file->uri);
return File::create((array) $file);
}
public function getTestFilesStubValid() {
return [
'parent' . DIRECTORY_SEPARATOR . 'index.html' => $this
->fixtureHtmlPage('Index page', $this
->fixtureLink('Go to Page 1', 'page1.html')),
'parent' . DIRECTORY_SEPARATOR . 'page1.html' => $this
->fixtureHtmlPage('Page 1', $this
->fixtureLink('Go to Page 2', 'page2.html')),
'parent' . DIRECTORY_SEPARATOR . 'page2.html' => $this
->fixtureHtmlPage('Page 2'),
'parent' . DIRECTORY_SEPARATOR . 'image.jpg' => file_get_contents($this
->getFixtureFileDir() . DIRECTORY_SEPARATOR . 'example.jpeg'),
];
}
public function getTestArchiveValid() {
$archive_file_absolute = $this
->fixtureCreateArchive($this
->getTestFilesStubValid());
return $this
->convertToFileEntity($archive_file_absolute);
}
public function getTestArchiveInvalidFormat() {
$filename = $this
->fixtureCreateFile('invalid.zip', rand(1, 9));
return $this
->convertToFileEntity($filename);
}
public function assertArchiveFileExist(FileInterface $file) {
$this
->assertFileEntryExists($file, 'Archive file entry exists');
$this
->assertFileUriExists(Minisite::getCommonArchiveDir() . DIRECTORY_SEPARATOR . $file
->getFilename(), 'Archive file exists');
}
public function assertArchiveFileNotExist(FileInterface $file) {
$this
->assertFileEntryNotExists($file, 'Archive file entry does not');
$this
->assertFileNotExists(Minisite::getCommonArchiveDir() . DIRECTORY_SEPARATOR . $file
->getFilename(), 'Archive file does not exist');
}
public function assertAssetFilesExist($files) {
$actual_files = array_keys(LegacyWrapper::scanDirectory(Minisite::getCommonAssetDir(), '/.*/'));
$this
->assertEquals(count($actual_files), count($files));
foreach ($files as $test_file) {
$found_files = array_filter($actual_files, function ($value) use ($test_file) {
return substr($value, -strlen($test_file)) === $test_file;
});
$this
->assertTrue(count($found_files) == 1, 'Asset file found in the list of created files');
}
}
public function assertAssetFilesNotExist($files) {
$actual_files = array_keys(LegacyWrapper::scanDirectory(Minisite::getCommonAssetDir(), '/.*/'));
foreach ($files as $test_file) {
$found_files = array_filter($actual_files, function ($value) use ($test_file) {
return substr($value, -strlen($test_file)) === $test_file;
});
$this
->assertTrue(empty($found_files), 'Asset file does not exist');
}
}
public function createFieldAndNode($node_type, $node_title, $description = NULL, array $edit = []) {
$field_name = 'ms_fn_' . strtolower($this
->randomMachineName(4));
$field_label = 'ms_fl_' . strtolower($this
->randomMachineName(4));
$storage_edit = [
'settings[uri_scheme]' => 'public',
];
$this
->fieldUIAddNewField("admin/structure/types/manage/{$node_type}", $field_name, $field_label, 'minisite', $storage_edit);
$test_archive = $this
->getTestArchiveValid();
\Drupal::service('entity_field.manager')
->clearCachedFieldDefinitions();
$edit1 = [
'files[field_' . $field_name . '_' . 0 . ']' => $test_archive
->getFileUri(),
];
$this
->drupalPostForm("node/add/{$node_type}", $edit1, $this
->t('Save'));
$edit2 = [
'title[0][value]' => $node_title,
'field_' . $field_name . '[' . 0 . '][options][alias_status]' => TRUE,
];
$edit = $edit2 + $edit;
if (!empty($description)) {
$edit['field_' . $field_name . '[' . 0 . '][description]'] = $description;
}
$this
->drupalPostForm(NULL, $edit, $this
->t('Save'));
return $field_name;
}
public function assertMinisiteUploaded($node, $field_name, $test_archive_assets) {
$archive_file = $this
->getUploadedArchiveFile($node, $field_name);
$this
->assertArchiveFileExist($archive_file);
$this
->assertAssetFilesExist($test_archive_assets);
}
public function assertMinisiteRemoved($node, $field_name, $test_archive_assets) {
$archive_file = $this
->getUploadedArchiveFile($node, $field_name);
$this
->assertArchiveFileNotExist($archive_file);
$this
->assertAssetFilesNotExist($test_archive_assets);
$this
->assertFileEntryNotExists($archive_file);
foreach ($test_archive_assets as $test_archive_asset) {
$this
->assertNull(Asset::loadByUri($test_archive_asset));
}
}
public function getUploadedArchiveFile(Node $node, $field_name) {
return File::load($node->{'field_' . $field_name}->target_id);
}
public function browseFixtureMinisite($node, $description) {
$this
->drupalGet('node/' . $node
->id());
$this
->assertResponse(200);
$this
->assertLink($description);
$this
->clickLink($description);
$this
->assertText('Index page');
$this
->assertLink('Go to Page 1');
$this
->clickLink('Go to Page 1');
$this
->assertText('Page 1');
$this
->assertLink('Go to Page 2');
$this
->clickLink('Go to Page 2');
$this
->assertResponse(200);
$this
->assertHeader('Content-Type', 'text/html; charset=UTF-8');
$this
->assertText('Page 2');
}
public function browseFixtureMinisiteAliased($alias, $description, $assets_paths) {
$this
->drupalGet($alias);
$this
->assertResponse(200);
$this
->assertLink($description);
$this
->assertLinkByHref($alias . '/' . $assets_paths[0]);
$this
->clickLink($description);
$this
->assertUrl($alias . '/' . $assets_paths[0]);
$this
->assertResponse(200);
$this
->assertHeader('Content-Type', 'text/html; charset=UTF-8');
$this
->assertText('Index page');
$this
->assertLink('Go to Page 1');
$this
->clickLink('Go to Page 1');
$this
->assertResponse(200);
$this
->assertHeader('Content-Type', 'text/html; charset=UTF-8');
$this
->assertText('Page 1');
$this
->assertUrl($alias . '/' . $assets_paths[1]);
$this
->assertLink('Go to Page 2');
$this
->clickLink('Go to Page 2');
$this
->assertResponse(200);
$this
->assertHeader('Content-Type', 'text/html; charset=UTF-8');
$this
->assertText('Page 2');
$this
->assertUrl($alias . '/' . $assets_paths[2]);
$this
->drupalGet($alias . '/' . $assets_paths[1], [
'query' => [
'param' => 'val',
],
'fragment' => 'someid',
]);
$this
->assertResponse(200);
$this
->assertHeader('Content-Type', 'text/html; charset=UTF-8');
$this
->drupalGet($alias . '/' . $assets_paths[3]);
$this
->assertResponse(200);
$this
->assertHeader('Content-Type', 'image/jpeg');
$this
->assertHeader('Content-Length', (string) filesize($this
->getFixtureFileDir() . DIRECTORY_SEPARATOR . 'example.jpeg'));
}
protected function getStubAssetPath() {
$randomizer = new Random();
$prefix = 'public://minisite/static/24c22dd1-2cf1-47ae-ac8a-23a7ff8b86c5/';
$suffix = '.html';
$dir_path = $randomizer
->name(10) . '/';
$file_path = $randomizer
->name(2048 - strlen($dir_path) - strlen($prefix) - strlen($suffix)) . $suffix;
$path = $prefix . $dir_path . $file_path;
return $path;
}
}