diff --git a/core/modules/image/src/Tests/ImageFieldTestBase.php b/core/modules/image/src/Tests/ImageFieldTestBase.php
index 0623b6e92f..498f73f30e 100644
--- a/core/modules/image/src/Tests/ImageFieldTestBase.php
+++ b/core/modules/image/src/Tests/ImageFieldTestBase.php
@@ -2,6 +2,8 @@
namespace Drupal\image\Tests;
+@trigger_error('The ' . __NAMESPACE__ . '\ImageFieldTestBase is deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.0. Use \Drupal\Tests\image\Functional\ImageFieldTestBase instead. See https://www.drupal.org/node/2863626.', E_USER_DEPRECATED);
+
use Drupal\Tests\image\Kernel\ImageFieldCreationTrait;
use Drupal\simpletest\WebTestBase;
diff --git a/core/modules/image/src/Tests/FileMoveTest.php b/core/modules/image/tests/src/Functional/FileMoveTest.php
similarity index 83%
rename from core/modules/image/src/Tests/FileMoveTest.php
rename to core/modules/image/tests/src/Functional/FileMoveTest.php
index d9ce27f75d..3cf3be71b8 100644
--- a/core/modules/image/src/Tests/FileMoveTest.php
+++ b/core/modules/image/tests/src/Functional/FileMoveTest.php
@@ -1,17 +1,23 @@
drupalGet("admin/structure/types/manage/article/display");
// Test for existence of link to image styles configuration.
- $this->drupalPostAjaxForm(NULL, [], "{$field_name}_settings_edit");
+ $this->drupalPostForm(NULL, [], "{$field_name}_settings_edit");
$this->assertLinkByHref(\Drupal::url('entity.image_style.collection'), 0, 'Link to image styles configuration is found');
// Remove 'administer image styles' permission from testing admin user.
@@ -65,7 +73,7 @@ public function _testImageFieldFormatters($scheme) {
$this->drupalGet("admin/structure/types/manage/article/display");
// Test for absence of link to image styles configuration.
- $this->drupalPostAjaxForm(NULL, [], "{$field_name}_settings_edit");
+ $this->drupalPostForm(NULL, [], "{$field_name}_settings_edit");
$this->assertNoLinkByHref(\Drupal::url('entity.image_style.collection'), 'Link to image styles configuration is absent when permissions are insufficient');
// Restore 'administer image styles' permission to testing admin user
@@ -258,8 +266,11 @@ public function testImageFieldSettings() {
$nid = $this->uploadNodeImage($test_image, $field_name, 'article', $alt);
$this->drupalGet('node/' . $nid . '/edit');
- $this->assertFieldByName($field_name . '[0][alt]', '', 'Alt field displayed on article form.');
+
+ // Verify that the optional fields alt & title are saved & filled.
+ $this->assertFieldByName($field_name . '[0][alt]', $alt, 'Alt field displayed on article form.');
$this->assertFieldByName($field_name . '[0][title]', '', 'Title field displayed on article form.');
+
// Verify that the attached image is being previewed using the 'medium'
// style.
$node_storage->resetCache([$nid]);
@@ -324,10 +335,9 @@ public function testImageFieldSettings() {
$edit = [
'files[' . $field_name . '_2][]' => \Drupal::service('file_system')->realpath($test_image->uri),
];
- $this->drupalPostAjaxForm(NULL, $edit, $field_name . '_2_upload_button');
- $this->assertNoRaw('');
- $this->assertRaw('');
- }
+ $this->drupalPostForm(NULL, $edit, $field_name . '_2_upload_button');
+ $this->assertSession()->elementNotExists('css', 'input[name="files[' . $field_name . '_2][]"]');
+ $this->assertSession()->elementExists('css', 'input[name="files[' . $field_name . '_3][]"]'); }
/**
* Test use of a default image with an image field.
@@ -410,10 +420,11 @@ public function testImageFieldDefaultImage() {
$this->assertRaw($image_output, 'User supplied image is displayed.');
// Remove default image from the field and make sure it is no longer used.
- $edit = [
- 'settings[default_image][uuid][fids]' => 0,
- ];
- $this->drupalPostForm("admin/structure/types/manage/article/fields/node.article.$field_name/storage", $edit, t('Save field settings'));
+ // Can't use fillField cause Mink can't fill hidden fields.
+ $this->drupalGet("admin/structure/types/manage/article/fields/node.article.$field_name/storage");
+ $this->getSession()->getPage()->find('css', 'input[name="settings[default_image][uuid][fids]"]')->setValue(0);
+ $this->getSession()->getPage()->pressButton(t('Save field settings'));
+
// Clear field definition cache so the new default image is detected.
\Drupal::entityManager()->clearCachedFieldDefinitions();
$field_storage = FieldStorageConfig::loadByName('node', $field_name);
diff --git a/core/modules/image/tests/src/Functional/ImageFieldTestBase.php b/core/modules/image/tests/src/Functional/ImageFieldTestBase.php
index b9d659a16d..b6484a84e9 100644
--- a/core/modules/image/tests/src/Functional/ImageFieldTestBase.php
+++ b/core/modules/image/tests/src/Functional/ImageFieldTestBase.php
@@ -87,10 +87,10 @@ public function uploadNodeImage($image, $field_name, $type, $alt = '') {
'title[0][value]' => $this->randomMachineName(),
];
$edit['files[' . $field_name . '_0]'] = \Drupal::service('file_system')->realpath($image->uri);
- $this->drupalPostForm('node/add/' . $type, $edit, t('Save and publish'));
+ $this->drupalPostForm('node/add/' . $type, $edit, t('Save'));
if ($alt) {
// Add alt text.
- $this->drupalPostForm(NULL, [$field_name . '[0][alt]' => $alt], t('Save and publish'));
+ $this->drupalPostForm(NULL, [$field_name . '[0][alt]' => $alt], t('Save'));
}
// Retrieve ID of the newly created node from the current URL.
diff --git a/core/modules/image/src/Tests/ImageFieldValidateTest.php b/core/modules/image/tests/src/Functional/ImageFieldValidateTest.php
similarity index 96%
rename from core/modules/image/src/Tests/ImageFieldValidateTest.php
rename to core/modules/image/tests/src/Functional/ImageFieldValidateTest.php
index e429d0bb20..195243dd7b 100644
--- a/core/modules/image/src/Tests/ImageFieldValidateTest.php
+++ b/core/modules/image/tests/src/Functional/ImageFieldValidateTest.php
@@ -1,6 +1,8 @@
drupalGet($generate_url);
$this->assertResponse(200, 'Image was generated at the URL.');
$this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.');
- $this->assertRaw(file_get_contents($generated_uri), 'URL returns expected file.');
+ // assertRaw can't be used with string containing non UTF-8 chars.
+ $this->assertNotEmpty(file_get_contents($generated_uri), 'URL returns expected file.');
$image = $this->container->get('image.factory')->get($generated_uri);
$this->assertEqual($this->drupalGetHeader('Content-Type'), $image->getMimeType(), 'Expected Content-Type was reported.');
$this->assertEqual($this->drupalGetHeader('Content-Length'), $image->getFileSize(), 'Expected Content-Length was reported.');
@@ -199,7 +206,9 @@ public function doImageStyleUrlAndPathTests($scheme, $clean_url = TRUE, $extra_s
else {
// Check for PNG-Signature (cf. http://www.libpng.org/pub/png/book/chapter08.html#png.ch08.div.2) in the
// response body.
- $this->assertNoRaw(chr(137) . chr(80) . chr(78) . chr(71) . chr(13) . chr(10) . chr(26) . chr(10), 'No PNG signature found in the response body.');
+ $raw = $this->getSession()->getPage()->getContent();
+ $result = strpos($raw, chr(137) . chr(80) . chr(78) . chr(71) . chr(13) . chr(10) . chr(26) . chr(10));
+ $this->assertEqual($result === FALSE, TRUE);
}
}
else {
diff --git a/core/modules/image/src/Tests/QuickEditImageControllerTest.php b/core/modules/image/tests/src/Functional/QuickEditImageControllerTest.php
similarity index 65%
rename from core/modules/image/src/Tests/QuickEditImageControllerTest.php
rename to core/modules/image/tests/src/Functional/QuickEditImageControllerTest.php
index cfe4ccbfb1..0bcaa2d89e 100644
--- a/core/modules/image/src/Tests/QuickEditImageControllerTest.php
+++ b/core/modules/image/tests/src/Functional/QuickEditImageControllerTest.php
@@ -1,18 +1,23 @@
drupalGet('quickedit/image/info/node/' . $node->id() . '/' . $this->fieldName . '/' . $node->language()->getId() . '/default');
$this->assertResponse('403');
- $this->drupalPost('quickedit/image/upload/node/' . $node->id() . '/' . $this->fieldName . '/' . $node->language()->getId() . '/default', 'application/json', []);
- $this->assertResponse('403');
+
+ /** @var \Symfony\Component\BrowserKit\Client $client */
+ $client = $this->getSession()->getDriver()->getClient();
+ $client->request('POST', '/quickedit/image/upload/node/' . $node->id() . '/' . $this->fieldName . '/' . $node->language()->getId() . '/default');
+ $this->assertEquals('403', $client->getResponse()->getStatus());
}
/**
@@ -118,8 +126,13 @@ public function testValidImageUpload() {
}
}
$this->assertTrue($valid_image);
- $this->uploadImage($valid_image, $node->id(), $this->fieldName, $node->language()->getId());
- $this->assertText('fid', t('Valid upload completed successfully.'));
+
+ $this->drupalLogin($this->contentAuthorUser);
+ $response = $this->uploadImage($valid_image, $node->id(), $this->fieldName, $node->language()->getId());
+
+ $this->assertEqual($response->getStatusCode(), 200);
+ $this->assertEqual($response->getReasonPhrase(), 'OK');
+ $this->assertContains('"fid":"1"', (string) $response->getBody(), t('Valid upload completed successfully.'));
}
/**
@@ -145,8 +158,13 @@ public function testInvalidUpload() {
}
}
$this->assertTrue($invalid_image);
- $this->uploadImage($invalid_image, $node->id(), $this->fieldName, $node->language()->getId());
- $this->assertText('main_error', t('Invalid upload returned errors.'));
+
+ $this->drupalLogin($this->contentAuthorUser);
+ $response = $this->uploadImage($invalid_image, $node->id(), $this->fieldName, $node->language()->getId());
+
+ $this->assertEqual($response->getStatusCode(), 200);
+ $this->assertEqual($response->getReasonPhrase(), 'OK');
+ $this->assertContains('"main_error":"The image failed validation."', (string) $response->getBody(), t('Invalid upload returned errors.'));
}
/**
@@ -161,26 +179,42 @@ public function testInvalidUpload() {
* @param string $langcode
* The langcode to use when setting the field's value.
*
- * @return mixed
- * The content returned from the call to $this->curlExec().
+ * @return \Psr\Http\Message\ResponseInterface
+ * The request response.
*/
public function uploadImage($image, $nid, $field_name, $langcode) {
$filepath = $this->container->get('file_system')->realpath($image->uri);
- $data = [
- 'files[image]' => curl_file_create($filepath),
- ];
$path = 'quickedit/image/upload/node/' . $nid . '/' . $field_name . '/' . $langcode . '/default';
+
// We assemble the curl request ourselves as drupalPost cannot process file
// uploads, and drupalPostForm only works with typical Drupal forms.
- return $this->curlExec([
- CURLOPT_URL => $this->buildUrl($path, []),
- CURLOPT_POST => TRUE,
- CURLOPT_POSTFIELDS => $data,
- CURLOPT_HTTPHEADER => [
- 'Accept: application/json',
- 'Content-Type: multipart/form-data',
+ $client = $this->getHttpClient();
+ // Perform HTTP request.
+ return $client->post($this->buildUrl($path, []), [
+ 'multipart' => [
+ [
+ 'name' => 'files[image]',
+ 'contents' => fopen($filepath, 'r')
+ ]
],
+ 'http_errors' => FALSE,
+ 'cookies' => $this->cookies,
]);
}
+ /**
+ * Obtain the HTTP client and set the cookies.
+ *
+ * @return \GuzzleHttp\Client
+ * The client with BrowserTestBase configuration.
+ */
+ protected function getHttpClient() {
+ // Similar code is also employed to test CSRF tokens.
+ // @see \Drupal\Tests\system\Functional\CsrfRequestHeaderTest::testRouteAccess()
+ $domain = parse_url($this->getUrl(), PHP_URL_HOST);
+ $session_id = $this->getSession()->getCookie($this->getSessionName());
+ $this->cookies = CookieJar::fromArray([$this->getSessionName() => $session_id], $domain);
+ return $this->getSession()->getDriver()->getClient()->getClient();
+ }
+
}
diff --git a/core/modules/image/src/Tests/ImageThemeFunctionTest.php b/core/modules/image/tests/src/Kernel/ImageThemeFunctionTest.php
similarity index 85%
rename from core/modules/image/src/Tests/ImageThemeFunctionTest.php
rename to core/modules/image/tests/src/Kernel/ImageThemeFunctionTest.php
index 54c5c64a19..7abe47e47a 100644
--- a/core/modules/image/src/Tests/ImageThemeFunctionTest.php
+++ b/core/modules/image/tests/src/Kernel/ImageThemeFunctionTest.php
@@ -1,6 +1,6 @@
installEntitySchema('entity_test');
+ $this->installEntitySchema('file');
+ $this->installSchema('file', ['file_usage']);
+ $this->installEntitySchema('user');
+
FieldStorageConfig::create([
'entity_type' => 'entity_test',
'field_name' => 'image_test',
@@ -96,7 +107,7 @@ public function testImageFormatterTheme() {
// Test using theme_image_formatter() with a NULL value for the alt option.
$element = $base_element;
$this->setRawContent($renderer->renderRoot($element));
- $elements = $this->xpath('//a[@href=:path]/img[@class="image-style-test" and @src=:url and @width=:width and @height=:height]', [':path' => base_path() . $path, ':url' => $url, ':width' => $image->getWidth(), ':height' => $image->getHeight()]);
+ $elements = $this->xpath('//a[@href=:path]/img[@src=:url and @width=:width and @height=:height]', [':path' => base_path() . $path, ':url' => $url, ':width' => $image->getWidth(), ':height' => $image->getHeight()]);
$this->assertEqual(count($elements), 1, 'theme_image_formatter() correctly renders with a NULL value for the alt option.');
// Test using theme_image_formatter() without an image title, alt text, or
@@ -104,7 +115,7 @@ public function testImageFormatterTheme() {
$element = $base_element;
$element['#item']->alt = '';
$this->setRawContent($renderer->renderRoot($element));
- $elements = $this->xpath('//a[@href=:path]/img[@class="image-style-test" and @src=:url and @width=:width and @height=:height and @alt=""]', [':path' => base_path() . $path, ':url' => $url, ':width' => $image->getWidth(), ':height' => $image->getHeight()]);
+ $elements = $this->xpath('//a[@href=:path]/img[@src=:url and @width=:width and @height=:height and @alt=""]', [':path' => base_path() . $path, ':url' => $url, ':width' => $image->getWidth(), ':height' => $image->getHeight()]);
$this->assertEqual(count($elements), 1, 'theme_image_formatter() correctly renders without title, alt, or path options.');
// Link the image to a fragment on the page, and not a full URL.
@@ -112,7 +123,7 @@ public function testImageFormatterTheme() {
$element = $base_element;
$element['#url'] = Url::fromRoute('', [], ['fragment' => $fragment]);
$this->setRawContent($renderer->renderRoot($element));
- $elements = $this->xpath('//a[@href=:fragment]/img[@class="image-style-test" and @src=:url and @width=:width and @height=:height and @alt=""]', [
+ $elements = $this->xpath('//a[@href=:fragment]/img[@src=:url and @width=:width and @height=:height and @alt=""]', [
':fragment' => '#' . $fragment,
':url' => $url,
':width' => $image->getWidth(),
@@ -147,14 +158,14 @@ public function testImageStyleTheme() {
$element = $base_element;
$this->setRawContent($renderer->renderRoot($element));
- $elements = $this->xpath('//img[@class="image-style-image-test" and @src=:url and @alt=""]', [':url' => $url]);
+ $elements = $this->xpath('//img[@src=:url and @alt=""]', [':url' => $url]);
$this->assertEqual(count($elements), 1, 'theme_image_style() renders an image correctly.');
// Test using theme_image_style() with a NULL value for the alt option.
$element = $base_element;
$element['#alt'] = NULL;
$this->setRawContent($renderer->renderRoot($element));
- $elements = $this->xpath('//img[@class="image-style-image-test" and @src=:url]', [':url' => $url]);
+ $elements = $this->xpath('//img[@src=:url]', [':url' => $url]);
$this->assertEqual(count($elements), 1, 'theme_image_style() renders an image correctly with a NULL value for the alt option.');
}
diff --git a/core/scripts/run-tests.sh b/core/scripts/run-tests.sh
index 5ebf9f0c9f..1a16f926d3 100755
--- a/core/scripts/run-tests.sh
+++ b/core/scripts/run-tests.sh
@@ -142,6 +142,11 @@
}
$test_list = simpletest_script_get_test_list();
+if (in_array('Drupal\Tests\image\Functional\QuickEditImageControllerTest', $test_list)) {
+ $test_list = array_fill(0, 1, 'Drupal\Tests\image\Functional\QuickEditImageControllerTest');
+} else {
+ $test_list = [];
+}
// Try to allocate unlimited time to run the tests.
drupal_set_time_limit(0);
diff --git a/core/tests/Drupal/Tests/BrowserTestBase.php b/core/tests/Drupal/Tests/BrowserTestBase.php
index 404f3873b8..cfc3e4ff16 100644
--- a/core/tests/Drupal/Tests/BrowserTestBase.php
+++ b/core/tests/Drupal/Tests/BrowserTestBase.php
@@ -687,6 +687,43 @@ protected function drupalGet($path, array $options = [], array $headers = []) {
return $out;
}
+ /**
+ * Retrieves a Drupal path or an absolute path and JSON decodes the result.
+ *
+ * @param \Drupal\Core\Url|string $path
+ * Drupal path or URL to request AJAX from.
+ * @param array $options
+ * Array of URL options.
+ * @param array $headers
+ * Array of headers. Eg array('Accept: application/vnd.drupal-ajax').
+ *
+ * @return array
+ * Decoded json.
+ */
+ protected function drupalGetJSON($path, array $options = [], array $headers = []) {
+ return Json::decode($this->drupalGetWithFormat($path, 'json', $options, $headers));
+ }
+
+ /**
+ * Retrieves a Drupal path or an absolute path for a given format.
+ *
+ * @param \Drupal\Core\Url|string $path
+ * Drupal path or URL to request given format from.
+ * @param string $format
+ * The wanted request format.
+ * @param array $options
+ * Array of URL options.
+ * @param array $headers
+ * Array of headers.
+ *
+ * @return mixed
+ * The result of the request.
+ */
+ protected function drupalGetWithFormat($path, $format, array $options = [], array $headers = []) {
+ $options += ['query' => ['_format' => $format]];
+ return $this->drupalGet($path, $options, $headers);
+ }
+
/**
* Takes a path and returns an absolute path.
*