class ImageUploadTest in Drupal 10
Test image upload.
@group ckeditor5 @internal
Hierarchy
- class \Drupal\Tests\ckeditor5\Functional\ImageUploadTest extends \Drupal\Tests\BrowserTestBase uses \Drupal\Tests\jsonapi\Functional\JsonApiRequestTestTrait, \Drupal\Tests\TestFileCreationTrait, \Drupal\Tests\ckeditor5\Traits\SynchronizeCsrfTokenSeedTrait
Expanded class hierarchy of ImageUploadTest
File
- core/
modules/ ckeditor5/ tests/ src/ Functional/ ImageUploadTest.php, line 21
Namespace
Drupal\Tests\ckeditor5\FunctionalView source
class ImageUploadTest extends BrowserTestBase {
use JsonApiRequestTestTrait;
use TestFileCreationTrait;
use SynchronizeCsrfTokenSeedTrait;
/**
* {@inheritdoc}
*/
protected static $modules = [
'editor',
'filter',
'ckeditor5',
];
/**
* A user without any particular permissions to be used in testing.
*
* @var \Drupal\user\Entity\User
*/
protected $user;
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* {@inheritdoc}
*/
protected function setUp() : void {
parent::setUp();
$this->user = $this
->drupalCreateUser();
$this
->drupalLogin($this->user);
}
/**
* Tests using the file upload route with a disallowed extension.
*/
public function testUploadFileExtension() {
$this
->createBasicFormat();
$this
->createEditorWithUpload([
'status' => TRUE,
'scheme' => 'public',
'directory' => 'inline-images',
'max_size' => '',
'max_dimensions' => [
'width' => 0,
'height' => 0,
],
]);
$url = $this
->getUploadUrl();
$image_file = file_get_contents(current($this
->getTestFiles('image'))->uri);
$non_image_file = file_get_contents(current($this
->getTestFiles('php'))->uri);
$response = $this
->uploadRequest($url, $non_image_file, 'test.php');
$this
->assertSame(422, $response
->getStatusCode());
$response = $this
->uploadRequest($url, $image_file, 'test.jpg');
$this
->assertSame(201, $response
->getStatusCode());
}
/**
* Tests using the file upload route with a file size larger than allowed.
*/
public function testFileUploadLargerFileSize() {
$this
->createBasicFormat();
$this
->createEditorWithUpload([
'status' => TRUE,
'scheme' => 'public',
'directory' => 'inline-images',
'max_size' => 30000,
'max_dimensions' => [
'width' => 0,
'height' => 0,
],
]);
$url = $this
->getUploadUrl();
$images = $this
->getTestFiles('image');
$large_image = $this
->getTestImageByStat($images, 'size', function ($size) {
return $size > 30000;
});
$small_image = $this
->getTestImageByStat($images, 'size', function ($size) {
return $size < 30000;
});
$response = $this
->uploadRequest($url, file_get_contents($large_image->uri), 'large.jpg');
$this
->assertSame(422, $response
->getStatusCode());
$response = $this
->uploadRequest($url, file_get_contents($small_image->uri), 'small.jpg');
$this
->assertSame(201, $response
->getStatusCode());
}
/**
* Test that lock is removed after a failed validation.
*
* @see https://www.drupal.org/project/drupal/issues/3184974
*/
public function testLockAfterFailedValidation() {
$this
->createBasicFormat();
$this
->createEditorWithUpload([
'status' => TRUE,
'scheme' => 'public',
'directory' => 'inline-images',
'max_size' => 30000,
'max_dimensions' => [
'width' => 0,
'height' => 0,
],
]);
$url = $this
->getUploadUrl();
$images = $this
->getTestFiles('image');
$large_image = $this
->getTestImageByStat($images, 'size', function ($size) {
return $size > 30000;
});
$small_image = $this
->getTestImageByStat($images, 'size', function ($size) {
return $size < 30000;
});
$response = $this
->uploadRequest($url, file_get_contents($large_image->uri), 'same.jpg');
$this
->assertSame(422, $response
->getStatusCode());
$response = $this
->uploadRequest($url, file_get_contents($small_image->uri), 'same.jpg');
$this
->assertSame(201, $response
->getStatusCode());
}
/**
* Make upload request to a controller.
*
* @param \Drupal\Core\Url $url
* The URL for the request.
* @param string $file_contents
* File contents.
* @param string $file_name
* Name of the file.
*
* @return \Psr\Http\Message\ResponseInterface
* The response.
*/
protected function uploadRequest(Url $url, string $file_contents, string $file_name) {
$request_options[RequestOptions::HEADERS] = [
'Accept' => 'application/json',
];
$request_options[RequestOptions::MULTIPART] = [
[
'name' => 'upload',
'filename' => $file_name,
'contents' => $file_contents,
],
];
return $this
->request('POST', $url, $request_options);
}
/**
* Provides the image upload url.
*
* @return \Drupal\Core\Url
* The upload image url for the basic_html format.
*/
protected function getUploadUrl() {
$token = $this->container
->get('csrf_token')
->get('ckeditor5/upload-image/basic_html');
return Url::fromRoute('ckeditor5.upload_image', [
'editor' => 'basic_html',
], [
'query' => [
'token' => $token,
],
]);
}
/**
* Create a basic_html text format for the editor to reference.
*
* @throws \Drupal\Core\Entity\EntityStorageException
*/
protected function createBasicFormat() {
$basic_html_format = FilterFormat::create([
'format' => 'basic_html',
'name' => 'Basic HTML',
'weight' => 1,
'filters' => [
'filter_html_escape' => [
'status' => 1,
],
],
'roles' => [
RoleInterface::AUTHENTICATED_ID,
],
]);
$basic_html_format
->save();
}
/**
* Create an editor entity with image_upload config.
*
* @param array $upload_config
* The editor image_upload config.
*
* @return \Drupal\Core\Entity\EntityBase|\Drupal\Core\Entity\EntityInterface
* The text editor entity.
*
* @throws \Drupal\Core\Entity\EntityStorageException
*/
protected function createEditorWithUpload(array $upload_config) {
$editor = Editor::create([
'editor' => 'ckeditor5',
'format' => 'basic_html',
'settings' => [
'toolbar' => [
'items' => [
'uploadImage',
],
],
'plugins' => [],
],
'image_upload' => $upload_config,
]);
$editor
->save();
return $editor;
}
/**
* Return the first image matching $condition.
*
* @param array $images
* Images created with getTestFiles().
* @param string $stat
* A key in the array returned from stat().
* @param callable $condition
* A function to compare a value of the image file.
*
* @return object|bool
* Objects with 'uri', 'filename', and 'name' properties.
*/
protected function getTestImageByStat(array $images, string $stat, callable $condition) {
return current(array_filter($images, function ($image) use ($condition, $stat) {
$stats = stat($image->uri);
return $condition($stats[$stat]);
}));
}
}