View source
<?php
namespace Drupal\libraries\Tests;
use Drupal\Component\Utility\Html;
use Drupal\Tests\BrowserTestBase;
class LibrariesWebTest extends BrowserTestBase {
protected $profile = 'testing';
protected $defaultTheme = 'stable';
public static $modules = [
'libraries',
'libraries_test',
];
protected $urlAssembler;
protected $state;
protected function setUp() {
parent::setUp();
$this->urlAssembler = $this->container
->get('unrouted_url_assembler');
$this->state = $this->container
->get('state');
}
public function testLibrariesDetectDependencies() {
$library = [
'name' => 'Example',
'dependencies' => [
'Example missing',
],
];
libraries_detect_dependencies($library);
$this
->assertEqual($library['error'], 'missing dependency', 'libraries_detect_dependencies() detects missing dependency');
$error_message = t('The %dependency library, which the %library library depends on, is not installed.', [
'%dependency' => 'Example missing',
'%library' => $library['name'],
]);
$this
->verbose("Expected:<br>{$error_message}");
$this
->verbose('Actual:<br>' . $library['error message']);
$this
->assertEqual($library['error message'], $error_message, 'Correct error message for a missing dependency');
$version = '1.1';
$compatible = [
'1.1',
'<=1.1',
'>=1.1',
'<1.2',
'<2.0',
'>1.0',
'>1.0-rc1',
'>1.0-beta2',
'>1.0-alpha3',
'>0.1',
'<1.2, >1.0',
'>0.1, <=1.1',
];
$incompatible = [
'1.2',
'2.0',
'<1.1',
'>1.1',
'<=1.0',
'<=1.0-rc1',
'<=1.0-beta2',
'<=1.0-alpha3',
'>=1.2',
'<1.1, >0.9',
'>=0.1, <1.1',
];
$library = [
'name' => 'Example',
];
foreach ($compatible as $version_string) {
$library['dependencies'][0] = "example_dependency ({$version_string})";
$library['installed'] = TRUE;
libraries_detect_dependencies($library);
$this
->assertTrue($library['installed'], "libraries_detect_dependencies() detects compatible version string: '{$version_string}' is compatible with '{$version}'");
}
foreach ($incompatible as $version_string) {
$library['dependencies'][0] = "example_dependency ({$version_string})";
$library['installed'] = TRUE;
unset($library['error'], $library['error message']);
libraries_detect_dependencies($library);
$this
->assertEqual($library['error'], 'incompatible dependency', "libraries_detect_dependencies() detects incompatible version strings: '{$version_string}' is incompatible with '{$version}'");
}
$error_message = t('The version %dependency_version of the %dependency library is not compatible with the %library library.', [
'%dependency_version' => $version,
'%dependency' => 'Example dependency',
'%library' => $library['name'],
]);
$this
->verbose("Expected:<br>{$error_message}");
$this
->verbose('Actual:<br>' . $library['error message']);
$this
->assertEqual($library['error message'], $error_message, 'Correct error message for an incompatible dependency');
}
public function testLibrariesScanInfoFiles() {
$expected = [
'example_info_file' => (object) [
'uri' => drupal_get_path('module', 'libraries') . '/tests/example/example_info_file.libraries.info.yml',
'filename' => 'example_info_file.libraries.info.yml',
'name' => 'example_info_file.libraries.info',
],
];
$actual = libraries_scan_info_files();
$this
->verbose('Expected:<pre>' . var_export($expected, TRUE) . '</pre>');
$this
->verbose('Actual:<pre>' . var_export($actual, TRUE) . '</pre>');
$this
->assertEqual($actual, $expected, 'libraries_scan_info_files() correctly finds the example info file.');
$this
->verbose('<pre>' . var_export(libraries_scan_info_files(), TRUE) . '</pre>');
}
public function testLibrariesInfo() {
$expected = [
'name' => 'Example files',
'library path' => drupal_get_path('module', 'libraries') . '/tests/example',
'version' => '1',
'files' => [
'js' => [
'example_1.js' => [],
],
'css' => [
'example_1.css' => [],
],
'php' => [
'example_1.php' => [],
],
],
'module' => 'libraries_test',
];
libraries_info_defaults($expected, 'example_files');
$library = libraries_info('example_files');
$this
->verbose('Expected:<pre>' . var_export($expected, TRUE) . '</pre>');
$this
->verbose('Actual:<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertEqual($library, $expected, 'Library information is correctly gathered.');
$expected = [
'name' => 'Example info file',
'info file' => drupal_get_path('module', 'libraries') . '/tests/example/example_info_file.libraries.info.yml',
];
libraries_info_defaults($expected, 'example_info_file');
$library = libraries_info('example_info_file');
unset($library['core'], $library['datestamp'], $library['project'], $library['version']);
$this
->verbose('Expected:<pre>' . var_export($expected, TRUE) . '</pre>');
$this
->verbose('Actual:<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertEqual($library, $expected, 'Library specified with an .info file found');
}
public function testLibrariesDetect() {
$library = libraries_detect('example_missing');
$this
->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertEqual($library['error'], 'not found', 'Missing library not found.');
$error_message = t('The %library library could not be found.', [
'%library' => $library['name'],
]);
$this
->assertEqual($library['error message'], $error_message, 'Correct error message for a missing library.');
$library = libraries_detect('example_undetected_version');
$this
->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertEqual($library['error'], 'not detected', 'Undetected version detected as such.');
$error_message = t('The version of the %library library could not be detected.', [
'%library' => $library['name'],
]);
$this
->assertEqual($library['error message'], $error_message, 'Correct error message for a library with an undetected version.');
$library = libraries_detect('example_unsupported_version');
$this
->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertEqual($library['error'], 'not supported', 'Unsupported version detected as such.');
$error_message = t('The installed version %version of the %library library is not supported.', [
'%version' => $library['version'],
'%library' => $library['name'],
]);
$this
->assertEqual($library['error message'], $error_message, 'Correct error message for a library with an unsupported version.');
$library = libraries_detect('example_supported_version');
$this
->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertEqual($library['installed'], TRUE, 'Supported library version found.');
$library = libraries_detect('example_default_version_callback');
$this
->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertEqual($library['version'], '1', 'Expected version returned by default version callback.');
$library = libraries_detect('example_multiple_parameter_version_callback');
$this
->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertEqual($library['version'], '1', 'Expected version returned by multiple parameter version callback.');
$library = libraries_detect('example_files');
$files = [
'js' => [
'example_1.js' => [],
],
'css' => [
'example_1.css' => [],
],
'php' => [
'example_1.php' => [],
],
];
$this
->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertEqual($library['files'], $files, 'Top-level files property works.');
$library = libraries_detect('example_versions');
$files = [
'js' => [
'example_2.js' => [],
],
'css' => [
'example_2.css' => [],
],
'php' => [
'example_2.php' => [],
],
];
$this
->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertEqual($library['files'], $files, 'Version-specific library files found.');
$library = libraries_detect('example_variant_missing');
$this
->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertEqual($library['variants']['example_variant']['error'], 'not found', 'Missing variant not found');
$error_message = t('The %variant variant of the %library library could not be found.', [
'%variant' => 'example_variant',
'%library' => 'Example variant missing',
]);
$this
->assertEqual($library['variants']['example_variant']['error message'], $error_message, 'Correct error message for a missing variant.');
$library = libraries_detect('example_variant');
$this
->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertEqual($library['variants']['example_variant']['installed'], TRUE, 'Existing variant found.');
}
public function _testLibrariesLoad() {
$library = libraries_load('example_dependency_missing');
$this
->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertFalse($library['loaded'], 'Library with missing dependency cannot be loaded');
$library = libraries_load('example_dependency_incompatible');
$this
->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertFalse($library['loaded'], 'Library with incompatible dependency cannot be loaded');
$library = libraries_load('example_dependency_compatible');
$this
->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertEqual($library['loaded'], 1, 'Library with compatible dependency is loaded');
$loaded =& drupal_static('libraries_load');
$this
->verbose('<pre>' . var_export($loaded, TRUE) . '</pre>');
$this
->assertEqual($loaded['example_dependency']['loaded'], 1, 'Dependency library is also loaded');
}
public function testCallbacks() {
$expected = [
'name' => 'Example callback',
'library path' => drupal_get_path('module', 'libraries') . '/tests/example',
'version' => '1',
'versions' => [
'1' => [
'variants' => [
'example_variant' => [
'info callback' => 'not applied',
'pre-detect callback' => 'not applied',
'post-detect callback' => 'not applied',
'pre-load callback' => 'not applied',
'post-load callback' => 'not applied',
],
],
'info callback' => 'not applied',
'pre-detect callback' => 'not applied',
'post-detect callback' => 'not applied',
'pre-load callback' => 'not applied',
'post-load callback' => 'not applied',
],
],
'variants' => [
'example_variant' => [
'info callback' => 'not applied',
'pre-detect callback' => 'not applied',
'post-detect callback' => 'not applied',
'pre-load callback' => 'not applied',
'post-load callback' => 'not applied',
],
],
'callbacks' => [
'info' => [
'_libraries_test_info_callback',
],
'pre-detect' => [
'_libraries_test_pre_detect_callback',
],
'post-detect' => [
'_libraries_test_post_detect_callback',
],
'pre-load' => [
'_libraries_test_pre_load_callback',
],
'post-load' => [
'_libraries_test_post_load_callback',
],
],
'info callback' => 'not applied',
'pre-detect callback' => 'not applied',
'post-detect callback' => 'not applied',
'pre-load callback' => 'not applied',
'post-load callback' => 'not applied',
'module' => 'libraries_test',
];
libraries_info_defaults($expected, 'example_callback');
$expected['info callback'] = 'applied (top-level)';
$expected['versions']['1']['info callback'] = 'applied (version 1)';
$expected['versions']['1']['variants']['example_variant']['info callback'] = 'applied (version 1, variant example_variant)';
$expected['variants']['example_variant']['info callback'] = 'applied (variant example_variant)';
$library = libraries_info('example_callback');
$this
->verbose('Expected:<pre>' . var_export($expected, TRUE) . '</pre>');
$this
->verbose('Actual:<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertEqual($library, $expected, 'Prepare callback was applied correctly.');
unset($expected['versions']);
$expected['installed'] = TRUE;
$expected['info callback'] = 'applied (version 1)';
$expected['variants']['example_variant']['installed'] = TRUE;
$expected['variants']['example_variant']['info callback'] = 'applied (version 1, variant example_variant)';
$expected['pre-detect callback'] = 'applied (version 1)';
$expected['post-detect callback'] = 'applied (top-level)';
$expected['variants']['example_variant']['pre-detect callback'] = 'applied (version 1, variant example_variant)';
$expected['variants']['example_variant']['post-detect callback'] = 'applied (variant example_variant)';
$library = libraries_detect('example_callback');
$this
->verbose('Expected:<pre>' . var_export($expected, TRUE) . '</pre>');
$this
->verbose('Actual:<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertEqual($library, $expected, 'Detect callback was applied correctly.');
unset($expected['variants']);
$expected['loaded'] = 0;
$expected['pre-load callback'] = 'applied (top-level)';
$expected['post-load callback'] = 'applied (top-level)';
$library = libraries_load('example_callback');
$this
->verbose('Expected:<pre>' . var_export($expected, TRUE) . '</pre>');
$this
->verbose('Actual:<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertEqual($library, $expected, 'Pre-load and post-load callbacks were applied correctly.');
drupal_static_reset('libraries_load');
$expected['info callback'] = 'applied (version 1, variant example_variant)';
$expected['pre-detect callback'] = 'applied (version 1, variant example_variant)';
$expected['post-detect callback'] = 'applied (variant example_variant)';
$library = libraries_load('example_callback', 'example_variant');
$this
->verbose('Expected:<pre>' . var_export($expected, TRUE) . '</pre>');
$this
->verbose('Actual:<pre>' . var_export($library, TRUE) . '</pre>');
$this
->assertEqual($library, $expected, 'Pre-detect and post-detect callbacks were applied correctly to a variant.');
}
public function _testLibrariesOutput() {
$this
->drupalGet('libraries_test/files');
$this
->assertLibraryFiles('example_1', 'File loading');
$this
->drupalGet('libraries_test/integration_files');
$this
->assertRaw('libraries_test.js', 'Integration file loading: libraries_test.js found');
$this
->assertRaw('libraries_test.css', 'Integration file loading: libraries_test.css found');
$this
->assertRaw('libraries_test.inc', 'Integration file loading: libraries_test.inc found');
$this
->drupalGet('libraries_test/versions');
$this
->assertLibraryFiles('example_2', 'Version overloading');
$this
->drupalGet('libraries_test/variant');
$this
->assertLibraryFiles('example_3', 'Variant loading');
$this
->drupalGet('libraries_test/versions_and_variants');
$this
->assertLibraryFiles('example_4', 'Concurrent version and variant overloading');
\Drupal::state()
->set('libraries_test.cache', TRUE);
\Drupal::cache('libraries')
->delete('example_callback');
$this
->drupalGet('libraries_test/cache');
$this
->assertRaw('The <em>info</em> callback group was invoked.', 'Info callback invoked for uncached libraries.');
$this
->assertRaw('The <em>pre-detect</em> callback group was invoked.', 'Pre-detect callback invoked for uncached libraries.');
$this
->assertRaw('The <em>post-detect</em> callback group was invoked.', 'Post-detect callback invoked for uncached libraries.');
$this
->assertRaw('The <em>pre-load</em> callback group was invoked.', 'Pre-load callback invoked for uncached libraries.');
$this
->assertRaw('The <em>post-load</em> callback group was invoked.', 'Post-load callback invoked for uncached libraries.');
$this
->drupalGet('libraries_test/cache');
$this
->assertNoRaw('The <em>info</em> callback group was not invoked.', 'Info callback not invoked for cached libraries.');
$this
->assertNoRaw('The <em>pre-detect</em> callback group was not invoked.', 'Pre-detect callback not invoked for cached libraries.');
$this
->assertNoRaw('The <em>post-detect</em> callback group was not invoked.', 'Post-detect callback not invoked for cached libraries.');
$this
->assertRaw('The <em>pre-load</em> callback group was invoked.', 'Pre-load callback invoked for cached libraries.');
$this
->assertRaw('The <em>post-load</em> callback group was invoked.', 'Post-load callback invoked for cached libraries.');
\Drupal::state()
->set('libraries_test.cache', FALSE);
}
public function assertLibraryFiles($name, $label = '', $extensions = [
'js',
'css',
'php',
]) {
$label = $label !== '' ? "{$label}: " : '';
$names = [
'example_1' => FALSE,
'example_2' => FALSE,
'example_3' => FALSE,
'example_4' => FALSE,
];
$names[$name] = TRUE;
$html = [
'js' => [
'<script src="',
'"></script>',
],
'css' => [
'<link rel="stylesheet" href="',
'" media="all" />',
],
'php' => [
'<li>',
'</li>',
],
];
$html_expected = [];
$html_not_expected = [];
foreach ($names as $name => $expected) {
foreach ($extensions as $extension) {
$filepath = drupal_get_path('module', 'libraries') . "/tests/example/{$name}.{$extension}";
if (in_array($extension, [
'js',
'css',
])) {
$filepath = $this->urlAssembler
->assemble("base://{$filepath}", [
'query' => [
$this->state
->get('system.css_js_query_string') ?: '0' => NULL,
],
'absolute' => TRUE,
]);
}
list($prefix, $suffix) = $html[$extension];
$raw = $prefix . $filepath . $suffix;
if ($expected) {
$html_expected[] = Html::escape($raw);
$this
->assertRaw($raw, "{$label}{$name}.{$extension} found.");
}
else {
$html_not_expected[] = Html::escape($raw);
$this
->assertNoRaw($raw, "{$label}{$name}.{$extension} not found.");
}
}
}
$html_expected = '<ul><li><pre>' . implode('</pre></li><li><pre>', $html_expected) . '</pre></li></ul>';
$html_not_expected = '<ul><li><pre>' . implode('</pre></li><li><pre>', $html_not_expected) . '</pre></li></ul>';
$this
->verbose("Strings of HTML that are expected to be present:{$html_expected}Strings of HTML that are expected to not be present:{$html_not_expected}");
}
}