Commit 0680aa06 authored by xjm's avatar xjm

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 1b68fb8f
......@@ -199,42 +199,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;
}
}
}
......@@ -297,9 +304,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);
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment