Drupal 8.0.0 beta 12. More info: https://www.drupal.org/node/2514176
This commit is contained in:
commit
9921556621
13277 changed files with 1459781 additions and 0 deletions
419
core/modules/update/src/Tests/UpdateContribTest.php
Normal file
419
core/modules/update/src/Tests/UpdateContribTest.php
Normal file
|
@ -0,0 +1,419 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\update\Tests\UpdateContribTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\update\Tests;
|
||||
|
||||
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 = array('update_test', 'update', 'aaa_update_test', 'bbb_update_test', 'ccc_update_test');
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$admin_user = $this->drupalCreateUser(array('administer site configuration'));
|
||||
$this->drupalLogin($admin_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests when there is no available release data for a contrib module.
|
||||
*/
|
||||
function testNoReleasesAvailable() {
|
||||
$system_info = array(
|
||||
'#all' => array(
|
||||
'version' => '8.0.0',
|
||||
),
|
||||
'aaa_update_test' => array(
|
||||
'project' => 'aaa_update_test',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
),
|
||||
);
|
||||
$this->config('update_test.settings')->set('system_info', $system_info)->save();
|
||||
$this->refreshUpdateStatus(array('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.
|
||||
*/
|
||||
function testUpdateContribBasic() {
|
||||
$system_info = array(
|
||||
'#all' => array(
|
||||
'version' => '8.0.0',
|
||||
),
|
||||
'aaa_update_test' => array(
|
||||
'project' => 'aaa_update_test',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
),
|
||||
);
|
||||
$this->config('update_test.settings')->set('system_info', $system_info)->save();
|
||||
$this->refreshUpdateStatus(
|
||||
array(
|
||||
'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(\Drupal::l(t('AAA Update test'), Url::fromUri('http://example.com/project/aaa_update_test')), '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).
|
||||
*/
|
||||
function testUpdateContribOrder() {
|
||||
// We want core to be version 8.0.0.
|
||||
$system_info = array(
|
||||
'#all' => array(
|
||||
'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' => array(
|
||||
'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' => array(
|
||||
'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' => array(
|
||||
'project' => 'ccc_update_test',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
),
|
||||
);
|
||||
$this->config('update_test.settings')->set('system_info', $system_info)->save();
|
||||
$this->refreshUpdateStatus(array('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.
|
||||
*/
|
||||
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(array('update_test_subtheme'));
|
||||
|
||||
// Define the initial state for core and the subtheme.
|
||||
$system_info = array(
|
||||
// We want core to be version 8.0.0.
|
||||
'#all' => array(
|
||||
'version' => '8.0.0',
|
||||
),
|
||||
// Show the update_test_basetheme
|
||||
'update_test_basetheme' => array(
|
||||
'project' => 'update_test_basetheme',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
),
|
||||
// Show the update_test_subtheme
|
||||
'update_test_subtheme' => array(
|
||||
'project' => 'update_test_subtheme',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
),
|
||||
);
|
||||
$this->config('update_test.settings')->set('system_info', $system_info)->save();
|
||||
$xml_mapping = array(
|
||||
'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.
|
||||
*/
|
||||
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 = array(
|
||||
// We want core to be version 8.0.0.
|
||||
'#all' => array(
|
||||
'version' => '8.0.0',
|
||||
),
|
||||
// The update_test_basetheme should be visible and up to date.
|
||||
'update_test_basetheme' => array(
|
||||
'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' => array(
|
||||
'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 = array(
|
||||
'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 (array(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('Disabled 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('Disabled 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.
|
||||
*/
|
||||
function testUpdateHiddenBaseTheme() {
|
||||
module_load_include('compare.inc', 'update');
|
||||
|
||||
// Install the subtheme.
|
||||
\Drupal::service('theme_handler')->install(array('update_test_subtheme'));
|
||||
|
||||
// Add a project and initial state for base theme and subtheme.
|
||||
$system_info = array(
|
||||
// Hide the update_test_basetheme.
|
||||
'update_test_basetheme' => array(
|
||||
'project' => 'update_test_basetheme',
|
||||
'hidden' => TRUE,
|
||||
),
|
||||
// Show the update_test_subtheme.
|
||||
'update_test_subtheme' => array(
|
||||
'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.
|
||||
*/
|
||||
function testUpdateBrokenFetchURL() {
|
||||
$system_info = array(
|
||||
'#all' => array(
|
||||
'version' => '8.0.0',
|
||||
),
|
||||
'aaa_update_test' => array(
|
||||
'project' => 'aaa_update_test',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
),
|
||||
'bbb_update_test' => array(
|
||||
'project' => 'bbb_update_test',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
),
|
||||
'ccc_update_test' => array(
|
||||
'project' => 'ccc_update_test',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
),
|
||||
);
|
||||
$this->config('update_test.settings')->set('system_info', $system_info)->save();
|
||||
|
||||
$xml_mapping = array(
|
||||
'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.
|
||||
*/
|
||||
function testHookUpdateStatusAlter() {
|
||||
$update_test_config = $this->config('update_test.settings');
|
||||
$update_admin_user = $this->drupalCreateUser(array('administer site configuration', 'administer software updates'));
|
||||
$this->drupalLogin($update_admin_user);
|
||||
|
||||
$system_info = array(
|
||||
'#all' => array(
|
||||
'version' => '8.0.0',
|
||||
),
|
||||
'aaa_update_test' => array(
|
||||
'project' => 'aaa_update_test',
|
||||
'version' => '8.x-1.0',
|
||||
'hidden' => FALSE,
|
||||
),
|
||||
);
|
||||
$update_test_config->set('system_info', $system_info)->save();
|
||||
$update_status = array(
|
||||
'aaa_update_test' => array(
|
||||
'status' => UPDATE_NOT_SECURE,
|
||||
),
|
||||
);
|
||||
$update_test_config->set('update_status', $update_status)->save();
|
||||
$this->refreshUpdateStatus(
|
||||
array(
|
||||
'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', array())->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', array())->save();
|
||||
$this->drupalGet('admin/modules/update');
|
||||
$this->assertNoText(t('Security update'));
|
||||
}
|
||||
|
||||
}
|
365
core/modules/update/src/Tests/UpdateCoreTest.php
Normal file
365
core/modules/update/src/Tests/UpdateCoreTest.php
Normal file
|
@ -0,0 +1,365 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\update\Tests\UpdateCoreTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\update\Tests;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Tests the Update Manager module through a series of functional tests using
|
||||
* mock XML data.
|
||||
*
|
||||
* @group update
|
||||
*/
|
||||
class UpdateCoreTest extends UpdateTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('update_test', 'update', 'language');
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$admin_user = $this->drupalCreateUser(array('administer site configuration', 'administer modules', 'administer themes'));
|
||||
$this->drupalLogin($admin_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the version to x.x.x when no project-specific mapping is defined.
|
||||
*
|
||||
* @param string $version
|
||||
* The version.
|
||||
*/
|
||||
protected function setSystemInfo($version) {
|
||||
$setting = array(
|
||||
'#all' => array(
|
||||
'version' => $version,
|
||||
),
|
||||
);
|
||||
$this->config('update_test.settings')->set('system_info', $setting)->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Update Manager module when no updates are available.
|
||||
*/
|
||||
function testNoUpdatesAvailable() {
|
||||
foreach (array(0, 1) as $minor_version) {
|
||||
foreach (array(0, 1) as $patch_version) {
|
||||
foreach (array('-alpha1', '-beta1', '') as $extra_version) {
|
||||
$this->setSystemInfo("8.$minor_version.$patch_version" . $extra_version);
|
||||
$this->refreshUpdateStatus(array('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.
|
||||
*/
|
||||
function testNormalUpdateAvailable() {
|
||||
$this->setSystemInfo('8.0.0');
|
||||
foreach (array(0, 1) as $minor_version) {
|
||||
foreach (array('-alpha1', '-beta1', '') as $extra_version) {
|
||||
$this->refreshUpdateStatus(array('drupal' => "$minor_version.1" . $extra_version));
|
||||
$this->standardTests();
|
||||
$this->drupalGet('admin/reports/updates/check');
|
||||
$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.
|
||||
*/
|
||||
function testMajorUpdateAvailable() {
|
||||
foreach (array(0, 1) as $minor_version) {
|
||||
foreach (array(0, 1) as $patch_version) {
|
||||
foreach (array('-alpha1', '-beta1', '') as $extra_version) {
|
||||
$this->setSystemInfo("8.$minor_version.$patch_version" . $extra_version);
|
||||
$this->refreshUpdateStatus(array('drupal' => '9'));
|
||||
$this->standardTests();
|
||||
$this->drupalGet('admin/reports/updates/check');
|
||||
$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.
|
||||
*/
|
||||
function testSecurityUpdateAvailable() {
|
||||
foreach (array(0, 1) as $minor_version) {
|
||||
$this->setSystemInfo("8.$minor_version.0");
|
||||
$this->refreshUpdateStatus(array('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.
|
||||
*/
|
||||
function testDatestampMismatch() {
|
||||
$system_info = array(
|
||||
'#all' => array(
|
||||
// We need to think we're running a -dev snapshot to see dates.
|
||||
'version' => '8.0.0-dev',
|
||||
'datestamp' => time(),
|
||||
),
|
||||
'block' => array(
|
||||
// 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(array('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.
|
||||
*/
|
||||
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', array('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.
|
||||
*/
|
||||
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', array('drupal' => '0.0'))
|
||||
->save();
|
||||
|
||||
$this->drupalGet('admin/reports/updates');
|
||||
$this->clickLink(t('Check manually'));
|
||||
$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.
|
||||
*/
|
||||
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', array('drupal' => '0.1'))
|
||||
->save();
|
||||
|
||||
$this->drupalGet('admin/reports/updates');
|
||||
$this->clickLink(t('Check manually'));
|
||||
$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.
|
||||
*/
|
||||
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', array('drupal' => '0.2-sec'))
|
||||
->save();
|
||||
|
||||
$this->drupalGet('admin/reports/updates');
|
||||
$this->clickLink(t('Check manually'));
|
||||
$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.
|
||||
*/
|
||||
function testServiceUnavailable() {
|
||||
$this->refreshUpdateStatus(array(), '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.
|
||||
*/
|
||||
function testFetchTasks() {
|
||||
$projecta = array(
|
||||
'name' => 'aaa_update_test',
|
||||
);
|
||||
$projectb = array(
|
||||
'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.
|
||||
*/
|
||||
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', array('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(array('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,52 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\update\Tests\UpdateDeleteFileIfStaleTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\update\Tests;
|
||||
|
||||
/**
|
||||
* Tests the update_delete_file_if_stale() function.
|
||||
*
|
||||
* @group update
|
||||
*/
|
||||
class UpdateDeleteFileIfStaleTest extends UpdateTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('update');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the deletion of stale files.
|
||||
*/
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
62
core/modules/update/src/Tests/UpdateTestBase.php
Normal file
62
core/modules/update/src/Tests/UpdateTestBase.php
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\update\Tests\UpdateTestBase.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace Drupal\update\Tests;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Defines some shared functions used by all update tests.
|
||||
*/
|
||||
abstract class UpdateTestBase extends WebTestBase {
|
||||
|
||||
/**
|
||||
* 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, array('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/check');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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'));
|
||||
}
|
||||
}
|
127
core/modules/update/src/Tests/UpdateUploadTest.php
Normal file
127
core/modules/update/src/Tests/UpdateUploadTest.php
Normal file
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\update\Tests\UpdateUploadTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\update\Tests;
|
||||
|
||||
use Drupal\Core\Updater\Updater;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Tests the Update Manager module's upload and extraction functionality.
|
||||
*
|
||||
* @group update
|
||||
*/
|
||||
class UpdateUploadTest extends UpdateTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('update', 'update_test');
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$admin_user = $this->drupalCreateUser(array('administer software updates', 'administer site configuration'));
|
||||
$this->drupalLogin($admin_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests upload and extraction of a module.
|
||||
*/
|
||||
public function testUploadModule() {
|
||||
// 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 = array(
|
||||
'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.', array('@archive_extensions' => archiver_get_extensions())),'Only valid archives can be uploaded.');
|
||||
|
||||
// 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 = drupal_get_path('module', 'update') . '/tests/aaa_update_test.tar.gz';
|
||||
$edit = array(
|
||||
'files[project_upload]' => $validArchiveFile,
|
||||
);
|
||||
$this->drupalPostForm('admin/modules/install', $edit, t('Install'));
|
||||
$this->assertText(t('@module_name is already installed.', array('@module_name' => 'AAA Update test')), 'Existing module was extracted and not reinstalled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that archiver extensions are properly merged in the UI.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
function testUpdateManagerCoreSecurityUpdateMessages() {
|
||||
$setting = array(
|
||||
'#all' => array(
|
||||
'version' => '8.0.0',
|
||||
),
|
||||
);
|
||||
$this->config('update_test.settings')
|
||||
->set('system_info', $setting)
|
||||
->set('xml_map', array('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.');
|
||||
}
|
||||
|
||||
}
|
Reference in a new issue