updated core and modules
This commit is contained in:
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2016-08-03
|
||||
version: '8.1.8'
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1470233790
|
||||
datestamp: 1502903957
|
||||
|
||||
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2016-08-03
|
||||
version: '8.1.8'
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1470233790
|
||||
datestamp: 1502903957
|
||||
|
||||
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2016-08-03
|
||||
version: '8.1.8'
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1470233790
|
||||
datestamp: 1502903957
|
||||
|
||||
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2016-08-03
|
||||
version: '8.1.8'
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1470233790
|
||||
datestamp: 1502903957
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ class UpdateTestController extends ControllerBase {
|
||||
}
|
||||
|
||||
$file = __DIR__ . "/../../$project_name.$availability_scenario.xml";
|
||||
$headers = array('Content-Type' => 'text/xml; charset=utf-8');
|
||||
$headers = ['Content-Type' => 'text/xml; charset=utf-8'];
|
||||
if (!is_file($file)) {
|
||||
// Return an empty response.
|
||||
return new Response('', 200, $headers);
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ class UpdateTestArchiver implements ArchiverInterface {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function extract($path, array $files = array()) {
|
||||
public function extract($path, array $files = []) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class UpdateTestArchiver implements ArchiverInterface {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function listContents() {
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -29,11 +29,11 @@ class TestFileTransferWithSettingsForm extends Local {
|
||||
* Returns a settings form with a text field to input a username.
|
||||
*/
|
||||
public function getSettingsForm() {
|
||||
$form = array();
|
||||
$form['update_test_username'] = array(
|
||||
$form = [];
|
||||
$form['update_test_username'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Update Test Username'),
|
||||
);
|
||||
];
|
||||
return $form;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2016-08-03
|
||||
version: '8.1.8'
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1470233790
|
||||
datestamp: 1502903957
|
||||
|
||||
@@ -20,7 +20,7 @@ use Drupal\Core\Extension\Extension;
|
||||
*/
|
||||
function update_test_system_info_alter(&$info, Extension $file) {
|
||||
$setting = \Drupal::config('update_test.settings')->get('system_info');
|
||||
foreach (array('#all', $file->getName()) as $id) {
|
||||
foreach (['#all', $file->getName()] as $id) {
|
||||
if (!empty($setting[$id])) {
|
||||
foreach ($setting[$id] as $key => $value) {
|
||||
$info[$key] = $value;
|
||||
@@ -44,7 +44,7 @@ function update_test_update_status_alter(&$projects) {
|
||||
$setting = \Drupal::config('update_test.settings')->get('update_status');
|
||||
if (!empty($setting)) {
|
||||
foreach ($projects as $project_name => &$project) {
|
||||
foreach (array('#all', $project_name) as $id) {
|
||||
foreach (['#all', $project_name] as $id) {
|
||||
if (!empty($setting[$id])) {
|
||||
foreach ($setting[$id] as $key => $value) {
|
||||
$project[$key] = $value;
|
||||
@@ -62,11 +62,11 @@ function update_test_filetransfer_info() {
|
||||
// Define a test file transfer method, to ensure that there will always be at
|
||||
// least one method available in the user interface (regardless of the
|
||||
// environment in which the update manager tests are run).
|
||||
return array(
|
||||
'system_test' => array(
|
||||
return [
|
||||
'system_test' => [
|
||||
'title' => t('Update Test FileTransfer'),
|
||||
'class' => 'Drupal\update_test\TestFileTransferWithSettingsForm',
|
||||
'weight' => -20,
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\update\Functional;
|
||||
|
||||
/**
|
||||
* Tests the Update Manager module upload via authorize.php functionality.
|
||||
*
|
||||
* @group update
|
||||
*/
|
||||
class FileTransferAuthorizeFormTest extends UpdateTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['update', 'update_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$admin_user = $this->drupalCreateUser(['administer modules', 'administer software updates', 'administer site configuration']);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
// Create a local cache so the module is not downloaded from drupal.org.
|
||||
$cache_directory = _update_manager_cache_directory(TRUE);
|
||||
$validArchiveFile = __DIR__ . '/../../update_test_new_module/8.x-1.0/update_test_new_module.tar.gz';
|
||||
copy($validArchiveFile, $cache_directory . '/update_test_new_module.tar.gz');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Update Manager module upload via authorize.php functionality.
|
||||
*/
|
||||
public function testViaAuthorize() {
|
||||
// Ensure the that we can select which file transfer backend to use.
|
||||
\Drupal::state()->set('test_uploaders_via_prompt', TRUE);
|
||||
|
||||
// Ensure the module does not already exist.
|
||||
$this->drupalGet('admin/modules');
|
||||
$this->assertNoText('Update test new module');
|
||||
|
||||
$edit = [
|
||||
// This project has been cached in the test's setUp() method.
|
||||
'project_url' => 'https://ftp.drupal.org/files/projects/update_test_new_module.tar.gz',
|
||||
];
|
||||
$this->drupalPostForm('admin/modules/install', $edit, t('Install'));
|
||||
$edit = [
|
||||
'connection_settings[authorize_filetransfer_default]' => 'system_test',
|
||||
'connection_settings[system_test][update_test_username]' => $this->randomMachineName(),
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Continue'));
|
||||
$this->assertText(t('Installation was completed successfully.'));
|
||||
|
||||
// Ensure the module is available to install.
|
||||
$this->drupalGet('admin/modules');
|
||||
$this->assertText('Update test new module');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,441 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\update\Functional;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Core\Utility\ProjectInfo;
|
||||
|
||||
/**
|
||||
* Tests how the Update Manager module handles contributed modules and themes in
|
||||
* a series of functional tests using mock XML data.
|
||||
*
|
||||
* @group update
|
||||
*/
|
||||
class UpdateContribTest extends UpdateTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['update_test', 'update', 'aaa_update_test', 'bbb_update_test', 'ccc_update_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$admin_user = $this->drupalCreateUser(['administer site configuration']);
|
||||
$this->drupalLogin($admin_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests when there is no available release data for a contrib module.
|
||||
*/
|
||||
public function testNoReleasesAvailable() {
|
||||
$system_info = [
|
||||
'#all' => [
|
||||
'version' => '8.0.0',
|
||||
],
|
||||
'aaa_update_test' => [
|
||||
'project' => 'aaa_update_test',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
],
|
||||
];
|
||||
$this->config('update_test.settings')->set('system_info', $system_info)->save();
|
||||
$this->refreshUpdateStatus(['drupal' => '0.0', 'aaa_update_test' => 'no-releases']);
|
||||
$this->drupalGet('admin/reports/updates');
|
||||
// Cannot use $this->standardTests() because we need to check for the
|
||||
// 'No available releases found' string.
|
||||
$this->assertRaw('<h3>' . t('Drupal core') . '</h3>');
|
||||
$this->assertRaw(\Drupal::l(t('Drupal'), Url::fromUri('http://example.com/project/drupal')));
|
||||
$this->assertText(t('Up to date'));
|
||||
$this->assertRaw('<h3>' . t('Modules') . '</h3>');
|
||||
$this->assertNoText(t('Update available'));
|
||||
$this->assertText(t('No available releases found'));
|
||||
$this->assertNoRaw(\Drupal::l(t('AAA Update test'), Url::fromUri('http://example.com/project/aaa_update_test')));
|
||||
|
||||
$available = update_get_available();
|
||||
$this->assertFalse(isset($available['aaa_update_test']['fetch_status']), 'Results are cached even if no releases are available.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the basic functionality of a contrib module on the status report.
|
||||
*/
|
||||
public function testUpdateContribBasic() {
|
||||
$project_link = \Drupal::l(t('AAA Update test'), Url::fromUri('http://example.com/project/aaa_update_test'));
|
||||
$system_info = [
|
||||
'#all' => [
|
||||
'version' => '8.0.0',
|
||||
],
|
||||
'aaa_update_test' => [
|
||||
'project' => 'aaa_update_test',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
],
|
||||
];
|
||||
$this->config('update_test.settings')->set('system_info', $system_info)->save();
|
||||
$this->refreshUpdateStatus(
|
||||
[
|
||||
'drupal' => '0.0',
|
||||
'aaa_update_test' => '1_0',
|
||||
]
|
||||
);
|
||||
$this->standardTests();
|
||||
$this->assertText(t('Up to date'));
|
||||
$this->assertRaw('<h3>' . t('Modules') . '</h3>');
|
||||
$this->assertNoText(t('Update available'));
|
||||
$this->assertRaw($project_link, 'Link to aaa_update_test project appears.');
|
||||
|
||||
// Since aaa_update_test is installed the fact it is hidden and in the
|
||||
// Testing package means it should not appear.
|
||||
$system_info['aaa_update_test']['hidden'] = TRUE;
|
||||
$this->config('update_test.settings')->set('system_info', $system_info)->save();
|
||||
$this->refreshUpdateStatus(
|
||||
[
|
||||
'drupal' => '0.0',
|
||||
'aaa_update_test' => '1_0',
|
||||
]
|
||||
);
|
||||
$this->assertNoRaw($project_link, 'Link to aaa_update_test project does not appear.');
|
||||
|
||||
// A hidden and installed project not in the Testing package should appear.
|
||||
$system_info['aaa_update_test']['package'] = 'aaa_update_test';
|
||||
$this->config('update_test.settings')->set('system_info', $system_info)->save();
|
||||
$this->refreshUpdateStatus(
|
||||
[
|
||||
'drupal' => '0.0',
|
||||
'aaa_update_test' => '1_0',
|
||||
]
|
||||
);
|
||||
$this->assertRaw($project_link, 'Link to aaa_update_test project appears.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that contrib projects are ordered by project name.
|
||||
*
|
||||
* If a project contains multiple modules, we want to make sure that the
|
||||
* available updates report is sorted by the parent project names, not by the
|
||||
* names of the modules included in each project. In this test case, we have
|
||||
* two contrib projects, "BBB Update test" and "CCC Update test". However, we
|
||||
* have a module called "aaa_update_test" that's part of the "CCC Update test"
|
||||
* project. We need to make sure that we see the "BBB" project before the
|
||||
* "CCC" project, even though "CCC" includes a module that's processed first
|
||||
* if you sort alphabetically by module name (which is the order we see things
|
||||
* inside system_rebuild_module_data() for example).
|
||||
*/
|
||||
public function testUpdateContribOrder() {
|
||||
// We want core to be version 8.0.0.
|
||||
$system_info = [
|
||||
'#all' => [
|
||||
'version' => '8.0.0',
|
||||
],
|
||||
// All the rest should be visible as contrib modules at version 8.x-1.0.
|
||||
|
||||
// aaa_update_test needs to be part of the "CCC Update test" project,
|
||||
// which would throw off the report if we weren't properly sorting by
|
||||
// the project names.
|
||||
'aaa_update_test' => [
|
||||
'project' => 'ccc_update_test',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
],
|
||||
|
||||
// This should be its own project, and listed first on the report.
|
||||
'bbb_update_test' => [
|
||||
'project' => 'bbb_update_test',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
],
|
||||
|
||||
// This will contain both aaa_update_test and ccc_update_test, and
|
||||
// should come after the bbb_update_test project.
|
||||
'ccc_update_test' => [
|
||||
'project' => 'ccc_update_test',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
],
|
||||
];
|
||||
$this->config('update_test.settings')->set('system_info', $system_info)->save();
|
||||
$this->refreshUpdateStatus(['drupal' => '0.0', '#all' => '1_0']);
|
||||
$this->standardTests();
|
||||
// We're expecting the report to say all projects are up to date.
|
||||
$this->assertText(t('Up to date'));
|
||||
$this->assertNoText(t('Update available'));
|
||||
// We want to see all 3 module names listed, since they'll show up either
|
||||
// as project names or as modules under the "Includes" listing.
|
||||
$this->assertText(t('AAA Update test'));
|
||||
$this->assertText(t('BBB Update test'));
|
||||
$this->assertText(t('CCC Update test'));
|
||||
// We want aaa_update_test included in the ccc_update_test project, not as
|
||||
// its own project on the report.
|
||||
$this->assertNoRaw(\Drupal::l(t('AAA Update test'), Url::fromUri('http://example.com/project/aaa_update_test')), 'Link to aaa_update_test project does not appear.');
|
||||
// The other two should be listed as projects.
|
||||
$this->assertRaw(\Drupal::l(t('BBB Update test'), Url::fromUri('http://example.com/project/bbb_update_test')), 'Link to bbb_update_test project appears.');
|
||||
$this->assertRaw(\Drupal::l(t('CCC Update test'), Url::fromUri('http://example.com/project/ccc_update_test')), 'Link to bbb_update_test project appears.');
|
||||
|
||||
// We want to make sure we see the BBB project before the CCC project.
|
||||
// Instead of just searching for 'BBB Update test' or something, we want
|
||||
// to use the full markup that starts the project entry itself, so that
|
||||
// we're really testing that the project listings are in the right order.
|
||||
$bbb_project_link = '<div class="project-update__title"><a href="http://example.com/project/bbb_update_test">BBB Update test</a>';
|
||||
$ccc_project_link = '<div class="project-update__title"><a href="http://example.com/project/ccc_update_test">CCC Update test</a>';
|
||||
$this->assertTrue(strpos($this->getRawContent(), $bbb_project_link) < strpos($this->getRawContent(), $ccc_project_link), "'BBB Update test' project is listed before the 'CCC Update test' project");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that subthemes are notified about security updates for base themes.
|
||||
*/
|
||||
public function testUpdateBaseThemeSecurityUpdate() {
|
||||
// @todo https://www.drupal.org/node/2338175 base themes have to be
|
||||
// installed.
|
||||
// Only install the subtheme, not the base theme.
|
||||
\Drupal::service('theme_handler')->install(['update_test_subtheme']);
|
||||
|
||||
// Define the initial state for core and the subtheme.
|
||||
$system_info = [
|
||||
// We want core to be version 8.0.0.
|
||||
'#all' => [
|
||||
'version' => '8.0.0',
|
||||
],
|
||||
// Show the update_test_basetheme
|
||||
'update_test_basetheme' => [
|
||||
'project' => 'update_test_basetheme',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
],
|
||||
// Show the update_test_subtheme
|
||||
'update_test_subtheme' => [
|
||||
'project' => 'update_test_subtheme',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
],
|
||||
];
|
||||
$this->config('update_test.settings')->set('system_info', $system_info)->save();
|
||||
$xml_mapping = [
|
||||
'drupal' => '0.0',
|
||||
'update_test_subtheme' => '1_0',
|
||||
'update_test_basetheme' => '1_1-sec',
|
||||
];
|
||||
$this->refreshUpdateStatus($xml_mapping);
|
||||
$this->assertText(t('Security update required!'));
|
||||
$this->assertRaw(\Drupal::l(t('Update test base theme'), Url::fromUri('http://example.com/project/update_test_basetheme')), 'Link to the Update test base theme project appears.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that disabled themes are only shown when desired.
|
||||
*
|
||||
* @todo https://www.drupal.org/node/2338175 extensions can not be hidden and
|
||||
* base themes have to be installed.
|
||||
*/
|
||||
public function testUpdateShowDisabledThemes() {
|
||||
$update_settings = $this->config('update.settings');
|
||||
// Make sure all the update_test_* themes are disabled.
|
||||
$extension_config = $this->config('core.extension');
|
||||
foreach ($extension_config->get('theme') as $theme => $weight) {
|
||||
if (preg_match('/^update_test_/', $theme)) {
|
||||
$extension_config->clear("theme.$theme");
|
||||
}
|
||||
}
|
||||
$extension_config->save();
|
||||
|
||||
// Define the initial state for core and the test contrib themes.
|
||||
$system_info = [
|
||||
// We want core to be version 8.0.0.
|
||||
'#all' => [
|
||||
'version' => '8.0.0',
|
||||
],
|
||||
// The update_test_basetheme should be visible and up to date.
|
||||
'update_test_basetheme' => [
|
||||
'project' => 'update_test_basetheme',
|
||||
'version' => '8.x-1.1',
|
||||
'hidden' => FALSE,
|
||||
],
|
||||
// The update_test_subtheme should be visible and up to date.
|
||||
'update_test_subtheme' => [
|
||||
'project' => 'update_test_subtheme',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
],
|
||||
];
|
||||
// When there are contributed modules in the site's file system, the
|
||||
// total number of attempts made in the test may exceed the default value
|
||||
// of update_max_fetch_attempts. Therefore this variable is set very high
|
||||
// to avoid test failures in those cases.
|
||||
$update_settings->set('fetch.max_attempts', 99999)->save();
|
||||
$this->config('update_test.settings')->set('system_info', $system_info)->save();
|
||||
$xml_mapping = [
|
||||
'drupal' => '0.0',
|
||||
'update_test_subtheme' => '1_0',
|
||||
'update_test_basetheme' => '1_1-sec',
|
||||
];
|
||||
$base_theme_project_link = \Drupal::l(t('Update test base theme'), Url::fromUri('http://example.com/project/update_test_basetheme'));
|
||||
$sub_theme_project_link = \Drupal::l(t('Update test subtheme'), Url::fromUri('http://example.com/project/update_test_subtheme'));
|
||||
foreach ([TRUE, FALSE] as $check_disabled) {
|
||||
$update_settings->set('check.disabled_extensions', $check_disabled)->save();
|
||||
$this->refreshUpdateStatus($xml_mapping);
|
||||
// In neither case should we see the "Themes" heading for installed
|
||||
// themes.
|
||||
$this->assertNoText(t('Themes'));
|
||||
if ($check_disabled) {
|
||||
$this->assertText(t('Uninstalled themes'));
|
||||
$this->assertRaw($base_theme_project_link, 'Link to the Update test base theme project appears.');
|
||||
$this->assertRaw($sub_theme_project_link, 'Link to the Update test subtheme project appears.');
|
||||
}
|
||||
else {
|
||||
$this->assertNoText(t('Uninstalled themes'));
|
||||
$this->assertNoRaw($base_theme_project_link, 'Link to the Update test base theme project does not appear.');
|
||||
$this->assertNoRaw($sub_theme_project_link, 'Link to the Update test subtheme project does not appear.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests updates with a hidden base theme.
|
||||
*/
|
||||
public function testUpdateHiddenBaseTheme() {
|
||||
module_load_include('compare.inc', 'update');
|
||||
|
||||
// Install the subtheme.
|
||||
\Drupal::service('theme_handler')->install(['update_test_subtheme']);
|
||||
|
||||
// Add a project and initial state for base theme and subtheme.
|
||||
$system_info = [
|
||||
// Hide the update_test_basetheme.
|
||||
'update_test_basetheme' => [
|
||||
'project' => 'update_test_basetheme',
|
||||
'hidden' => TRUE,
|
||||
],
|
||||
// Show the update_test_subtheme.
|
||||
'update_test_subtheme' => [
|
||||
'project' => 'update_test_subtheme',
|
||||
'hidden' => FALSE,
|
||||
],
|
||||
];
|
||||
$this->config('update_test.settings')->set('system_info', $system_info)->save();
|
||||
$projects = \Drupal::service('update.manager')->getProjects();
|
||||
$theme_data = \Drupal::service('theme_handler')->rebuildThemeData();
|
||||
$project_info = new ProjectInfo();
|
||||
$project_info->processInfoList($projects, $theme_data, 'theme', TRUE);
|
||||
|
||||
$this->assertTrue(!empty($projects['update_test_basetheme']), 'Valid base theme (update_test_basetheme) was found.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure that if we fetch from a broken URL, sane things happen.
|
||||
*/
|
||||
public function testUpdateBrokenFetchURL() {
|
||||
$system_info = [
|
||||
'#all' => [
|
||||
'version' => '8.0.0',
|
||||
],
|
||||
'aaa_update_test' => [
|
||||
'project' => 'aaa_update_test',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
],
|
||||
'bbb_update_test' => [
|
||||
'project' => 'bbb_update_test',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
],
|
||||
'ccc_update_test' => [
|
||||
'project' => 'ccc_update_test',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
],
|
||||
];
|
||||
$this->config('update_test.settings')->set('system_info', $system_info)->save();
|
||||
|
||||
// Ensure that the update information is correct before testing.
|
||||
$this->drupalGet('admin/reports/updates');
|
||||
|
||||
$xml_mapping = [
|
||||
'drupal' => '0.0',
|
||||
'aaa_update_test' => '1_0',
|
||||
'bbb_update_test' => 'does-not-exist',
|
||||
'ccc_update_test' => '1_0',
|
||||
];
|
||||
$this->refreshUpdateStatus($xml_mapping);
|
||||
|
||||
$this->assertText(t('Up to date'));
|
||||
// We're expecting the report to say most projects are up to date, so we
|
||||
// hope that 'Up to date' is not unique.
|
||||
$this->assertNoUniqueText(t('Up to date'));
|
||||
// It should say we failed to get data, not that we're missing an update.
|
||||
$this->assertNoText(t('Update available'));
|
||||
|
||||
// We need to check that this string is found as part of a project row, not
|
||||
// just in the "Failed to get available update data" message at the top of
|
||||
// the page.
|
||||
$this->assertRaw('<div class="project-update__status">' . t('Failed to get available update data'));
|
||||
|
||||
// We should see the output messages from fetching manually.
|
||||
$this->assertUniqueText(t('Checked available update data for 3 projects.'));
|
||||
$this->assertUniqueText(t('Failed to get available update data for one project.'));
|
||||
|
||||
// The other two should be listed as projects.
|
||||
$this->assertRaw(\Drupal::l(t('AAA Update test'), Url::fromUri('http://example.com/project/aaa_update_test')), 'Link to aaa_update_test project appears.');
|
||||
$this->assertNoRaw(\Drupal::l(t('BBB Update test'), Url::fromUri('http://example.com/project/bbb_update_test')), 'Link to bbb_update_test project does not appear.');
|
||||
$this->assertRaw(\Drupal::l(t('CCC Update test'), Url::fromUri('http://example.com/project/ccc_update_test')), 'Link to bbb_update_test project appears.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that hook_update_status_alter() works to change a status.
|
||||
*
|
||||
* We provide the same external data as if aaa_update_test 8.x-1.0 were
|
||||
* installed and that was the latest release. Then we use
|
||||
* hook_update_status_alter() to try to mark this as missing a security
|
||||
* update, then assert if we see the appropriate warnings on the right pages.
|
||||
*/
|
||||
public function testHookUpdateStatusAlter() {
|
||||
$update_test_config = $this->config('update_test.settings');
|
||||
$update_admin_user = $this->drupalCreateUser(['administer site configuration', 'administer software updates']);
|
||||
$this->drupalLogin($update_admin_user);
|
||||
|
||||
$system_info = [
|
||||
'#all' => [
|
||||
'version' => '8.0.0',
|
||||
],
|
||||
'aaa_update_test' => [
|
||||
'project' => 'aaa_update_test',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
],
|
||||
];
|
||||
$update_test_config->set('system_info', $system_info)->save();
|
||||
$update_status = [
|
||||
'aaa_update_test' => [
|
||||
'status' => UPDATE_NOT_SECURE,
|
||||
],
|
||||
];
|
||||
$update_test_config->set('update_status', $update_status)->save();
|
||||
$this->refreshUpdateStatus(
|
||||
[
|
||||
'drupal' => '0.0',
|
||||
'aaa_update_test' => '1_0',
|
||||
]
|
||||
);
|
||||
$this->drupalGet('admin/reports/updates');
|
||||
$this->assertRaw('<h3>' . t('Modules') . '</h3>');
|
||||
$this->assertText(t('Security update required!'));
|
||||
$this->assertRaw(\Drupal::l(t('AAA Update test'), Url::fromUri('http://example.com/project/aaa_update_test')), 'Link to aaa_update_test project appears.');
|
||||
|
||||
// Visit the reports page again without the altering and make sure the
|
||||
// status is back to normal.
|
||||
$update_test_config->set('update_status', [])->save();
|
||||
$this->drupalGet('admin/reports/updates');
|
||||
$this->assertRaw('<h3>' . t('Modules') . '</h3>');
|
||||
$this->assertNoText(t('Security update required!'));
|
||||
$this->assertRaw(\Drupal::l(t('AAA Update test'), Url::fromUri('http://example.com/project/aaa_update_test')), 'Link to aaa_update_test project appears.');
|
||||
|
||||
// Turn the altering back on and visit the Update manager UI.
|
||||
$update_test_config->set('update_status', $update_status)->save();
|
||||
$this->drupalGet('admin/modules/update');
|
||||
$this->assertText(t('Security update'));
|
||||
|
||||
// Turn the altering back off and visit the Update manager UI.
|
||||
$update_test_config->set('update_status', [])->save();
|
||||
$this->drupalGet('admin/modules/update');
|
||||
$this->assertNoText(t('Security update'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,376 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\update\Functional;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\Traits\Core\CronRunTrait;
|
||||
|
||||
/**
|
||||
* Tests the Update Manager module through a series of functional tests using
|
||||
* mock XML data.
|
||||
*
|
||||
* @group update
|
||||
*/
|
||||
class UpdateCoreTest extends UpdateTestBase {
|
||||
|
||||
use CronRunTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['update_test', 'update', 'language', 'block'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$admin_user = $this->drupalCreateUser(['administer site configuration', 'administer modules', 'administer themes']);
|
||||
$this->drupalLogin($admin_user);
|
||||
$this->drupalPlaceBlock('local_actions_block');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the version to x.x.x when no project-specific mapping is defined.
|
||||
*
|
||||
* @param string $version
|
||||
* The version.
|
||||
*/
|
||||
protected function setSystemInfo($version) {
|
||||
$setting = [
|
||||
'#all' => [
|
||||
'version' => $version,
|
||||
],
|
||||
];
|
||||
$this->config('update_test.settings')->set('system_info', $setting)->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Update Manager module when no updates are available.
|
||||
*/
|
||||
public function testNoUpdatesAvailable() {
|
||||
foreach ([0, 1] as $minor_version) {
|
||||
foreach ([0, 1] as $patch_version) {
|
||||
foreach (['-alpha1', '-beta1', ''] as $extra_version) {
|
||||
$this->setSystemInfo("8.$minor_version.$patch_version" . $extra_version);
|
||||
$this->refreshUpdateStatus(['drupal' => "$minor_version.$patch_version" . $extra_version]);
|
||||
$this->standardTests();
|
||||
$this->assertText(t('Up to date'));
|
||||
$this->assertNoText(t('Update available'));
|
||||
$this->assertNoText(t('Security update required!'));
|
||||
$this->assertRaw('check.svg', 'Check icon was found.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Update Manager module when one normal update is available.
|
||||
*/
|
||||
public function testNormalUpdateAvailable() {
|
||||
$this->setSystemInfo('8.0.0');
|
||||
|
||||
// Ensure that the update check requires a token.
|
||||
$this->drupalGet('admin/reports/updates/check');
|
||||
$this->assertResponse(403, 'Accessing admin/reports/updates/check without a CSRF token results in access denied.');
|
||||
|
||||
foreach ([0, 1] as $minor_version) {
|
||||
foreach (['-alpha1', '-beta1', ''] as $extra_version) {
|
||||
$this->refreshUpdateStatus(['drupal' => "$minor_version.1" . $extra_version]);
|
||||
$this->standardTests();
|
||||
$this->drupalGet('admin/reports/updates');
|
||||
$this->clickLink(t('Check manually'));
|
||||
$this->checkForMetaRefresh();
|
||||
$this->assertNoText(t('Security update required!'));
|
||||
$this->assertRaw(\Drupal::l("8.$minor_version.1" . $extra_version, Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version-release")), 'Link to release appears.');
|
||||
$this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version.tar.gz")), 'Link to download appears.');
|
||||
$this->assertRaw(\Drupal::l(t('Release notes'), Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version-release")), 'Link to release notes appears.');
|
||||
|
||||
switch ($minor_version) {
|
||||
case 0:
|
||||
// Both stable and unstable releases are available.
|
||||
// A stable release is the latest.
|
||||
if ($extra_version == '') {
|
||||
$this->assertNoText(t('Up to date'));
|
||||
$this->assertText(t('Update available'));
|
||||
$this->assertText(t('Recommended version:'));
|
||||
$this->assertNoText(t('Latest version:'));
|
||||
$this->assertRaw('warning.svg', 'Warning icon was found.');
|
||||
}
|
||||
// Only unstable releases are available.
|
||||
// An unstable release is the latest.
|
||||
else {
|
||||
$this->assertText(t('Up to date'));
|
||||
$this->assertNoText(t('Update available'));
|
||||
$this->assertNoText(t('Recommended version:'));
|
||||
$this->assertText(t('Latest version:'));
|
||||
$this->assertRaw('check.svg', 'Check icon was found.');
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// Both stable and unstable releases are available.
|
||||
// A stable release is the latest.
|
||||
if ($extra_version == '') {
|
||||
$this->assertNoText(t('Up to date'));
|
||||
$this->assertText(t('Update available'));
|
||||
$this->assertText(t('Recommended version:'));
|
||||
$this->assertNoText(t('Latest version:'));
|
||||
$this->assertRaw('warning.svg', 'Warning icon was found.');
|
||||
}
|
||||
// Both stable and unstable releases are available.
|
||||
// An unstable release is the latest.
|
||||
else {
|
||||
$this->assertNoText(t('Up to date'));
|
||||
$this->assertText(t('Update available'));
|
||||
$this->assertText(t('Recommended version:'));
|
||||
$this->assertText(t('Latest version:'));
|
||||
$this->assertRaw('warning.svg', 'Warning icon was found.');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Update Manager module when a major update is available.
|
||||
*/
|
||||
public function testMajorUpdateAvailable() {
|
||||
foreach ([0, 1] as $minor_version) {
|
||||
foreach ([0, 1] as $patch_version) {
|
||||
foreach (['-alpha1', '-beta1', ''] as $extra_version) {
|
||||
$this->setSystemInfo("8.$minor_version.$patch_version" . $extra_version);
|
||||
$this->refreshUpdateStatus(['drupal' => '9']);
|
||||
$this->standardTests();
|
||||
$this->drupalGet('admin/reports/updates');
|
||||
$this->clickLink(t('Check manually'));
|
||||
$this->checkForMetaRefresh();
|
||||
$this->assertNoText(t('Security update required!'));
|
||||
$this->assertRaw(\Drupal::l('9.0.0', Url::fromUri("http://example.com/drupal-9-0-0-release")), 'Link to release appears.');
|
||||
$this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-9-0-0.tar.gz")), 'Link to download appears.');
|
||||
$this->assertRaw(\Drupal::l(t('Release notes'), Url::fromUri("http://example.com/drupal-9-0-0-release")), 'Link to release notes appears.');
|
||||
$this->assertNoText(t('Up to date'));
|
||||
$this->assertText(t('Not supported!'));
|
||||
$this->assertText(t('Recommended version:'));
|
||||
$this->assertNoText(t('Latest version:'));
|
||||
$this->assertRaw('error.svg', 'Error icon was found.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Update Manager module when a security update is available.
|
||||
*/
|
||||
public function testSecurityUpdateAvailable() {
|
||||
foreach ([0, 1] as $minor_version) {
|
||||
$this->setSystemInfo("8.$minor_version.0");
|
||||
$this->refreshUpdateStatus(['drupal' => "$minor_version.2-sec"]);
|
||||
$this->standardTests();
|
||||
$this->assertNoText(t('Up to date'));
|
||||
$this->assertNoText(t('Update available'));
|
||||
$this->assertText(t('Security update required!'));
|
||||
$this->assertRaw(\Drupal::l("8.$minor_version.2", Url::fromUri("http://example.com/drupal-8-$minor_version-2-release")), 'Link to release appears.');
|
||||
$this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-8-$minor_version-2.tar.gz")), 'Link to download appears.');
|
||||
$this->assertRaw(\Drupal::l(t('Release notes'), Url::fromUri("http://example.com/drupal-8-$minor_version-2-release")), 'Link to release notes appears.');
|
||||
$this->assertRaw('error.svg', 'Error icon was found.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures proper results where there are date mismatches among modules.
|
||||
*/
|
||||
public function testDatestampMismatch() {
|
||||
$system_info = [
|
||||
'#all' => [
|
||||
// We need to think we're running a -dev snapshot to see dates.
|
||||
'version' => '8.1.0-dev',
|
||||
'datestamp' => time(),
|
||||
],
|
||||
'block' => [
|
||||
// This is 2001-09-09 01:46:40 GMT, so test for "2001-Sep-".
|
||||
'datestamp' => '1000000000',
|
||||
],
|
||||
];
|
||||
$this->config('update_test.settings')->set('system_info', $system_info)->save();
|
||||
$this->refreshUpdateStatus(['drupal' => 'dev']);
|
||||
$this->assertNoText(t('2001-Sep-'));
|
||||
$this->assertText(t('Up to date'));
|
||||
$this->assertNoText(t('Update available'));
|
||||
$this->assertNoText(t('Security update required!'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that running cron updates the list of available updates.
|
||||
*/
|
||||
public function testModulePageRunCron() {
|
||||
$this->setSystemInfo('8.0.0');
|
||||
$this->config('update.settings')
|
||||
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
|
||||
->save();
|
||||
$this->config('update_test.settings')
|
||||
->set('xml_map', ['drupal' => '0.0'])
|
||||
->save();
|
||||
|
||||
$this->cronRun();
|
||||
$this->drupalGet('admin/modules');
|
||||
$this->assertNoText(t('No update information available.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the messages at admin/modules when the site is up to date.
|
||||
*/
|
||||
public function testModulePageUpToDate() {
|
||||
$this->setSystemInfo('8.0.0');
|
||||
// Instead of using refreshUpdateStatus(), set these manually.
|
||||
$this->config('update.settings')
|
||||
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
|
||||
->save();
|
||||
$this->config('update_test.settings')
|
||||
->set('xml_map', ['drupal' => '0.0'])
|
||||
->save();
|
||||
|
||||
$this->drupalGet('admin/reports/updates');
|
||||
$this->clickLink(t('Check manually'));
|
||||
$this->checkForMetaRefresh();
|
||||
$this->assertText(t('Checked available update data for one project.'));
|
||||
$this->drupalGet('admin/modules');
|
||||
$this->assertNoText(t('There are updates available for your version of Drupal.'));
|
||||
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the messages at admin/modules when an update is missing.
|
||||
*/
|
||||
public function testModulePageRegularUpdate() {
|
||||
$this->setSystemInfo('8.0.0');
|
||||
// Instead of using refreshUpdateStatus(), set these manually.
|
||||
$this->config('update.settings')
|
||||
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
|
||||
->save();
|
||||
$this->config('update_test.settings')
|
||||
->set('xml_map', ['drupal' => '0.1'])
|
||||
->save();
|
||||
|
||||
$this->drupalGet('admin/reports/updates');
|
||||
$this->clickLink(t('Check manually'));
|
||||
$this->checkForMetaRefresh();
|
||||
$this->assertText(t('Checked available update data for one project.'));
|
||||
$this->drupalGet('admin/modules');
|
||||
$this->assertText(t('There are updates available for your version of Drupal.'));
|
||||
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the messages at admin/modules when a security update is missing.
|
||||
*/
|
||||
public function testModulePageSecurityUpdate() {
|
||||
$this->setSystemInfo('8.0.0');
|
||||
// Instead of using refreshUpdateStatus(), set these manually.
|
||||
$this->config('update.settings')
|
||||
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
|
||||
->save();
|
||||
$this->config('update_test.settings')
|
||||
->set('xml_map', ['drupal' => '0.2-sec'])
|
||||
->save();
|
||||
|
||||
$this->drupalGet('admin/reports/updates');
|
||||
$this->clickLink(t('Check manually'));
|
||||
$this->checkForMetaRefresh();
|
||||
$this->assertText(t('Checked available update data for one project.'));
|
||||
$this->drupalGet('admin/modules');
|
||||
$this->assertNoText(t('There are updates available for your version of Drupal.'));
|
||||
$this->assertText(t('There is a security update available for your version of Drupal.'));
|
||||
|
||||
// Make sure admin/appearance warns you you're missing a security update.
|
||||
$this->drupalGet('admin/appearance');
|
||||
$this->assertNoText(t('There are updates available for your version of Drupal.'));
|
||||
$this->assertText(t('There is a security update available for your version of Drupal.'));
|
||||
|
||||
// Make sure duplicate messages don't appear on Update status pages.
|
||||
$this->drupalGet('admin/reports/status');
|
||||
// We're expecting "There is a security update..." inside the status report
|
||||
// itself, but the drupal_set_message() appears as an li so we can prefix
|
||||
// with that and search for the raw HTML.
|
||||
$this->assertNoRaw('<li>' . t('There is a security update available for your version of Drupal.'));
|
||||
|
||||
$this->drupalGet('admin/reports/updates');
|
||||
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
|
||||
|
||||
$this->drupalGet('admin/reports/updates/settings');
|
||||
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Update Manager module when the update server returns 503 errors.
|
||||
*/
|
||||
public function testServiceUnavailable() {
|
||||
$this->refreshUpdateStatus([], '503-error');
|
||||
// Ensure that no "Warning: SimpleXMLElement..." parse errors are found.
|
||||
$this->assertNoText('SimpleXMLElement');
|
||||
$this->assertUniqueText(t('Failed to get available update data for one project.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that exactly one fetch task per project is created and not more.
|
||||
*/
|
||||
public function testFetchTasks() {
|
||||
$projecta = [
|
||||
'name' => 'aaa_update_test',
|
||||
];
|
||||
$projectb = [
|
||||
'name' => 'bbb_update_test',
|
||||
];
|
||||
$queue = \Drupal::queue('update_fetch_tasks');
|
||||
$this->assertEqual($queue->numberOfItems(), 0, 'Queue is empty');
|
||||
update_create_fetch_task($projecta);
|
||||
$this->assertEqual($queue->numberOfItems(), 1, 'Queue contains one item');
|
||||
update_create_fetch_task($projectb);
|
||||
$this->assertEqual($queue->numberOfItems(), 2, 'Queue contains two items');
|
||||
// Try to add project a again.
|
||||
update_create_fetch_task($projecta);
|
||||
$this->assertEqual($queue->numberOfItems(), 2, 'Queue still contains two items');
|
||||
|
||||
// Clear storage and try again.
|
||||
update_storage_clear();
|
||||
update_create_fetch_task($projecta);
|
||||
$this->assertEqual($queue->numberOfItems(), 2, 'Queue contains two items');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks language module in core package at admin/reports/updates.
|
||||
*/
|
||||
public function testLanguageModuleUpdate() {
|
||||
$this->setSystemInfo('8.0.0');
|
||||
// Instead of using refreshUpdateStatus(), set these manually.
|
||||
$this->config('update.settings')
|
||||
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
|
||||
->save();
|
||||
$this->config('update_test.settings')
|
||||
->set('xml_map', ['drupal' => '0.1'])
|
||||
->save();
|
||||
|
||||
$this->drupalGet('admin/reports/updates');
|
||||
$this->assertText(t('Language'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the local actions appear.
|
||||
*/
|
||||
public function testLocalActions() {
|
||||
$admin_user = $this->drupalCreateUser(['administer site configuration', 'administer modules', 'administer software updates', 'administer themes']);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
$this->drupalGet('admin/modules');
|
||||
$this->clickLink(t('Install new module'));
|
||||
$this->assertUrl('admin/modules/install');
|
||||
|
||||
$this->drupalGet('admin/appearance');
|
||||
$this->clickLink(t('Install new theme'));
|
||||
$this->assertUrl('admin/theme/install');
|
||||
|
||||
$this->drupalGet('admin/reports/updates');
|
||||
$this->clickLink(t('Install new module or theme'));
|
||||
$this->assertUrl('admin/reports/updates/install');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\update\Functional;
|
||||
|
||||
/**
|
||||
* Tests the update_delete_file_if_stale() function.
|
||||
*
|
||||
* @group update
|
||||
*/
|
||||
class UpdateDeleteFileIfStaleTest extends UpdateTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['update'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the deletion of stale files.
|
||||
*/
|
||||
public function testUpdateDeleteFileIfStale() {
|
||||
$file_name = file_unmanaged_save_data($this->randomMachineName());
|
||||
$this->assertNotNull($file_name);
|
||||
|
||||
// During testing the file change and the stale checking occurs in the same
|
||||
// request, so the beginning of request will be before the file changes and
|
||||
// REQUEST_TIME - $filectime is negative. Set the maximum age to a number
|
||||
// even smaller than that.
|
||||
$this->config('system.file')
|
||||
->set('temporary_maximum_age', -100000)
|
||||
->save();
|
||||
|
||||
$file_path = drupal_realpath($file_name);
|
||||
update_delete_file_if_stale($file_path);
|
||||
|
||||
$this->assertFalse(is_file($file_path));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\update\Functional;
|
||||
|
||||
use Drupal\Core\DrupalKernel;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Defines some shared functions used by all update tests.
|
||||
*
|
||||
* The overarching methodology of these tests is we need to compare a given
|
||||
* state of installed modules and themes (e.g., version, project grouping,
|
||||
* timestamps, etc) against a current state of what the release history XML
|
||||
* files we fetch say is available. We have dummy XML files (in the
|
||||
* core/modules/update/tests directory) that describe various scenarios of
|
||||
* what's available for different test projects, and we have dummy .info file
|
||||
* data (specified via hook_system_info_alter() in the update_test helper
|
||||
* module) describing what's currently installed. Each test case defines a set
|
||||
* of projects to install, their current state (via the
|
||||
* 'update_test_system_info' variable) and the desired available update data
|
||||
* (via the 'update_test_xml_map' variable), and then performs a series of
|
||||
* assertions that the report matches our expectations given the specific
|
||||
* initial state and availability scenario.
|
||||
*/
|
||||
abstract class UpdateTestBase extends BrowserTestBase {
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Change the root path which Update Manager uses to install and update
|
||||
// projects to be inside the testing site directory. See
|
||||
// \Drupal\update\UpdateRootFactory::get() for equivalent changes to the
|
||||
// test child site.
|
||||
$request = \Drupal::request();
|
||||
$update_root = $this->container->get('update.root') . '/' . DrupalKernel::findSitePath($request);
|
||||
$this->container->set('update.root', $update_root);
|
||||
\Drupal::setContainer($this->container);
|
||||
|
||||
// Create the directories within the root path within which the Update
|
||||
// Manager will install projects.
|
||||
foreach (drupal_get_updaters() as $updater_info) {
|
||||
$updater = $updater_info['class'];
|
||||
$install_directory = $update_root . '/' . $updater::getRootDirectoryRelativePath();
|
||||
if (!is_dir($install_directory)) {
|
||||
mkdir($install_directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the update status based on the desired available update scenario.
|
||||
*
|
||||
* @param $xml_map
|
||||
* Array that maps project names to availability scenarios to fetch. The key
|
||||
* '#all' is used if a project-specific mapping is not defined.
|
||||
* @param $url
|
||||
* (optional) A string containing the URL to fetch update data from.
|
||||
* Defaults to 'update-test'.
|
||||
*
|
||||
* @see \Drupal\update_test\Controller\UpdateTestController::updateTest()
|
||||
*/
|
||||
protected function refreshUpdateStatus($xml_map, $url = 'update-test') {
|
||||
// Tell the Update Manager module to fetch from the URL provided by
|
||||
// update_test module.
|
||||
$this->config('update.settings')->set('fetch.url', Url::fromUri('base:' . $url, ['absolute' => TRUE])->toString())->save();
|
||||
// Save the map for UpdateTestController::updateTest() to use.
|
||||
$this->config('update_test.settings')->set('xml_map', $xml_map)->save();
|
||||
// Manually check the update status.
|
||||
$this->drupalGet('admin/reports/updates');
|
||||
$this->clickLink(t('Check manually'));
|
||||
$this->checkForMetaRefresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a series of assertions that are applicable to all update statuses.
|
||||
*/
|
||||
protected function standardTests() {
|
||||
$this->assertRaw('<h3>' . t('Drupal core') . '</h3>');
|
||||
$this->assertRaw(\Drupal::l(t('Drupal'), Url::fromUri('http://example.com/project/drupal')), 'Link to the Drupal project appears.');
|
||||
$this->assertNoText(t('No available releases found'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\update\Functional;
|
||||
|
||||
use Drupal\Core\Extension\InfoParserDynamic;
|
||||
use Drupal\Core\Updater\Updater;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\TestFileCreationTrait;
|
||||
|
||||
/**
|
||||
* Tests the Update Manager module's upload and extraction functionality.
|
||||
*
|
||||
* @group update
|
||||
*/
|
||||
class UpdateUploadTest extends UpdateTestBase {
|
||||
|
||||
use TestFileCreationTrait {
|
||||
getTestFiles as drupalGetTestFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['update', 'update_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$admin_user = $this->drupalCreateUser(['administer modules', 'administer software updates', 'administer site configuration']);
|
||||
$this->drupalLogin($admin_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests upload, extraction, and update of a module.
|
||||
*/
|
||||
public function testUploadModule() {
|
||||
// Ensure that the update information is correct before testing.
|
||||
update_get_available(TRUE);
|
||||
|
||||
// Images are not valid archives, so get one and try to install it. We
|
||||
// need an extra variable to store the result of drupalGetTestFiles()
|
||||
// since reset() takes an argument by reference and passing in a constant
|
||||
// emits a notice in strict mode.
|
||||
$imageTestFiles = $this->drupalGetTestFiles('image');
|
||||
$invalidArchiveFile = reset($imageTestFiles);
|
||||
$edit = [
|
||||
'files[project_upload]' => $invalidArchiveFile->uri,
|
||||
];
|
||||
// This also checks that the correct archive extensions are allowed.
|
||||
$this->drupalPostForm('admin/modules/install', $edit, t('Install'));
|
||||
$this->assertText(t('Only files with the following extensions are allowed: @archive_extensions.', ['@archive_extensions' => archiver_get_extensions()]), 'Only valid archives can be uploaded.');
|
||||
$this->assertUrl('admin/modules/install');
|
||||
|
||||
// Check to ensure an existing module can't be reinstalled. Also checks that
|
||||
// the archive was extracted since we can't know if the module is already
|
||||
// installed until after extraction.
|
||||
$validArchiveFile = __DIR__ . '/../../aaa_update_test.tar.gz';
|
||||
$edit = [
|
||||
'files[project_upload]' => $validArchiveFile,
|
||||
];
|
||||
$this->drupalPostForm('admin/modules/install', $edit, t('Install'));
|
||||
$this->assertText(t('@module_name is already installed.', ['@module_name' => 'AAA Update test']), 'Existing module was extracted and not reinstalled.');
|
||||
$this->assertUrl('admin/modules/install');
|
||||
|
||||
// Ensure that a new module can be extracted and installed.
|
||||
$updaters = drupal_get_updaters();
|
||||
$moduleUpdater = $updaters['module']['class'];
|
||||
$installedInfoFilePath = $this->container->get('update.root') . '/' . $moduleUpdater::getRootDirectoryRelativePath() . '/update_test_new_module/update_test_new_module.info.yml';
|
||||
$this->assertFalse(file_exists($installedInfoFilePath), 'The new module does not exist in the filesystem before it is installed with the Update Manager.');
|
||||
$validArchiveFile = __DIR__ . '/../../update_test_new_module/8.x-1.0/update_test_new_module.tar.gz';
|
||||
$edit = [
|
||||
'files[project_upload]' => $validArchiveFile,
|
||||
];
|
||||
$this->drupalPostForm('admin/modules/install', $edit, t('Install'));
|
||||
// Check that submitting the form takes the user to authorize.php.
|
||||
$this->assertUrl('core/authorize.php');
|
||||
$this->assertTitle('Update manager | Drupal');
|
||||
// Check for a success message on the page, and check that the installed
|
||||
// module now exists in the expected place in the filesystem.
|
||||
$this->assertRaw(t('Installed %project_name successfully', ['%project_name' => 'update_test_new_module']));
|
||||
$this->assertTrue(file_exists($installedInfoFilePath), 'The new module exists in the filesystem after it is installed with the Update Manager.');
|
||||
// Ensure the links are relative to the site root and not
|
||||
// core/authorize.php.
|
||||
$this->assertLink(t('Install another module'));
|
||||
$this->assertLinkByHref(Url::fromRoute('update.module_install')->toString());
|
||||
$this->assertLink(t('Enable newly added modules'));
|
||||
$this->assertLinkByHref(Url::fromRoute('system.modules_list')->toString());
|
||||
$this->assertLink(t('Administration pages'));
|
||||
$this->assertLinkByHref(Url::fromRoute('system.admin')->toString());
|
||||
// Ensure we can reach the "Install another module" link.
|
||||
$this->clickLink(t('Install another module'));
|
||||
$this->assertResponse(200);
|
||||
$this->assertUrl('admin/modules/install');
|
||||
|
||||
// Check that the module has the correct version before trying to update
|
||||
// it. Since the module is installed in sites/simpletest, which only the
|
||||
// child site has access to, standard module API functions won't find it
|
||||
// when called here. To get the version, the info file must be parsed
|
||||
// directly instead.
|
||||
$info_parser = new InfoParserDynamic();
|
||||
$info = $info_parser->parse($installedInfoFilePath);
|
||||
$this->assertEqual($info['version'], '8.x-1.0');
|
||||
|
||||
// Enable the module.
|
||||
$this->drupalPostForm('admin/modules', ['modules[update_test_new_module][enable]' => TRUE], t('Install'));
|
||||
|
||||
// Define the update XML such that the new module downloaded above needs an
|
||||
// update from 8.x-1.0 to 8.x-1.1.
|
||||
$update_test_config = $this->config('update_test.settings');
|
||||
$system_info = [
|
||||
'update_test_new_module' => [
|
||||
'project' => 'update_test_new_module',
|
||||
],
|
||||
];
|
||||
$update_test_config->set('system_info', $system_info)->save();
|
||||
$xml_mapping = [
|
||||
'update_test_new_module' => '1_1',
|
||||
];
|
||||
$this->refreshUpdateStatus($xml_mapping);
|
||||
|
||||
// Run the updates for the new module.
|
||||
$this->drupalPostForm('admin/reports/updates/update', ['projects[update_test_new_module]' => TRUE], t('Download these updates'));
|
||||
$this->drupalPostForm(NULL, ['maintenance_mode' => FALSE], t('Continue'));
|
||||
$this->assertText(t('Update was completed successfully.'));
|
||||
$this->assertRaw(t('Installed %project_name successfully', ['%project_name' => 'update_test_new_module']));
|
||||
|
||||
// Parse the info file again to check that the module has been updated to
|
||||
// 8.x-1.1.
|
||||
$info = $info_parser->parse($installedInfoFilePath);
|
||||
$this->assertEqual($info['version'], '8.x-1.1');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that archiver extensions are properly merged in the UI.
|
||||
*/
|
||||
public function testFileNameExtensionMerging() {
|
||||
$this->drupalGet('admin/modules/install');
|
||||
// Make sure the bogus extension supported by update_test.module is there.
|
||||
$this->assertPattern('/file extensions are supported:.*update-test-extension/', "Found 'update-test-extension' extension.");
|
||||
// Make sure it didn't clobber the first option from core.
|
||||
$this->assertPattern('/file extensions are supported:.*tar/', "Found 'tar' extension.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the messages on update manager pages when missing a security update.
|
||||
*/
|
||||
public function testUpdateManagerCoreSecurityUpdateMessages() {
|
||||
$setting = [
|
||||
'#all' => [
|
||||
'version' => '8.0.0',
|
||||
],
|
||||
];
|
||||
$this->config('update_test.settings')
|
||||
->set('system_info', $setting)
|
||||
->set('xml_map', ['drupal' => '0.2-sec'])
|
||||
->save();
|
||||
$this->config('update.settings')
|
||||
->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
|
||||
->save();
|
||||
// Initialize the update status.
|
||||
$this->drupalGet('admin/reports/updates');
|
||||
|
||||
// Now, make sure none of the Update manager pages have duplicate messages
|
||||
// about core missing a security update.
|
||||
|
||||
$this->drupalGet('admin/modules/install');
|
||||
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
|
||||
|
||||
$this->drupalGet('admin/modules/update');
|
||||
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
|
||||
|
||||
$this->drupalGet('admin/appearance/install');
|
||||
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
|
||||
|
||||
$this->drupalGet('admin/appearance/update');
|
||||
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
|
||||
|
||||
$this->drupalGet('admin/reports/updates/install');
|
||||
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
|
||||
|
||||
$this->drupalGet('admin/reports/updates/update');
|
||||
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
|
||||
|
||||
$this->drupalGet('admin/update/ready');
|
||||
$this->assertNoText(t('There is a security update available for your version of Drupal.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests only an *.info.yml file are detected without supporting files.
|
||||
*/
|
||||
public function testUpdateDirectory() {
|
||||
$type = Updater::getUpdaterFromDirectory(\Drupal::root() . '/core/modules/update/tests/modules/aaa_update_test');
|
||||
$this->assertEqual($type, 'Drupal\\Core\\Updater\\Module', 'Detected a Module');
|
||||
|
||||
$type = Updater::getUpdaterFromDirectory(\Drupal::root() . '/core/modules/update/tests/themes/update_test_basetheme');
|
||||
$this->assertEqual($type, 'Drupal\\Core\\Updater\\Theme', 'Detected a Theme.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Drupal\Tests\update\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\config\Tests\SchemaCheckTestTrait;
|
||||
use Drupal\Tests\SchemaCheckTestTrait;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
@@ -17,7 +17,7 @@ class MigrateUpdateConfigsTest extends MigrateDrupal6TestBase {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = array('update');
|
||||
public static $modules = ['update'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -35,7 +35,7 @@ class MigrateUpdateConfigsTest extends MigrateDrupal6TestBase {
|
||||
$this->assertIdentical(2, $config->get('fetch.max_attempts'));
|
||||
$this->assertIdentical('http://updates.drupal.org/release-history', $config->get('fetch.url'));
|
||||
$this->assertIdentical('all', $config->get('notification.threshold'));
|
||||
$this->assertIdentical(array(), $config->get('notification.emails'));
|
||||
$this->assertIdentical([], $config->get('notification.emails'));
|
||||
$this->assertIdentical(7, $config->get('check.interval_days'));
|
||||
$this->assertConfigSchema(\Drupal::service('config.typed'), 'update.settings', $config->get());
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ use Drupal\Tests\Core\Menu\LocalTaskIntegrationTestBase;
|
||||
class UpdateLocalTasksTest extends LocalTaskIntegrationTestBase {
|
||||
|
||||
protected function setUp() {
|
||||
$this->directoryList = array('update' => 'core/modules/update');
|
||||
$this->directoryList = ['update' => 'core/modules/update'];
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
@@ -22,20 +22,20 @@ class UpdateLocalTasksTest extends LocalTaskIntegrationTestBase {
|
||||
* @dataProvider getUpdateReportRoutes
|
||||
*/
|
||||
public function testUpdateReportLocalTasks($route) {
|
||||
$this->assertLocalTasks($route, array(
|
||||
0 => array('update.status', 'update.settings', 'update.report_update'),
|
||||
));
|
||||
$this->assertLocalTasks($route, [
|
||||
0 => ['update.status', 'update.settings', 'update.report_update'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a list of report routes to test.
|
||||
*/
|
||||
public function getUpdateReportRoutes() {
|
||||
return array(
|
||||
array('update.status'),
|
||||
array('update.settings'),
|
||||
array('update.report_update'),
|
||||
);
|
||||
return [
|
||||
['update.status'],
|
||||
['update.settings'],
|
||||
['update.report_update'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,9 +44,9 @@ class UpdateLocalTasksTest extends LocalTaskIntegrationTestBase {
|
||||
* @dataProvider getUpdateModuleRoutes
|
||||
*/
|
||||
public function testUpdateModuleLocalTasks($route) {
|
||||
$this->assertLocalTasks($route, array(
|
||||
0 => array('update.module_update'),
|
||||
));
|
||||
$this->assertLocalTasks($route, [
|
||||
0 => ['update.module_update'],
|
||||
]);
|
||||
;
|
||||
}
|
||||
|
||||
@@ -54,9 +54,9 @@ class UpdateLocalTasksTest extends LocalTaskIntegrationTestBase {
|
||||
* Provides a list of module routes to test.
|
||||
*/
|
||||
public function getUpdateModuleRoutes() {
|
||||
return array(
|
||||
array('update.module_update'),
|
||||
);
|
||||
return [
|
||||
['update.module_update'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,9 +65,9 @@ class UpdateLocalTasksTest extends LocalTaskIntegrationTestBase {
|
||||
* @dataProvider getUpdateThemeRoutes
|
||||
*/
|
||||
public function testUpdateThemeLocalTasks($route) {
|
||||
$this->assertLocalTasks($route, array(
|
||||
0 => array('update.theme_update'),
|
||||
));
|
||||
$this->assertLocalTasks($route, [
|
||||
0 => ['update.theme_update'],
|
||||
]);
|
||||
;
|
||||
}
|
||||
|
||||
@@ -75,9 +75,9 @@ class UpdateLocalTasksTest extends LocalTaskIntegrationTestBase {
|
||||
* Provides a list of theme routes to test.
|
||||
*/
|
||||
public function getUpdateThemeRoutes() {
|
||||
return array(
|
||||
array('update.theme_update'),
|
||||
);
|
||||
return [
|
||||
['update.theme_update'],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class UpdateFetcherTest extends UnitTestCase {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$config_factory = $this->getConfigFactoryStub(array('update.settings' => array('fetch_url' => 'http://www.example.com')));
|
||||
$config_factory = $this->getConfigFactoryStub(['update.settings' => ['fetch_url' => 'http://www.example.com']]);
|
||||
$http_client_mock = $this->getMock('\GuzzleHttp\ClientInterface');
|
||||
$this->updateFetcher = new UpdateFetcher($config_factory, $http_client_mock);
|
||||
}
|
||||
@@ -62,25 +62,25 @@ class UpdateFetcherTest extends UnitTestCase {
|
||||
* - 'expected' - The expected url from UpdateFetcher::buildFetchUrl().
|
||||
*/
|
||||
public function providerTestUpdateBuildFetchUrl() {
|
||||
$data = array();
|
||||
$data = [];
|
||||
|
||||
// First test that we didn't break the trivial case.
|
||||
$project['name'] = 'update_test';
|
||||
$project['project_type'] = '';
|
||||
$project['info']['version'] = '';
|
||||
$project['info']['project status url'] = 'http://www.example.com';
|
||||
$project['includes'] = array('module1' => 'Module 1', 'module2' => 'Module 2');
|
||||
$project['includes'] = ['module1' => 'Module 1', 'module2' => 'Module 2'];
|
||||
$site_key = '';
|
||||
$expected = 'http://www.example.com/' . $project['name'] . '/' . DRUPAL_CORE_COMPATIBILITY;
|
||||
|
||||
$data[] = array($project, $site_key, $expected);
|
||||
$data[] = [$project, $site_key, $expected];
|
||||
|
||||
// For disabled projects it shouldn't add the site key either.
|
||||
$site_key = 'site_key';
|
||||
$project['project_type'] = 'disabled';
|
||||
$expected = 'http://www.example.com/' . $project['name'] . '/' . DRUPAL_CORE_COMPATIBILITY;
|
||||
|
||||
$data[] = array($project, $site_key, $expected);
|
||||
$data[] = [$project, $site_key, $expected];
|
||||
|
||||
// For enabled projects, test adding the site key.
|
||||
$project['project_type'] = '';
|
||||
@@ -88,7 +88,7 @@ class UpdateFetcherTest extends UnitTestCase {
|
||||
$expected .= '?site_key=site_key';
|
||||
$expected .= '&list=' . rawurlencode('module1,module2');
|
||||
|
||||
$data[] = array($project, $site_key, $expected);
|
||||
$data[] = [$project, $site_key, $expected];
|
||||
|
||||
// Test when the URL contains a question mark.
|
||||
$project['info']['project status url'] = 'http://www.example.com/?project=';
|
||||
@@ -96,7 +96,7 @@ class UpdateFetcherTest extends UnitTestCase {
|
||||
$expected .= '&site_key=site_key';
|
||||
$expected .= '&list=' . rawurlencode('module1,module2');
|
||||
|
||||
$data[] = array($project, $site_key, $expected);
|
||||
$data[] = [$project, $site_key, $expected];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
+3
-3
@@ -4,8 +4,8 @@ description: 'Test theme which acts as a base theme for other test subthemes.'
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2016-08-03
|
||||
version: '8.1.8'
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1470233790
|
||||
datestamp: 1502903957
|
||||
|
||||
@@ -5,8 +5,8 @@ description: 'Test theme which uses update_test_basetheme as the base theme.'
|
||||
# core: 8.x
|
||||
base theme: update_test_basetheme
|
||||
|
||||
# Information added by Drupal.org packaging script on 2016-08-03
|
||||
version: '8.1.8'
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1470233790
|
||||
datestamp: 1502903957
|
||||
|
||||
Reference in New Issue
Block a user