From a39fb7367594803a6a52bad65581c2d63fda099d Mon Sep 17 00:00:00 2001 From: Ilias Dimopoulos Date: Tue, 30 Mar 2021 11:55:12 +0300 Subject: [PATCH 01/11] ISAICP-6139: Provide a test for the new field. --- .../asset_distribution/track_download.feature | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/tests/features/asset_distribution/track_download.feature b/tests/features/asset_distribution/track_download.feature index bc77c3c137..d758a45abe 100644 --- a/tests/features/asset_distribution/track_download.feature +++ b/tests/features/asset_distribution/track_download.feature @@ -118,11 +118,16 @@ Feature: Asset distribution editing. And the following solution: | title | Solution | | state | validated | + And the following release: + | title | Release 1 | + | is version of | Solution | + | state | validated | + | And the following distributions: - | title | parent | access url | - | Distribution 1 | Solution | text.pdf | - | Distribution 2 | Solution | test.zip | - | Distribution 3 | Solution | test1.zip | + | title | parent | access url | + | Distribution 1 | Release 1 | text.pdf | + | Distribution 2 | Solution | test.zip | + | Distribution 3 | Solution | test1.zip | And the following distribution download events: | distribution | user | | Distribution 1 | visitor@example.com | @@ -139,9 +144,9 @@ Feature: Asset distribution editing. Then I should see the success message "Export complete. Download the file here if file is not automatically downloaded." And I should see the link "here" And the file downloaded from the "here" link contains the following strings: - | ID,User,Email,"File name",Distribution,Created | - | ,"Anonymous (not verified)",visitor@example.com,text.pdf,"Distribution 1", | - | ,user1,user1@example.com,text.pdf,"Distribution 1", | - | ,user2,user2@example.com,test.zip,"Distribution 2", | - | ,"Anonymous (not verified)",anon@example.com,test1.zip,"Distribution 3", | - | ,user1,user1@example.com,test1.zip,"Distribution 3", | + | ID,User,Email,"File name",Distribution,Parent,Created | + | ,"Anonymous (not verified)",visitor@example.com,text.pdf,"Distribution 1",Release 1, | + | ,user1,user1@example.com,text.pdf,"Distribution 1",Release 1, | + | ,user2,user2@example.com,test.zip,"Distribution 2",Solution, | + | ,"Anonymous (not verified)",anon@example.com,test1.zip,"Distribution 3",Solution, | + | ,user1,user1@example.com,test1.zip,"Distribution 3",Solution, | From 031caec120b30ebc6d9c252df50b6bcdc7e135ea Mon Sep 17 00:00:00 2001 From: Ilias Dimopoulos Date: Tue, 30 Mar 2021 11:56:45 +0300 Subject: [PATCH 02/11] ISAICP-6139: Track the parent of the distribution that is downloaded. --- .../Controller/DownloadTrackingController.php | 36 +++++++++++++-- .../src/Entity/DownloadEvent.php | 10 +++++ .../src/Form/AnonymousDownloadForm.php | 44 ++++++++++++++++++- 3 files changed, 85 insertions(+), 5 deletions(-) diff --git a/web/modules/custom/asset_distribution/src/Controller/DownloadTrackingController.php b/web/modules/custom/asset_distribution/src/Controller/DownloadTrackingController.php index 9d0cfd055b..d2ba897c0d 100644 --- a/web/modules/custom/asset_distribution/src/Controller/DownloadTrackingController.php +++ b/web/modules/custom/asset_distribution/src/Controller/DownloadTrackingController.php @@ -12,7 +12,9 @@ use Drupal\Core\Session\AccountInterface; use Drupal\asset_distribution\Form\AnonymousDownloadForm; use Drupal\file\FileInterface; +use Drupal\file\FileUsage\FileUsageInterface; use Drupal\file_url\FileUrlHandler; +use Drupal\sparql_entity_storage\SparqlEntityStorageInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Response; @@ -49,10 +51,17 @@ class DownloadTrackingController extends ControllerBase { */ protected $sparqlStorage; + /** + * The file usage service. + * + * @var \Drupal\file\FileUsage\FileUsageInterface + */ + protected $fileUsage; + /** * Instantiates a new DownloadTrackingController object. * - * @param \Drupal\Core\Entity\ContentEntityStorageInterface $sparql_storage + * @param \Drupal\sparql_entity_storage\SparqlEntityStorageInterface $sparql_storage * The RDF entity storage. * @param \Drupal\Core\Entity\ContentEntityStorageInterface $event_storage * The download event entity storage. @@ -62,13 +71,16 @@ class DownloadTrackingController extends ControllerBase { * The form builder. * @param \Drupal\Core\Session\AccountInterface $current_user * The current logged in user. + * @param \Drupal\file\FileUsage\FileUsageInterface $file_usage + * The file usage service. */ - public function __construct(ContentEntityStorageInterface $sparql_storage, ContentEntityStorageInterface $event_storage, FileUrlHandler $file_url_handler, FormBuilderInterface $form_builder, AccountInterface $current_user) { + public function __construct(SparqlEntityStorageInterface $sparql_storage, ContentEntityStorageInterface $event_storage, FileUrlHandler $file_url_handler, FormBuilderInterface $form_builder, AccountInterface $current_user, FileUsageInterface $file_usage) { $this->sparqlStorage = $sparql_storage; $this->eventStorage = $event_storage; $this->fileUrlHandler = $file_url_handler; $this->formBuilder = $form_builder; $this->currentUser = $current_user; + $this->fileUsage = $file_usage; } /** @@ -80,7 +92,8 @@ public static function create(ContainerInterface $container) { $container->get('entity_type.manager')->getStorage('download_event'), $container->get('file_url.handler'), $container->get('form_builder'), - $container->get('current_user') + $container->get('current_user'), + $container->get('file.usage') ); } @@ -124,9 +137,26 @@ protected function trackAnonymousDownload(FileInterface $file) { * The generated response. */ protected function trackAuthenticatedDownload(FileInterface $file) { + $usages = $this->fileUsage->listUsage($file); + + // Normally, only one distribution is allowed to use a file and only + // distributions call this code. + if (empty($usages['file']['rdf_entity'])) { + throw new \RuntimeException('No distributions were found using the file with ID ' . $file->id()); + } + if (count($usages['file']['rdf_entity']) > 1) { + throw new \RuntimeException('More than one distributions were found for the file with ID ' . $file->id()); + } + $distribution = $this->sparqlStorage->load(key($usages['file']['rdf_entity'])); + + /** @var \Drupal\solution\Entity\SolutionInterface|\Drupal\asset_release\Entity\AssetReleaseInterface $parent */ + $parent = $distribution->getParent(); + $event = $this->eventStorage->create([ 'uid' => $this->currentUser->id(), 'file' => $file->id(), + 'parent_entity_type' => $parent->getEntityTypeId(), + 'parent_entity_id' => $parent->id(), ]); $event->save(); diff --git a/web/modules/custom/asset_distribution/src/Entity/DownloadEvent.php b/web/modules/custom/asset_distribution/src/Entity/DownloadEvent.php index 6cafd407a8..db04919f08 100644 --- a/web/modules/custom/asset_distribution/src/Entity/DownloadEvent.php +++ b/web/modules/custom/asset_distribution/src/Entity/DownloadEvent.php @@ -59,6 +59,16 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setSetting('target_type', 'file') ->setRequired(TRUE); + $fields['parent_entity_type'] = BaseFieldDefinition::create('string') + ->setLabel(t('Parent entity type')) + ->setDescription(t('The solution or release that the distribution belongs to.')) + ->setRequired(FALSE); + + $fields['parent_entity_id'] = BaseFieldDefinition::create('string') + ->setLabel(t('Parent entity ID')) + ->setDescription(t('The entity ID of the solution or release that the distribution belongs to.')) + ->setRequired(FALSE); + return $fields; } diff --git a/web/modules/custom/asset_distribution/src/Form/AnonymousDownloadForm.php b/web/modules/custom/asset_distribution/src/Form/AnonymousDownloadForm.php index 442d77d7e2..73889e74b0 100644 --- a/web/modules/custom/asset_distribution/src/Form/AnonymousDownloadForm.php +++ b/web/modules/custom/asset_distribution/src/Form/AnonymousDownloadForm.php @@ -13,6 +13,8 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; use Drupal\file\FileInterface; +use Drupal\file\FileUsage\FileUsageInterface; +use Drupal\sparql_entity_storage\SparqlEntityStorageInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; @@ -21,6 +23,13 @@ */ class AnonymousDownloadForm extends FormBase { + /** + * The RDF entity storage. + * + * @var \Drupal\Core\Entity\ContentEntityStorageInterface + */ + protected $sparqlStorage; + /** * The download_event entity storage. * @@ -28,6 +37,13 @@ class AnonymousDownloadForm extends FormBase { */ protected $eventStorage; + /** + * The file usage service. + * + * @var \Drupal\file\FileUsage\FileUsageInterface + */ + protected $fileUsage; + /** * The file being downloaded. * @@ -38,11 +54,17 @@ class AnonymousDownloadForm extends FormBase { /** * Instantiates a new AnonymousDownloadForm object. * + * @param \Drupal\sparql_entity_storage\SparqlEntityStorageInterface $sparql_storage + * The RDF entity storage. * @param \Drupal\Core\Entity\ContentEntityStorageInterface $event_storage * The download event entity storage. + * @param \Drupal\file\FileUsage\FileUsageInterface $file_usage + * The file usage service. */ - public function __construct(ContentEntityStorageInterface $event_storage) { + public function __construct(SparqlEntityStorageInterface $sparql_storage, ContentEntityStorageInterface $event_storage, FileUsageInterface $file_usage) { + $this->sparqlStorage = $sparql_storage; $this->eventStorage = $event_storage; + $this->fileUsage = $file_usage; } /** @@ -50,7 +72,9 @@ public function __construct(ContentEntityStorageInterface $event_storage) { */ public static function create(ContainerInterface $container) { return new static( - $container->get('entity_type.manager')->getStorage('download_event') + $container->get('entity_type.manager')->getStorage('rdf_entity'), + $container->get('entity_type.manager')->getStorage('download_event'), + $container->get('file.usage') ); } @@ -119,10 +143,26 @@ public function submitForm(array &$form, FormStateInterface $form_state) { throw new BadRequestHttpException(); } + $usages = $this->fileUsage->listUsage($this->file); + + // Normally, only one distribution is allowed to use a file and only + // distributions call this code. + if (empty($usages['file']['rdf_entity'])) { + throw new \RuntimeException('No distributions were found using the file with ID ' . $file->id()); + } + if (count($usages['file']['rdf_entity']) > 1) { + throw new \RuntimeException('More than one distributions were found for the file with ID ' . $file->id()); + } + $distribution = $this->sparqlStorage->load(key($usages['file']['rdf_entity'])); + + /** @var \Drupal\solution\Entity\SolutionInterface|\Drupal\asset_release\Entity\AssetReleaseInterface $parent */ + $parent = $distribution->getParent(); $event = $this->eventStorage->create([ 'uid' => 0, 'mail' => $form_state->getValue('email'), 'file' => $this->file->id(), + 'parent_entity_type' => $parent->getEntityTypeId(), + 'parent_entity_id' => $parent->id(), ]); $event->save(); From a567264ac94b7349d171c8d19d3fed9b9780934b Mon Sep 17 00:00:00 2001 From: Ilias Dimopoulos Date: Tue, 30 Mar 2021 12:01:37 +0300 Subject: [PATCH 03/11] ISAICP-6139: Update the view to show the new field. --- ...iews.view.asset_distribution_downloads.yml | 130 ++++++++++++++++++ .../asset_distribution.module | 35 +++++ 2 files changed, 165 insertions(+) diff --git a/config/sync/views.view.asset_distribution_downloads.yml b/config/sync/views.view.asset_distribution_downloads.yml index 89dd4ce18b..d0473ada7e 100644 --- a/config/sync/views.view.asset_distribution_downloads.yml +++ b/config/sync/views.view.asset_distribution_downloads.yml @@ -449,6 +449,136 @@ display: hide_alter_empty: true link_to_entity: true plugin_id: entity_label + parent_entity_type: + id: parent_entity_type + table: joinup_download_event + field: parent_entity_type + relationship: none + group_type: group + admin_label: '' + label: '' + exclude: true + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: false + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: string + settings: + link_to_entity: false + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: download_event + entity_field: parent_entity_type + plugin_id: field + parent_entity_id: + id: parent_entity_id + table: joinup_download_event + field: parent_entity_id + relationship: none + group_type: group + admin_label: '' + label: 'Parent' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: string + settings: + link_to_entity: false + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: download_event + entity_field: parent_entity_id + plugin_id: field created: id: created table: joinup_download_event diff --git a/web/modules/custom/asset_distribution/asset_distribution.module b/web/modules/custom/asset_distribution/asset_distribution.module index 9f9b2265aa..06ca4bf71c 100644 --- a/web/modules/custom/asset_distribution/asset_distribution.module +++ b/web/modules/custom/asset_distribution/asset_distribution.module @@ -309,3 +309,38 @@ function asset_distribution_rdf_entity_delete(RdfInterface $distribution) { } } + +/** + * Implements hook_preprocess_HOOK(). + */ +function asset_distribution_preprocess_views_view_field(&$variables) { + $view = $variables['view']; + $field = $variables['field']; + if ($view->storage->id() !== 'asset_distribution_downloads' || $view->current_display !== 'page' || $field->field !== 'parent_entity_id') { + return; + } + + /** @var \Drupal\asset_distribution\Entity\DownloadEvent $download_event */ + $download_event = $variables['row']->_entity; + if ($download_event->get('parent_entity_type')->isEmpty() || $download_event->get('parent_entity_id')->isEmpty()) { + return; + } + + // Notice: This code works for any entity type, though it is only meant for + // distributions so it might be too much. + $entity_type = $download_event->get('parent_entity_type')->value; + $entity_id = $download_event->get('parent_entity_id')->value; + + try { + $storage = $storages[$entity_type] ?? \Drupal::entityTypeManager()->getStorage($entity_type); + } + catch (Exception $exception) { + return; + } + + $storages[$entity_type] = $storage; + $entity = $storage->load($entity_id); + if (!empty($entity)) { + $variables['output'] = $entity->toLink($entity->label()); + } +} From 39e21b45777fe26cfe54eb5fedc05a22af314cc2 Mon Sep 17 00:00:00 2001 From: Ilias Dimopoulos Date: Tue, 30 Mar 2021 12:02:46 +0300 Subject: [PATCH 04/11] ISAICP-6139: Provide update paths for the field and existing data. --- .../custom/joinup_core/joinup_core.deploy.php | 50 +++++++++++++++++++ .../custom/joinup_core/joinup_core.install | 18 +++++++ 2 files changed, 68 insertions(+) diff --git a/web/modules/custom/joinup_core/joinup_core.deploy.php b/web/modules/custom/joinup_core/joinup_core.deploy.php index f60759fed0..a3fb39ec00 100644 --- a/web/modules/custom/joinup_core/joinup_core.deploy.php +++ b/web/modules/custom/joinup_core/joinup_core.deploy.php @@ -13,3 +13,53 @@ */ declare(strict_types = 1); + +use Drupal\asset_distribution\Entity\DownloadEvent; + +/** + * Fill the parent of the distribution downloads. + */ +function joinup_core_deploy_0107000(array &$sandbox): string { + if (empty($sandbox['entity_ids'])) { + $sandbox['entity_ids'] = \Drupal::database()->query('SELECT `id` FROM joinup_download_event')->fetchCol(); + $sandbox['progress'] = 0; + $sandbox['max'] = count($sandbox['entity_ids']); + } + + $file_usage = \Drupal::getContainer()->get('file.usage'); + $sparql_storage = \Drupal::entityTypeManager()->getStorage('rdf_entity'); + $entity_ids = array_splice($sandbox['entity_ids'], 0, 100); + /** @var \Drupal\asset_distribution\Entity\DownloadEvent $download_event */ + foreach (DownloadEvent::loadMultiple($entity_ids) as $download_event) { + $file = $download_event->file->entity; + if (empty($file)) { + continue; + } + + $usages = $file_usage->listUsage($file); + if (empty($usages['file']['rdf_entity'])) { + continue; + } + $distribution = $sparql_storage->load(key($usages['file']['rdf_entity'])); + if (empty($distribution)) { + continue; + } + + /** @var \Drupal\solution\Entity\SolutionInterface|\Drupal\asset_release\Entity\AssetReleaseInterface $parent */ + try { + $parent = $distribution->getParent(); + } + catch (\Exception $e) { + // We don't want to force anything for old regords. + continue; + } + + $download_event->set('parent_entity_type', 'rdf_entity'); + $download_event->set('parent_entity_id', $parent->id()); + $download_event->save(); + } + + $sandbox['progress'] += count($entity_ids); + $sandbox['#finished'] = (float) $sandbox['progress'] / (float) $sandbox['max']; + return "Completed {$sandbox['progress']} out of {$sandbox['max']}."; +} diff --git a/web/modules/custom/joinup_core/joinup_core.install b/web/modules/custom/joinup_core/joinup_core.install index 4f923d06da..d54d5c7709 100644 --- a/web/modules/custom/joinup_core/joinup_core.install +++ b/web/modules/custom/joinup_core/joinup_core.install @@ -91,3 +91,21 @@ function joinup_core_requirements($phase): array { return $requirements; } + +/** + * Install new fields in the download event entity. + */ +function joinup_core_update_0107000(array &$sandbox): void { + $update_manager = \Drupal::entityDefinitionUpdateManager(); + $base_fields = \Drupal::getContainer()->get('entity_field.manager')->getBaseFieldDefinitions('download_event'); + + $fields = [ + 'parent_entity_type', + 'parent_entity_id', + ]; + + foreach ($fields as $field) { + $storage = $base_fields[$field]->getFieldStorageDefinition(); + $update_manager->installFieldStorageDefinition($field, 'download_event', 'download_event', $storage); + } +} From 8178e9055ecced9204aeb263ab438b168e4afad5 Mon Sep 17 00:00:00 2001 From: Ilias Dimopoulos Date: Tue, 30 Mar 2021 18:26:37 +0300 Subject: [PATCH 05/11] ISAICP-6139: Encapsulate the title to double quotes. --- .../asset_distribution/track_download.feature | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/features/asset_distribution/track_download.feature b/tests/features/asset_distribution/track_download.feature index d758a45abe..7b551c5d71 100644 --- a/tests/features/asset_distribution/track_download.feature +++ b/tests/features/asset_distribution/track_download.feature @@ -144,9 +144,9 @@ Feature: Asset distribution editing. Then I should see the success message "Export complete. Download the file here if file is not automatically downloaded." And I should see the link "here" And the file downloaded from the "here" link contains the following strings: - | ID,User,Email,"File name",Distribution,Parent,Created | - | ,"Anonymous (not verified)",visitor@example.com,text.pdf,"Distribution 1",Release 1, | - | ,user1,user1@example.com,text.pdf,"Distribution 1",Release 1, | - | ,user2,user2@example.com,test.zip,"Distribution 2",Solution, | - | ,"Anonymous (not verified)",anon@example.com,test1.zip,"Distribution 3",Solution, | - | ,user1,user1@example.com,test1.zip,"Distribution 3",Solution, | + | ID,User,Email,"File name",Distribution,Parent,Created | + | ,"Anonymous (not verified)",visitor@example.com,text.pdf,"Distribution 1","Release 1", | + | ,user1,user1@example.com,text.pdf,"Distribution 1","Release 1", | + | ,user2,user2@example.com,test.zip,"Distribution 2",Solution, | + | ,"Anonymous (not verified)",anon@example.com,test1.zip,"Distribution 3",Solution, | + | ,user1,user1@example.com,test1.zip,"Distribution 3",Solution, | From d02db50d1d8c699942dce7afd2e36f0ae8db378b Mon Sep 17 00:00:00 2001 From: Ilias Dimopoulos Date: Tue, 30 Mar 2021 19:43:45 +0300 Subject: [PATCH 06/11] ISAICP-6139: Remove wrong character. --- tests/features/asset_distribution/track_download.feature | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/features/asset_distribution/track_download.feature b/tests/features/asset_distribution/track_download.feature index 7b551c5d71..03432c06d0 100644 --- a/tests/features/asset_distribution/track_download.feature +++ b/tests/features/asset_distribution/track_download.feature @@ -122,7 +122,6 @@ Feature: Asset distribution editing. | title | Release 1 | | is version of | Solution | | state | validated | - | And the following distributions: | title | parent | access url | | Distribution 1 | Release 1 | text.pdf | From 72fae281af3c87c5d9432aa7fabf7990a12b3f48 Mon Sep 17 00:00:00 2001 From: Ilias Dimopoulos Date: Tue, 30 Mar 2021 23:27:24 +0300 Subject: [PATCH 07/11] ISAICP-6139: Test that the exported file contains the IDs of the parents. --- .../asset_distribution/track_download.feature | 11 ++++++----- tests/features/bootstrap/FeatureContext.php | 17 +++++++++++++---- tests/src/Context/AssetDistributionContext.php | 6 +++++- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/tests/features/asset_distribution/track_download.feature b/tests/features/asset_distribution/track_download.feature index 03432c06d0..1171b11f1a 100644 --- a/tests/features/asset_distribution/track_download.feature +++ b/tests/features/asset_distribution/track_download.feature @@ -144,8 +144,9 @@ Feature: Asset distribution editing. And I should see the link "here" And the file downloaded from the "here" link contains the following strings: | ID,User,Email,"File name",Distribution,Parent,Created | - | ,"Anonymous (not verified)",visitor@example.com,text.pdf,"Distribution 1","Release 1", | - | ,user1,user1@example.com,text.pdf,"Distribution 1","Release 1", | - | ,user2,user2@example.com,test.zip,"Distribution 2",Solution, | - | ,"Anonymous (not verified)",anon@example.com,test1.zip,"Distribution 3",Solution, | - | ,user1,user1@example.com,test1.zip,"Distribution 3",Solution, | + # The %title% variable will translate the title to the entity ID since that is what is exported in the CSV file. + | ,"Anonymous (not verified)",visitor@example.com,text.pdf,"Distribution 1",%Release 1%, | + | ,user1,user1@example.com,text.pdf,"Distribution 1",%Release 1%, | + | ,user2,user2@example.com,test.zip,"Distribution 2",%Solution%, | + | ,"Anonymous (not verified)",anon@example.com,test1.zip,"Distribution 3",%Solution%, | + | ,user1,user1@example.com,test1.zip,"Distribution 3",%Solution%, | diff --git a/tests/features/bootstrap/FeatureContext.php b/tests/features/bootstrap/FeatureContext.php index 9179b9efe0..9f65d0c731 100644 --- a/tests/features/bootstrap/FeatureContext.php +++ b/tests/features/bootstrap/FeatureContext.php @@ -2006,11 +2006,20 @@ public function assertDownloadedFileContainsStrings(string $link_label, TableNod throw new \Exception("The downloaded file has no content."); } - $not_found = array_filter($strings_table->getColumn(0), function (string $text) use ($content): bool { - return strpos($content, $text) === FALSE; - }); + $not_found = []; + foreach ($strings_table->getColumn(0) as $text) { + $matches = []; + if (preg_match('/^.*%(.*?)%.*$/', $text, $matches)) { + $entity = $this->getEntityByLabel('rdf_entity', $matches[1]); + $text = str_replace("%{$matches[1]}%", $entity->id(), $text); + } - if ($not_found) { + if (strpos($content, $text) === FALSE) { + $not_found[] = $text; + } + } + + if (!empty($not_found)) { throw new ExpectationFailedException("Following strings were not found in the downloaded file:\n- " . implode("\n- ", $not_found)); } } diff --git a/tests/src/Context/AssetDistributionContext.php b/tests/src/Context/AssetDistributionContext.php index a3ac36948b..f2ba05671f 100644 --- a/tests/src/Context/AssetDistributionContext.php +++ b/tests/src/Context/AssetDistributionContext.php @@ -483,15 +483,19 @@ public function clickLinkInCompactDistribution(string $link, string $heading): v */ public function downloadEvents(TableNode $table): void { foreach ($table->getColumnsHash() as $row) { + /** @var \Drupal\asset_distribution\Entity\AssetDistributionInterface $distribution */ $distribution = $this->getRdfEntityByLabel($row['distribution'], 'asset_distribution'); - /** @var \Drupal\file\FileInterface $file */ $file = FileUrlHandler::urlToFile($distribution->get('field_ad_access_url')->target_id); $account = \Drupal::service('email.validator')->isValid($row['user']) ? new AnonymousUserSession() : user_load_by_name($row['user']); $mail = $account->isAnonymous() ? $row['user'] : $account->getEmail(); + + $parent = $distribution->getParent(); $entity = DownloadEvent::create([ 'uid' => $account->id(), 'mail' => $mail, 'file' => $file->id(), + 'parent_entity_type' => $parent->getEntityTypeId(), + 'parent_entity_id' => $parent->id(), ]); $entity->save(); $this->entities['download_event'][$entity->id()] = $entity; From 06ee8c02305db21759cb83938e87c855c4aef5e6 Mon Sep 17 00:00:00 2001 From: Ilias Dimopoulos Date: Wed, 31 Mar 2021 14:54:48 +0300 Subject: [PATCH 08/11] ISAICP-6139: Give a grace period for the creation/publication date comparison. --- tests/src/Context/JoinupCommunityContentContext.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/src/Context/JoinupCommunityContentContext.php b/tests/src/Context/JoinupCommunityContentContext.php index 0248d41fd7..7d4bd884f7 100644 --- a/tests/src/Context/JoinupCommunityContentContext.php +++ b/tests/src/Context/JoinupCommunityContentContext.php @@ -147,7 +147,11 @@ public function assertSamePublishedCreatedTime(string $title, string $type): voi throw new \InvalidArgumentException('Node does not have a publication date field.'); } Assert::assertNotEmpty($node->getPublicationTime()); - Assert::assertEquals($node->created->value, $node->getPublicationTime()); + + // Since there can be minor differences in the timestamp depending on the + // performacne of the request, we allow a grace period of 5 milliseconds + // for the difference between the created and the publication date. + Assert::assertTrue(abs((int) $node->created->value - (int) $node->getPublicationTime()) < 5); } /** From b6edbc2166b9096fdefa7af9934745d27b20ea3b Mon Sep 17 00:00:00 2001 From: Pieter Frenssen Date: Thu, 1 Apr 2021 17:40:34 +0300 Subject: [PATCH 09/11] ISAICP-6139: Improve scenario title. --- tests/features/asset_distribution/track_download.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/features/asset_distribution/track_download.feature b/tests/features/asset_distribution/track_download.feature index 1171b11f1a..76a6496165 100644 --- a/tests/features/asset_distribution/track_download.feature +++ b/tests/features/asset_distribution/track_download.feature @@ -110,7 +110,7 @@ Feature: Asset distribution editing. When I go to the "Winter of 95" release Then I should see the link "External" in the "i386" tile - Scenario: Tests the CSV download. + Scenario: Download a CSV export of the distributions download report. Given users: | Username | E-mail | | user1 | user1@example.com | From c3e8ac167684a12e552c1fe00f732ccecbe982d3 Mon Sep 17 00:00:00 2001 From: Pieter Frenssen Date: Thu, 1 Apr 2021 17:53:09 +0300 Subject: [PATCH 10/11] ISAICP-6139: Return a DistributionsParentInterface when retrieving the parent of a distribution. --- .../asset_distribution/src/Entity/AssetDistribution.php | 4 ++-- .../src/Entity/AssetDistributionInterface.php | 4 ++-- .../src/Entity/DistributionsParentInterface.php | 4 +++- web/modules/custom/joinup_core/joinup_core.deploy.php | 1 - 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/web/modules/custom/asset_distribution/src/Entity/AssetDistribution.php b/web/modules/custom/asset_distribution/src/Entity/AssetDistribution.php index d0aa76a950..a729327595 100644 --- a/web/modules/custom/asset_distribution/src/Entity/AssetDistribution.php +++ b/web/modules/custom/asset_distribution/src/Entity/AssetDistribution.php @@ -36,12 +36,12 @@ class AssetDistribution extends Rdf implements AssetDistributionInterface { /** * {@inheritdoc} */ - public function getParent() { + public function getParent(): DistributionsParentInterface { /** @var \Drupal\asset_distribution\DistributionParentFieldItemList $field */ $field = $this->get('parent'); /** @var \Drupal\asset_release\Entity\AssetReleaseInterface|\Drupal\solution\Entity\SolutionInterface $parent */ - if ($field->isEmpty() || !($parent = $field->entity)) { + if ($field->isEmpty() || !($parent = $field->entity) || !$parent instanceof DistributionsParentInterface) { // During normal operation every distribution should have a parent entity, // so the only way a parent can be missing is because of an unexpected // condition occurring at runtime, for example if a data store goes diff --git a/web/modules/custom/asset_distribution/src/Entity/AssetDistributionInterface.php b/web/modules/custom/asset_distribution/src/Entity/AssetDistributionInterface.php index f1b85cd333..e53ba04c99 100644 --- a/web/modules/custom/asset_distribution/src/Entity/AssetDistributionInterface.php +++ b/web/modules/custom/asset_distribution/src/Entity/AssetDistributionInterface.php @@ -17,7 +17,7 @@ interface AssetDistributionInterface extends RdfInterface, CollectionContentInte /** * Return the distribution's parent, either a release or a solution. * - * @return \Drupal\asset_release\Entity\AssetReleaseInterface|\Drupal\solution\Entity\SolutionInterface + * @return \Drupal\asset_distribution\Entity\DistributionsParentInterface * The parent entity, either a release or a solution. * * @throws \Drupal\asset_distribution\Exception\MissingDistributionParentException @@ -26,7 +26,7 @@ interface AssetDistributionInterface extends RdfInterface, CollectionContentInte * need to catch this exception. This will only be thrown in case something * is seriously wrong, e.g. if the database is down. */ - public function getParent(); + public function getParent(): DistributionsParentInterface; /** * Checks whether the distribution parent is a solution rather than a release. diff --git a/web/modules/custom/asset_distribution/src/Entity/DistributionsParentInterface.php b/web/modules/custom/asset_distribution/src/Entity/DistributionsParentInterface.php index 0c2cae8919..29a5202f29 100644 --- a/web/modules/custom/asset_distribution/src/Entity/DistributionsParentInterface.php +++ b/web/modules/custom/asset_distribution/src/Entity/DistributionsParentInterface.php @@ -4,10 +4,12 @@ namespace Drupal\asset_distribution\Entity; +use Drupal\Core\Entity\ContentEntityInterface; + /** * Bundle class for content having distributions as children. */ -interface DistributionsParentInterface { +interface DistributionsParentInterface extends ContentEntityInterface { /** * Returns the child distribution IDs. diff --git a/web/modules/custom/joinup_core/joinup_core.deploy.php b/web/modules/custom/joinup_core/joinup_core.deploy.php index a3fb39ec00..a066ba1d77 100644 --- a/web/modules/custom/joinup_core/joinup_core.deploy.php +++ b/web/modules/custom/joinup_core/joinup_core.deploy.php @@ -45,7 +45,6 @@ function joinup_core_deploy_0107000(array &$sandbox): string { continue; } - /** @var \Drupal\solution\Entity\SolutionInterface|\Drupal\asset_release\Entity\AssetReleaseInterface $parent */ try { $parent = $distribution->getParent(); } From 098c6179460236337e03478cd176f114e30f9731 Mon Sep 17 00:00:00 2001 From: Pieter Frenssen Date: Thu, 1 Apr 2021 18:17:56 +0300 Subject: [PATCH 11/11] ISAICP-6139: Fix spelling mistague. --- web/modules/custom/joinup_core/joinup_core.deploy.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/modules/custom/joinup_core/joinup_core.deploy.php b/web/modules/custom/joinup_core/joinup_core.deploy.php index a066ba1d77..bfc0182995 100644 --- a/web/modules/custom/joinup_core/joinup_core.deploy.php +++ b/web/modules/custom/joinup_core/joinup_core.deploy.php @@ -49,7 +49,7 @@ function joinup_core_deploy_0107000(array &$sandbox): string { $parent = $distribution->getParent(); } catch (\Exception $e) { - // We don't want to force anything for old regords. + // We don't want to force anything for old records. continue; }