diff --git a/.github/workflows/build-8.x-1.x.yml b/.github/workflows/build-8.x-1.x.yml index 5216753b..99e69571 100644 --- a/.github/workflows/build-8.x-1.x.yml +++ b/.github/workflows/build-8.x-1.x.yml @@ -94,7 +94,8 @@ jobs: git -C "$GITHUB_WORKSPACE/build_dir" checkout -b travis-testing cd $DRUPAL_DIR composer config repositories.local path "$GITHUB_WORKSPACE/build_dir" - composer require "islandora/islandora:dev-travis-testing as dev-8.x-1.x" --prefer-source --update-with-all-dependencies + composer config minimum-stability dev + composer require "islandora/islandora:dev-travis-testing as dev-8.x-1.x" - name: Install modules run: | diff --git a/islandora.module b/islandora.module index 22b2ad8a..0a86a6ac 100644 --- a/islandora.module +++ b/islandora.module @@ -18,9 +18,9 @@ use Drupal\Component\Plugin\Exception\PluginNotFoundException; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Site\Settings; use Drupal\Core\Url; use Drupal\islandora\Form\IslandoraSettingsForm; -use Drupal\islandora\GeminiLookup; use Drupal\node\NodeInterface; use Drupal\media\MediaInterface; use Drupal\file\FileInterface; @@ -466,27 +466,54 @@ function islandora_entity_view(array &$build, EntityInterface $entity, EntityVie // Ensure the entity matches the route. if ($entity === $route_match_item) { if ($display->getComponent('field_gemini_uri')) { - $gemini = \Drupal::service('islandora.gemini.lookup'); - if ($gemini instanceof GeminiLookup) { - $fedora_uri = $gemini->lookup($entity); - if (!is_null($fedora_uri)) { - $build['field_gemini_uri'] = [ - '#type' => 'container', - '#attributes' => [ - 'id' => 'field-gemini-uri', - ], - 'internal_label' => [ - '#type' => 'item', - '#title' => t('Fedora URI'), - 'internal_uri' => [ - '#type' => 'link', - '#title' => t("@url", ['@url' => $fedora_uri]), - '#url' => Url::fromUri($fedora_uri), - ], - ], - ]; + $mapper = \Drupal::service('islandora.entity_mapper'); + $flysystem_config = Settings::get('flysystem'); + $fedora_root = $flysystem_config['fedora']['config']['root']; + $fedora_root = rtrim($fedora_root, '/'); + + if ($entity->getEntityTypeId() == 'media') { + // Check if the source file is in Fedora or not. + $media_source_service = \Drupal::service('islandora.media_source_service'); + $source_file = $media_source_service->getSourceFile($entity); + $uri = $source_file->getFileUri(); + $scheme = \Drupal::service('stream_wrapper_manager')->getScheme($uri); + $flysystem_config = Settings::get('flysystem'); + + // Use the file's path if it's in fedora. + // Otherwise do the UUID -> pair tree thang. + if (isset($flysystem_config[$scheme]) && $flysystem_config[$scheme]['driver'] == 'fedora') { + $parts = parse_url($uri); + $path = $parts['host'] . $parts['path']; } + else { + $path = $mapper->getFedoraPath($source_file->uuid()); + } + $path = trim($path, '/'); + $fedora_uri = "$fedora_root/$path/fcr:metadata"; + } + else { + // All non-media entities do the UUID -> pair tree thang. + $path = $mapper->getFedoraPath($entity->uuid()); + $path = trim($path, '/'); + $fedora_uri = "$fedora_root/$path"; } + + // Stuff the fedora url into the pseudo field. + $build['field_gemini_uri'] = [ + '#type' => 'container', + '#attributes' => [ + 'id' => 'field-gemini-uri', + ], + 'internal_label' => [ + '#type' => 'item', + '#title' => t('Fedora URI'), + 'internal_uri' => [ + '#type' => 'link', + '#title' => t("@url", ['@url' => $fedora_uri]), + '#url' => Url::fromUri($fedora_uri), + ], + ], + ]; } } } diff --git a/islandora.services.yml b/islandora.services.yml index 0112f41a..39ebbab0 100644 --- a/islandora.services.yml +++ b/islandora.services.yml @@ -52,10 +52,5 @@ services: islandora.utils: class: Drupal\islandora\IslandoraUtils arguments: ['@entity_type.manager', '@entity_field.manager', '@context.manager', '@flysystem_factory', '@language_manager'] - islandora.gemini.client: - class: Islandora\Crayfish\Commons\Client\GeminiClient - factory: ['Drupal\islandora\GeminiClientFactory', create] - arguments: ['@config.factory', '@logger.channel.islandora'] - islandora.gemini.lookup: - class: Drupal\islandora\GeminiLookup - arguments: ['@islandora.gemini.client', '@jwt.authentication.jwt', '@islandora.media_source_service', '@http_client', '@logger.channel.islandora'] + islandora.entity_mapper: + class: Islandora\Crayfish\Commons\EntityMapper\EntityMapper diff --git a/modules/islandora_core_feature/config/install/views.view.all_taxonomy_terms.yml b/modules/islandora_core_feature/config/install/views.view.all_taxonomy_terms.yml new file mode 100644 index 00000000..56b45066 --- /dev/null +++ b/modules/islandora_core_feature/config/install/views.view.all_taxonomy_terms.yml @@ -0,0 +1,171 @@ +langcode: en +status: true +dependencies: + module: + - taxonomy + - user +id: all_taxonomy_terms +label: 'All Taxonomy Terms' +module: views +description: '' +tag: '' +base_table: taxonomy_term_field_data +base_field: tid +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: perm + options: + perm: 'access content' + 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: default + options: + grouping: { } + row_class: '' + default_row_class: true + uses_fields: false + row: + type: fields + options: + inline: { } + separator: '' + hide_empty: false + default_field_elements: true + fields: + name: + id: name + table: taxonomy_term_field_data + field: name + entity_type: taxonomy_term + entity_field: name + label: '' + alter: + alter_text: false + make_link: false + absolute: false + trim: false + word_boundary: false + ellipsis: false + strip_tags: false + html: false + hide_empty: false + empty_zero: false + type: string + settings: + link_to_entity: true + plugin_id: term_name + relationship: none + group_type: group + admin_label: '' + exclude: 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_alter_empty: true + click_sort_column: value + 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 + convert_spaces: false + filters: + status: + value: '1' + table: taxonomy_term_field_data + field: status + plugin_id: boolean + entity_type: taxonomy_term + entity_field: status + id: status + expose: + operator: '' + operator_limit_selection: false + operator_list: { } + group: 1 + sorts: { } + header: { } + footer: { } + empty: { } + relationships: { } + arguments: { } + display_extenders: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + - user.permissions + tags: { } + block_1: + display_plugin: block + id: block_1 + display_title: Block + position: 1 + display_options: + display_extenders: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + - user.permissions + tags: { } + diff --git a/modules/islandora_core_feature/config/install/views.view.non_fedora_files.yml b/modules/islandora_core_feature/config/install/views.view.non_fedora_files.yml new file mode 100644 index 00000000..88b0f308 --- /dev/null +++ b/modules/islandora_core_feature/config/install/views.view.non_fedora_files.yml @@ -0,0 +1,197 @@ +langcode: en +status: true +dependencies: + module: + - file + - user +id: non_fedora_files +label: 'Non-Fedora Files' +module: views +description: '' +tag: '' +base_table: file_managed +base_field: fid +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: perm + options: + perm: 'access content' + 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: default + options: + grouping: { } + row_class: '' + default_row_class: true + uses_fields: false + row: + type: fields + options: + inline: { } + separator: '' + hide_empty: false + default_field_elements: true + fields: + filename: + id: filename + table: file_managed + field: filename + entity_type: file + entity_field: filename + label: '' + alter: + alter_text: false + make_link: false + absolute: false + trim: false + word_boundary: false + ellipsis: false + strip_tags: false + html: false + hide_empty: false + empty_zero: false + plugin_id: field + type: file_link + relationship: none + group_type: group + admin_label: '' + exclude: 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_alter_empty: true + click_sort_column: value + settings: { } + 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 + filters: + uri: + id: uri + table: file_managed + field: uri + relationship: none + group_type: group + admin_label: '' + operator: not_starts + value: 'fedora://' + group: 1 + exposed: false + expose: + operator_id: '' + label: '' + description: '' + use_operator: false + operator: '' + operator_limit_selection: false + operator_list: { } + identifier: '' + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + placeholder: '' + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + entity_type: file + entity_field: uri + plugin_id: string + sorts: { } + header: { } + footer: { } + empty: { } + relationships: { } + arguments: { } + display_extenders: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + - user.permissions + tags: { } + block_1: + display_plugin: block + id: block_1 + display_title: Block + position: 1 + display_options: + display_extenders: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + - user.permissions + tags: { } + diff --git a/src/Form/IslandoraSettingsForm.php b/src/Form/IslandoraSettingsForm.php index 6bb868d2..cdaa358d 100644 --- a/src/Form/IslandoraSettingsForm.php +++ b/src/Form/IslandoraSettingsForm.php @@ -7,9 +7,6 @@ use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Site\Settings; -use Drupal\Core\Url; -use GuzzleHttp\Exception\ConnectException; -use Islandora\Crayfish\Commons\Client\GeminiClient; use Stomp\Client; use Stomp\Exception\StompException; use Stomp\StatefulStomp; @@ -25,7 +22,6 @@ class IslandoraSettingsForm extends ConfigFormBase { const BROKER_USER = 'broker_user'; const BROKER_PASSWORD = 'broker_password'; const JWT_EXPIRY = 'jwt_expiry'; - const GEMINI_URL = 'gemini_url'; const GEMINI_PSEUDO = 'gemini_pseudo_bundles'; const FEDORA_URL = 'fedora_url'; const TIME_INTERVALS = [ @@ -148,12 +144,6 @@ class IslandoraSettingsForm extends ConfigFormBase { ), ]; - $form[self::GEMINI_URL] = [ - '#type' => 'textfield', - '#title' => $this->t('Gemini URL'), - '#default_value' => $config->get(self::GEMINI_URL), - ]; - $flysystem_config = Settings::get('flysystem'); if ($flysystem_config != NULL) { $fedora_url = $flysystem_config['fedora']['config']['root']; @@ -269,45 +259,6 @@ class IslandoraSettingsForm extends ConfigFormBase { ); } } - - // Needed for the elseif below. - $pseudo_types = array_filter($form_state->getValue(self::GEMINI_PSEUDO)); - - // Validate Gemini URL by validating the URL. - $geminiUrlValue = trim($form_state->getValue(self::GEMINI_URL)); - if (!empty($geminiUrlValue)) { - try { - $geminiUrl = Url::fromUri($geminiUrlValue); - $client = GeminiClient::create($geminiUrlValue, $this->logger('islandora')); - $client->findByUri('http://example.org'); - } - // Uri is invalid. - catch (\InvalidArgumentException $e) { - $form_state->setErrorByName( - self::GEMINI_URL, - $this->t( - 'Cannot parse URL @url', - ['@url' => $geminiUrlValue] - ) - ); - } - // Uri is not available. - catch (ConnectException $e) { - $form_state->setErrorByName( - self::GEMINI_URL, - $this->t( - 'Cannot connect to URL @url', - ['@url' => $geminiUrlValue] - ) - ); - } - } - elseif (count($pseudo_types) > 0) { - $form_state->setErrorByName( - self::GEMINI_URL, - $this->t('Must enter Gemini URL before selecting bundles to display a pseudo field on.') - ); - } } /** @@ -337,7 +288,6 @@ class IslandoraSettingsForm extends ConfigFormBase { $config ->set(self::BROKER_URL, $form_state->getValue(self::BROKER_URL)) ->set(self::JWT_EXPIRY, $form_state->getValue(self::JWT_EXPIRY)) - ->set(self::GEMINI_URL, $form_state->getValue(self::GEMINI_URL)) ->set(self::GEMINI_PSEUDO, $pseudo_types) ->save(); diff --git a/src/GeminiClientFactory.php b/src/GeminiClientFactory.php deleted file mode 100644 index 5a8ccd5b..00000000 --- a/src/GeminiClientFactory.php +++ /dev/null @@ -1,47 +0,0 @@ -get(IslandoraSettingsForm::CONFIG_NAME); - $geminiUrl = $settings->get(IslandoraSettingsForm::GEMINI_URL); - - // Only attempt if there is one. - if (!empty($geminiUrl)) { - return GeminiClient::create($geminiUrl, $logger); - } - else { - $logger->notice("Attempted to create Gemini client without a Gemini URL defined."); - throw new PreconditionFailedHttpException("Unable to instantiate GeminiClient, missing Gemini URI in Islandora setting."); - } - } - -} diff --git a/src/GeminiLookup.php b/src/GeminiLookup.php deleted file mode 100644 index a712ddf3..00000000 --- a/src/GeminiLookup.php +++ /dev/null @@ -1,168 +0,0 @@ -geminiClient = $client; - $this->jwtProvider = $jwt_auth; - $this->mediaSource = $media_source; - $this->guzzle = $guzzle; - $this->logger = $logger; - } - - /** - * Lookup this entity's URI in the Gemini db and return the other URI. - * - * @param \Drupal\Core\Entity\EntityInterface $entity - * The entity to look for. - * - * @return string|null - * Return the URI or null - */ - public function lookup(EntityInterface $entity) { - // Exit early if the entity hasn't been saved yet. - if ($entity->id() == NULL) { - return NULL; - } - - $is_media = $entity->getEntityTypeId() == 'media'; - - // Use the entity's uuid unless it's a media, - // use its file's uuid instead. - if ($is_media) { - try { - $file = $this->mediaSource->getSourceFile($entity); - $uuid = $file->uuid(); - } - // If the media has no source file, exit early. - catch (NotFoundHttpException $e) { - return NULL; - } - } - else { - $uuid = $entity->uuid(); - } - - // Look it up in Gemini. - $token = "Bearer " . $this->jwtProvider->generateToken(); - $urls = $this->geminiClient->getUrls($uuid, $token); - - // Exit early if there's no results from Gemini. - if (empty($urls)) { - return NULL; - } - - // If it's not a media, just return the url from Gemini;. - if (!$is_media) { - return $urls['fedora']; - } - - // If it's a media, perform a HEAD request against - // the file in Fedora and get its 'describedy' link header. - try { - $head = $this->guzzle->head( - $urls['fedora'], - ['allow_redirects' => FALSE, 'headers' => ['Authorization' => $token]] - ); - // phpcs:disable - if (class_exists(\GuzzleHttp\Psr7\Header::class)) { - $links = \GuzzleHttp\Psr7\Header::parse($head->getHeader('Link')); - } - else { - $links = \GuzzleHttp\Psr7\parse_header($head->getHeader('Link')); - } - //phpcs:enable - foreach ($links as $link) { - if ($link['rel'] == 'describedby') { - return trim($link[0], '<>'); - } - } - } - catch (RequestException $e) { - $this->logger->warning( - "Error performing Gemini lookup for media. Fedora HEAD to @url returned @status => @message", - [ - '@url' => $urls['fedora'], - '@status' => $e->getCode(), - '@message' => $e->getMessage, - ] - ); - return NULL; - } - - // Return null if no link header is found. - return NULL; - } - -} diff --git a/tests/src/Functional/IslandoraSettingsFormTest.php b/tests/src/Functional/IslandoraSettingsFormTest.php index 5373a3dd..92cfc6a2 100644 --- a/tests/src/Functional/IslandoraSettingsFormTest.php +++ b/tests/src/Functional/IslandoraSettingsFormTest.php @@ -28,36 +28,6 @@ class IslandoraSettingsFormTest extends IslandoraFunctionalTestBase { $this->drupalLogin($account); } - /** - * Test Gemini URL validation. - */ - public function testGeminiUri() { - $this->drupalGet('/admin/config/islandora/core'); - $this->assertSession()->statusCodeEquals(200); - $this->assertSession()->pageTextContains("Gemini URL"); - $this->assertSession()->fieldValueEquals('edit-gemini-url', ''); - - $this->drupalPostForm('admin/config/islandora/core', ['edit-gemini-url' => 'not_a_url'], $this->t('Save configuration')); - $this->assertSession()->pageTextContainsOnce("Cannot parse URL not_a_url"); - - $this->drupalPostForm('admin/config/islandora/core', ['edit-gemini-url' => 'http://whaturl.bob'], $this->t('Save configuration')); - $this->assertSession()->pageTextContainsOnce("Cannot connect to URL http://whaturl.bob"); - } - - /** - * Test block on choosing Pseudo field bundles without a Gemini URL. - */ - public function testPseudoFieldBundles() { - $this->drupalGet('/admin/config/islandora/core'); - $this->assertSession()->statusCodeEquals(200); - - $this->drupalPostForm('admin/config/islandora/core', [ - 'gemini_pseudo_bundles[test_type:node]' => TRUE, - ], $this->t('Save configuration')); - $this->assertSession()->pageTextContainsOnce("Must enter Gemini URL before selecting bundles to display a pseudo field on."); - - } - /** * Test form validation for JWT expiry. */ diff --git a/tests/src/Kernel/GeminiClientFactoryTest.php b/tests/src/Kernel/GeminiClientFactoryTest.php deleted file mode 100644 index 826723ff..00000000 --- a/tests/src/Kernel/GeminiClientFactoryTest.php +++ /dev/null @@ -1,88 +0,0 @@ -prophesize(LoggerInterface::class); - $prophecy->notice(Argument::any()); - $this->logger = $prophecy->reveal(); - } - - /** - * @covers ::create - */ - public function testNoUrlBlank() { - $this->expectException(PreconditionFailedHttpException::class); - $prophecy = $this->prophesize(ImmutableConfig::class); - $prophecy->get(Argument::any())->willReturn(''); - $immutConfig = $prophecy->reveal(); - - $prophecy = $this->prophesize(ConfigFactoryInterface::class); - $prophecy->get(Argument::any())->willReturn($immutConfig); - $configFactory = $prophecy->reveal(); - - GeminiClientFactory::create($configFactory, $this->logger); - } - - /** - * @covers ::create - */ - public function testNoUrlNull() { - $this->expectException(PreconditionFailedHttpException::class); - $prophecy = $this->prophesize(ImmutableConfig::class); - $prophecy->get(Argument::any())->willReturn(NULL); - $immutConfig = $prophecy->reveal(); - - $prophecy = $this->prophesize(ConfigFactoryInterface::class); - $prophecy->get(Argument::any())->willReturn($immutConfig); - $configFactory = $prophecy->reveal(); - - GeminiClientFactory::create($configFactory, $this->logger); - } - - /** - * @covers ::create - * @throws \Exception - */ - public function testUrl() { - $prophecy = $this->prophesize(ImmutableConfig::class); - $prophecy->get(Argument::any())->willReturn('http://localhost:8000/gemini'); - $immutConfig = $prophecy->reveal(); - - $prophecy = $this->prophesize(ConfigFactoryInterface::class); - $prophecy->get(Argument::any())->willReturn($immutConfig); - $configFactory = $prophecy->reveal(); - - $this->assertInstanceOf(GeminiClient::class, GeminiClientFactory::create($configFactory, $this->logger)); - } - -} diff --git a/tests/src/Kernel/GeminiLookupTest.php b/tests/src/Kernel/GeminiLookupTest.php deleted file mode 100644 index e15f4303..00000000 --- a/tests/src/Kernel/GeminiLookupTest.php +++ /dev/null @@ -1,293 +0,0 @@ -prophesize(JwtAuth::class); - $this->jwtAuth = $prophecy->reveal(); - - $prophecy = $this->prophesize(LoggerInterface::class); - $this->logger = $prophecy->reveal(); - - $prophecy = $this->prophesize(MediaSourceService::class); - $this->mediaSource = $prophecy->reveal(); - - $prophecy = $this->prophesize(GeminiClient::class); - $this->geminiClient = $prophecy->reveal(); - - $prophecy = $this->prophesize(Client::class); - $this->guzzle = $prophecy->reveal(); - - // Mock up an entity to use (node in this case). - $prophecy = $this->prophesize(EntityInterface::class); - $prophecy->id()->willReturn(1); - $prophecy->getEntityTypeId()->willReturn('node'); - $prophecy->uuid()->willReturn('abc123'); - $this->entity = $prophecy->reveal(); - - // Mock up a media to use. - $prophecy = $this->prophesize(MediaInterface::class); - $prophecy->id()->willReturn(1); - $prophecy->getEntityTypeId()->willReturn('media'); - $prophecy->uuid()->willReturn('abc123'); - $this->media = $prophecy->reveal(); - } - - /** - * Mocks up a gemini client that fails its lookup. - */ - private function mockGeminiClientForFail() { - $prophecy = $this->prophesize(GeminiClient::class); - $prophecy->getUrls(Argument::any(), Argument::any()) - ->willReturn([]); - $this->geminiClient = $prophecy->reveal(); - } - - /** - * Mocks up a gemini client that finds a fedora url. - */ - private function mockGeminiClientForSuccess() { - $prophecy = $this->prophesize(GeminiClient::class); - $prophecy->getUrls(Argument::any(), Argument::any()) - ->willReturn([ - 'drupal' => '', - 'fedora' => 'http://localhost:8080/fcrepo/rest/abc123', - ]); - $this->geminiClient = $prophecy->reveal(); - } - - /** - * Mocks up a media source service that finds the source file for a media. - */ - private function mockMediaSourceForSuccess() { - $prophecy = $this->prophesize(FileInterface::class); - $prophecy->uuid()->willReturn('abc123'); - $file = $prophecy->reveal(); - - $prophecy = $this->prophesize(MediaSourceService::class); - $prophecy->getSourceFile(Argument::any()) - ->willReturn($file); - $this->mediaSource = $prophecy->reveal(); - } - - /** - * Make the gemini lookup out of class variables. - */ - private function createGeminiLookup() { - return new GeminiLookup( - $this->geminiClient, - $this->jwtAuth, - $this->mediaSource, - $this->guzzle, - $this->logger - ); - } - - /** - * @covers ::lookup - * @covers ::__construct - */ - public function testEntityNotSaved() { - // Mock an entity that returns a null id. - // That means it's not saved in the db yet. - $prophecy = $this->prophesize(EntityInterface::class); - $prophecy->id()->willReturn(NULL); - $this->entity = $prophecy->reveal(); - - $gemini_lookup = $this->createGeminiLookup(); - - $this->assertEquals( - NULL, - $gemini_lookup->lookup($this->entity) - ); - } - - /** - * @covers ::lookup - * @covers ::__construct - */ - public function testEntityNotFound() { - $this->mockGeminiClientForFail(); - - $gemini_lookup = $this->createGeminiLookup(); - - $this->assertEquals( - NULL, - $gemini_lookup->lookup($this->entity) - ); - } - - /** - * @covers ::lookup - * @covers ::__construct - */ - public function testEntityFound() { - $this->mockGeminiClientForSuccess(); - - $gemini_lookup = $this->createGeminiLookup(); - - $this->assertEquals( - 'http://localhost:8080/fcrepo/rest/abc123', - $gemini_lookup->lookup($this->entity) - ); - } - - /** - * @covers ::lookup - * @covers ::__construct - */ - public function testMediaHasNoSourceFile() { - // Mock a media source service that fails to find - // the source file for a media. - $prophecy = $this->prophesize(MediaSourceService::class); - $prophecy->getSourceFile(Argument::any()) - ->willThrow(new NotFoundHttpException("Media has no source")); - $this->mediaSource = $prophecy->reveal(); - - $gemini_lookup = $this->createGeminiLookup(); - - $this->assertEquals( - NULL, - $gemini_lookup->lookup($this->media) - ); - } - - /** - * @covers ::lookup - * @covers ::__construct - */ - public function testMediaNotFound() { - $this->mockMediaSourceForSuccess(); - $this->mockGeminiClientForFail(); - - $gemini_lookup = $this->createGeminiLookup(); - - $this->assertEquals( - NULL, - $gemini_lookup->lookup($this->media) - ); - } - - /** - * @covers ::lookup - * @covers ::__construct - */ - public function testFileFoundButNoDescribedby() { - $this->mockMediaSourceForSuccess(); - $this->mockGeminiClientForSuccess(); - - // Mock up a guzzle client that does not return - // the describedby header. - $prophecy = $this->prophesize(Client::class); - $prophecy->head(Argument::any(), Argument::any()) - ->willReturn(new Response(200, [])); - $this->guzzle = $prophecy->reveal(); - - $gemini_lookup = $this->createGeminiLookup(); - - $this->assertEquals( - NULL, - $gemini_lookup->lookup($this->media) - ); - } - - /** - * @covers ::lookup - * @covers ::__construct - */ - public function testMediaFound() { - $this->mockMediaSourceForSuccess(); - $this->mockGeminiClientForSuccess(); - - // Mock up a guzzle client that returns - // the describedby header. - $prophecy = $this->prophesize(Client::class); - $prophecy->head(Argument::any(), Argument::any()) - ->willReturn(new Response(200, ['Link' => '; rel="describedby"'])); - $this->guzzle = $prophecy->reveal(); - - $gemini_lookup = $this->createGeminiLookup(); - - $this->assertEquals( - 'http://localhost:8080/fcrepo/rest/abc123/fcr:metadata', - $gemini_lookup->lookup($this->media) - ); - } - -}