Skip to content
Snippets Groups Projects
Commit 189d7cc4 authored by Jess's avatar Jess
Browse files

Issue #3113992 by dww, tedbow, xjm, Meenakshi.g, benjifisher, kualee,...

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

(cherry picked from commit 949038a0)
parent 643bea89
No related branches found
No related tags found
No related merge requests found
......@@ -197,42 +197,49 @@ public function buildForm(array $form, FormStateInterface $form_state) {
// 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;
case 'module':
case 'theme':
$projects['enabled'][$name] = $entry;
break;
case 'module-disabled':
case 'theme-disabled':
$projects['disabled'][$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-disabled':
case 'theme-disabled':
$projects['disabled'][$name] = $entry;
break;
}
}
}
......@@ -295,9 +302,45 @@ public function buildForm(array $form, FormStateInterface $form_state) {
];
}
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}
*/
......
<?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>
<?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>
<?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);
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment