diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index ff8c178a9..89da49b3d 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -7,27 +7,24 @@ on: jobs: drupal: name: Drupal ${{ matrix.drupal-core }} (PHP ${{ matrix.php-versions }}) - runs-on: ubuntu-latest + # We cannot use ubuntu-latest right now as it still points to 22.04 and we need a newer database driver. + runs-on: ubuntu-24.04 env: extensions: mbstring, xml, pdo_sqlite, gd, opcache strategy: fail-fast: false matrix: - php-versions: ['8.1', '8.2'] + php-versions: ['8.1', '8.2', '8.3'] drupal-core: ['10.3.x'] phpstan: ['0'] include: - # Extra run to test older supported Drupal 10.1.x. - - php-versions: '8.1' - drupal-core: '10.1.x' - phpstan: '0' # Extra run to test older supported Drupal 10.2.x. - php-versions: '8.1' drupal-core: '10.2.x' phpstan: '0' # We only need to run PHPStan once on the latest PHP version. - php-versions: '8.3' - drupal-core: '10.3.x' + drupal-core: '11.0.x' phpstan: '1' steps: - name: Checkout Drupal core @@ -86,12 +83,13 @@ jobs: composer --no-interaction run-script drupal-phpunit-upgrade composer config --no-plugins allow-plugins.phpstan/extension-installer true + # Revisit - check for latest release of dependent modules. - name: Install GraphQL dependencies run: | composer --no-interaction --no-progress require \ webonyx/graphql-php:^14.8 \ - drupal/typed_data:^1.0 \ - drupal/redirect:^1.0 + drupal/typed_data:^2.0 \ + drupal/redirect:dev-1.x - name: Run PHPUnit run: | @@ -109,8 +107,8 @@ jobs: mglaman/phpstan-drupal:^1.1.2 \ phpstan/phpstan-deprecation-rules:^1.0.0 \ jangregor/phpstan-prophecy:^1.0.0 \ - phpstan/phpstan-phpunit:^1.0.0 \ - phpstan/extension-installer:^1.0 + phpstan/phpstan-phpunit:^1.4 \ + phpstan/extension-installer:^1.4 composer --no-interaction --no-progress --with-all-dependencies upgrade drupal/coder:8.3.24 - name: Run PHPStan diff --git a/composer.json b/composer.json index e3c4620da..2db50bd0a 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,8 @@ "homepage": "http://drupal.org/project/graphql", "license": "GPL-2.0+", "require": { - "php": ">=7.3", + "drupal/typed_data": "^1.0 || ^2.0", + "php": ">=8.1", "webonyx/graphql-php": "^14.8.0" }, "minimum-stability": "dev" diff --git a/examples/graphql_composable/graphql_composable.info.yml b/examples/graphql_composable/graphql_composable.info.yml index 92ebd73cd..08add43f5 100644 --- a/examples/graphql_composable/graphql_composable.info.yml +++ b/examples/graphql_composable/graphql_composable.info.yml @@ -5,4 +5,4 @@ package: GraphQL dependencies: - graphql:graphql - node:node -core_version_requirement: ^10.1 +core_version_requirement: ^10.2 || ^11 diff --git a/examples/graphql_example/graphql_examples.info.yml b/examples/graphql_example/graphql_examples.info.yml index 57bb865b3..4f03a1abe 100644 --- a/examples/graphql_example/graphql_examples.info.yml +++ b/examples/graphql_example/graphql_examples.info.yml @@ -5,4 +5,4 @@ package: GraphQL dependencies: - graphql:graphql - node:node -core_version_requirement: ^10.1 +core_version_requirement: ^10.2 || ^11 diff --git a/graphql.info.yml b/graphql.info.yml index c8cc6d095..8b43f0087 100644 --- a/graphql.info.yml +++ b/graphql.info.yml @@ -3,6 +3,6 @@ type: module description: 'Base module for integrating GraphQL with Drupal.' package: GraphQL configure: graphql.config_page -core_version_requirement: ^10.1 +core_version_requirement: ^10.2 || ^11 dependencies: - typed_data:typed_data diff --git a/graphql.services.yml b/graphql.services.yml index ad0c2c9a7..23c01419f 100644 --- a/graphql.services.yml +++ b/graphql.services.yml @@ -184,6 +184,7 @@ services: - '@renderer' - '@event_dispatcher' - '@image.factory' + - '@file.validator' plugin.manager.graphql.persisted_query: class: Drupal\graphql\Plugin\PersistedQueryPluginManager diff --git a/src/EventSubscriber/ApqSubscriber.php b/src/EventSubscriber/ApqSubscriber.php index ada2b53dd..0dcd364e5 100644 --- a/src/EventSubscriber/ApqSubscriber.php +++ b/src/EventSubscriber/ApqSubscriber.php @@ -65,7 +65,7 @@ public function onBeforeOperation(OperationEvent $event): void { /** * {@inheritdoc} */ - public static function getSubscribedEvents() { + public static function getSubscribedEvents(): array { return [ OperationEvent::GRAPHQL_OPERATION_BEFORE => 'onBeforeOperation', ]; diff --git a/src/EventSubscriber/OperationSubscriber.php b/src/EventSubscriber/OperationSubscriber.php index a79cd94ba..989f07e85 100644 --- a/src/EventSubscriber/OperationSubscriber.php +++ b/src/EventSubscriber/OperationSubscriber.php @@ -73,7 +73,7 @@ public function onAfterOperation(OperationEvent $event): void { /** * {@inheritdoc} */ - public static function getSubscribedEvents() { + public static function getSubscribedEvents(): array { return [ OperationEvent::GRAPHQL_OPERATION_BEFORE => 'onBeforeOperation', OperationEvent::GRAPHQL_OPERATION_AFTER => 'onAfterOperation', diff --git a/src/EventSubscriber/SubrequestSubscriber.php b/src/EventSubscriber/SubrequestSubscriber.php index 7466a4a64..bf09068a4 100644 --- a/src/EventSubscriber/SubrequestSubscriber.php +++ b/src/EventSubscriber/SubrequestSubscriber.php @@ -67,7 +67,7 @@ public function onKernelRequestFinished(FinishRequestEvent $event): void { /** * {@inheritdoc} */ - public static function getSubscribedEvents() { + public static function getSubscribedEvents(): array { return [ KernelEvents::REQUEST => 'onKernelRequest', KernelEvents::FINISH_REQUEST => 'onKernelRequestFinished', diff --git a/src/GraphQL/Utility/FileUpload.php b/src/GraphQL/Utility/FileUpload.php index 7543ea5c7..2282ce831 100644 --- a/src/GraphQL/Utility/FileUpload.php +++ b/src/GraphQL/Utility/FileUpload.php @@ -17,9 +17,11 @@ use Drupal\Core\Render\RenderContext; use Drupal\Core\Render\RendererInterface; use Drupal\Core\Session\AccountProxyInterface; +use Drupal\Core\StringTranslation\ByteSizeMarkup; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Utility\Token; use Drupal\file\FileInterface; +use Drupal\file\Validation\FileValidatorInterface; use Drupal\graphql\GraphQL\Response\FileUploadResponse; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\File\UploadedFile; @@ -111,6 +113,13 @@ class FileUpload { */ protected $imageFactory; + /** + * The file validator service. + * + * @var \Drupal\file\Validation\FileValidatorInterface + */ + protected FileValidatorInterface $fileValidator; + /** * Constructor. */ @@ -126,6 +135,7 @@ public function __construct( RendererInterface $renderer, EventDispatcherInterface $eventDispatcher, ImageFactory $image_factory, + FileValidatorInterface $file_validator, ) { /** @var \Drupal\file\FileStorageInterface $file_storage */ $file_storage = $entityTypeManager->getStorage('file'); @@ -140,6 +150,7 @@ public function __construct( $this->renderer = $renderer; $this->eventDispatcher = $eventDispatcher; $this->imageFactory = $image_factory; + $this->fileValidator = $file_validator; } /** @@ -193,10 +204,7 @@ public function saveFileUpload(UploadedFile $uploaded_file, array $settings): Fi switch ($uploaded_file->getError()) { case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: - // @todo Drupal 10.1 compatibility, needs to be converted to - // ByteSizeMarkup later. - // @phpstan-ignore-next-line - $maxUploadSize = format_size($this->getMaxUploadSize($settings)); + $maxUploadSize = ByteSizeMarkup::create($this->getMaxUploadSize($settings)); $response->addViolation($this->t('The file @file could not be saved because it exceeds @maxsize, the maximum allowed size for uploads.', [ '@file' => $uploaded_file->getClientOriginalName(), '@maxsize' => $maxUploadSize, @@ -248,8 +256,8 @@ public function saveFileUpload(UploadedFile $uploaded_file, array $settings): Fi $temp_file_path = $uploaded_file->getRealPath(); - // Drupal 10.2 compatibility: use the deprecated constant for now. - // @phpstan-ignore-next-line + // Drupal 10.3 compatibility: use the deprecated constant for now. + // @phpstan-ignore-next-line as it is deprecated in D12. $file_uri = $this->fileSystem->getDestinationFilename($file_uri, FileSystemInterface::EXISTS_RENAME); // Lock based on the prepared file URI. @@ -272,11 +280,17 @@ public function saveFileUpload(UploadedFile $uploaded_file, array $settings): Fi // before it is saved. $file->setSize(@filesize($temp_file_path)); - // Validate against file_validate() first with the temporary path. - // @todo Drupal 10.1 compatibility, needs to be converted to file validate - // service later. - // @phpstan-ignore-next-line - $errors = file_validate($file, $validators); + // Validate against fileValidator first with the temporary path. + /** @var \Symfony\Component\Validator\ConstraintViolationListInterface $file_validate_errors */ + $file_validate_errors = $this->fileValidator->validate($file, $validators); + $errors = []; + if (count($file_validate_errors) > 0) { + foreach ($file_validate_errors as $violation) { + $errors[] = $violation->getMessage(); + } + } + + // Validate Image resolution. $maxResolution = $settings['max_resolution'] ?? 0; $minResolution = $settings['min_resolution'] ?? 0; if (!empty($maxResolution) || !empty($minResolution)) { @@ -287,14 +301,13 @@ public function saveFileUpload(UploadedFile $uploaded_file, array $settings): Fi $response->addViolations($errors); return $response; } - $file->setFileUri($file_uri); // Move the file to the correct location after validation. Use // FileSystemInterface::EXISTS_ERROR as the file location has already been // determined above in FileSystem::getDestinationFilename(). try { - // Drupal 10.2 compatibility: use the deprecated constant for now. - // @phpstan-ignore-next-line + // Drupal 10.3 compatibility: use the deprecated constant for now. + // @phpstan-ignore-next-line as it is deprecated in D12. $this->fileSystem->move($temp_file_path, $file_uri, FileSystemInterface::EXISTS_ERROR); } catch (FileException $e) { @@ -315,7 +328,6 @@ public function saveFileUpload(UploadedFile $uploaded_file, array $settings): Fi } $file->save(); - $response->setFileEntity($file); return $response; } @@ -487,12 +499,12 @@ protected function validateFileImageResolution(FileInterface $file, $maximum_dim protected function prepareFilename(string $filename, array &$validators): string { // Don't rename if 'allow_insecure_uploads' evaluates to TRUE. if (!$this->systemFileConfig->get('allow_insecure_uploads')) { - if (!empty($validators['file_validate_extensions'][0])) { - // If there is a file_validate_extensions validator and a list of - // valid extensions, munge the filename to protect against possible - // malicious extension hiding within an unknown file type. For example, - // "filename.html.foo". - $event = new FileUploadSanitizeNameEvent($filename, $validators['file_validate_extensions'][0]); + if (!empty($validators['FileExtension']['extensions'])) { + // If there is a fileValidator service to validate FileExtension and + // a list of valid extensions, munge the filename to protect against + // possible malicious extension hiding within an unknown file type. + // For example, "filename.html.foo". + $event = new FileUploadSanitizeNameEvent($filename, $validators['FileExtension']['extensions']); $this->eventDispatcher->dispatch($event); $filename = $event->getFilename(); } @@ -502,33 +514,30 @@ protected function prepareFilename(string $filename, array &$validators): string // and filename._php.txt, respectively). if (preg_match(FileSystemInterface::INSECURE_EXTENSION_REGEX, $filename)) { // If the file will be rejected anyway due to a disallowed extension, it - // should not be renamed; rather, we'll let file_validate_extensions() - // reject it below. + // should not be renamed; rather, we'll let fileValidator service + // to validate FileExtension reject it below. $passes_validation = FALSE; - if (!empty($validators['file_validate_extensions'][0])) { + if (!empty($validators['FileExtension']['extensions'])) { /** @var \Drupal\file\FileInterface $file */ $file = $this->fileStorage->create([]); $file->setFilename($filename); - // @todo Drupal 10.1 compatibility, needs to be converted to file - // validator service later. - // @phpstan-ignore-next-line - $passes_validation = empty(file_validate_extensions($file, $validators['file_validate_extensions'][0])); + $passes_validation = count($this->fileValidator->validate($file, $validators['FileExtension']['extensions'])); } - if (empty($validators['file_validate_extensions'][0]) || $passes_validation) { + if (empty($validators['FileExtension']['extensions']) || ($passes_validation > 0)) { if ((substr($filename, -4) != '.txt')) { // The destination filename will also later be used to create the // URI. $filename .= '.txt'; } - $event = new FileUploadSanitizeNameEvent($filename, $validators['file_validate_extensions'][0] ?? ''); + $event = new FileUploadSanitizeNameEvent($filename, $validators['FileExtension']['extensions'] ?? ''); $this->eventDispatcher->dispatch($event); $filename = $event->getFilename(); // The .txt extension may not be in the allowed list of extensions. We // have to add it here or else the file upload will fail. - if (!empty($validators['file_validate_extensions'][0])) { - $validators['file_validate_extensions'][0] .= ' txt'; + if (!empty($validators['FileExtension']['extensions'])) { + $validators['FileExtension']['extensions'] .= ' txt'; } } } @@ -579,7 +588,7 @@ protected function getUploadLocation(array $settings): string { protected function getUploadValidators(array $settings): array { $validators = [ // Add in our check of the file name length. - 'file_validate_name_length' => [], + 'FileNameLength' => [], ]; // Cap the upload size according to the PHP limit. @@ -589,11 +598,11 @@ protected function getUploadValidators(array $settings): array { } // There is always a file size limit due to the PHP server limit. - $validators['file_validate_size'] = [$max_filesize]; + $validators['FileSizeLimit'] = ['fileLimit' => $max_filesize]; // Add the extension check if necessary. if (!empty($settings['file_extensions'])) { - $validators['file_validate_extensions'] = [$settings['file_extensions']]; + $validators['FileExtension'] = ['extensions' => $settings['file_extensions']]; } return $validators; diff --git a/src/Plugin/GraphQL/DataProducer/Entity/Fields/Image/ImageDerivative.php b/src/Plugin/GraphQL/DataProducer/Entity/Fields/Image/ImageDerivative.php index 0454a69cc..1df82d3a4 100644 --- a/src/Plugin/GraphQL/DataProducer/Entity/Fields/Image/ImageDerivative.php +++ b/src/Plugin/GraphQL/DataProducer/Entity/Fields/Image/ImageDerivative.php @@ -97,12 +97,12 @@ public function resolve(FileInterface $entity = NULL, $style, RefinableCacheable $access = $entity->access('view', NULL, TRUE); $metadata->addCacheableDependency($access); if ($access->isAllowed() && $image_style = ImageStyle::load($style)) { - + // @phpstan-ignore-next-line $width = $entity->width; + // @phpstan-ignore-next-line $height = $entity->height; - // @phpstan-ignore-next-line - if (empty($width) || empty($height)) { + if ($width == NULL || $height == NULL) { /** @var \Drupal\Core\Image\ImageInterface $image */ $image = \Drupal::service('image.factory')->get($entity->getFileUri()); if ($image->isValid()) { diff --git a/tests/modules/graphql_file_validate/graphql_file_validate.info.yml b/tests/modules/graphql_file_validate/graphql_file_validate.info.yml index 1443533b4..c548ca7c1 100644 --- a/tests/modules/graphql_file_validate/graphql_file_validate.info.yml +++ b/tests/modules/graphql_file_validate/graphql_file_validate.info.yml @@ -1,5 +1,5 @@ type: module name: GraphQL File Validate Test -description: Tests hook_file_validate() on uploads. +description: Tests file validate on uploads. package: Testing hidden: TRUE diff --git a/tests/modules/graphql_file_validate/graphql_file_validate.module b/tests/modules/graphql_file_validate/graphql_file_validate.module deleted file mode 100644 index ae89684be..000000000 --- a/tests/modules/graphql_file_validate/graphql_file_validate.module +++ /dev/null @@ -1,17 +0,0 @@ -getFileUri())) { - throw new \Exception('File does not exist during validation: ' . $file->getFileUri()); - } -} diff --git a/tests/modules/graphql_file_validate/graphql_file_validate.services.yml b/tests/modules/graphql_file_validate/graphql_file_validate.services.yml new file mode 100644 index 000000000..57167a17f --- /dev/null +++ b/tests/modules/graphql_file_validate/graphql_file_validate.services.yml @@ -0,0 +1,5 @@ +services: + graphql_file_validate_test_subscriber: + class: Drupal\graphql_file_validate\EventSubscriber\GraphqlFileValidationTestSubscriber + tags: + - { name: event_subscriber } diff --git a/tests/modules/graphql_file_validate/src/EventSubscriber/GraphqlFileValidationTestSubscriber.php b/tests/modules/graphql_file_validate/src/EventSubscriber/GraphqlFileValidationTestSubscriber.php new file mode 100644 index 000000000..ddfe155bb --- /dev/null +++ b/tests/modules/graphql_file_validate/src/EventSubscriber/GraphqlFileValidationTestSubscriber.php @@ -0,0 +1,34 @@ +file->getFileUri())) { + throw new \Exception('File does not exist during validation: ' . $event->file->getFileUri()); + } + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents(): array { + return [FileValidationEvent::class => 'onFileValidation']; + } + +} diff --git a/tests/src/Kernel/DataProducer/DefaultValueTest.php b/tests/src/Kernel/DataProducer/DefaultValueTest.php index 2185d2e7b..7e459e088 100644 --- a/tests/src/Kernel/DataProducer/DefaultValueTest.php +++ b/tests/src/Kernel/DataProducer/DefaultValueTest.php @@ -54,7 +54,7 @@ public function testLegacyDefaultValueSetting(bool $populate_setting, string $te /** * Data provider for the testLegacyDefaultValueSetting test. */ - public function settingsProvider(): array { + public static function settingsProvider(): array { return [ [FALSE, TestLegacyEntityLoad::class], [TRUE, TestNewEntityLoad::class], diff --git a/tests/src/Kernel/DataProducer/EntityReferenceTest.php b/tests/src/Kernel/DataProducer/EntityReferenceTest.php index bb3a8cc40..976ce0e14 100644 --- a/tests/src/Kernel/DataProducer/EntityReferenceTest.php +++ b/tests/src/Kernel/DataProducer/EntityReferenceTest.php @@ -5,33 +5,9 @@ use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\node\Entity\Node; use Drupal\node\Entity\NodeType; +use Drupal\Tests\field\Traits\EntityReferenceFieldCreationTrait; use Drupal\Tests\graphql\Kernel\GraphQLTestBase; -// @todo Drupal 10.1 compatibility: use the deprecated trait for Drupal 10.1. -if (strpos(\Drupal::VERSION, '10.1') === 0) { - - /** - * Helper trait for compatibility with Drupal 9. - * - * @phpcs:disable Drupal.Classes.ClassFileName.NoMatch - */ - trait EntityReferenceFieldCreationTrait { - // @phpstan-ignore-next-line - use \Drupal\Tests\field\Traits\EntityReferenceTestTrait; - - } -} -else { - - /** - * Helper trait for compatibility with Drupal 10. - */ - trait EntityReferenceFieldCreationTrait { - use \Drupal\Tests\field\Traits\EntityReferenceFieldCreationTrait; - - } -} - /** * Tests the entity_reference data producers. * @@ -136,7 +112,7 @@ public function testEmptyResults(string $data_producer, array $contexts): void { /** * Data provider for testEmptyResults(). */ - public function emptyResultsProvider(): array { + public static function emptyResultsProvider(): array { return [ // Test that an empty reference field returns an empty array. ['entity_reference', [ diff --git a/tests/src/Kernel/DataProducer/Images/ImageResourceUrlTest.php b/tests/src/Kernel/DataProducer/Images/ImageResourceUrlTest.php index ca2d40b85..4abbe3c0a 100644 --- a/tests/src/Kernel/DataProducer/Images/ImageResourceUrlTest.php +++ b/tests/src/Kernel/DataProducer/Images/ImageResourceUrlTest.php @@ -27,7 +27,7 @@ public function testImageResourceUrl(array $input, string $expected): void { /** * Provider for testImageResourceUrl(). */ - public function imageResourceUrlProvider(): array { + public static function imageResourceUrlProvider(): array { return [ [ ['url' => 'http://localhost/test_image.jpg'], diff --git a/tests/src/Kernel/DataProducer/SeekTest.php b/tests/src/Kernel/DataProducer/SeekTest.php index e31dbf885..f4c45ffba 100644 --- a/tests/src/Kernel/DataProducer/SeekTest.php +++ b/tests/src/Kernel/DataProducer/SeekTest.php @@ -37,7 +37,7 @@ public function testSeek(array $input, int $position, $expected): void { * * @return array */ - public function seekProvider(): array { + public static function seekProvider(): array { return [ [ [1, 2, 3], diff --git a/tests/src/Kernel/DataProducer/StringTest.php b/tests/src/Kernel/DataProducer/StringTest.php index d82f522d3..4184f11e5 100644 --- a/tests/src/Kernel/DataProducer/StringTest.php +++ b/tests/src/Kernel/DataProducer/StringTest.php @@ -27,7 +27,7 @@ public function testUppercase(string $input, string $expected): void { /** * Tests the upper case data producer. */ - public function uppercaseProvider(): array { + public static function uppercaseProvider(): array { return [ ['test', 'TEST'], ['123 ..!!', '123 ..!!'], diff --git a/tests/src/Kernel/Framework/CsrfTest.php b/tests/src/Kernel/Framework/CsrfTest.php index 34d451b30..61ca2e33a 100644 --- a/tests/src/Kernel/Framework/CsrfTest.php +++ b/tests/src/Kernel/Framework/CsrfTest.php @@ -64,7 +64,7 @@ public function testEvilOrigin(string $content_type): void { /** * Data provider for testContentTypeCsrf(). */ - public function provideSimpleContentTypes(): array { + public static function provideSimpleContentTypes(): array { // Three content types that can be sent with simple no-cors POST requests. return [ ['text/plain'], @@ -115,7 +115,7 @@ public function testAllowedJsonRequests(array $headers): void { /** * Data provider for testAllowedJsonRequests(). */ - public function provideAllowedJsonHeaders(): array { + public static function provideAllowedJsonHeaders(): array { return [ [['CONTENT_TYPE' => 'application/json']], [['CONTENT_TYPE' => 'application/graphql']], @@ -149,7 +149,7 @@ public function testAllowedFormRequests(array $headers, array $allowedDomains = /** * Data provider for testAllowedFormRequests(). */ - public function provideAllowedFormRequests(): array { + public static function provideAllowedFormRequests(): array { return [ // Omitting the Origin and Apollo-Require-Preflight is allowed. [['CONTENT_TYPE' => 'multipart/form-data']], diff --git a/tests/src/Kernel/Framework/PersistedQueriesTest.php b/tests/src/Kernel/Framework/PersistedQueriesTest.php index e28e0b5d9..7958d7f0c 100644 --- a/tests/src/Kernel/Framework/PersistedQueriesTest.php +++ b/tests/src/Kernel/Framework/PersistedQueriesTest.php @@ -75,7 +75,7 @@ public function testPersistedQueries(array $instanceIds, string $queryId, array /** * Data provider for testPersistedQueries(). */ - public function persistedQueriesDataProvider(): array { + public static function persistedQueriesDataProvider(): array { return [ // This is the most usual case, all the three plugins are enabled. [ diff --git a/tests/src/Kernel/Framework/UploadFileServiceTest.php b/tests/src/Kernel/Framework/UploadFileServiceTest.php index 79ddf8c2c..c119895c2 100644 --- a/tests/src/Kernel/Framework/UploadFileServiceTest.php +++ b/tests/src/Kernel/Framework/UploadFileServiceTest.php @@ -18,7 +18,7 @@ class UploadFileServiceTest extends GraphQLTestBase { /** * {@inheritdoc} */ - protected static $modules = ['file', 'graphql_file_validate']; + protected static $modules = ['graphql_file_validate']; /** * The FileUpload object we want to test, gets prepared in setUp(). @@ -67,7 +67,6 @@ public function testSuccess(): void { 'file_directory' => 'test', ]); $file_entity = $file_upload_response->getFileEntity(); - $this->assertSame('public://test/test.txt', $file_entity->getFileUri()); $this->assertFileExists($file_entity->getFileUri()); } @@ -104,7 +103,7 @@ public function testPartialFile(): void { ]); $violations = $file_upload_response->getViolations(); - $this->assertStringMatchesFormat( + $this->assertStringContainsString( 'The file "test.txt" could not be saved because the upload did not complete.', $violations[0]['message'] ); @@ -140,7 +139,7 @@ public function testSizeValidation(): void { $violations = $file_upload_response->getViolations(); // @todo Do we want HTML tags in our violations or not? - $this->assertStringMatchesFormat( + $this->assertStringContainsString( 'The file is 4 bytes exceeding the maximum file size of 1 byte.', $violations[0]['message'] ); @@ -190,7 +189,7 @@ public function testDimensionTooSmallValidation(): void { ]); $violations = $file_upload_response->getViolations(); - $this->assertStringMatchesFormat( + $this->assertStringContainsString( 'The image is too small. The minimum dimensions are 15x15 pixels and the image size is 10x10 pixels.', $violations[0]['message'] ); @@ -228,7 +227,7 @@ public function testExtensionValidation(): void { $violations = $file_upload_response->getViolations(); // @todo Do we want HTML tags in our violations or not? - $this->assertStringMatchesFormat( + $this->assertStringContainsString( 'Only files with the following extensions are allowed: odt.', $violations[0]['message'] ); @@ -256,6 +255,7 @@ public function testLockReleased(): void { \Drupal::service('renderer'), \Drupal::service('event_dispatcher'), \Drupal::service('image.factory'), + \Drupal::service('file.validator'), ); // Create a Symfony dummy uploaded file in test mode. @@ -319,7 +319,7 @@ public function testUnsuccessWithMultipleFileUploads(): void { // There must be violation regarding forbidden file extension. $violations = $file_upload_response->getViolations(); - $this->assertStringMatchesFormat( + $this->assertStringContainsString( 'Only files with the following extensions are allowed: txt.', $violations[0]['message'] ); diff --git a/tests/src/Kernel/GraphQLTestBase.php b/tests/src/Kernel/GraphQLTestBase.php index 20425566f..e529215c5 100644 --- a/tests/src/Kernel/GraphQLTestBase.php +++ b/tests/src/Kernel/GraphQLTestBase.php @@ -50,6 +50,7 @@ abstract class GraphQLTestBase extends KernelTestBase { 'content_translation', 'entity_reference_test', 'field', + 'file', 'menu_link_content', 'link', 'typed_data', @@ -75,6 +76,7 @@ protected function setUp(): void { $this->installEntitySchema('graphql_server'); $this->installEntitySchema('configurable_language'); $this->installConfig(['language']); + $this->installEntitySchema('file'); $this->installEntitySchema('menu_link_content'); $this->setUpCurrentUser([], $this->userPermissions()); diff --git a/tests/src/Kernel/ResolverBuilderTest.php b/tests/src/Kernel/ResolverBuilderTest.php index d800923fe..8fb178e87 100644 --- a/tests/src/Kernel/ResolverBuilderTest.php +++ b/tests/src/Kernel/ResolverBuilderTest.php @@ -62,7 +62,7 @@ public function testBuilderProducing($input, $expected): void { /** * @return array */ - public function builderProducingProvider(): array { + public static function builderProducingProvider(): array { return [ ['entity_load', ResolverInterface::class], ['entity_id', ResolverInterface::class], diff --git a/tests/src/Traits/MockingTrait.php b/tests/src/Traits/MockingTrait.php index b45077e15..1770ffc0e 100644 --- a/tests/src/Traits/MockingTrait.php +++ b/tests/src/Traits/MockingTrait.php @@ -53,6 +53,7 @@ trait MockingTrait { * The return callback promise. */ protected function toPromise($value) { + // @phpstan-ignore-next-line return $this->returnCallback(is_callable($value) ? $value : function () use ($value) { yield $value; }); @@ -89,7 +90,7 @@ protected function setUpSchema($schema, $id = 'test', array $values = []): void $this->schemaPluginManager->method('createInstance') ->with($this->equalTo($id)) - ->will($this->returnValue($this->schema)); + ->willReturn($this->schema); $this->container->set('plugin.manager.graphql.schema', $this->schemaPluginManager); } @@ -169,14 +170,14 @@ protected function mockSchemaPluginManager($id): void { $this->schemaPluginManager->expects($this->any()) ->method('getDefinitions') - ->will($this->returnValue([ + ->willReturn([ $id => [ 'id' => $id, 'name' => 'Test schema', 'provider' => 'graphql', 'class' => '\Drupal\graphql\Plugin\GraphQL\Schema\SdlSchemaPluginBase', ], - ])); + ]); } /**