Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement recast service #44

Merged
merged 8 commits into from
Feb 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ coverage.xml
*.key
*.log
syn-settings.xml
cfg/config.yaml
*/cfg/config.yaml
27 changes: 27 additions & 0 deletions Gemini/src/Controller/GeminiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,31 @@ public function delete($uuid)
$deleted = $this->urlMapper->deleteUrls($uuid);
return new Response(null, $deleted ? 204 : 404);
}

/**
* Find the opposite URI for the on provided in X-Islandora-URI.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The incoming request.
*
* @return \Symfony\Component\HttpFoundation\Response
* A response 200 with Location or 404.
*/
public function getByUri(Request $request)
{
if (!$request->headers->has('X-Islandora-URI')) {
return new Response('Require the X-Islandora-URI header', 400);
}
$uri = $request->headers->get('X-Islandora-URI');
if (is_array($uri)) {
// Can only return one Location header.
$uri = reset($uri);
}
$uri = $this->urlMapper->findUrls($uri);
$headers = [];
if ($uri) {
$headers['Location'] = $uri;
}
return new Response(null, ($uri ? 200 : 404), $headers);
}
}
14 changes: 14 additions & 0 deletions Gemini/src/UrlMapper/UrlMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,18 @@ public function deleteUrls($uuid)
throw $e;
}
}

/**
* {@inheritdoc}
*/
public function findUrls($uri)
{
$query =
'SELECT fedora_uri as uri FROM Gemini WHERE drupal_uri = :uri union
SELECT drupal_uri as uri FROM Gemini WHERE fedora_uri = :uri';
return $this->connection->fetchAssoc(
$query,
['uri' => $uri]
);
}
}
16 changes: 16 additions & 0 deletions Gemini/src/UrlMapper/UrlMapperInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,20 @@ public function saveUrls(
public function deleteUrls(
$uuid
);

/**
* Locate a URI provided the opposite URI.
*
* Given either the Drupal or Fedora URI, search the Gemini DB and return
* the other URI. Otherwise return null.
*
* @param string $uri
* The known URI (either Fedora or Drupal).
*
* @return mixed array|null
* The other URI if found.
*/
public function findUrls(
$uri
);
}
2 changes: 2 additions & 0 deletions Gemini/src/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
);
};

$app->get('/by_uri', "gemini.controller:getByUri");

$app->get('/{uuid}', "gemini.controller:get");

$app->post('/', "gemini.controller:post");
Expand Down
163 changes: 163 additions & 0 deletions Gemini/tests/Islandora/Gemini/Tests/GetByUriTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<?php

namespace Islandora\Gemini\Tests;

use Islandora\Gemini\Controller\GeminiController;
use Islandora\Gemini\UrlMapper\UrlMapperInterface;
use Islandora\Gemini\UrlMinter\UrlMinterInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGenerator;

/**
* Class GetByUriTest
*
* @package Islandora\Gemini\Tests
* @coversDefaultClass \Islandora\Gemini\Controller\GeminiController
*/
class GetByUriTest extends TestCase
{

/**
* @covers ::getByUri
*/
public function testGetByUriOk()
{
$mapper = $this->prophesize(UrlMapperInterface::class);
$mapper->findUrls(Argument::any())
->willReturn(['uri' => 'abc']);
$mapper = $mapper->reveal();

$minter = $this->prophesize(UrlMinterInterface::class)->reveal();

$generator = $this->prophesize(UrlGenerator::class)->reveal();

$request = new Request();
$request->headers->add(['X-Islandora-URI' => 'blah']);

$controller = new GeminiController(
$mapper,
$minter,
$generator
);

$response = $controller->getByUri($request);

$this->assertEquals(
200,
$response->getStatusCode(),
"Response must be 200 on success"
);
$this->assertTrue(
$response->headers->has('Location'),
"Response must have Location header"
);
$this->assertEquals(
'abc',
$response->headers->get('Location'),
"Location header should be 'abc'"
);
}

/**
* @covers ::getByUri
*/
public function testGetByUriFailed()
{
$mapper = $this->prophesize(UrlMapperInterface::class);
$mapper->findUrls(Argument::any())
->willReturn([]);
$mapper = $mapper->reveal();

$minter = $this->prophesize(UrlMinterInterface::class)->reveal();

$generator = $this->prophesize(UrlGenerator::class)->reveal();

$request = new Request();
$request->headers->add(['X-Islandora-URI' => 'blah']);

$controller = new GeminiController(
$mapper,
$minter,
$generator
);

$response = $controller->getByUri($request);

$this->assertEquals(
404,
$response->getStatusCode(),
"Response must be 200 on success"
);
}

/**
* @covers ::getByUri
*/
public function testGetByUriMultiple()
{
$mapper = $this->prophesize(UrlMapperInterface::class);
$mapper->findUrls('foo')
->willReturn(['uri' => 'abc']);
$mapper->findUrls('bar')
->willReturn(['uri' => 'oops']);
$mapper = $mapper->reveal();

$minter = $this->prophesize(UrlMinterInterface::class)->reveal();

$generator = $this->prophesize(UrlGenerator::class)->reveal();

$request = new Request();
$request->headers->add(['X-Islandora-URI' => ['foo', 'bar']]);

$controller = new GeminiController(
$mapper,
$minter,
$generator
);

$response = $controller->getByUri($request);

$this->assertEquals(
200,
$response->getStatusCode(),
"Response must be 200 on success"
);
$this->assertTrue(
$response->headers->has('Location'),
"Response must have Location header"
);
$this->assertEquals(
'abc',
$response->headers->get('Location'),
"Location header should be 'abc'"
);
}

/**
* @covers ::getByUri
*/
public function testGetByUriNoToken()
{
$mapper = $this->prophesize(UrlMapperInterface::class)->reveal();
$minter = $this->prophesize(UrlMinterInterface::class)->reveal();
$generator = $this->prophesize(UrlGenerator::class)->reveal();

$request = new Request();

$controller = new GeminiController(
$mapper,
$minter,
$generator
);

$response = $controller->getByUri($request);

$this->assertEquals(
400,
$response->getStatusCode(),
"Response must be 400 with no X-Islandora-URI header"
);
}
}
29 changes: 29 additions & 0 deletions Gemini/tests/Islandora/Gemini/Tests/UrlMapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,33 @@ public function testDeleteUrlsRollsBackOnException()
$mapper = new UrlMapper($connection);
$mapper->deleteUrls("foo");
}

/**
* @covers ::findUrls
*/
public function testFindUrls()
{
// Simulate a record being returned.
$connection = $this->prophesize(Connection::class);
$connection->fetchAssoc(Argument::any(), Argument::any())
->willReturn(['uri' => 'foo']);
$connection = $connection->reveal();
$mapper = new UrlMapper($connection);
$results = $mapper->findUrls("abc");
$this->assertTrue(
$results['uri'] == 'foo',
"getUrls() modified connection results. Actual: ${results['uri']}. Expected: foo"
);
// Simulate when no record is found.
$connection = $this->prophesize(Connection::class);
$connection->fetchAssoc(Argument::any(), Argument::any())
->willReturn([]);
$connection = $connection->reveal();
$mapper = new UrlMapper($connection);
$results = $mapper->findUrls("abc");
$this->assertTrue(
empty($results),
"getUrls() modified connection results. Expected empty array, received " . json_encode($results)
);
}
}
Loading