Browse Source
* Make a pseudo field we can use * coder * Fix config and coder for root level * Default to empty array * Add tests and clean up some deprecations * Form validation of Gemini URI before bundle selection. * Coder * Add functional test for Islandora Settingspull/729/head
Jared Whiklo
6 years ago
committed by
Natkeeran
13 changed files with 609 additions and 9 deletions
@ -0,0 +1,47 @@ |
|||||||
|
<?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."); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,101 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\islandora; |
||||||
|
|
||||||
|
use Drupal\Core\Entity\EntityInterface; |
||||||
|
use Drupal\jwt\Authentication\Provider\JwtAuth; |
||||||
|
use Islandora\Crayfish\Commons\Client\GeminiClient; |
||||||
|
use Psr\Log\LoggerInterface; |
||||||
|
use Symfony\Component\DependencyInjection\ContainerInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* 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; |
||||||
|
|
||||||
|
/** |
||||||
|
* 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 \Psr\Log\LoggerInterface $logger |
||||||
|
* The Islandora logger. |
||||||
|
*/ |
||||||
|
public function __construct(GeminiClient $client, JwtAuth $jwt_auth, LoggerInterface $logger) { |
||||||
|
$this->geminiClient = $client; |
||||||
|
$this->jwtProvider = $jwt_auth; |
||||||
|
$this->logger = $logger; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Static creator. |
||||||
|
* |
||||||
|
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container |
||||||
|
* The container. |
||||||
|
* |
||||||
|
* @return \Drupal\islandora\GeminiLookup |
||||||
|
* A GeminiLookup service. |
||||||
|
*/ |
||||||
|
public static function create(ContainerInterface $container) { |
||||||
|
return new static( |
||||||
|
$container->get('islandora.gemini_client'), |
||||||
|
$container->get('jwt.authentication.jwt'), |
||||||
|
$container->get('logger.channel.islandora') |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 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 |
||||||
|
* |
||||||
|
* @throws \Drupal\Core\Entity\EntityMalformedException |
||||||
|
* If the entity cannot be converted to a URL. |
||||||
|
*/ |
||||||
|
public function lookup(EntityInterface $entity) { |
||||||
|
if ($entity->id() != NULL) { |
||||||
|
$drupal_uri = $entity->toUrl()->setAbsolute()->toString(); |
||||||
|
$drupal_uri .= '?_format=jsonld'; |
||||||
|
$token = "Bearer " . $this->jwtProvider->generateToken(); |
||||||
|
$linked_uri = $this->geminiClient->findByUri($drupal_uri, $token); |
||||||
|
if (!is_null($linked_uri)) { |
||||||
|
if (is_array($linked_uri)) { |
||||||
|
$linked_uri = reset($linked_uri); |
||||||
|
} |
||||||
|
return $linked_uri; |
||||||
|
} |
||||||
|
} |
||||||
|
// Return null if we weren't in a saved entity or we didn't find a uri. |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\Tests\islandora\Functional; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class IslandoraSettingsFormTest. |
||||||
|
* |
||||||
|
* @package Drupal\Tests\islandora\Functional |
||||||
|
* @group islandora |
||||||
|
* @coversDefaultClass \Drupal\islandora\Form\IslandoraSettingsForm |
||||||
|
*/ |
||||||
|
class IslandoraSettingsFormTest extends IslandoraFunctionalTestBase { |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function setUp() { |
||||||
|
parent::setUp(); |
||||||
|
|
||||||
|
// Create a test user. |
||||||
|
$account = $this->drupalCreateUser([ |
||||||
|
'bypass node access', |
||||||
|
'administer site configuration', |
||||||
|
'view media', |
||||||
|
'create media', |
||||||
|
'update media', |
||||||
|
]); |
||||||
|
$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'], t('Save configuration')); |
||||||
|
$this->assertSession()->pageTextContainsOnce("Cannot parse URL not_a_url"); |
||||||
|
|
||||||
|
$this->drupalPostForm('admin/config/islandora/core', ['edit-gemini-url' => 'http://whaturl.bob'], 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, |
||||||
|
], t('Save configuration')); |
||||||
|
$this->assertSession()->pageTextContainsOnce("Must enter Gemini URL before selecting bundles to display a pseudo field on."); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,82 @@ |
|||||||
|
<?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; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class GeminiClientFactoryTest. |
||||||
|
* |
||||||
|
* @package Drupal\Tests\islandora\Kernel |
||||||
|
* @group islandora |
||||||
|
* @coversDefaultClass \Drupal\islandora\GeminiClientFactory |
||||||
|
*/ |
||||||
|
class GeminiClientFactoryTest extends IslandoraKernelTestBase { |
||||||
|
|
||||||
|
private $logger; |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function setUp() { |
||||||
|
parent::setUp(); |
||||||
|
|
||||||
|
$prophecy = $this->prophesize(LoggerInterface::class); |
||||||
|
$prophecy->notice(Argument::any()); |
||||||
|
$this->logger = $prophecy->reveal(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @covers ::create |
||||||
|
* @expectedException \Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException |
||||||
|
*/ |
||||||
|
public function testNoUrlBlank() { |
||||||
|
$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 |
||||||
|
* @expectedException \Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException |
||||||
|
*/ |
||||||
|
public function testNoUrlNull() { |
||||||
|
$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)); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,121 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\Tests\islandora\Kernel; |
||||||
|
|
||||||
|
use Drupal\Core\Entity\EntityInterface; |
||||||
|
use Drupal\Core\Url; |
||||||
|
use Drupal\islandora\GeminiLookup; |
||||||
|
use Drupal\jwt\Authentication\Provider\JwtAuth; |
||||||
|
use Islandora\Crayfish\Commons\Client\GeminiClient; |
||||||
|
use Prophecy\Argument; |
||||||
|
use Psr\Log\LoggerInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Class GeminiLookupTest. |
||||||
|
* |
||||||
|
* @group islandora |
||||||
|
* @coversDefaultClass \Drupal\islandora\GeminiLookup |
||||||
|
*/ |
||||||
|
class GeminiLookupTest extends IslandoraKernelTestBase { |
||||||
|
|
||||||
|
private $geminiLookup; |
||||||
|
|
||||||
|
private $geminiClient; |
||||||
|
|
||||||
|
private $jwtAuth; |
||||||
|
|
||||||
|
private $logger; |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function setUp() { |
||||||
|
parent::setUp(); |
||||||
|
$prophecy = $this->prophesize(JwtAuth::class); |
||||||
|
$prophecy->generateToken()->willReturn("islandora"); |
||||||
|
$this->jwtAuth = $prophecy->reveal(); |
||||||
|
|
||||||
|
$prophecy = $this->prophesize(LoggerInterface::class); |
||||||
|
$this->logger = $prophecy->reveal(); |
||||||
|
|
||||||
|
$prophecy = $this->prophesize(GeminiClient::class); |
||||||
|
$prophecy->findByUri(Argument::any(), Argument::any())->willReturn(NULL); |
||||||
|
$this->geminiClient = $prophecy->reveal(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @covers ::lookup |
||||||
|
* @covers ::__construct |
||||||
|
* @throws \Drupal\Core\Entity\EntityMalformedException |
||||||
|
*/ |
||||||
|
public function testEntityNotSaved() { |
||||||
|
$prophecy = $this->prophesize(EntityInterface::class); |
||||||
|
$prophecy->id()->willReturn(NULL); |
||||||
|
$entity = $prophecy->reveal(); |
||||||
|
$this->geminiLookup = new GeminiLookup( |
||||||
|
$this->geminiClient, |
||||||
|
$this->jwtAuth, |
||||||
|
$this->logger |
||||||
|
); |
||||||
|
$this->assertEquals(NULL, $this->geminiLookup->lookup($entity)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @covers ::lookup |
||||||
|
* @covers ::__construct |
||||||
|
* @throws \Drupal\Core\Entity\EntityMalformedException |
||||||
|
*/ |
||||||
|
public function testEntityNotFound() { |
||||||
|
$prop1 = $this->prophesize(Url::class); |
||||||
|
$prop1->toString()->willReturn("http://localhost:8000/node/456"); |
||||||
|
|
||||||
|
$prop2 = $this->prophesize(Url::class); |
||||||
|
$prop2->setAbsolute()->willReturn($prop1->reveal()); |
||||||
|
$url = $prop2->reveal(); |
||||||
|
|
||||||
|
$prophecy = $this->prophesize(EntityInterface::class); |
||||||
|
$prophecy->id()->willReturn(456); |
||||||
|
$prophecy->toUrl()->willReturn($url); |
||||||
|
$entity = $prophecy->reveal(); |
||||||
|
|
||||||
|
$this->geminiLookup = new GeminiLookup( |
||||||
|
$this->geminiClient, |
||||||
|
$this->jwtAuth, |
||||||
|
$this->logger |
||||||
|
); |
||||||
|
|
||||||
|
$this->assertEquals(NULL, $this->geminiLookup->lookup($entity)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @covers ::lookup |
||||||
|
* @covers ::__construct |
||||||
|
* @throws \Drupal\Core\Entity\EntityMalformedException |
||||||
|
*/ |
||||||
|
public function testEntityFound() { |
||||||
|
$prop1 = $this->prophesize(Url::class); |
||||||
|
$prop1->toString()->willReturn("http://localhost:8000/node/456"); |
||||||
|
|
||||||
|
$prop2 = $this->prophesize(Url::class); |
||||||
|
$prop2->setAbsolute()->willReturn($prop1->reveal()); |
||||||
|
$url = $prop2->reveal(); |
||||||
|
|
||||||
|
$prophecy = $this->prophesize(EntityInterface::class); |
||||||
|
$prophecy->id()->willReturn(456); |
||||||
|
$prophecy->toUrl()->willReturn($url); |
||||||
|
$entity = $prophecy->reveal(); |
||||||
|
|
||||||
|
$prophecy = $this->prophesize(GeminiClient::class); |
||||||
|
$prophecy->findByUri(Argument::any(), Argument::any())->willReturn(["http://fedora:8080/some/uri"]); |
||||||
|
$this->geminiClient = $prophecy->reveal(); |
||||||
|
|
||||||
|
$this->geminiLookup = new GeminiLookup( |
||||||
|
$this->geminiClient, |
||||||
|
$this->jwtAuth, |
||||||
|
$this->logger |
||||||
|
); |
||||||
|
|
||||||
|
$this->assertEquals("http://fedora:8080/some/uri", $this->geminiLookup->lookup($entity)); |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue