From 8276680b412d497467e38f0a48e8e8211eb7435f Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Thu, 10 Jan 2019 11:34:14 -0600 Subject: [PATCH] Homarus refactor / Increase test coverage (#57) * Tell if we failed Fix some missed things * Clean up tester, fix test coverage * Fix last tests I hope * Refactor Homarus Update test coverage * Coder fix --- Gemini/phpunit.xml.dist | 2 + .../Islandora/Gemini/Tests/DeleteTest.php | 2 + .../tests/Islandora/Gemini/Tests/GetTest.php | 2 + .../tests/Islandora/Gemini/Tests/PostTest.php | 2 + .../tests/Islandora/Gemini/Tests/PutTest.php | 3 + .../Islandora/Gemini/Tests/UrlMapperTest.php | 7 + .../Islandora/Gemini/Tests/UrlMinterTest.php | 4 + Homarus/cfg/config.example.yaml | 3 +- Homarus/src/Controller/HomarusController.php | 91 ++++++-- Homarus/src/app.php | 5 +- .../Homarus/Tests/HomarusControllerTest.php | 213 ++++++++++++++++-- .../Houdini/Tests/HoudiniControllerTest.php | 51 +++++ .../Tests/HypercubeControllerTest.php | 3 + Milliner/static/MediaLDP-RS-no_date.jsonld | 15 ++ .../Islandora/Milliner/Tests/DeleteTest.php | 5 + .../Milliner/Tests/GeminiClientTest.php | 43 +++- .../Milliner/Tests/MillinerControllerTest.php | 6 + .../Milliner/Tests/SaveMediaTest.php | 128 +++++++++++ .../Islandora/Milliner/Tests/SaveNodeTest.php | 97 +++++++- 19 files changed, 638 insertions(+), 44 deletions(-) create mode 100644 Milliner/static/MediaLDP-RS-no_date.jsonld diff --git a/Gemini/phpunit.xml.dist b/Gemini/phpunit.xml.dist index 13a7ecfe..cf6580e5 100644 --- a/Gemini/phpunit.xml.dist +++ b/Gemini/phpunit.xml.dist @@ -23,6 +23,8 @@ ./src/index.php ./src/app.php + ./src/console.php + ./src/Migrations ./src diff --git a/Gemini/tests/Islandora/Gemini/Tests/DeleteTest.php b/Gemini/tests/Islandora/Gemini/Tests/DeleteTest.php index 02a2c6b8..6aac0864 100644 --- a/Gemini/tests/Islandora/Gemini/Tests/DeleteTest.php +++ b/Gemini/tests/Islandora/Gemini/Tests/DeleteTest.php @@ -16,6 +16,7 @@ class DeleteTest extends \PHPUnit_Framework_TestCase { /** + * @covers ::__construct * @covers ::delete */ public function testReturns404WhenNotFound() @@ -44,6 +45,7 @@ public function testReturns404WhenNotFound() } /** + * @covers ::__construct * @covers ::delete */ public function testReturns204WhenDeleted() diff --git a/Gemini/tests/Islandora/Gemini/Tests/GetTest.php b/Gemini/tests/Islandora/Gemini/Tests/GetTest.php index 9e18794c..b0eda5c3 100644 --- a/Gemini/tests/Islandora/Gemini/Tests/GetTest.php +++ b/Gemini/tests/Islandora/Gemini/Tests/GetTest.php @@ -16,6 +16,7 @@ class GetTest extends \PHPUnit_Framework_TestCase { /** + * @covers ::__construct * @covers ::get */ public function testReturns404WhenNotFound() @@ -44,6 +45,7 @@ public function testReturns404WhenNotFound() } /** + * @covers ::__construct * @covers ::get */ public function testReturns200WhenFound() diff --git a/Gemini/tests/Islandora/Gemini/Tests/PostTest.php b/Gemini/tests/Islandora/Gemini/Tests/PostTest.php index 41f91b09..62df1280 100644 --- a/Gemini/tests/Islandora/Gemini/Tests/PostTest.php +++ b/Gemini/tests/Islandora/Gemini/Tests/PostTest.php @@ -16,6 +16,7 @@ class PostTest extends \PHPUnit_Framework_TestCase { /** + * @covers ::__construct * @covers ::post */ public function testReturns400OnMalformedRequest() @@ -68,6 +69,7 @@ public function testReturns400OnMalformedRequest() } /** + * @covers ::__construct * @covers ::post */ public function testReturns200OnSuccess() diff --git a/Gemini/tests/Islandora/Gemini/Tests/PutTest.php b/Gemini/tests/Islandora/Gemini/Tests/PutTest.php index a11eed51..6c7f78d0 100644 --- a/Gemini/tests/Islandora/Gemini/Tests/PutTest.php +++ b/Gemini/tests/Islandora/Gemini/Tests/PutTest.php @@ -17,6 +17,7 @@ class PutTest extends \PHPUnit_Framework_TestCase { /** + * @covers ::__construct * @covers ::put */ public function testReturns204OnUpdate() @@ -58,6 +59,7 @@ public function testReturns204OnUpdate() } /** + * @covers ::__construct * @covers ::put */ public function testReturns201OnCreation() @@ -107,6 +109,7 @@ public function testReturns201OnCreation() } /** + * @covers ::__construct * @covers ::put */ public function testReturns400OnMalformedRequest() diff --git a/Gemini/tests/Islandora/Gemini/Tests/UrlMapperTest.php b/Gemini/tests/Islandora/Gemini/Tests/UrlMapperTest.php index 7c69b3e1..da4b26bc 100644 --- a/Gemini/tests/Islandora/Gemini/Tests/UrlMapperTest.php +++ b/Gemini/tests/Islandora/Gemini/Tests/UrlMapperTest.php @@ -16,6 +16,7 @@ class UrlMapperTest extends \PHPUnit_Framework_TestCase { /** + * @covers ::__construct * @covers ::getUrls */ public function testGetUrlsReturnsUnmodifiedResults() @@ -56,6 +57,7 @@ public function testGetUrlsReturnsUnmodifiedResults() } /** + * @covers ::__construct * @covers ::saveUrls */ public function testSaveUrlsReturnsTrueOnCreation() @@ -78,6 +80,7 @@ public function testSaveUrlsReturnsTrueOnCreation() } /** + * @covers ::__construct * @covers ::saveUrls */ public function testSaveUrlsReturnsFalseOnUpdate() @@ -104,6 +107,7 @@ public function testSaveUrlsReturnsFalseOnUpdate() } /** + * @covers ::__construct * @covers ::saveUrls * @expectedException \Exception */ @@ -121,6 +125,7 @@ public function testSaveUrlsRollsBackOnException() } /** + * @covers ::__construct * @covers ::deleteUrls */ public function testDeleteUrlsReturnsTrueIfFound() @@ -141,6 +146,7 @@ public function testDeleteUrlsReturnsTrueIfFound() } /** + * @covers ::__construct * @covers ::deleteUrls */ public function testDeleteUrlsReturnsFalseIfNotFound() @@ -161,6 +167,7 @@ public function testDeleteUrlsReturnsFalseIfNotFound() } /** + * @covers ::__construct * @covers ::deleteUrls * @expectedException \Exception */ diff --git a/Gemini/tests/Islandora/Gemini/Tests/UrlMinterTest.php b/Gemini/tests/Islandora/Gemini/Tests/UrlMinterTest.php index 294edd9c..490ff5e9 100644 --- a/Gemini/tests/Islandora/Gemini/Tests/UrlMinterTest.php +++ b/Gemini/tests/Islandora/Gemini/Tests/UrlMinterTest.php @@ -12,6 +12,7 @@ class UrlMinterTest extends \PHPUnit_Framework_TestCase { /** + * @covers ::__construct * @covers ::mint * @expectedException \InvalidArgumentException * @expectedExceptionCode 400 @@ -23,6 +24,7 @@ public function testThrowsExceptionOnBlankString() } /** + * @covers ::__construct * @covers ::mint * @expectedException \InvalidArgumentException * @expectedExceptionCode 400 @@ -34,6 +36,7 @@ public function testThrowsExceptionOnShortUUID() } /** + * @covers ::__construct * @covers ::mint */ public function testHandlesMissingTrailingSlashInBaseUrl() @@ -51,6 +54,7 @@ public function testHandlesMissingTrailingSlashInBaseUrl() } /** + * @covers ::__construct * @covers ::mint */ public function testMintsUrlWithPairTrees() diff --git a/Homarus/cfg/config.example.yaml b/Homarus/cfg/config.example.yaml index f3b36314..eb223daf 100644 --- a/Homarus/cfg/config.example.yaml +++ b/Homarus/cfg/config.example.yaml @@ -7,12 +7,13 @@ homarus: - video/mp4 - video/x-msvideo - video/ogg - default_video: video/mp4 + default: video/mp4 mime_to_format: valid: - video/mp4_mp4 - video/x-msvideo_avi - video/ogg_ogg + default: mp4 fedora_resource: base_url: http://localhost:8080/fcrepo/rest diff --git a/Homarus/src/Controller/HomarusController.php b/Homarus/src/Controller/HomarusController.php index 68c35be8..1af75b67 100644 --- a/Homarus/src/Controller/HomarusController.php +++ b/Homarus/src/Controller/HomarusController.php @@ -29,28 +29,66 @@ class HomarusController */ protected $log; + /** + * Not used I think. + * + * @var array + */ + private $mimetypes; + + /** + * Default FFmpeg format + * + * @var string + */ + private $default_mimetype; + + /** + * Mapping of mime-type to ffmpeg formats. + * + * @var array + */ + private $mime_to_format; + + /** + * The default format. + * + * @var string + */ + private $default_format; + + /** + * The executable. + * + * @var string + */ + private $executable; + /** * Controller constructor. * @param \Islandora\Crayfish\Commons\CmdExecuteService $cmd - * @param array $formats - * @param string $default_format + * @param array $mimetypes + * @param string $default_mimetype * @param string $executable * @param $log + * @param array $mime_to_format */ public function __construct( CmdExecuteService $cmd, - $formats, - $default_format, + $mimetypes, + $default_mimetype, $executable, $log, - $mime_to_format + $mime_to_format, + $default_format ) { $this->cmd = $cmd; - $this->formats = $formats; - $this->default_format = $default_format; + $this->mimetypes = $mimetypes; + $this->default_mimetype = $default_mimetype; $this->executable = $executable; $this->log = $log; $this->mime_to_format = $mime_to_format; + $this->default_format = $default_format; } /** @@ -63,7 +101,7 @@ public function convert(Request $request) // Short circuit if there's no Apix-Ldp-Resource header. if (!$request->headers->has("Apix-Ldp-Resource")) { - $this->log->debug("Malformed request, no Apix-Ldp-Resource header present"); + $this->log->error("Malformed request, no Apix-Ldp-Resource header present"); return new Response( "Malformed request, no Apix-Ldp-Resource header present", 400 @@ -74,8 +112,7 @@ public function convert(Request $request) // Find the format $content_types = $request->getAcceptableContentTypes(); - $content_type = $this->getContentType($content_types); - $format = $this->getFfmpegFormat($content_type); + list($content_type, $format) = $this->getFfmpegFormat($content_types); $cmd_params = ""; if ($format == "mp4") { @@ -89,7 +126,7 @@ public function convert(Request $request) $this->log->debug("X-Islandora-Args:", ['args' => $args]); $cmd_string = "$this->executable -i $source $cmd_params -f $format -"; - $this->log->info('Ffempg Command:', ['cmd' => $cmd_string]); + $this->log->debug('Ffempg Command:', ['cmd' => $cmd_string]); // Return response. try { @@ -104,34 +141,38 @@ public function convert(Request $request) } } - - private function getContentType($content_types) + /** + * Filters through an array of acceptable content-types and returns a FFmpeg format. + * + * @param array $content_types + * The Accept content-types. + * + * @return array + * Array with [ $content-type, $format ], falls back to defaults. + */ + private function getFfmpegFormat(array $content_types) { $content_type = null; foreach ($content_types as $type) { - if (in_array($type, $this->formats)) { + if (in_array($type, $this->mimetypes)) { $content_type = $type; break; } } if ($content_type === null) { - $content_type = $this->default_format; - $this->log->info('Falling back to default content type'); + $this->log->info('No matching content-type, falling back to default.'); + return [$this->default_mimetype, $this->default_format]; } - return $content_type; - } - private function getFfmpegFormat($content_type) - { foreach ($this->mime_to_format as $format) { - if (strpos($format, $content_type) !== false) { - $this->log->info("does it get here"); - $format_info = explode("_", $format); - break; + $format_info = explode("_", $format); + if ($format_info[0] == $content_type) { + return [$content_type, $format_info[1]]; } } - return $format_info[1]; + $this->log->info('No matching content-type to format mapping, falling back to default.'); + return [$this->default_mimetype, $this->default_format]; } /** diff --git a/Homarus/src/app.php b/Homarus/src/app.php index 335ac721..d4b5431c 100644 --- a/Homarus/src/app.php +++ b/Homarus/src/app.php @@ -16,10 +16,11 @@ return new HomarusController( $app['crayfish.cmd_execute_service'], $app['crayfish.homarus.mime_types.valid'], - $app['crayfish.homarus.mime_types.default_video'], + $app['crayfish.homarus.mime_types.default'], $app['crayfish.homarus.executable'], $app['monolog'], - $app['crayfish.homarus.mime_to_format'] + $app['crayfish.homarus.mime_to_format.valid'], + $app['crayfish.homarus.mime_to_format.default'] ); }; diff --git a/Homarus/tests/Islandora/Homarus/Tests/HomarusControllerTest.php b/Homarus/tests/Islandora/Homarus/Tests/HomarusControllerTest.php index 40bfa900..1c793eb4 100644 --- a/Homarus/tests/Islandora/Homarus/Tests/HomarusControllerTest.php +++ b/Homarus/tests/Islandora/Homarus/Tests/HomarusControllerTest.php @@ -2,14 +2,14 @@ namespace Islandora\Homarus\Tests; -use Islandora\Crayfish\Commons\CmdExecuteService; use Islandora\Crayfish\Commons\ApixFedoraResourceRetriever; +use Islandora\Crayfish\Commons\CmdExecuteService; use Islandora\Homarus\Controller\HomarusController; +use Monolog\Logger; use Prophecy\Argument; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\StreamInterface; use Symfony\Component\HttpFoundation\Request; -use Monolog\Logger; /** * @coversDefaultClass \Islandora\Homarus\Controller\HomarusController @@ -17,22 +17,42 @@ class HomarusControllerTest extends \PHPUnit_Framework_TestCase { + private $mime_to_format; + + private $default_format; + + private $content_types; + + private $default_content_type; + /** - * @covers ::convert - * @covers ::getContentType - * @covers ::getFfmpegFormat + * Setup to reset to defaults. + */ + public function setUp() + { + $this->mime_to_format = [ + 'video/mp4_mp4', + 'video/x-msvideo_avi', + 'video/ogg_ogg', + ]; + + $this->default_format = 'mp4'; + + $this->content_types = [ + 'video/mp4', + 'video/x-msvideo', + 'video/ogg', + ]; + + $this->default_content_type = 'video/mp4'; + } + + /** + * @covers ::convertOptions */ public function testOptions() { - $mock_service = $this->prophesize(CmdExecuteService::class)->reveal(); - $controller = new HomarusController( - $mock_service, - [], - '', - 'convert', - $this->prophesize(Logger::class)->reveal(), - '' - ); + $controller = $this->getDefaultController(); $response = $controller->convertOptions(); $this->assertTrue($response->getStatusCode() == 200, 'Convert OPTIONS should return 200'); @@ -41,4 +61,169 @@ public function testOptions() 'Convert OPTIONS should return turtle' ); } + + /** + * @covers ::__construct + * @covers ::convert + */ + public function testErrorReturns500() + { + + $prophecy = $this->prophesize(CmdExecuteService::class); + $prophecy->execute(Argument::any(), Argument::any())->willThrow(new \RuntimeException("ERROR", 500)); + $mock_service = $prophecy->reveal(); + // Create a controller. + $controller = new HomarusController( + $mock_service, + $this->content_types, + $this->default_content_type, + 'convert', + $this->prophesize(Logger::class)->reveal(), + $this->mime_to_format, + $this->default_format + ); + + $mock_fedora_response = $this->getMockFedoraResource(); + + // Create a Request. + $request = Request::create( + "/", + "GET" + ); + $request->headers->set('Authorization', 'some_token'); + $request->headers->set('Apix-Ldp-Resource', 'http://localhost:8080/fcrepo/rest/foo'); + $request->attributes->set('fedora_resource', $mock_fedora_response); + + // Test convert + $response = $controller->convert($request); + $this->assertEquals(500, $response->getStatusCode(), "Response must return 500"); + $this->assertEquals("ERROR", $response->getContent(), "Response must return exception's message"); + } + + /** + * @covers ::__construct + * @covers ::convert + * @covers ::getFfmpegFormat + */ + public function testSuccessReturns200ValidContentType() + { + $controller = $this->getDefaultController(); + $mock_fedora_response = $this->getMockFedoraResource(); + + $request = Request::create( + "/", + "GET" + ); + $request->headers->set('Authorization', 'some_token'); + $request->headers->set('Apix-Ldp-Resource', 'http://localhost:8080/fcrepo/rest/foo'); + $request->headers->set('Accept', 'video/mp4'); + $request->attributes->set('fedora_resource', $mock_fedora_response); + + $response = $controller->convert($request); + $this->assertEquals(200, $response->getStatusCode(), "Response must return 200"); + $this->assertEquals('video/mp4', $response->headers->get('Content-type'), "Content-type must be video/mp4"); + } + + /** + * @covers ::__construct + * @covers ::convert + * @covers ::getFfmpegFormat + */ + public function testUnmappedContentType() + { + $new_content_type = 'video/x-flv'; + $this->content_types[] = $new_content_type; + $controller = $this->getDefaultController(); + $mock_fedora_response = $this->getMockFedoraResource(); + + $request = Request::create( + "/", + "GET" + ); + $request->headers->set('Authorization', 'some_token'); + $request->headers->set('Apix-Ldp-Resource', 'http://localhost:8080/fcrepo/rest/foo'); + $request->headers->set('Accept', $new_content_type); + $request->attributes->set('fedora_resource', $mock_fedora_response); + + $response = $controller->convert($request); + $this->assertEquals(200, $response->getStatusCode(), "Response must return 200"); + $this->assertEquals('video/mp4', $response->headers->get('Content-type'), "Content-type must be video/mp4"); + } + + /** + * @covers ::__construct + * @covers ::convert + * @covers ::getFfmpegFormat + */ + public function testInvalidContentType() + { + $new_content_type = 'video/x-flv'; + $controller = $this->getDefaultController(); + $mock_fedora_response = $this->getMockFedoraResource(); + + $request = Request::create( + "/", + "GET" + ); + $request->headers->set('Authorization', 'some_token'); + $request->headers->set('Apix-Ldp-Resource', 'http://localhost:8080/fcrepo/rest/foo'); + $request->headers->set('Accept', $new_content_type); + $request->attributes->set('fedora_resource', $mock_fedora_response); + + $response = $controller->convert($request); + $this->assertEquals(200, $response->getStatusCode(), "Response must return 200"); + $this->assertEquals('video/mp4', $response->headers->get('Content-type'), "Content-type must be video/mp4"); + } + + public function testFailOnNoApixHeader() + { + $controller = $this->getDefaultController(); + $mock_fedora_response = $this->getMockFedoraResource(); + + $request = Request::create( + "/", + "GET" + ); + $request->headers->set('Authorization', 'some_token'); + $request->headers->set('Accept', 'video/mp4'); + $request->attributes->set('fedora_resource', $mock_fedora_response); + + $response = $controller->convert($request); + $this->assertEquals(400, $response->getStatusCode(), "Response must return 400"); + } + + private function getDefaultController() + { + // Mock a CmdExecuteService. + $prophecy = $this->prophesize(CmdExecuteService::class); + $mock_service = $prophecy->reveal(); + + // Create a controller. + $controller = new HomarusController( + $mock_service, + $this->content_types, + $this->default_content_type, + 'convert', + $this->prophesize(Logger::class)->reveal(), + $this->mime_to_format, + $this->default_format + ); + return $controller; + } + + private function getMockFedoraResource() + { + // Mock a stream body for a Fedora response. + $prophecy = $this->prophesize(StreamInterface::class); + $prophecy->isReadable()->willReturn(true); + $prophecy->isWritable()->willReturn(false); + $mock_stream = $prophecy->reveal(); + + // Mock a Fedora response. + $prophecy = $this->prophesize(ResponseInterface::class); + $prophecy->getStatusCode()->willReturn(200); + $prophecy->getBody()->willReturn($mock_stream); + $mock_fedora_response = $prophecy->reveal(); + return $mock_fedora_response; + } } diff --git a/Houdini/tests/Islandora/Houdini/Tests/HoudiniControllerTest.php b/Houdini/tests/Islandora/Houdini/Tests/HoudiniControllerTest.php index 7ca4ee0f..86ee9d4a 100644 --- a/Houdini/tests/Islandora/Houdini/Tests/HoudiniControllerTest.php +++ b/Houdini/tests/Islandora/Houdini/Tests/HoudiniControllerTest.php @@ -18,6 +18,7 @@ class HoudiniControllerTest extends \PHPUnit_Framework_TestCase { /** + * @covers ::__construct * @covers ::identifyOptions * @covers ::convertOptions */ @@ -48,6 +49,7 @@ public function testOptions() } /** + * @covers ::__construct * @covers ::identify * @covers ::convert */ @@ -98,6 +100,7 @@ public function testErrorReturns500() } /** + * @covers ::__construct * @covers ::identify * @covers ::convert */ @@ -119,6 +122,54 @@ public function testSuccessReturns200() $prophecy = $this->prophesize(CmdExecuteService::class); $mock_service = $prophecy->reveal(); + // Create a controller. + $controller = new HoudiniController( + $mock_service, + ['image/jpeg', 'image/png'], + 'image/jpeg', + 'convert', + $this->prophesize(Logger::class)->reveal() + ); + + $request = Request::create( + "/", + "GET" + ); + $request->headers->set('Authorization', 'some_token'); + $request->headers->set('Apix-Ldp-Resource', 'http://localhost:8080/fcrepo/rest/foo'); + $request->headers->set('Accept', 'image/png'); + $request->attributes->set('fedora_resource', $mock_fedora_response); + + $response = $controller->identify($request); + $this->assertTrue($response->getStatusCode() == 200, "Response must return 200"); + + $response = $controller->convert($request); + $this->assertTrue($response->getStatusCode() == 200, "Response must return 200"); + } + + /** + * @covers ::__construct + * @covers ::identify + * @covers ::convert + */ + public function testSuccessReturns200Fallback() + { + // Mock a stream body for a Fedora response. + $prophecy = $this->prophesize(StreamInterface::class); + $prophecy->isReadable()->willReturn(true); + $prophecy->isWritable()->willReturn(false); + $mock_stream = $prophecy->reveal(); + + // Mock a Fedora response. + $prophecy = $this->prophesize(ResponseInterface::class); + $prophecy->getStatusCode()->willReturn(200); + $prophecy->getBody()->willReturn($mock_stream); + $mock_fedora_response = $prophecy->reveal(); + + // Mock a CmdExecuteService. + $prophecy = $this->prophesize(CmdExecuteService::class); + $mock_service = $prophecy->reveal(); + // Create a controller. $controller = new HoudiniController( $mock_service, diff --git a/Hypercube/tests/Islandora/Hypercube/Tests/HypercubeControllerTest.php b/Hypercube/tests/Islandora/Hypercube/Tests/HypercubeControllerTest.php index c5ade10b..8a0af4c8 100644 --- a/Hypercube/tests/Islandora/Hypercube/Tests/HypercubeControllerTest.php +++ b/Hypercube/tests/Islandora/Hypercube/Tests/HypercubeControllerTest.php @@ -15,6 +15,7 @@ class HypercubeControllerTest extends \PHPUnit_Framework_TestCase { /** + * @covers ::__construct * @covers ::options */ public function testOptions() @@ -34,6 +35,7 @@ public function testOptions() } /** + * @covers ::__construct * @covers ::get */ public function testTesseractErrorReturns500() @@ -71,6 +73,7 @@ public function testTesseractErrorReturns500() } /** + * @covers ::__construct * @covers ::get */ public function testTesseractSuccessReturns200() diff --git a/Milliner/static/MediaLDP-RS-no_date.jsonld b/Milliner/static/MediaLDP-RS-no_date.jsonld new file mode 100644 index 00000000..9729de43 --- /dev/null +++ b/Milliner/static/MediaLDP-RS-no_date.jsonld @@ -0,0 +1,15 @@ +[ + { + "@id": "http://localhost:8080/fcrepo/rest/24/02/a5/84/2402a584-b353-4062-950d-ef9070d74d1f", + "http://www.loc.gov/premis/rdf/v1#hasMessageDigest": [ + { + "@id": "urn:sha1:abc123" + } + ], + "http://www.ebu.ch/metadata/ontologies/ebucore/ebucore#hasMimeType": [ + { + "@value": "image/jpeg" + } + ] + } +] \ No newline at end of file diff --git a/Milliner/tests/Islandora/Milliner/Tests/DeleteTest.php b/Milliner/tests/Islandora/Milliner/Tests/DeleteTest.php index 920484dc..2e18707a 100644 --- a/Milliner/tests/Islandora/Milliner/Tests/DeleteTest.php +++ b/Milliner/tests/Islandora/Milliner/Tests/DeleteTest.php @@ -10,6 +10,7 @@ use Monolog\Handler\NullHandler; use Monolog\Logger; use Prophecy\Argument; +use Psr\Log\LoggerInterface; /** * Class MillinerServiceTest @@ -42,6 +43,7 @@ protected function setUp() } /** + * @covers ::__construct * @covers ::deleteNode * @expectedException \RuntimeException * @expectedExceptionCode 403 @@ -72,6 +74,7 @@ public function testDeleteReturnsFedoraError() } /** + * @covers ::__construct * @covers ::deleteNode */ public function testDeleteReturns204OnGeminiSuccess() @@ -116,6 +119,7 @@ public function testDeleteReturns204OnGeminiSuccess() } /** + * @covers ::__construct * @covers ::deleteNode */ public function testDeleteReturns404IfNotMappedAndGeminiFails() @@ -148,6 +152,7 @@ public function testDeleteReturns404IfNotMappedAndGeminiFails() } /** + * @covers ::__construct * @covers ::deleteNode */ public function testDeleteReturnsFedoraErrorIfMappedButGeminiFails() diff --git a/Milliner/tests/Islandora/Milliner/Tests/GeminiClientTest.php b/Milliner/tests/Islandora/Milliner/Tests/GeminiClientTest.php index 971c5aab..470e3e71 100644 --- a/Milliner/tests/Islandora/Milliner/Tests/GeminiClientTest.php +++ b/Milliner/tests/Islandora/Milliner/Tests/GeminiClientTest.php @@ -7,6 +7,7 @@ use Islandora\Milliner\Gemini\GeminiClient; use Monolog\Handler\NullHandler; use Monolog\Logger; +use PHPUnit\Framework\TestCase; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\RequestInterface; use Prophecy\Argument; @@ -17,7 +18,7 @@ * @package Islandora\Milliner\Tests * @coversDefaultClass \Islandora\Milliner\Gemini\GeminiClient */ -class GeminiClientTest extends \PHPUnit_Framework_TestCase +class GeminiClientTest extends TestCase { /** * @var LoggerInterface @@ -36,6 +37,7 @@ protected function setUp() } /** + * @covers ::__construct * @covers ::getUrls */ public function testGetUrls() @@ -75,6 +77,7 @@ public function testGetUrls() } /** + * @covers ::__construct * @covers ::getUrls */ public function testGetUrlsReturnsEmptyArrayWhenNotFound() @@ -107,6 +110,33 @@ public function testGetUrlsReturnsEmptyArrayWhenNotFound() } /** + * @covers ::__construct + * @covers ::getUrls + * @expectedException \GuzzleHttp\Exception\RequestException + */ + public function testGetUrlsException() + { + $request = $this->prophesize(RequestInterface::class)->reveal(); + + $response = $this->prophesize(ResponseInterface::class); + $response->getStatusCode()->willReturn(500); + $response = $response->reveal(); + + $client = $this->prophesize(Client::class); + $client->get(Argument::any(), Argument::any())->willThrow( + new RequestException("Server Error", $request, $response) + ); + $client = $client->reveal(); + + $gemini = new GeminiClient( + $client, + $this->logger + ); + $gemini->getUrls("abc123"); + } + + /** + * @covers ::__construct * @covers ::mintFedoraUrl */ public function testMintFedoraUrl() @@ -138,6 +168,7 @@ public function testMintFedoraUrl() } /** + * @covers ::__construct * @covers ::saveUrls */ public function testSaveUrls() @@ -163,6 +194,7 @@ public function testSaveUrls() } /** + * @covers ::__construct * @covers ::deleteUrls */ public function testDeleteUrls() @@ -186,4 +218,13 @@ public function testDeleteUrls() "Gemini client must return true on successful deleteUrls(). Received $out" ); } + + /** + * @covers ::create + */ + public function testCreateClient() + { + $client = GeminiClient::create('http://example.org', $this->logger); + $this->assertTrue($client instanceof GeminiClient, 'Must get back a GeminiClient instance'); + } } diff --git a/Milliner/tests/Islandora/Milliner/Tests/MillinerControllerTest.php b/Milliner/tests/Islandora/Milliner/Tests/MillinerControllerTest.php index 0c8894f0..ab590edc 100644 --- a/Milliner/tests/Islandora/Milliner/Tests/MillinerControllerTest.php +++ b/Milliner/tests/Islandora/Milliner/Tests/MillinerControllerTest.php @@ -35,6 +35,7 @@ protected function setUp() } /** + * @covers ::__construct * @covers ::saveNode * @covers ::saveMedia * @covers ::deleteNode @@ -113,6 +114,7 @@ public function testMethodsReturnMillinerErrors() } /** + * @covers ::__construct * @covers ::saveNode */ public function testSaveNodeReturns400WithoutContentLocation() @@ -138,6 +140,7 @@ public function testSaveNodeReturns400WithoutContentLocation() } /** + * @covers ::__construct * @covers ::saveMedia */ public function testSaveMediaReturn400WithoutContentLocation() @@ -164,6 +167,7 @@ public function testSaveMediaReturn400WithoutContentLocation() } /** + * @covers ::__construct * @covers ::saveNode */ public function testSaveNodeReturnsSuccessOnSuccess() @@ -220,6 +224,7 @@ public function testSaveNodeReturnsSuccessOnSuccess() } /** + * @covers ::__construct * @covers ::saveMedia */ public function testSaveMediaReturnsSuccessOnSuccess() @@ -275,6 +280,7 @@ public function testSaveMediaReturnsSuccessOnSuccess() } /** + * @covers ::__construct * @covers ::deleteNode */ public function testDeleteReturnsSuccessOnSuccess() diff --git a/Milliner/tests/Islandora/Milliner/Tests/SaveMediaTest.php b/Milliner/tests/Islandora/Milliner/Tests/SaveMediaTest.php index 89a7586e..2fbd2563 100644 --- a/Milliner/tests/Islandora/Milliner/Tests/SaveMediaTest.php +++ b/Milliner/tests/Islandora/Milliner/Tests/SaveMediaTest.php @@ -42,7 +42,12 @@ protected function setUp() } /** + * @covers ::__construct * @covers ::saveMedia + * @covers ::getFirstPredicate + * @covers ::getModifiedTimestamp + * @covers ::processJsonld + * @covers ::getLinkHeader * @expectedException \RuntimeException * @expectedExceptionCode 500 */ @@ -78,7 +83,12 @@ public function testSaveMediaThrows500WithNoFileField() } /** + * @covers ::__construct * @covers ::saveMedia + * @covers ::getFirstPredicate + * @covers ::getModifiedTimestamp + * @covers ::processJsonld + * @covers ::getLinkHeader * @expectedException \RuntimeException * @expectedExceptionCode 500 */ @@ -114,7 +124,12 @@ public function testSaveMediaThrows500WithEmptyFileField() } /** + * @covers ::__construct * @covers ::saveMedia + * @covers ::getFirstPredicate + * @covers ::getModifiedTimestamp + * @covers ::processJsonld + * @covers ::getLinkHeader * @expectedException \RuntimeException * @expectedExceptionCode 404 */ @@ -153,7 +168,12 @@ public function testSaveMediaThrows404WhenFileIsNotInGemini() } /** + * @covers ::__construct * @covers ::saveMedia + * @covers ::getFirstPredicate + * @covers ::getModifiedTimestamp + * @covers ::processJsonld + * @covers ::getLinkHeader * @expectedException \RuntimeException * @expectedExceptionCode 404 */ @@ -200,7 +220,12 @@ public function testSaveMediaThrowsFedoraHeadError() } /** + * @covers ::__construct * @covers ::saveMedia + * @covers ::getFirstPredicate + * @covers ::getModifiedTimestamp + * @covers ::processJsonld + * @covers ::getLinkHeader * @expectedException \RuntimeException * @expectedExceptionCode 500 */ @@ -247,7 +272,12 @@ public function testSaveMediaThrows500WhenNoDescribedbyHeader() } /** + * @covers ::__construct * @covers ::saveMedia + * @covers ::getFirstPredicate + * @covers ::getModifiedTimestamp + * @covers ::processJsonld + * @covers ::getLinkHeader * @expectedException \RuntimeException * @expectedExceptionCode 404 */ @@ -304,7 +334,12 @@ public function testSaveMediaThrowsFedoraGetError() } /** + * @covers ::__construct * @covers ::saveMedia + * @covers ::getFirstPredicate + * @covers ::getModifiedTimestamp + * @covers ::processJsonld + * @covers ::getLinkHeader * @expectedException \RuntimeException * @expectedExceptionCode 412 */ @@ -373,7 +408,12 @@ public function testSaveMediaThrows412OnStaleData() } /** + * @covers ::__construct * @covers ::saveMedia + * @covers ::getFirstPredicate + * @covers ::getModifiedTimestamp + * @covers ::processJsonld + * @covers ::getLinkHeader * @expectedException \RuntimeException * @expectedExceptionCode 403 */ @@ -447,7 +487,12 @@ public function testSaveMediaThrowsFedoraPutError() } /** + * @covers ::__construct * @covers ::saveMedia + * @covers ::getFirstPredicate + * @covers ::getModifiedTimestamp + * @covers ::processJsonld + * @covers ::getLinkHeader */ public function testSaveMediaReturnsFedoraSuccess() { @@ -523,4 +568,87 @@ public function testSaveMediaReturnsFedoraSuccess() "Milliner must return 204 when Fedora returns 204. Received: $status" ); } + + /** + * @covers ::__construct + * @covers ::saveMedia + * @covers ::getFirstPredicate + * @covers ::getModifiedTimestamp + * @covers ::processJsonld + * @covers ::getLinkHeader + */ + public function testSaveMediaReturnsNoModifiedDate() + { + $drupal_json_response = new Response( + 200, + [ + 'Content-Type' => 'application/json', + "Link" => '; rel="alternate"; type="application/ld+json"', + ], + file_get_contents(__DIR__ . '/../../../../static/Media.json') + ); + $drupal_jsonld_response = new Response( + 200, + ['Content-Type' => 'application/ld+json'], + file_get_contents(__DIR__ . '/../../../../static/Media.jsonld') + ); + $drupal = $this->prophesize(Client::class); + $drupal->get('http://localhost:8000/media/6?_format=json', Argument::any()) + ->willReturn($drupal_json_response); + $drupal->get('http://localhost:8000/media/6?_format=jsonld', Argument::any()) + ->willReturn($drupal_jsonld_response); + $drupal = $drupal->reveal(); + + $link = ''; + $link .= '; rel="describedby"'; + $fedora_head_response = new Response( + 200, + ['Link' => $link] + ); + $fedora_get_response = new Response( + 200, + ['Content-Type' => 'application/ld+json', 'ETag' => 'W\abc123'], + file_get_contents(__DIR__ . '/../../../../static/MediaLDP-RS-no_date.jsonld') + ); + $fedora_put_response = new Response( + 204 + ); + $fedora = $this->prophesize(IFedoraClient::class); + $fedora->getResourceHeaders(Argument::any(), Argument::any()) + ->willReturn($fedora_head_response); + $fedora->getResource(Argument::any(), Argument::any()) + ->willReturn($fedora_get_response); + $fedora->saveResource(Argument::any(), Argument::any(), Argument::any()) + ->willReturn($fedora_put_response); + $fedora = $fedora->reveal(); + + $mapping = [ + 'drupal' => 'http://localhost:8000/media/6?_format=jsonld', + 'fedora' => 'http://localhost:8080/fcrepo/rest/ff/b1/5b/4f/ffb15b4f-54db-44ce-ad0b-3588889a3c9b', + ]; + $gemini = $this->prophesize(GeminiClient::class); + $gemini->getUrls(Argument::any(), Argument::any()) + ->willReturn($mapping); + $gemini = $gemini->reveal(); + + $milliner = new MillinerService( + $fedora, + $drupal, + $gemini, + $this->logger, + $this->modifiedDatePredicate + ); + + $response = $milliner->saveMedia( + "field_image", + "http://localhost:8000/media/6?_format=json", + "Bearer islandora" + ); + + $status = $response->getStatusCode(); + $this->assertTrue( + $status == 204, + "Milliner must return 204 when Fedora returns 204. Received: $status" + ); + } } diff --git a/Milliner/tests/Islandora/Milliner/Tests/SaveNodeTest.php b/Milliner/tests/Islandora/Milliner/Tests/SaveNodeTest.php index b9c4e839..03f2a772 100644 --- a/Milliner/tests/Islandora/Milliner/Tests/SaveNodeTest.php +++ b/Milliner/tests/Islandora/Milliner/Tests/SaveNodeTest.php @@ -9,6 +9,7 @@ use Islandora\Milliner\Service\MillinerService; use Monolog\Handler\NullHandler; use Monolog\Logger; +use PHPUnit\Framework\TestCase; use Prophecy\Argument; /** @@ -16,7 +17,7 @@ * @package Islandora\Milliner\Tests * @coversDefaultClass \Islandora\Milliner\Service\MillinerService */ -class SaveNodeTest extends \PHPUnit_Framework_TestCase +class SaveNodeTest extends TestCase { /** * @var LoggerInterface @@ -42,7 +43,9 @@ protected function setUp() } /** + * @covers ::__construct * @covers ::saveNode + * @covers ::processJsonld * @expectedException \RuntimeException * @expectedExceptionCode 403 */ @@ -88,7 +91,66 @@ public function testCreateNodeThrowsOnFedoraError() } /** + * @covers ::__construct * @covers ::saveNode + * @covers ::createNode + * @covers ::processJsonld + * @expectedException \RuntimeException + * @expectedExceptionCode 403 + */ + public function testCreateNodeThrowsOnFedoraSaveError() + { + $url = "http://localhost:8080/fcrepo/rest/95/41/c0/c1/9541c0c1-5bee-4973-a9d0-e55c1658bc8"; + $gemini = $this->prophesize(GeminiClient::class); + $gemini->getUrls(Argument::any(), Argument::any()) + ->willReturn([]); + $gemini->mintFedoraUrl(Argument::any(), Argument::any()) + ->willReturn($url); + $gemini = $gemini->reveal(); + + $drupal_response = new Response( + 200, + ['Content-Type' => 'application/ld+json'], + file_get_contents(__DIR__ . '/../../../../static/Content.jsonld') + ); + $drupal = $this->prophesize(Client::class); + $drupal->get(Argument::any(), Argument::any()) + ->willReturn($drupal_response); + $drupal = $drupal->reveal(); + + $fedora_get_response = new Response( + 200, + ['Content-Type' => 'application/ld+json'], + file_get_contents(__DIR__ . '/../../../../static/ContentLDP-RS.jsonld') + ); + $fedora_save_response = new Response(403, [], null, '1.1', 'UNAUTHORIZED'); + $fedora = $this->prophesize(IFedoraClient::class); + $fedora->getResource(Argument::any(), Argument::any(), Argument::any()) + ->willReturn($fedora_get_response); + $fedora->saveResource(Argument::any(), Argument::any(), Argument::any()) + ->willReturn($fedora_save_response); + $fedora = $fedora->reveal(); + + $milliner = new MillinerService( + $fedora, + $drupal, + $gemini, + $this->logger, + $this->modifiedDatePredicate + ); + + $milliner->saveNode( + "9541c0c1-5bee-4973-a9d0-e55c1658bc81", + "http://localhost:8000/node/1?_format=jsonld", + "Bearer islandora" + ); + } + + /** + * @covers ::__construct + * @covers ::saveNode + * @covers ::updateNode + * @covers ::processJsonld */ public function testCreateNodeReturnsFedora201() { @@ -140,7 +202,10 @@ public function testCreateNodeReturnsFedora201() } /** + * @covers ::__construct * @covers ::saveNode + * @covers ::createNode + * @covers ::processJsonld */ public function testCreateNodeReturnsFedora204() { @@ -192,7 +257,12 @@ public function testCreateNodeReturnsFedora204() } /** + * @covers ::__construct * @covers ::saveNode + * @covers ::updateNode + * @covers ::processJsonld + * @covers ::getModifiedTimestamp + * @covers ::getFirstPredicate * @expectedException \RuntimeException * @expectedExceptionCode 403 */ @@ -231,7 +301,12 @@ public function testUpdateNodeThrowsOnFedoraGetError() } /** + * @covers ::__construct * @covers ::saveNode + * @covers ::updateNode + * @covers ::processJsonld + * @covers ::getModifiedTimestamp + * @covers ::getFirstPredicate * @expectedException \RuntimeException * @expectedExceptionCode 500 */ @@ -282,7 +357,12 @@ public function testUpdateNodeThrows500OnBadDatePredicate() } /** + * @covers ::__construct * @covers ::saveNode + * @covers ::updateNode + * @covers ::processJsonld + * @covers ::getModifiedTimestamp + * @covers ::getFirstPredicate * @expectedException \RuntimeException * @expectedExceptionCode 412 */ @@ -333,7 +413,12 @@ public function testUpdateNodeThrows412OnStaleContent() } /** + * @covers ::__construct * @covers ::saveNode + * @covers ::updateNode + * @covers ::processJsonld + * @covers ::getModifiedTimestamp + * @covers ::getFirstPredicate * @expectedException \RuntimeException * @expectedExceptionCode 403 */ @@ -387,7 +472,12 @@ public function testUpdateNodeThrowsOnFedoraSaveError() } /** + * @covers ::__construct * @covers ::saveNode + * @covers ::updateNode + * @covers ::processJsonld + * @covers ::getModifiedTimestamp + * @covers ::getFirstPredicate */ public function testUpdateNodeReturnsFedora201() { @@ -447,7 +537,12 @@ public function testUpdateNodeReturnsFedora201() } /** + * @covers ::__construct * @covers ::saveNode + * @covers ::updateNode + * @covers ::processJsonld + * @covers ::getModifiedTimestamp + * @covers ::getFirstPredicate */ public function testUpdateNodeReturnsFedora204() {