-
-
Notifications
You must be signed in to change notification settings - Fork 14
[#629] Added fixture path expansion for file fields on nodes. #634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
bfbc1e0
0c390d7
6d0a456
174c7a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,126 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace DrevOps\BehatSteps\Drupal; | ||
|
|
||
| use Drupal\Driver\DrupalDriverInterface; | ||
| use Drupal\Driver\Entity\EntityStubInterface; | ||
|
|
||
| /** | ||
| * Internal helper for fixture path expansion on entity stubs. | ||
| * | ||
| * Shared by Drupal entity creation traits (e.g. ContentTrait, MediaTrait) | ||
| * that need to rewrite bare fixture filenames on 'file' and 'image' fields | ||
| * to absolute fixture paths before drupal-driver's FileHandler reads them. | ||
| * | ||
| * Requires a Drupal context: the consumer must expose 'getMinkParameter()' | ||
| * and 'getDriver()' (e.g. via MinkContext / RawDrupalContext) and Drupal | ||
| * must be bootstrapped at call time. | ||
| * | ||
| * This is an internal trait and should not be used directly in step | ||
| * definitions. | ||
| */ | ||
| trait EntityFixtureTrait { | ||
|
|
||
| /** | ||
| * Expand fixture file paths for file/image fields on an entity stub. | ||
| * | ||
| * Rewrites bare fixture filenames (e.g. 'document.pdf') on 'file' and | ||
| * 'image' field types to absolute paths under the Mink 'files_path' so | ||
| * drupal-driver's FileHandler can read and upload them during entity | ||
| * creation. Skips expansion when a managed file with the same basename | ||
| * already exists in public:// or private://, so existing files take | ||
| * precedence and behaviour stays backward compatible. | ||
| * | ||
| * @param string $entity_type | ||
| * The entity type machine name (e.g. 'node', 'media'). | ||
| * @param \Drupal\Driver\Entity\EntityStubInterface $stub | ||
| * The entity stub mutated in place. | ||
| */ | ||
| protected function entityFixtureExpand(string $entity_type, EntityStubInterface $stub): void { | ||
| $files_path = $this->getMinkParameter('files_path'); | ||
|
|
||
| if (empty($files_path)) { | ||
| return; | ||
| } | ||
|
|
||
| $resolved_files_path = realpath((string) $files_path); | ||
|
|
||
| if ($resolved_files_path === FALSE || !is_dir($resolved_files_path)) { | ||
| return; | ||
| } | ||
|
|
||
| $fixture_path = rtrim($resolved_files_path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; | ||
|
|
||
| $driver = $this->getDriver(); | ||
|
|
||
| if (!$driver instanceof DrupalDriverInterface) { | ||
| return; | ||
| } | ||
|
|
||
| $field_types = $driver->getCore()->getEntityFieldTypes($entity_type); | ||
|
|
||
| foreach ($stub->getValues() as $name => $value) { | ||
| if (empty($field_types[$name]) || ($field_types[$name] !== 'image' && $field_types[$name] !== 'file')) { | ||
| continue; | ||
| } | ||
|
|
||
| $basename = is_array($value) ? ($value[0] ?? NULL) : $value; | ||
|
|
||
| if (!is_string($basename) || $basename === '') { | ||
| continue; | ||
| } | ||
|
|
||
| if (str_contains($basename, '/') || str_contains($basename, '\\') || $basename !== basename($basename)) { | ||
| continue; | ||
| } | ||
|
|
||
| if ($this->entityFixtureManagedFileExists($basename)) { | ||
| continue; | ||
| } | ||
|
|
||
| if (!is_file($fixture_path . $basename)) { | ||
| continue; | ||
| } | ||
|
|
||
| if (is_array($value)) { | ||
| $value[0] = $fixture_path . $basename; | ||
| $stub->setValue($name, $value); | ||
| } | ||
| else { | ||
| $stub->setValue($name, $fixture_path . $basename); | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
+41
to
+95
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial | 🏗️ Heavy lift Split This method currently handles path resolution, driver checks, field filtering, basename validation, managed-file lookup, and value mutation in one block. Please extract at least basename normalization/validation and stub-value rewrite into dedicated helpers to lower cyclomatic/NPath complexity and make future changes safer. 🧰 Tools🪛 PHPMD (2.15.0)[warning] 41-95: The method entityFixtureExpand() has a Cyclomatic Complexity of 18. The configured cyclomatic complexity threshold is 10. (undefined) (CyclomaticComplexity) [warning] 41-95: The method entityFixtureExpand() has an NPath complexity of 9228. The configured NPath complexity threshold is 200. (undefined) (NPathComplexity) [error] 41-95: The parameter $entity_type is not named in camelCase. (undefined) (CamelCaseParameterName) [error] 91-93: The method entityFixtureExpand uses an else expression. Else clauses are basically not necessary and you can simplify the code by not using them. (undefined) (ElseExpression) 🤖 Prompt for AI Agents
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not adopting. PHPMD is not part of this project's enforced lint pipeline (see The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
(=^・ω・^=)∫ ✏️ Learnings added
🧠 Learnings used |
||
|
|
||
| /** | ||
| * Check whether a managed file with the given basename already exists. | ||
| * | ||
| * Mirrors drupal-driver FileHandler::resolveExistingFile() for bare | ||
| * basenames so callers do not pre-empt the driver's own lookup. | ||
| * | ||
| * @param string $basename | ||
| * Candidate basename (no path separators). | ||
| * | ||
| * @return bool | ||
| * TRUE when a managed file exists at public://basename or | ||
| * private://basename. | ||
| */ | ||
| protected function entityFixtureManagedFileExists(string $basename): bool { | ||
| if (str_contains($basename, '/') || str_contains($basename, '\\')) { | ||
| return FALSE; | ||
| } | ||
|
|
||
| $storage = \Drupal::entityTypeManager()->getStorage('file'); | ||
|
|
||
| foreach (['public', 'private'] as $scheme) { | ||
| if ($storage->loadByProperties(['uri' => $scheme . '://' . $basename])) { | ||
| return TRUE; | ||
| } | ||
| } | ||
|
|
||
| return FALSE; | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -352,3 +352,22 @@ Feature: Check that ContentTrait works | |||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||
| Unable to find "page" content with title "[TEST] Non-existing". | ||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| @api | ||||||||||||||||||||||||||||||||
| Scenario: Assert file field on node resolves bare fixture filename without explicit managed file | ||||||||||||||||||||||||||||||||
| Given the following article content: | ||||||||||||||||||||||||||||||||
| | title | field_file | | ||||||||||||||||||||||||||||||||
| | [TEST] Fixture file | text.txt | | ||||||||||||||||||||||||||||||||
| And I am logged in as a user with the "administrator" role | ||||||||||||||||||||||||||||||||
| When I visit the "article" content edit page with the title "[TEST] Fixture file" | ||||||||||||||||||||||||||||||||
| Then I should see "[TEST] Fixture file" | ||||||||||||||||||||||||||||||||
| And the response should contain ".txt" | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| @api | ||||||||||||||||||||||||||||||||
| Scenario: Assert image field on node resolves bare fixture filename without explicit managed file | ||||||||||||||||||||||||||||||||
| Given the following article content: | ||||||||||||||||||||||||||||||||
| | title | field_image | | ||||||||||||||||||||||||||||||||
| | [TEST] Fixture image | image.png | | ||||||||||||||||||||||||||||||||
| And I am logged in as a user with the "administrator" role | ||||||||||||||||||||||||||||||||
| When I visit the "article" content edit page with the title "[TEST] Fixture image" | ||||||||||||||||||||||||||||||||
| Then I should see "[TEST] Fixture image" | ||||||||||||||||||||||||||||||||
|
Comment on lines
+367
to
+373
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win Strengthen the image-fixture scenario with a field-specific assertion. This scenario currently proves node creation, but not necessarily that Suggested tweak `@api`
Scenario: Assert image field on node resolves bare fixture filename without explicit managed file
Given the following article content:
| title | field_image |
| [TEST] Fixture image | image.png |
And I am logged in as a user with the "administrator" role
When I visit the "article" content edit page with the title "[TEST] Fixture image"
Then I should see "[TEST] Fixture image"
+ And the response should contain "image.png"📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not adopting. The drupal-driver There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
( ˘ ω˘ *) ✏️ Learnings added
🧠 Learnings used |
||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.