Browse Source

Removing gemini (#822)

* Removing gemini

* Forgot a test

* Update composer.json

* Adding views needed for reindexing

* Trying to fix composer update fail on D9.1.1

* Another attempt

* Coding standards

* Removing some validation tests from IslandoraSettingsFormTest

* Update islandora.module

* Update composer.json

* Update build-8.x-1.x.yml
pull/834/head
dannylamb 4 years ago committed by GitHub
parent
commit
1b6bea7902
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      .github/workflows/build-8.x-1.x.yml
  2. 41
      islandora.module
  3. 9
      islandora.services.yml
  4. 171
      modules/islandora_core_feature/config/install/views.view.all_taxonomy_terms.yml
  5. 197
      modules/islandora_core_feature/config/install/views.view.non_fedora_files.yml
  6. 50
      src/Form/IslandoraSettingsForm.php
  7. 47
      src/GeminiClientFactory.php
  8. 168
      src/GeminiLookup.php
  9. 30
      tests/src/Functional/IslandoraSettingsFormTest.php
  10. 88
      tests/src/Kernel/GeminiClientFactoryTest.php
  11. 293
      tests/src/Kernel/GeminiLookupTest.php

3
.github/workflows/build-8.x-1.x.yml

@ -94,7 +94,8 @@ jobs:
git -C "$GITHUB_WORKSPACE/build_dir" checkout -b travis-testing git -C "$GITHUB_WORKSPACE/build_dir" checkout -b travis-testing
cd $DRUPAL_DIR cd $DRUPAL_DIR
composer config repositories.local path "$GITHUB_WORKSPACE/build_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 - name: Install modules
run: | run: |

41
islandora.module

@ -18,9 +18,9 @@ use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Site\Settings;
use Drupal\Core\Url; use Drupal\Core\Url;
use Drupal\islandora\Form\IslandoraSettingsForm; use Drupal\islandora\Form\IslandoraSettingsForm;
use Drupal\islandora\GeminiLookup;
use Drupal\node\NodeInterface; use Drupal\node\NodeInterface;
use Drupal\media\MediaInterface; use Drupal\media\MediaInterface;
use Drupal\file\FileInterface; use Drupal\file\FileInterface;
@ -466,10 +466,39 @@ function islandora_entity_view(array &$build, EntityInterface $entity, EntityVie
// Ensure the entity matches the route. // Ensure the entity matches the route.
if ($entity === $route_match_item) { if ($entity === $route_match_item) {
if ($display->getComponent('field_gemini_uri')) { if ($display->getComponent('field_gemini_uri')) {
$gemini = \Drupal::service('islandora.gemini.lookup'); $mapper = \Drupal::service('islandora.entity_mapper');
if ($gemini instanceof GeminiLookup) { $flysystem_config = Settings::get('flysystem');
$fedora_uri = $gemini->lookup($entity); $fedora_root = $flysystem_config['fedora']['config']['root'];
if (!is_null($fedora_uri)) { $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'] = [ $build['field_gemini_uri'] = [
'#type' => 'container', '#type' => 'container',
'#attributes' => [ '#attributes' => [
@ -487,8 +516,6 @@ function islandora_entity_view(array &$build, EntityInterface $entity, EntityVie
]; ];
} }
} }
}
}
} }
/** /**

9
islandora.services.yml

@ -52,10 +52,5 @@ services:
islandora.utils: islandora.utils:
class: Drupal\islandora\IslandoraUtils class: Drupal\islandora\IslandoraUtils
arguments: ['@entity_type.manager', '@entity_field.manager', '@context.manager', '@flysystem_factory', '@language_manager'] arguments: ['@entity_type.manager', '@entity_field.manager', '@context.manager', '@flysystem_factory', '@language_manager']
islandora.gemini.client: islandora.entity_mapper:
class: Islandora\Crayfish\Commons\Client\GeminiClient class: Islandora\Crayfish\Commons\EntityMapper\EntityMapper
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']

171
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: { }

197
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: { }

50
src/Form/IslandoraSettingsForm.php

@ -7,9 +7,6 @@ use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Site\Settings; use Drupal\Core\Site\Settings;
use Drupal\Core\Url;
use GuzzleHttp\Exception\ConnectException;
use Islandora\Crayfish\Commons\Client\GeminiClient;
use Stomp\Client; use Stomp\Client;
use Stomp\Exception\StompException; use Stomp\Exception\StompException;
use Stomp\StatefulStomp; use Stomp\StatefulStomp;
@ -25,7 +22,6 @@ class IslandoraSettingsForm extends ConfigFormBase {
const BROKER_USER = 'broker_user'; const BROKER_USER = 'broker_user';
const BROKER_PASSWORD = 'broker_password'; const BROKER_PASSWORD = 'broker_password';
const JWT_EXPIRY = 'jwt_expiry'; const JWT_EXPIRY = 'jwt_expiry';
const GEMINI_URL = 'gemini_url';
const GEMINI_PSEUDO = 'gemini_pseudo_bundles'; const GEMINI_PSEUDO = 'gemini_pseudo_bundles';
const FEDORA_URL = 'fedora_url'; const FEDORA_URL = 'fedora_url';
const TIME_INTERVALS = [ 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'); $flysystem_config = Settings::get('flysystem');
if ($flysystem_config != NULL) { if ($flysystem_config != NULL) {
$fedora_url = $flysystem_config['fedora']['config']['root']; $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 $config
->set(self::BROKER_URL, $form_state->getValue(self::BROKER_URL)) ->set(self::BROKER_URL, $form_state->getValue(self::BROKER_URL))
->set(self::JWT_EXPIRY, $form_state->getValue(self::JWT_EXPIRY)) ->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) ->set(self::GEMINI_PSEUDO, $pseudo_types)
->save(); ->save();

47
src/GeminiClientFactory.php

@ -1,47 +0,0 @@
<?php
namespace Drupal\islandora;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\islandora\Form\IslandoraSettingsForm;
use Islandora\Crayfish\Commons\Client\GeminiClient;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException;
/**
* Creates a GeminiClient as a Drupal service.
*
* @package Drupal\islandora
*/
class GeminiClientFactory {
/**
* Factory function.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config
* Config.
* @param \Psr\Log\LoggerInterface $logger
* The logger channel.
*
* @return \Islandora\Crayfish\Commons\Client\GeminiClient
* Return GeminiClient
*
* @throws \Exception
* If there is no URL to connect to.
*/
public static function create(ConfigFactoryInterface $config, LoggerInterface $logger) {
// Get broker url from config.
$settings = $config->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.");
}
}
}

