Unverified Commit 0b8ffb42 authored by alexpott's avatar alexpott
Browse files

Issue #2870443 by Tessa Bakker, Lendude, michielnugter, dawehner: Convert web...

Issue #2870443 by Tessa Bakker, Lendude, michielnugter, dawehner: Convert web tests to browser tests for editor module
parent f6c164cd
<?php
namespace Drupal\editor\Tests;
namespace Drupal\Tests\editor\Functional;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\filter\Entity\FilterFormat;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\simpletest\WebTestBase;
use Drupal\Tests\BrowserTestBase;
/**
* Tests administration of text editors.
*
* @group editor
*/
class EditorAdminTest extends WebTestBase {
class EditorAdminTest extends BrowserTestBase {
/**
* Modules to enable.
......@@ -64,8 +65,8 @@ public function testNoEditorAvailable() {
$this->assertTrue(count($select) === 1, 'The Text Editor select exists.');
$this->assertTrue(count($select_is_disabled) === 1, 'The Text Editor select is disabled.');
$this->assertTrue(count($options) === 1, 'The Text Editor select has only one option.');
$this->assertTrue(((string) $options[0]) === 'None', 'Option 1 in the Text Editor select is "None".');
$this->assertRaw(t('This option is disabled because no modules that provide a text editor are currently enabled.'), 'Description for select present that tells users to install a text editor module.');
$this->assertTrue(($options[0]->getText()) === 'None', 'Option 1 in the Text Editor select is "None".');
$this->assertRaw('This option is disabled because no modules that provide a text editor are currently enabled.', 'Description for select present that tells users to install a text editor module.');
}
/**
......@@ -85,7 +86,7 @@ public function testAddEditorToExistingFormat() {
$edit = [
'editor[editor]' => '',
];
$this->drupalPostAjaxForm(NULL, $edit, 'editor_configure');
$this->drupalPostForm(NULL, $edit, 'Configure');
$unicorn_setting = $this->xpath('//input[@name="editor[settings][ponies_too]" and @type="checkbox" and @checked]');
$this->assertTrue(count($unicorn_setting) === 0, "Unicorn Editor's settings form is no longer present.");
}
......@@ -134,7 +135,7 @@ public function testDisableFormatWithEditor() {
$this->drupalLogin($account);
// The node edit page header.
$text = t('<em>Edit @type</em> @title', ['@type' => $node_type->label(), '@title' => $node->label()]);
$text = (string) new FormattableMarkup('<em>Edit @type</em> @title', ['@type' => $node_type->label(), '@title' => $node->label()]);
// Go to node edit form.
$this->drupalGet('node/' . $node->id() . '/edit');
......@@ -192,17 +193,17 @@ protected function selectUnicornEditor() {
$this->assertTrue(count($select) === 1, 'The Text Editor select exists.');
$this->assertTrue(count($select_is_disabled) === 0, 'The Text Editor select is not disabled.');
$this->assertTrue(count($options) === 2, 'The Text Editor select has two options.');
$this->assertTrue(((string) $options[0]) === 'None', 'Option 1 in the Text Editor select is "None".');
$this->assertTrue(((string) $options[1]) === 'Unicorn Editor', 'Option 2 in the Text Editor select is "Unicorn Editor".');
$this->assertTrue(((string) $options[0]['selected']) === 'selected', 'Option 1 ("None") is selected.');
$this->assertTrue(($options[0]->getText()) === 'None', 'Option 1 in the Text Editor select is "None".');
$this->assertTrue(($options[1]->getText()) === 'Unicorn Editor', 'Option 2 in the Text Editor select is "Unicorn Editor".');
$this->assertTrue($options[0]->hasAttribute('selected'), 'Option 1 ("None") is selected.');
// Ensure the none option is selected.
$this->assertNoRaw(t('This option is disabled because no modules that provide a text editor are currently enabled.'), 'Description for select absent that tells users to install a text editor module.');
$this->assertNoRaw('This option is disabled because no modules that provide a text editor are currently enabled.', 'Description for select absent that tells users to install a text editor module.');
// Select the "Unicorn Editor" editor and click the "Configure" button.
$edit = [
'editor[editor]' => 'unicorn',
];
$this->drupalPostAjaxForm(NULL, $edit, 'editor_configure');
$this->drupalPostForm(NULL, $edit, 'Configure');
$unicorn_setting = $this->xpath('//input[@name="editor[settings][ponies_too]" and @type="checkbox" and @checked]');
$this->assertTrue(count($unicorn_setting), "Unicorn Editor's settings form is present.");
......@@ -229,7 +230,7 @@ protected function verifyUnicornEditorConfiguration($format_id, $ponies_too = TR
$this->assertTrue(count($select) === 1, 'The Text Editor select exists.');
$this->assertTrue(count($select_is_disabled) === 0, 'The Text Editor select is not disabled.');
$this->assertTrue(count($options) === 2, 'The Text Editor select has two options.');
$this->assertTrue(((string) $options[1]['selected']) === 'selected', 'Option 2 ("Unicorn Editor") is selected.');
$this->assertTrue($options[1]->hasAttribute('selected'), 'Option 2 ("Unicorn Editor") is selected.');
}
}
<?php
namespace Drupal\editor\Tests;
namespace Drupal\Tests\editor\Functional;
use Drupal\editor\Entity\Editor;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\simpletest\WebTestBase;
use Drupal\filter\Entity\FilterFormat;
use Drupal\Tests\BrowserTestBase;
/**
* Tests loading of text editors.
*
* @group editor
*/
class EditorLoadingTest extends WebTestBase {
class EditorLoadingTest extends BrowserTestBase {
/**
* Modules to enable.
......
<?php
namespace Drupal\editor\Tests;
namespace Drupal\Tests\editor\Functional;
use Drupal\Component\Serialization\Json;
use Drupal\editor\Entity\Editor;
use Drupal\simpletest\WebTestBase;
use Drupal\filter\Entity\FilterFormat;
use Drupal\Tests\BrowserTestBase;
use GuzzleHttp\Cookie\CookieJar;
/**
* Tests XSS protection for content creators when using text editors.
*
* @group editor
*/
class EditorSecurityTest extends WebTestBase {
class EditorSecurityTest extends BrowserTestBase {
/**
* The sample content to use in all tests.
......@@ -283,7 +284,7 @@ public function testInitialSecurity() {
$this->drupalLogin($account);
$this->drupalGet('node/' . $case['node_id'] . '/edit');
$dom_node = $this->xpath('//textarea[@id="edit-body-0-value"]');
$this->assertIdentical($case['value'], (string) $dom_node[0], 'The value was correctly filtered for XSS attack vectors.');
$this->assertIdentical($case['value'], $dom_node[0]->getText(), 'The value was correctly filtered for XSS attack vectors.');
}
}
}
......@@ -389,13 +390,15 @@ public function testSwitchingSecurity() {
// - switch to every other text format/editor
// - assert the XSS-filtered values that we get from the server
$this->drupalLogin($this->privilegedUser);
$cookies = $this->getCookies();
foreach ($expected as $case) {
$this->drupalGet('node/' . $case['node_id'] . '/edit');
// Verify data- attributes.
$dom_node = $this->xpath('//textarea[@id="edit-body-0-value"]');
$this->assertIdentical(self::$sampleContent, (string) $dom_node[0]['data-editor-value-original'], 'The data-editor-value-original attribute is correctly set.');
$this->assertIdentical('false', (string) $dom_node[0]['data-editor-value-is-changed'], 'The data-editor-value-is-changed attribute is correctly set.');
$this->assertIdentical(self::$sampleContent, $dom_node[0]->getAttribute('data-editor-value-original'), 'The data-editor-value-original attribute is correctly set.');
$this->assertIdentical('false', (string) $dom_node[0]->getAttribute('data-editor-value-is-changed'), 'The data-editor-value-is-changed attribute is correctly set.');
// Switch to every other text format/editor and verify the results.
foreach ($case['switch_to'] as $format => $expected_filtered_value) {
......@@ -404,13 +407,25 @@ public function testSwitchingSecurity() {
'%original_format' => $case['format'],
'%format' => $format,
]));
$post = [
'value' => self::$sampleContent,
'original_format_id' => $case['format'],
];
$response = $this->drupalPostWithFormat('editor/filter_xss/' . $format, 'json', $post);
$this->assertResponse(200);
$json = Json::decode($response);
$client = $this->getHttpClient();
$response = $client->post($this->buildUrl('/editor/filter_xss/' . $format), [
'body' => http_build_query($post),
'cookies' => $cookies,
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/x-www-form-urlencoded',
],
'http_errors' => FALSE,
]);
$this->assertEquals(200, $response->getStatusCode());
$json = Json::decode($response->getBody());
$this->assertIdentical($json, $expected_filtered_value, 'The value was correctly filtered for XSS attack vectors.');
}
}
......@@ -424,7 +439,7 @@ public function testEditorXssFilterOverride() {
$this->drupalLogin($this->normalUser);
$this->drupalGet('node/2/edit');
$dom_node = $this->xpath('//textarea[@id="edit-body-0-value"]');
$this->assertIdentical(self::$sampleContentSecured, (string) $dom_node[0], 'The value was filtered by the Standard text editor XSS filter.');
$this->assertIdentical(self::$sampleContentSecured, $dom_node[0]->getText(), 'The value was filtered by the Standard text editor XSS filter.');
// Enable editor_test.module's hook_editor_xss_filter_alter() implementation
// to alter the text editor XSS filter class being used.
......@@ -433,7 +448,21 @@ public function testEditorXssFilterOverride() {
// First: the Insecure text editor XSS filter.
$this->drupalGet('node/2/edit');
$dom_node = $this->xpath('//textarea[@id="edit-body-0-value"]');
$this->assertIdentical(self::$sampleContent, (string) $dom_node[0], 'The value was filtered by the Insecure text editor XSS filter.');
$this->assertIdentical(self::$sampleContent, $dom_node[0]->getText(), 'The value was filtered by the Insecure text editor XSS filter.');
}
/**
* Get session cookies from current session.
*
* @return \GuzzleHttp\Cookie\CookieJar
* A cookie jar with the current session.
*/
protected function getCookies() {
$domain = parse_url($this->getUrl(), PHP_URL_HOST);
$session_id = $this->getSession()->getCookie($this->getSessionName());
$cookies = CookieJar::fromArray([$this->getSessionName() => $session_id], $domain);
return $cookies;
}
}
<?php
namespace Drupal\editor\Tests;
namespace Drupal\Tests\editor\Functional;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\editor\Entity\Editor;
use Drupal\filter\Entity\FilterFormat;
use Drupal\simpletest\WebTestBase;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\TestFileCreationTrait;
/**
* Tests scaling of inline images.
*
* @group editor
*/
class EditorUploadImageScaleTest extends WebTestBase {
class EditorUploadImageScaleTest extends BrowserTestBase {
use TestFileCreationTrait;
/**
* Modules to enable.
......@@ -66,7 +70,7 @@ protected function setUp() {
*/
public function testEditorUploadImageScale() {
// Generate testing images.
$testing_image_list = $this->drupalGetTestFiles('image');
$testing_image_list = $this->getTestFiles('image');
// Case 1: no max dimensions set: uploaded image not scaled.
$test_image = $testing_image_list[0];
......@@ -78,7 +82,7 @@ public function testEditorUploadImageScale() {
list($uploaded_image_file_width, $uploaded_image_file_height) = $this->uploadImage($test_image->uri);
$this->assertEqual($uploaded_image_file_width, $image_file_width);
$this->assertEqual($uploaded_image_file_height, $image_file_height);
$this->assertNoRaw(t('The image was resized to fit within the maximum allowed dimensions of %dimensions pixels.', ['%dimensions' => $max_width . 'x' . $max_height]));
$this->assertNoRaw((string) new FormattableMarkup('The image was resized to fit within the maximum allowed dimensions of %dimensions pixels.', ['%dimensions' => $max_width . 'x' . $max_height]));
// Case 2: max width smaller than uploaded image: image scaled down.
$test_image = $testing_image_list[1];
......@@ -90,7 +94,7 @@ public function testEditorUploadImageScale() {
list($uploaded_image_file_width, $uploaded_image_file_height) = $this->uploadImage($test_image->uri);
$this->assertEqual($uploaded_image_file_width, $max_width);
$this->assertEqual($uploaded_image_file_height, $uploaded_image_file_height * ($uploaded_image_file_width / $max_width));
$this->assertRaw(t('The image was resized to fit within the maximum allowed dimensions of %dimensions pixels.', ['%dimensions' => $max_width . 'x' . $max_height]));
$this->assertRaw((string) new FormattableMarkup('The image was resized to fit within the maximum allowed dimensions of %dimensions pixels.', ['%dimensions' => $max_width . 'x' . $max_height]));
// Case 3: max height smaller than uploaded image: image scaled down.
$test_image = $testing_image_list[2];
......@@ -102,7 +106,7 @@ public function testEditorUploadImageScale() {
list($uploaded_image_file_width, $uploaded_image_file_height) = $this->uploadImage($test_image->uri);
$this->assertEqual($uploaded_image_file_width, $uploaded_image_file_width * ($uploaded_image_file_height / $max_height));
$this->assertEqual($uploaded_image_file_height, $max_height);
$this->assertRaw(t('The image was resized to fit within the maximum allowed dimensions of %dimensions pixels.', ['%dimensions' => $max_width . 'x' . $max_height]));
$this->assertRaw((string) new FormattableMarkup('The image was resized to fit within the maximum allowed dimensions of %dimensions pixels.', ['%dimensions' => $max_width . 'x' . $max_height]));
// Case 4: max dimensions greater than uploaded image: image not scaled.
$test_image = $testing_image_list[3];
......@@ -114,7 +118,7 @@ public function testEditorUploadImageScale() {
list($uploaded_image_file_width, $uploaded_image_file_height) = $this->uploadImage($test_image->uri);
$this->assertEqual($uploaded_image_file_width, $image_file_width);
$this->assertEqual($uploaded_image_file_height, $image_file_height);
$this->assertNoRaw(t('The image was resized to fit within the maximum allowed dimensions of %dimensions pixels.', ['%dimensions' => $max_width . 'x' . $max_height]));
$this->assertNoRaw((string) new FormattableMarkup('The image was resized to fit within the maximum allowed dimensions of %dimensions pixels.', ['%dimensions' => $max_width . 'x' . $max_height]));
// Case 5: only max width dimension was provided and it was smaller than
// uploaded image: image scaled down.
......@@ -127,7 +131,7 @@ public function testEditorUploadImageScale() {
list($uploaded_image_file_width, $uploaded_image_file_height) = $this->uploadImage($test_image->uri);
$this->assertEqual($uploaded_image_file_width, $max_width);
$this->assertEqual($uploaded_image_file_height, $uploaded_image_file_height * ($uploaded_image_file_width / $max_width));
$this->assertRaw(t('The image was resized to fit within the maximum allowed width of %width pixels.', ['%width' => $max_width]));
$this->assertRaw((string) new FormattableMarkup('The image was resized to fit within the maximum allowed width of %width pixels.', ['%width' => $max_width]));
// Case 6: only max height dimension was provided and it was smaller than
// uploaded image: image scaled down.
......@@ -140,7 +144,7 @@ public function testEditorUploadImageScale() {
list($uploaded_image_file_width, $uploaded_image_file_height) = $this->uploadImage($test_image->uri);
$this->assertEqual($uploaded_image_file_width, $uploaded_image_file_width * ($uploaded_image_file_height / $max_height));
$this->assertEqual($uploaded_image_file_height, $max_height);
$this->assertRaw(t('The image was resized to fit within the maximum allowed height of %height pixels.', ['%height' => $max_height]));
$this->assertRaw((string) new FormattableMarkup('The image was resized to fit within the maximum allowed height of %height pixels.', ['%height' => $max_height]));
}
/**
......
<?php
namespace Drupal\editor\Tests;
namespace Drupal\Tests\editor\Functional;
use Drupal\Component\Serialization\Json;
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
use Drupal\simpletest\WebTestBase;
use Drupal\filter\Entity\FilterFormat;
use Drupal\Tests\BrowserTestBase;
use GuzzleHttp\Cookie\CookieJar;
/**
* Tests Quick Edit module integration endpoints.
*
* @group editor
*/
class QuickEditIntegrationLoadingTest extends WebTestBase {
class QuickEditIntegrationLoadingTest extends BrowserTestBase {
/**
* Modules to enable.
......@@ -84,17 +85,30 @@ public function testUsersWithoutPermission() {
// Ensure the text is transformed.
$this->assertRaw('<p>Do you also love Drupal?</p><figure role="group" class="caption caption-img"><img src="druplicon.png" /><figcaption>Druplicon</figcaption></figure>');
$client = $this->getHttpClient();
// Retrieving the untransformed text should result in an 403 response and
// return a different error message depending of the missing permission.
$response = $this->drupalPost('editor/' . 'node/1/body/en/full', '', [], ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
$this->assertResponse(403);
$response = $client->post($this->buildUrl('editor/node/1/body/en/full'), [
'query' => http_build_query([MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']),
'cookies' => $this->getCookies(),
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/x-www-form-urlencoded',
],
'http_errors' => FALSE,
]);
$this->assertEquals(403, $response->getStatusCode());
if (!$user->hasPermission('access in-place editing')) {
$message = "The 'access in-place editing' permission is required.";
}
else {
$message = '';
}
$this->assertIdentical(Json::encode(['message' => $message]), $response);
$body = Json::decode($response->getBody());
$this->assertIdentical($message, $body['message']);
}
}
......@@ -108,13 +122,35 @@ public function testUserWithPermission() {
// Ensure the text is transformed.
$this->assertRaw('<p>Do you also love Drupal?</p><figure role="group" class="caption caption-img"><img src="druplicon.png" /><figcaption>Druplicon</figcaption></figure>');
$client = $this->getHttpClient();
$response = $client->post($this->buildUrl('editor/node/1/body/en/full'), [
'query' => http_build_query([MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']),
'cookies' => $this->getCookies(),
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/x-www-form-urlencoded',
],
'http_errors' => FALSE,
]);
$response = $this->drupalPost('editor/' . 'node/1/body/en/full', '', [], ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
$this->assertResponse(200);
$ajax_commands = Json::decode($response);
$this->assertEquals(200, $response->getStatusCode());
$ajax_commands = Json::decode($response->getBody());
$this->assertIdentical(1, count($ajax_commands), 'The untransformed text POST request results in one AJAX command.');
$this->assertIdentical('editorGetUntransformedText', $ajax_commands[0]['command'], 'The first AJAX command is an editorGetUntransformedText command.');
$this->assertIdentical('<p>Do you also love Drupal?</p><img src="druplicon.png" data-caption="Druplicon" />', $ajax_commands[0]['data'], 'The editorGetUntransformedText command contains the expected data.');
}
/**
* Get session cookies from current session.
*
* @return \GuzzleHttp\Cookie\CookieJar
*/
protected function getCookies() {
$domain = parse_url($this->getUrl(), PHP_URL_HOST);
$session_id = $this->getSession()->getCookie($this->getSessionName());
$cookies = CookieJar::fromArray([$this->getSessionName() => $session_id], $domain);
return $cookies;
}
}
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