diff --git a/README.md b/README.md index e6c2573a..4c42dc4c 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,13 @@ ## Introduction -Islandora modules for Drupal 8.2.x +CLAW's core Islandora module for Drupal 8.x + +## Installation + +For a fully automated install, see [claw-playbook](https://github.com/Islandora-Devops/claw-playbook). If you're installing +manually, the REST configuration for both Nodes and Media need to be enabled. `jwt_auth` and `jsonld` formats needs to be set +for both, with Media additionally needing the `json` format. ## Maintainers diff --git a/composer.json b/composer.json index dcebb5a8..100dfef3 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,8 @@ "islandora/jsonld": "dev-8.x-1.x", "stomp-php/stomp-php": "4.*", "drupal/jwt": "1.0.0-alpha6", - "drupal/media_entity_image": "^1.2" + "drupal/media_entity_image": "^1.2", + "drupal/filehash": "^1.1" }, "require-dev": { "phpunit/phpunit": "^4.8", diff --git a/config/install/rdf.mapping.media.tn.yml b/config/install/rdf.mapping.media.tn.yml index f2885085..f65e03da 100644 --- a/config/install/rdf.mapping.media.tn.yml +++ b/config/install/rdf.mapping.media.tn.yml @@ -21,10 +21,6 @@ fieldMappings: properties: - 'dc:title' - 'rdf:label' - field_image: - properties: - - 'iana:describes' - mapping_type: rel created: properties: - 'schema:dateCreated' @@ -39,3 +35,6 @@ fieldMappings: properties: - 'schema:author' mapping_type: rel + field_mimetype: + properties: + - 'ebucore:hasMimeType' diff --git a/config/install/rest.resource.entity.media.yml b/config/install/rest.resource.entity.media.yml deleted file mode 100644 index 9c52f2e1..00000000 --- a/config/install/rest.resource.entity.media.yml +++ /dev/null @@ -1,27 +0,0 @@ -uuid: bf3d7c56-77d9-4154-a7b8-bb77c7188569 -langcode: en -status: true -dependencies: - module: - - basic_auth - - hal - - jsonld - - jwt - - media_entity - - user - enforced: - module: - - islandora -id: entity.media -plugin_id: 'entity:media' -granularity: resource -configuration: - methods: - - GET - formats: - - hal_json - - jsonld - authentication: - - basic_auth - - jwt_auth - - cookie diff --git a/config/install/rules.reaction.broadcast_content_create_event.yml b/config/install/rules.reaction.broadcast_content_create_event.yml index 448a2d9f..4265178c 100644 --- a/config/install/rules.reaction.broadcast_content_create_event.yml +++ b/config/install/rules.reaction.broadcast_content_create_event.yml @@ -40,8 +40,8 @@ expression: uuid: 0e953790-c751-4de8-99b3-c729ba1e09e3 context_values: recipients: - - "activemq:queue:islandora-indexing-fcrepo-create\r" - - 'activemq:queue:islandora-indexing-triplestore' + - "activemq:queue:islandora-indexing-fcrepo-content\r" + - 'activemq:queue:islandora-indexing-triplestore-index' context_mapping: message: event_message context_processors: diff --git a/config/install/rules.reaction.broadcast_content_delete_event.yml b/config/install/rules.reaction.broadcast_content_delete_event.yml index 995fd1ca..f6c989aa 100644 --- a/config/install/rules.reaction.broadcast_content_delete_event.yml +++ b/config/install/rules.reaction.broadcast_content_delete_event.yml @@ -41,7 +41,7 @@ expression: context_values: recipients: - "activemq:queue:islandora-indexing-fcrepo-delete\r" - - 'activemq:queue:islandora-indexing-triplestore' + - 'activemq:queue:islandora-indexing-triplestore-delete' context_mapping: message: event_message context_processors: diff --git a/config/install/rules.reaction.broadcast_content_update_event.yml b/config/install/rules.reaction.broadcast_content_update_event.yml index b71f287a..614720c7 100644 --- a/config/install/rules.reaction.broadcast_content_update_event.yml +++ b/config/install/rules.reaction.broadcast_content_update_event.yml @@ -40,8 +40,8 @@ expression: uuid: 7b9cf7be-40e4-4490-ae6f-07a84eb112c4 context_values: recipients: - - "activemq:queue:islandora-indexing-fcrepo-update\r" - - 'activemq:queue:islandora-indexing-triplestore' + - "activemq:queue:islandora-indexing-fcrepo-content\r" + - 'activemq:queue:islandora-indexing-triplestore-index' context_mapping: message: event_message context_processors: diff --git a/config/install/rules.reaction.broadcast_file_create_event.yml b/config/install/rules.reaction.broadcast_file_create_event.yml new file mode 100644 index 00000000..cf1379f5 --- /dev/null +++ b/config/install/rules.reaction.broadcast_file_create_event.yml @@ -0,0 +1,50 @@ +uuid: 5a444d61-ac7f-4cde-a8b7-2693bd825753 +langcode: en +status: true +dependencies: + enforced: + module: + - islandora +id: broadcast_file_create_event +label: 'Broadcast File Create Event' +events: + - + event_name: 'rules_entity_insert:file' +description: 'Broadcasts an AS2 event to a message broker when a File is created.' +tags: + - '' +config_version: '3' +expression: + id: rules_rule + uuid: 54c6585d-453d-4143-8e54-760019f251d5 + conditions: + id: rules_and + uuid: d82f7041-6522-4127-9676-d5534f7c1684 + conditions: { } + actions: + id: rules_action_set + uuid: 0dc80d3b-2a60-4a47-afd6-4026d0fdffe6 + actions: + - + id: rules_action + uuid: 0e42b62d-39ca-4f51-baa5-fdd1b37605fe + context_values: { } + context_mapping: + entity: file + user: '@user.current_user_context:current_user' + context_processors: { } + provides_mapping: { } + action_id: islandora_create_event_generator + - + id: rules_action + uuid: bcbbe914-54a9-4ff2-9d4b-98945682e087 + context_values: + recipients: + - 'activemq:queue:islandora-indexing-fcrepo-file' + context_mapping: + message: event_message + context_processors: + recipients: + rules_tokens: { } + provides_mapping: { } + action_id: islandora_broadcast diff --git a/config/install/rules.reaction.broadcast_file_delete_event.yml b/config/install/rules.reaction.broadcast_file_delete_event.yml new file mode 100644 index 00000000..c8016eaa --- /dev/null +++ b/config/install/rules.reaction.broadcast_file_delete_event.yml @@ -0,0 +1,50 @@ +uuid: d35441d4-62d6-4e0d-bf6f-23ff32eab457 +langcode: en +status: true +dependencies: + enforced: + module: + - islandora +id: broadcast_file_delete_event +label: 'Broadcast File Delete Event' +events: + - + event_name: 'rules_entity_delete:file' +description: 'Broadcasts an AS2 event to a message broker when a File is deleted.' +tags: + - '' +config_version: '3' +expression: + id: rules_rule + uuid: 69e8870c-9d20-4cc3-9a17-de940d4c9932 + conditions: + id: rules_and + uuid: f465ad23-88a2-4026-a7ca-dbfc2d3aa031 + conditions: { } + actions: + id: rules_action_set + uuid: 65ce1b3b-7986-4cf2-ab03-b950212f505e + actions: + - + id: rules_action + uuid: 2d6b2435-e986-4e53-8831-e4328aa63af3 + context_values: { } + context_mapping: + entity: file + user: '@user.current_user_context:current_user' + context_processors: { } + provides_mapping: { } + action_id: islandora_delete_event_generator + - + id: rules_action + uuid: f1a6a455-5486-4a4a-a3c9-4e9b3867cf64 + context_values: + recipients: + - 'activemq:queue:islandora-indexing-fcrepo-delete' + context_mapping: + message: event_message + context_processors: + recipients: + rules_tokens: { } + provides_mapping: { } + action_id: islandora_broadcast diff --git a/config/install/rules.reaction.broadcast_file_update_event.yml b/config/install/rules.reaction.broadcast_file_update_event.yml new file mode 100644 index 00000000..fc2755a7 --- /dev/null +++ b/config/install/rules.reaction.broadcast_file_update_event.yml @@ -0,0 +1,50 @@ +d: 129d52bf-c67f-41fc-81fc-83f126f59a66 +langcode: en +status: true +dependencies: + enforced: + module: + - islandora +id: broadcast_file_update_event +label: 'Broadcast File Update Event' +events: + - + event_name: 'rules_entity_update:file' +description: 'Broadcasts an AS2 event to a message broker when a File is updated.' +tags: + - '' +config_version: '3' +expression: + id: rules_rule + uuid: 5355a324-0af0-48bb-8168-e2810a9ee0a2 + conditions: + id: rules_and + uuid: 0b266024-65ea-4e91-b0e6-ae88b8bfd5ed + conditions: { } + actions: + id: rules_action_set + uuid: 85a784ad-7f03-4ba9-8c01-f87f33f15d5e + actions: + - + id: rules_action + uuid: a7dcf8e2-7e2d-4c9b-b658-e4f3f28898a1 + context_values: { } + context_mapping: + entity: file + user: '@user.current_user_context:current_user' + context_processors: { } + provides_mapping: { } + action_id: islandora_update_event_generator + - + id: rules_action + uuid: 60aa1b60-9ea4-40d1-bfbf-d036a617179a + context_values: + recipients: + - 'activemq:queue:islandora-indexing-fcrepo-file' + context_mapping: + message: event_message + context_processors: + recipients: + rules_tokens: { } + provides_mapping: { } + action_id: islandora_broadcast diff --git a/config/install/rules.reaction.broadcast_media_create_event.yml b/config/install/rules.reaction.broadcast_media_create_event.yml index b162bc0c..5ea4799f 100644 --- a/config/install/rules.reaction.broadcast_media_create_event.yml +++ b/config/install/rules.reaction.broadcast_media_create_event.yml @@ -40,8 +40,8 @@ expression: uuid: 6b0d07b3-048e-43ac-8a9f-2c5203f8080e context_values: recipients: - - "activemq:queue:islandora-indexing-triplestore\r" - - 'activemq:queue:islandora-indexing-fcrepo-binary-create' + - "activemq:queue:islandora-indexing-fcrepo-media\r" + - "activemq:queue:islandora-indexing-triplestore-index" context_mapping: message: event_message context_processors: diff --git a/config/install/rules.reaction.broadcast_media_delete_event.yml b/config/install/rules.reaction.broadcast_media_delete_event.yml index 5eb15ba3..59065e48 100644 --- a/config/install/rules.reaction.broadcast_media_delete_event.yml +++ b/config/install/rules.reaction.broadcast_media_delete_event.yml @@ -1,4 +1,4 @@ -uuid: 71df1b5d-2f04-42fa-a660-5375de9c6c51 +uuid: af85f943-2cc0-455c-97b0-4035d15f55ec langcode: en status: true dependencies: @@ -16,18 +16,18 @@ tags: config_version: '3' expression: id: rules_rule - uuid: c12184e7-8230-4bc7-b625-2a26b4a5a913 + uuid: abb78ad6-5f27-43e7-890c-c2a12e76ce51 conditions: id: rules_and - uuid: 5147d740-4e32-4935-8c30-f893e7c3f86f + uuid: 8c386012-6796-4138-b4e7-d438916c713f conditions: { } actions: id: rules_action_set - uuid: 4a023b99-1cf8-410a-a082-b0c0369a807d + uuid: 6599d3f0-dcd7-482c-bcb4-fa76b012da6a actions: - id: rules_action - uuid: 1fdc07dc-72ba-4666-abb8-8d79f29b67ff + uuid: 7003fe72-49f7-4a3a-b95b-781ef1c61615 context_values: { } context_mapping: entity: media @@ -37,11 +37,10 @@ expression: action_id: islandora_delete_event_generator - id: rules_action - uuid: 75d0cf84-715b-4167-8ec2-92047a0bec56 + uuid: 8a5dc149-9629-4e94-a8d5-3ff6069d6af6 context_values: recipients: - - "activemq:queue:islandora-indexing-triplestore\r" - - 'activemq:queue:islandora-indexing-fcrepo-binary-delete' + - 'activemq:queue:islandora-indexing-triplestore-delete' context_mapping: message: event_message context_processors: diff --git a/config/install/rules.reaction.broadcast_media_update_event.yml b/config/install/rules.reaction.broadcast_media_update_event.yml index f5a6d292..5673dedb 100644 --- a/config/install/rules.reaction.broadcast_media_update_event.yml +++ b/config/install/rules.reaction.broadcast_media_update_event.yml @@ -40,8 +40,8 @@ expression: uuid: ee50c8ae-a9cd-479a-aa86-3567629a01b8 context_values: recipients: - - "activemq:queue:islandora-indexing-triplestore\r" - - 'activemq:queue:islandora-indexing-fcrepo-binary-update' + - "activemq:queue:islandora-indexing-fcrepo-media\r" + - "activemq:queue:islandora-indexing-triplestore-index" context_mapping: message: event_message context_processors: diff --git a/config/install/views.view.file_checksum.yml b/config/install/views.view.file_checksum.yml new file mode 100644 index 00000000..e7526fdb --- /dev/null +++ b/config/install/views.view.file_checksum.yml @@ -0,0 +1,213 @@ +uuid: cd3f8b61-8032-4c3d-9de3-624b298c9bca +langcode: en +status: true +dependencies: + module: + - basic_auth + - file + - jwt + - rest + - serialization + - user +_core: + default_config_hash: e7XqQa-N16XDqeDTA7Ohgx6iLb6mIQ1RUs0krFFIbAw +id: file_checksum +label: 'File Checksum' +module: views +description: 'Exposes a REST endpoint for getting the checksum of a File' +tag: '' +base_table: file_managed +base_field: fid +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: none + options: { } + cache: + type: tag + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: mini + options: + items_per_page: 10 + offset: 0 + id: 0 + total_pages: null + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + tags: + previous: ‹‹ + next: ›› + style: + type: serializer + row: + type: 'entity:file' + options: + relationship: none + view_mode: default + fields: + sha1: + id: sha1 + table: filehash + field: sha1 + relationship: none + group_type: group + admin_label: '' + label: '' + 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: false + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + plugin_id: standard + filters: { } + sorts: { } + header: { } + footer: { } + empty: { } + relationships: { } + arguments: + fid: + id: fid + table: file_managed + field: fid + relationship: none + group_type: group + admin_label: '' + default_action: 'not found' + exception: + value: all + title_enable: false + title: All + title_enable: false + title: '' + default_argument_type: fixed + default_argument_options: + argument: '' + default_argument_skip_url: false + summary_options: + base_path: '' + count: true + items_per_page: 25 + override: false + summary: + sort_order: asc + number_of_records: 0 + format: default_summary + specify_validation: false + validate: + type: none + fail: 'not found' + validate_options: { } + break_phrase: false + not: false + entity_type: file + entity_field: fid + plugin_id: file_fid + display_extenders: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_interface' + - request_format + - url + - url.query_args + tags: { } + rest_export_1: + display_plugin: rest_export + id: rest_export_1 + display_title: 'REST export' + position: 1 + display_options: + display_extenders: { } + path: checksum/%file + pager: + type: some + options: + items_per_page: 10 + offset: 0 + style: + type: serializer + options: + formats: + json: json + row: + type: data_field + options: + field_options: { } + auth: + - basic_auth + - jwt_auth + - cookie + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_interface' + - request_format + - url + tags: { } diff --git a/islandora.info.yml b/islandora.info.yml index 1884b7f4..e33fc662 100644 --- a/islandora.info.yml +++ b/islandora.info.yml @@ -18,3 +18,5 @@ dependencies: - jwt - media_entity_image - rest + - filehash + - basic_auth diff --git a/islandora.install b/islandora.install index 6cd04214..e900f2f6 100644 --- a/islandora.install +++ b/islandora.install @@ -40,28 +40,3 @@ function islandora_schema() { ]; return $schema; } - -/** - * Implements hook_install(). - */ -function islandora_install() { - if (\Drupal::moduleHandler()->moduleExists('rest')) { - $rest_resource_config_storage = \Drupal::service('entity_type.manager')->getStorage('rest_resource_config'); - $rest_resource_config = $rest_resource_config_storage->load('entity.node'); - - if ($rest_resource_config) { - $configuration = $rest_resource_config->get('configuration'); - - if (!in_array('jsonld', $configuration['formats'])) { - $configuration['formats'][] = 'jsonld'; - } - - if (!in_array('jwt_auth', $configuration['authentication'])) { - $configuration['authentication'][] = 'jwt_auth'; - } - - $rest_resource_config->set('configuration', $configuration); - $rest_resource_config->save(TRUE); - } - } -} diff --git a/islandora.permissions.yml b/islandora.permissions.yml new file mode 100644 index 00000000..f8cca135 --- /dev/null +++ b/islandora.permissions.yml @@ -0,0 +1,4 @@ + +view checksums: + title: 'View Checksums' + description: 'Allows access to viewing file checksums' diff --git a/src/EventGenerator/EventGenerator.php b/src/EventGenerator/EventGenerator.php index b8486381..551889ce 100644 --- a/src/EventGenerator/EventGenerator.php +++ b/src/EventGenerator/EventGenerator.php @@ -3,8 +3,11 @@ namespace Drupal\islandora\EventGenerator; use Drupal\Core\Entity\EntityInterface; -use Drupal\media_entity\Entity\Media; +use Drupal\Core\Url; +use Drupal\file\FileInterface; use Drupal\user\UserInterface; +use Drupal\media_entity\MediaInterface; +use Drupal\node\NodeInterface; /** * The default EventGenerator implementation. @@ -17,20 +20,8 @@ class EventGenerator implements EventGeneratorInterface { * {@inheritdoc} */ public function generateCreateEvent(EntityInterface $entity, UserInterface $user) { - $event = [ - "@context" => "https://www.w3.org/ns/activitystreams", - "type" => "Create", - "actor" => [ - "type" => "Person", - "id" => $user->toUrl()->setAbsolute()->toString(), - ], - "object" => $entity->toUrl()->setAbsolute()->toString(), - ]; - - if ($entity instanceof Media) { - $this->addAttachment($entity, $event); - } - + $event = $this->generateEvent($entity, $user); + $event["type"] = "Create"; return json_encode($event); } @@ -38,20 +29,8 @@ class EventGenerator implements EventGeneratorInterface { * {@inheritdoc} */ public function generateUpdateEvent(EntityInterface $entity, UserInterface $user) { - $event = [ - "@context" => "https://www.w3.org/ns/activitystreams", - "type" => "Update", - "actor" => [ - "type" => "Person", - "id" => $user->toUrl()->setAbsolute()->toString(), - ], - "object" => $entity->toUrl()->setAbsolute()->toString(), - ]; - - if ($entity instanceof Media) { - $this->addAttachment($entity, $event); - } - + $event = $this->generateEvent($entity, $user); + $event["type"] = "Update"; return json_encode($event); } @@ -59,57 +38,158 @@ class EventGenerator implements EventGeneratorInterface { * {@inheritdoc} */ public function generateDeleteEvent(EntityInterface $entity, UserInterface $user) { - $event = [ + $event = $this->generateEvent($entity, $user); + $event["type"] = "Delete"; + return json_encode($event); + } + + /** + * Shared event generation function that does not impose a 'Type'. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity that was created. + * @param \Drupal\user\UserInterface $user + * The user who created the entity. + * + * @return array + * Event message as an array. + */ + protected function generateEvent(EntityInterface $entity, UserInterface $user) { + + $user_url = $user->toUrl()->setAbsolute()->toString(); + + return [ "@context" => "https://www.w3.org/ns/activitystreams", - "type" => "Delete", "actor" => [ "type" => "Person", - "id" => $user->toUrl()->setAbsolute()->toString(), + "id" => "urn:uuid:{$user->uuid()}", + "url" => [ + [ + "name" => "Canonical", + "type" => "Link", + "href" => "$user_url", + "mediaType" => "text/html", + "rel" => "canonical", + ], + ], + ], + "object" => [ + "id" => "urn:uuid:{$entity->uuid()}", + "url" => $this->generateEntityLinks($entity), ], - "object" => $entity->toUrl()->setAbsolute()->toString(), ]; + } - if ($entity instanceof Media) { - $this->addAttachment($entity, $event); + /** + * Generates entity urls depending on entity type. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity. + * + * @return array + * AS2 Links. + */ + protected function generateEntityLinks(EntityInterface $entity) { + if ($entity instanceof FileInterface) { + return $this->generateFileLinks($entity); + } + elseif ($entity instanceof MediaInterface) { + return $this->generateMediaLinks($entity); } - return json_encode($event); + return $this->generateNodeLinks($entity); } /** - * Adds the 'attachment' info to the event array. + * Generates file urls. * - * @param \Drupal\media_entity\Entity\Media $entity - * The entity that was updated. - * @param array $event - * Array of info to be serialized to jsonld. + * @param \Drupal\file\FileInterface $file + * The file. + * + * @return array + * AS2 Links. */ - protected function addAttachment(Media $entity, array &$event) { - if ($entity->hasField("field_image")) { - $file = $entity->field_image->entity; - } - elseif ($entity->hasField("field_file")) { - $file = $entity->field_file->entity; - } - else { - \Drupal::logger('islandora')->warning( - "Cannot parse 'field_image' or 'field_file' from Media entity {$entity->id()}" - ); - return; - } + protected function generateFileLinks(FileInterface $file) { + $file_url = $file->url(); + $checksum_url = Url::fromRoute('view.file_checksum.rest_export_1', ['file' => $file->id()]) + ->setAbsolute() + ->toString(); + + return [ + [ + "name" => "File", + "type" => "Link", + "href" => "$file_url", + "mediaType" => $file->getMimeType(), + ], + [ + "name" => "Checksum", + "type" => "Link", + "href" => "$checksum_url?_format=json", + "mediaType" => "application/json", + ], + ]; + } - if ($file === NULL) { - \Drupal::logger('islandora')->debug( - "'field_image' or 'field_file' is null in Media entity {$entity->id()}" - ); - return; - } + /** + * Generates media urls. + * + * @param \Drupal\media_entity\MediaInterface $media + * The media. + * + * @return array + * AS2 Links. + */ + protected function generateMediaLinks(MediaInterface $media) { + $url = $media->toUrl()->setAbsolute()->toString(); + return [ + [ + "name" => "Canoncial", + "type" => "Link", + "href" => "$url", + "mediaType" => "text/html", + "rel" => "canonical", + ], + [ + "name" => "JSONLD", + "type" => "Link", + "href" => "$url?_format=jsonld", + "mediaType" => "application/ld+json", + ], + [ + "name" => "JSON", + "type" => "Link", + "href" => "$url?_format=json", + "mediaType" => "application/json", + ], + ]; + } - $url = file_create_url($file->getFileUri()); - $mime = $file->getMimeType(); - $event['attachment'] = [ - 'url' => $url, - 'mediaType' => $mime, + /** + * Generates node urls. + * + * @param \Drupal\node\NodeInterface $node + * The node. + * + * @return array + * AS2 Links. + */ + protected function generateNodeLinks(NodeInterface $node) { + $url = $node->toUrl()->setAbsolute()->toString(); + return [ + [ + "name" => "Canoncial", + "type" => "Link", + "href" => "$url", + "mediaType" => "text/html", + "rel" => "canonical", + ], + [ + "name" => "JSONLD", + "type" => "Link", + "href" => "$url?_format=jsonld", + "mediaType" => "application/ld+json", + ], ]; } diff --git a/src/Tests/Web/IslandoraWebTestBase.php b/src/Tests/Web/IslandoraWebTestBase.php index 9f541cbf..25ce79bb 100644 --- a/src/Tests/Web/IslandoraWebTestBase.php +++ b/src/Tests/Web/IslandoraWebTestBase.php @@ -32,6 +32,8 @@ abstract class IslandoraWebTestBase extends WebTestBase { 'views', 'key', 'jwt', + 'basic_auth', + 'filehash', 'islandora', ]; diff --git a/tests/src/Kernel/EventGeneratorTest.php b/tests/src/Kernel/EventGeneratorTest.php index 52906f0e..07d67352 100644 --- a/tests/src/Kernel/EventGeneratorTest.php +++ b/tests/src/Kernel/EventGeneratorTest.php @@ -76,8 +76,8 @@ class EventGeneratorTest extends EventGeneratorTestBase { */ protected function assertBasicStructure(array $msg) { // Looking for @context. - $this->assertTrue(array_key_exists('@context', $msg), "Context key exists"); - $this->assertTrue($msg["@context"] == "https://www.w3.org/ns/activitystreams", "Context must be activity stream."); + $this->assertTrue(array_key_exists('@context', $msg), "Expected @context entry"); + $this->assertTrue($msg["@context"] == "https://www.w3.org/ns/activitystreams", "@context must be activity stream."); // Make sure it has a type. $this->assertTrue(array_key_exists('type', $msg), "Message must have 'type' key."); @@ -87,11 +87,34 @@ class EventGeneratorTest extends EventGeneratorTestBase { $this->assertTrue(array_key_exists("type", $msg["actor"]), "Actor must have 'type' key."); $this->assertTrue($msg["actor"]["type"] == "Person", "Actor must be a 'Person'."); $this->assertTrue(array_key_exists("id", $msg["actor"]), "Actor must have 'id' key."); - $this->assertTrue($msg["actor"]["id"] == $this->user->toUrl()->setAbsolute()->toString(), "Id must be a user's uri"); + $this->assertTrue( + $msg["actor"]["id"] == "urn:uuid:{$this->user->uuid()}", + "Id must be an URN with user's UUID" + ); + $this->assertTrue(array_key_exists("url", $msg["actor"]), "Actor must have 'url' key."); + foreach ($msg['actor']['url'] as $url) { + $this->assertTrue($url['type'] == 'Link', "'url' entries must have type 'Link'"); + $this->assertTrue( + $url['mediaType'] == 'application/ld+json' || $url['mediaType'] == 'text/html', + "'url' entries must be either html or jsonld" + ); + } // Make sure the object exists and is a uri. $this->assertTrue(array_key_exists('object', $msg), "Message must have 'object' key."); - $this->assertTrue($msg["object"] == $this->entity->toUrl()->setAbsolute()->toString(), "Object must be an entity uri."); + $this->assertTrue(array_key_exists("id", $msg["object"]), "Object must have 'id' key."); + $this->assertTrue( + $msg["object"]["id"] == "urn:uuid:{$this->entity->uuid()}", + "Id must be an URN with entity's UUID" + ); + $this->assertTrue(array_key_exists("url", $msg["actor"]), "Object must have 'url' key."); + foreach ($msg['actor']['url'] as $url) { + $this->assertTrue($url['type'] == 'Link', "'url' entries must have type 'Link'"); + $this->assertTrue( + $url['mediaType'] == 'application/ld+json' || $url['mediaType'] == 'text/html', + "'url' entries must be either html or jsonld" + ); + } } } diff --git a/tests/src/Kernel/IslandoraKernelTestBase.php b/tests/src/Kernel/IslandoraKernelTestBase.php index b801ec5a..b4f5aef0 100644 --- a/tests/src/Kernel/IslandoraKernelTestBase.php +++ b/tests/src/Kernel/IslandoraKernelTestBase.php @@ -25,6 +25,7 @@ abstract class IslandoraKernelTestBase extends KernelTestBase { 'inline_entity_form', 'serialization', 'rest', + 'basic_auth', 'hal', 'rdf', 'typed_data',