168
src/GeminiLookup.php

@ -1,168 +0,0 @@
<?php
namespace Drupal\islandora;
use Drupal\Core\Entity\EntityInterface;
use Drupal\islandora\MediaSource\MediaSourceService;
use Drupal\jwt\Authentication\Provider\JwtAuth;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use Islandora\Crayfish\Commons\Client\GeminiClient;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Locates the matching Fedora URI from the Gemini database.
*
* @package Drupal\islandora
*/
class GeminiLookup {
/**
* A GeminiClient.
*
* @var \Islandora\Crayfish\Commons\Client\GeminiClient
*/
private $geminiClient;
/**
* A JWT Provider service.
*
* @var \Drupal\jwt\Authentication\Provider\JwtAuth
*/
private $jwtProvider;
/**
* A MediaSourceService.
*
* @var \Drupal\islandora\MediaSource\MediaSourceService
*/
private $mediaSource;
/**
* An http client.
*
* @var \GuzzleHttp\Client
*/
private $guzzle;
/**
* The islandora logger channel.
*
* @var \Psr\Log\LoggerInterface
*/
private $logger;
/**
* GeminiField constructor.
*
* @param \Islandora\Crayfish\Commons\Client\GeminiClient $client
* The Gemini client.
* @param \Drupal\jwt\Authentication\Provider\JwtAuth $jwt_auth
* The JWT provider.
* @param \Drupal\islandora\MediaSource\MediaSourceService $media_source
* Media source service.
* @param \GuzzleHttp\Client $guzzle
* Guzzle client.
* @param \Psr\Log\LoggerInterface $logger
* The Islandora logger.
*/
public function __construct(
GeminiClient $client,
JwtAuth $jwt_auth,
MediaSourceService $media_source,
Client $guzzle,
LoggerInterface $logger
) {
$this->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;
}
}

30
tests/src/Functional/IslandoraSettingsFormTest.php

@ -28,36 +28,6 @@ class IslandoraSettingsFormTest extends IslandoraFunctionalTestBase {
$this->drupalLogin($account); $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. * Test form validation for JWT expiry.
*/ */

88
tests/src/Kernel/GeminiClientFactoryTest.php

@ -1,88 +0,0 @@
<?php
namespace Drupal\Tests\islandora\Kernel;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\islandora\GeminiClientFactory;
use Islandora\Crayfish\Commons\Client\GeminiClient;
use Prophecy\Argument;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException;
/**
* Tests GeminiClientFactory.
*
* @package Drupal\Tests\islandora\Kernel
* @group islandora
* @coversDefaultClass \Drupal\islandora\GeminiClientFactory
*/
class GeminiClientFactoryTest extends IslandoraKernelTestBase {
/**
* Logger.
*
* @var \Psr\Log\LoggerInterface
*/
private $logger;
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
$prophecy = $this->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));
}
}

293
tests/src/Kernel/GeminiLookupTest.php

@ -1,293 +0,0 @@
<?php
namespace Drupal\Tests\islandora\Kernel;
use Drupal\Core\Entity\EntityInterface;
use Drupal\file\FileInterface;
use Drupal\islandora\GeminiLookup;
use Drupal\islandora\MediaSource\MediaSourceService;
use Drupal\jwt\Authentication\Provider\JwtAuth;
use Drupal\media\MediaInterface;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Response;
use Islandora\Crayfish\Commons\Client\GeminiClient;
use Prophecy\Argument;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Tests Gemini Lookup.
*
* @group islandora
* @coversDefaultClass \Drupal\islandora\GeminiLookup
*/
class GeminiLookupTest extends IslandoraKernelTestBase {
/**
* JWT Auth.
*
* @var \Drupal\jwt\Authentication\Provider\JwtAuth
*/
private $jwtAuth;
/**
* Logger.
*
* @var \Psr\Log\LoggerInterface
*/
private $logger;
/**
* Guzzle.
*
* @var \GuzzleHttp\Client
*/
private $guzzle;
/**
* Gemini client.
*
* @var \Islandora\Crayfish\Commons\Client\GeminiClient
*/
private $geminiClient;
/**
* Media source service.
*
* @var \Drupal\islandora\MediaSource\MediaSourceService
*/
private $mediaSource;
/**
* An entity.
*
* @var \Drupal\Core\Entity\EntityInterface
*/
private $entity;
/**
* A media.
*
* @var \Drupal\media\MediaInterface
*/
private $media;
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
// Mock up dummy objects by default.
$prophecy = $this->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' => '<http://localhost:8080/fcrepo/rest/abc123/fcr:metadata>; 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)
);
}
}
Loading…
Cancel
Save