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