Issue #3113992 by dww, tedbow, xjm, Meenakshi.g, benjifisher, kualee, tim.plunkett, webchick, AaronMcHale, ckrina, shaal, mandclu, klonos, lauriii, Gábor Hojtsy, worldlinemine, alexpott: The 'Update' page has no idea that some updates are incompatible
parent
8cefc6c159
commit
949038a0aa
|
@ -199,42 +199,49 @@ class UpdateManagerUpdate extends FormBase {
|
|||
// Drupal core needs to be upgraded manually.
|
||||
$needs_manual = $project['project_type'] == 'core';
|
||||
|
||||
// If the recommended release for a contributed project is not compatible
|
||||
// with the currently installed version of core, list that project in a
|
||||
// separate table. To determine if the release is compatible, we inspect
|
||||
// the 'core_compatible' key from the release info array. If it's not
|
||||
// defined, it means we can't determine compatibility requirements (or
|
||||
// we're looking at core), so we assume it is compatible.
|
||||
$compatible = $recommended_release['core_compatible'] ?? TRUE;
|
||||
|
||||
if ($needs_manual) {
|
||||
// There are no checkboxes in the 'Manual updates' table so it will be
|
||||
// rendered by '#theme' => 'table', not '#theme' => 'tableselect'. Since
|
||||
// the data formats are incompatible, we convert now to the format
|
||||
// expected by '#theme' => 'table'.
|
||||
unset($entry['#weight']);
|
||||
$attributes = $entry['#attributes'];
|
||||
unset($entry['#attributes']);
|
||||
$entry = [
|
||||
'data' => $entry,
|
||||
] + $attributes;
|
||||
$this->removeCheckboxFromRow($entry);
|
||||
$projects['manual'][$name] = $entry;
|
||||
}
|
||||
elseif (!$compatible) {
|
||||
$this->removeCheckboxFromRow($entry);
|
||||
// If the release has a core_compatibility_message, inject it.
|
||||
if (!empty($recommended_release['core_compatibility_message'])) {
|
||||
// @todo In https://www.drupal.org/project/drupal/issues/3121769
|
||||
// refactor this into something theme-friendly so we don't have a
|
||||
// classless <div> here.
|
||||
$entry['data']['recommended_version']['data']['#template'] .= ' <div>{{ core_compatibility_message }}</div>';
|
||||
$entry['data']['recommended_version']['data']['#context']['core_compatibility_message'] = $recommended_release['core_compatibility_message'];
|
||||
}
|
||||
$projects['not-compatible'][$name] = $entry;
|
||||
}
|
||||
else {
|
||||
$form['project_downloads'][$name] = [
|
||||
'#type' => 'value',
|
||||
'#value' => $recommended_release['download_link'],
|
||||
];
|
||||
}
|
||||
|
||||
// Based on what kind of project this is, save the entry into the
|
||||
// appropriate subarray.
|
||||
switch ($project['project_type']) {
|
||||
case 'core':
|
||||
// Core needs manual updates at this time.
|
||||
$projects['manual'][$name] = $entry;
|
||||
break;
|
||||
// Based on what kind of project this is, save the entry into the
|
||||
// appropriate subarray.
|
||||
switch ($project['project_type']) {
|
||||
case 'module':
|
||||
case 'theme':
|
||||
$projects['enabled'][$name] = $entry;
|
||||
break;
|
||||
|
||||
case 'module':
|
||||
case 'theme':
|
||||
$projects['enabled'][$name] = $entry;
|
||||
break;
|
||||
|
||||
case 'module-disabled':
|
||||
case 'theme-disabled':
|
||||
$projects['disabled'][$name] = $entry;
|
||||
break;
|
||||
case 'module-disabled':
|
||||
case 'theme-disabled':
|
||||
$projects['disabled'][$name] = $entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,9 +304,45 @@ class UpdateManagerUpdate extends FormBase {
|
|||
];
|
||||
}
|
||||
|
||||
if (!empty($projects['not-compatible'])) {
|
||||
$form['not_compatible'] = [
|
||||
'#type' => 'table',
|
||||
'#header' => $headers,
|
||||
'#rows' => $projects['not-compatible'],
|
||||
'#prefix' => '<h2>' . $this->t('Not compatible') . '</h2>',
|
||||
'#weight' => 150,
|
||||
];
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a row entry for use in a regular table, not a 'tableselect'.
|
||||
*
|
||||
* There are no checkboxes in the 'Manual updates' or 'Not compatible' tables,
|
||||
* so they will be rendered by '#theme' => 'table', not 'tableselect'. Since
|
||||
* the data formats are incompatible, this method converts to the format
|
||||
* expected by '#theme' => 'table'. Generally, rows end up in the main tables
|
||||
* that have a checkbox to allow the site admin to select which missing
|
||||
* updates to install. This method is only used for the special case tables
|
||||
* that have no such checkbox.
|
||||
*
|
||||
* @todo In https://www.drupal.org/project/drupal/issues/3121775 refactor
|
||||
* self::buildForm() so that we don't need this method at all.
|
||||
*
|
||||
* @param array[] $row
|
||||
* The render array for a table row.
|
||||
*/
|
||||
protected function removeCheckboxFromRow(array &$row) {
|
||||
unset($row['#weight']);
|
||||
$attributes = $row['#attributes'];
|
||||
unset($row['#attributes']);
|
||||
$row = [
|
||||
'data' => $row,
|
||||
] + $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This fixture is used by Drupal\Tests\update\Functional\UpdateManagerUpdateTest.
|
||||
|
||||
It contains 2 releases, 8.x-1.0 (which is the currently installed version) and
|
||||
8.x-1.1, which is the only available update.
|
||||
|
||||
To ensure we've got test coverage for the case where the '<core_compatibility>'
|
||||
tag is not defined at all, this fixture does not include that value.
|
||||
-->
|
||||
<project xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<title>BBB Update test</title>
|
||||
<short_name>bbb_update_test</short_name>
|
||||
<dc:creator>Drupal</dc:creator>
|
||||
<supported_branches>8.x-1.</supported_branches>
|
||||
<project_status>published</project_status>
|
||||
<link>http://example.com/project/bbb_update_test</link>
|
||||
<terms>
|
||||
<term><name>Projects</name><value>Modules</value></term>
|
||||
</terms>
|
||||
<releases>
|
||||
<release>
|
||||
<name>bbb_update_test 8.x-1.1</name>
|
||||
<version>8.x-1.1</version>
|
||||
<tag>8.x-1.1</tag>
|
||||
<status>published</status>
|
||||
<release_link>http://example.com/bbb_update_test-8-x-1-1-release</release_link>
|
||||
<download_link>http://example.com/bbb_update_test-8.x-1.1.tar.gz</download_link>
|
||||
<date>1250444521</date>
|
||||
<terms>
|
||||
<term><name>Release type</name><value>Bug fixes</value></term>
|
||||
</terms>
|
||||
</release>
|
||||
<release>
|
||||
<name>bbb_update_test 8.x-1.0</name>
|
||||
<version>8.x-1.0</version>
|
||||
<tag>8.x-1.0</tag>
|
||||
<status>published</status>
|
||||
<release_link>http://example.com/bbb_update_test-8-x-1-0-release</release_link>
|
||||
<download_link>http://example.com/bbb_update_test-8.x-1.0.tar.gz</download_link>
|
||||
<date>1250424521</date>
|
||||
<terms>
|
||||
<term><name>Release type</name><value>New features</value></term>
|
||||
<term><name>Release type</name><value>Bug fixes</value></term>
|
||||
</terms>
|
||||
</release>
|
||||
</releases>
|
||||
</project>
|
|
@ -0,0 +1,62 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This fixture is used by Drupal\Tests\update\Functional\UpdateManagerUpdateTest.
|
||||
|
||||
It contains 3 releases:
|
||||
- 8.x-1.0: The currently installed version in the test scenarios.
|
||||
- 8.x-1.1: An available update that does not specify '<core_compatibility>'.
|
||||
- 8.x-1.2: An available update that uses '<core_compatibility>' to require at
|
||||
least Drupal core version 8.1.0. Since the currently installed Drupal core
|
||||
for the tests is 8.0.0, this release will be flagged as 'Not compatible'.
|
||||
-->
|
||||
<project xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<title>BBB Update test</title>
|
||||
<short_name>bbb_update_test</short_name>
|
||||
<dc:creator>Drupal</dc:creator>
|
||||
<supported_branches>8.x-1.</supported_branches>
|
||||
<project_status>published</project_status>
|
||||
<link>http://example.com/project/bbb_update_test</link>
|
||||
<terms>
|
||||
<term><name>Projects</name><value>Modules</value></term>
|
||||
</terms>
|
||||
<releases>
|
||||
<release>
|
||||
<name>bbb_update_test 8.x-1.2</name>
|
||||
<version>8.x-1.2</version>
|
||||
<tag>8.x-1.2</tag>
|
||||
<core_compatibility>^8.1.0</core_compatibility>
|
||||
<status>published</status>
|
||||
<release_link>http://example.com/bbb_update_test-8-x-1-2-release</release_link>
|
||||
<download_link>http://example.com/bbb_update_test-8.x-1.2.tar.gz</download_link>
|
||||
<date>1250445521</date>
|
||||
<terms>
|
||||
<term><name>Release type</name><value>Bug fixes</value></term>
|
||||
</terms>
|
||||
</release>
|
||||
<release>
|
||||
<name>bbb_update_test 8.x-1.1</name>
|
||||
<version>8.x-1.1</version>
|
||||
<tag>8.x-1.1</tag>
|
||||
<status>published</status>
|
||||
<release_link>http://example.com/bbb_update_test-8-x-1-1-release</release_link>
|
||||
<download_link>http://example.com/bbb_update_test-8.x-1.1.tar.gz</download_link>
|
||||
<date>1250444521</date>
|
||||
<terms>
|
||||
<term><name>Release type</name><value>Bug fixes</value></term>
|
||||
</terms>
|
||||
</release>
|
||||
<release>
|
||||
<name>bbb_update_test 8.x-1.0</name>
|
||||
<version>8.x-1.0</version>
|
||||
<tag>8.x-1.0</tag>
|
||||
<status>published</status>
|
||||
<release_link>http://example.com/bbb_update_test-8-x-1-0-release</release_link>
|
||||
<download_link>http://example.com/bbb_update_test-8.x-1.0.tar.gz</download_link>
|
||||
<date>1250424521</date>
|
||||
<terms>
|
||||
<term><name>Release type</name><value>New features</value></term>
|
||||
<term><name>Release type</name><value>Bug fixes</value></term>
|
||||
</terms>
|
||||
</release>
|
||||
</releases>
|
||||
</project>
|
|
@ -0,0 +1,236 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\update\Functional;
|
||||
|
||||
/**
|
||||
* Tests the Update Manager module's 'Update' form and functionality.
|
||||
*
|
||||
* @todo In https://www.drupal.org/project/drupal/issues/3117229 expand this.
|
||||
*
|
||||
* @group update
|
||||
*/
|
||||
class UpdateManagerUpdateTest extends UpdateTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $modules = [
|
||||
'update',
|
||||
'update_test',
|
||||
'aaa_update_test',
|
||||
'bbb_update_test',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $defaultTheme = 'stark';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$admin_user = $this->drupalCreateUser([
|
||||
'administer software updates',
|
||||
'administer site configuration',
|
||||
]);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
// The installed state of the system is the same for all test cases. What
|
||||
// varies for each test scenario is which release history fixture we fetch,
|
||||
// which in turn changes the expected state of the UpdateManagerUpdateForm.
|
||||
$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,
|
||||
],
|
||||
];
|
||||
$this->config('update_test.settings')->set('system_info', $system_info)->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides data for test scenarios involving incompatible updates.
|
||||
*
|
||||
* These test cases rely on the following fixtures containing the following
|
||||
* releases:
|
||||
* - aaa_update_test.8.x-1.2.xml
|
||||
* - 8.x-1.2 Compatible with 8.0.0 core.
|
||||
* - aaa_update_test.core_compatibility.8.x-1.2_8.x-2.2.xml
|
||||
* - 8.x-1.2 Requires 8.1.0 and above.
|
||||
* - bbb_update_test.1_0.xml
|
||||
* - 8.x-1.0 is the only available release.
|
||||
* - bbb_update_test.1_1.xml
|
||||
* - 8.x-1.1 is available and compatible with everything (does not define
|
||||
* <core_compatibility> at all).
|
||||
* - bbb_update_test.1_2.xml
|
||||
* - 8.x-1.1 is available and compatible with everything (does not define
|
||||
* <core_compatibility> at all).
|
||||
* - 8.x-1.2 is available and requires Drupal 8.1.0 and above.
|
||||
*
|
||||
* @todo In https://www.drupal.org/project/drupal/issues/3112962:
|
||||
* Change the 'core_fixture' values here to use:
|
||||
* - '1.1' instead of '1.1-core_compatibility'.
|
||||
* - '1.1-alpha1' instead of '1.1-alpha1-core_compatibility'.
|
||||
* Delete the files:
|
||||
* - core/modules/update/tests/modules/update_test/drupal.1.1-alpha1-core_compatibility.xml
|
||||
* - core/modules/update/tests/modules/update_test/drupal.1.1-core_compatibility.xml
|
||||
*
|
||||
* @return array[]
|
||||
* Test data.
|
||||
*/
|
||||
public function incompatibleUpdatesTableProvider() {
|
||||
return [
|
||||
'only one compatible' => [
|
||||
'core_fixture' => '1.1-core_compatibility',
|
||||
// aaa_update_test.8.x-1.2.xml has core compatibility set and will test
|
||||
// the case where $recommended_release['core_compatible'] === TRUE in
|
||||
// \Drupal\update\Form\UpdateManagerUpdate.
|
||||
'a_fixture' => '8.x-1.2',
|
||||
// Use a fixture with only a 8.x-1.0 release so BBB is up to date.
|
||||
'b_fixture' => '1_0',
|
||||
'compatible' => [
|
||||
'AAA' => '8.x-1.2',
|
||||
],
|
||||
'incompatible' => [],
|
||||
],
|
||||
'only one incompatible' => [
|
||||
'core_fixture' => '1.1-core_compatibility',
|
||||
'a_fixture' => 'core_compatibility.8.x-1.2_8.x-2.2',
|
||||
// Use a fixture with only a 8.x-1.0 release so BBB is up to date.
|
||||
'b_fixture' => '1_0',
|
||||
'compatible' => [],
|
||||
'incompatible' => [
|
||||
'AAA' => [
|
||||
'recommended' => '8.x-1.2',
|
||||
'range' => '8.1.0 to 8.1.1',
|
||||
],
|
||||
],
|
||||
],
|
||||
'two compatible, no incompatible' => [
|
||||
'core_fixture' => '1.1-core_compatibility',
|
||||
'a_fixture' => '8.x-1.2',
|
||||
// bbb_update_test.1_1.xml does not have core compatibility set and will
|
||||
// test the case where $recommended_release['core_compatible'] === NULL
|
||||
// in \Drupal\update\Form\UpdateManagerUpdate.
|
||||
'b_fixture' => '1_1',
|
||||
'compatible' => [
|
||||
'AAA' => '8.x-1.2',
|
||||
'BBB' => '8.x-1.1',
|
||||
],
|
||||
'incompatible' => [],
|
||||
],
|
||||
'two incompatible, no compatible' => [
|
||||
'core_fixture' => '1.1-core_compatibility',
|
||||
'a_fixture' => 'core_compatibility.8.x-1.2_8.x-2.2',
|
||||
// bbb_update_test.1_2.xml has core compatibility set and will test the
|
||||
// case where $recommended_release['core_compatible'] === FALSE in
|
||||
// \Drupal\update\Form\UpdateManagerUpdate.
|
||||
'b_fixture' => '1_2',
|
||||
'compatible' => [],
|
||||
'incompatible' => [
|
||||
'AAA' => [
|
||||
'recommended' => '8.x-1.2',
|
||||
'range' => '8.1.0 to 8.1.1',
|
||||
],
|
||||
'BBB' => [
|
||||
'recommended' => '8.x-1.2',
|
||||
'range' => '8.1.0 to 8.1.1',
|
||||
],
|
||||
],
|
||||
],
|
||||
'one compatible, one incompatible' => [
|
||||
'core_fixture' => '1.1-core_compatibility',
|
||||
'a_fixture' => 'core_compatibility.8.x-1.2_8.x-2.2',
|
||||
'b_fixture' => '1_1',
|
||||
'compatible' => [
|
||||
'BBB' => '8.x-1.1',
|
||||
],
|
||||
'incompatible' => [
|
||||
'AAA' => [
|
||||
'recommended' => '8.x-1.2',
|
||||
'range' => '8.1.0 to 8.1.1',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Update form for a single test scenario of incompatible updates.
|
||||
*
|
||||
* @dataProvider incompatibleUpdatesTableProvider
|
||||
*
|
||||
* @param string $core_fixture
|
||||
* The fixture file to use for Drupal core.
|
||||
* @param string $a_fixture
|
||||
* The fixture file to use for the aaa_update_test module.
|
||||
* @param string $b_fixture
|
||||
* The fixture file to use for the bbb_update_test module.
|
||||
* @param string[] $compatible
|
||||
* Compatible recommended updates (if any). Keys are module identifier
|
||||
* ('AAA' or 'BBB') and values are the expected recommended release.
|
||||
* @param string[][] $incompatible
|
||||
* Incompatible recommended updates (if any). Keys are module identifier
|
||||
* ('AAA' or 'BBB') and values are subarrays with the following keys:
|
||||
* - 'recommended': The recommended version.
|
||||
* - 'range': The versions of Drupal core required for that version.
|
||||
*/
|
||||
public function testIncompatibleUpdatesTable($core_fixture, $a_fixture, $b_fixture, array $compatible, array $incompatible) {
|
||||
|
||||
$assert_session = $this->assertSession();
|
||||
$compatible_table_locator = '[data-drupal-selector="edit-projects"]';
|
||||
$incompatible_table_locator = '[data-drupal-selector="edit-not-compatible"]';
|
||||
|
||||
$this->refreshUpdateStatus(['drupal' => $core_fixture, 'aaa_update_test' => $a_fixture, 'bbb_update_test' => $b_fixture]);
|
||||
$this->drupalGet('admin/reports/updates/update');
|
||||
|
||||
if ($compatible) {
|
||||
// Verify the number of rows in the table.
|
||||
$assert_session->elementsCount('css', "$compatible_table_locator tbody tr", count($compatible));
|
||||
// We never want to see a compatibility range in the compatible table.
|
||||
$assert_session->elementTextNotContains('css', $compatible_table_locator, 'Requires Drupal core');
|
||||
foreach ($compatible as $module => $version) {
|
||||
$compatible_row = "$compatible_table_locator tbody tr:contains('$module Update test')";
|
||||
// First <td> is the checkbox, so start with td #2.
|
||||
$assert_session->elementTextContains('css', "$compatible_row td:nth-of-type(2)", "$module Update test");
|
||||
// Both contrib modules use 8.x-1.0 as the currently installed version.
|
||||
$assert_session->elementTextContains('css', "$compatible_row td:nth-of-type(3)", '8.x-1.0');
|
||||
$assert_session->elementTextContains('css', "$compatible_row td:nth-of-type(4)", $version);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Verify there is no compatible updates table.
|
||||
$assert_session->elementNotExists('css', $compatible_table_locator);
|
||||
}
|
||||
|
||||
if ($incompatible) {
|
||||
// Verify the number of rows in the table.
|
||||
$assert_session->elementsCount('css', "$incompatible_table_locator tbody tr", count($incompatible));
|
||||
foreach ($incompatible as $module => $data) {
|
||||
$incompatible_row = "$incompatible_table_locator tbody tr:contains('$module Update test')";
|
||||
$assert_session->elementTextContains('css', "$incompatible_row td:nth-of-type(1)", "$module Update test");
|
||||
// Both contrib modules use 8.x-1.0 as the currently installed version.
|
||||
$assert_session->elementTextContains('css', "$incompatible_row td:nth-of-type(2)", '8.x-1.0');
|
||||
$assert_session->elementTextContains('css', "$incompatible_row td:nth-of-type(3)", $data['recommended']);
|
||||
$assert_session->elementTextContains('css', "$incompatible_row td:nth-of-type(3)", 'Requires Drupal core: ' . $data['range']);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Verify there is no incompatible updates table.
|
||||
$assert_session->elementNotExists('css', $incompatible_table_locator);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue