From c9989957a589fb18b1db7ff2630e1ea6adc9295d Mon Sep 17 00:00:00 2001 From: =?utf-8?q?Fr=C3=A9d=C3=A9ric=20Demians?= Date: Mon, 24 Oct 2016 14:54:17 +0000 Subject: [PATCH] Bug 17493 Improve OAI Server tests Content-Type: text/plain; charset=utf-8 Add several tests for OAI Servers. TEST PLAN: - Check that after aplying this patch, this still works: prove -v t/db_dependent/OAI/Server.t - Read the test to see what has been added: - Testing process simplification - ListIdentifiers verb with resumption token, until the whole catalog is harvested - ListRecords verb with resumption token, until the whole catalog is harvested - Returned metadata returned is tested, marcxml & oai_dc Signed-off-by: Josef Moravec Signed-off-by: Marcel de Rooy --- t/db_dependent/OAI/Server.t | 314 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 265 insertions(+), 49 deletions(-) diff --git a/t/db_dependent/OAI/Server.t b/t/db_dependent/OAI/Server.t index 05c2d87..1a23291 100644 --- a/t/db_dependent/OAI/Server.t +++ b/t/db_dependent/OAI/Server.t @@ -1,6 +1,6 @@ #!/usr/bin/perl -# Copyright Tamil s.a.r.l. 2015 +# Copyright Tamil s.a.r.l. 2016 # # This file is part of Koha. # @@ -21,12 +21,14 @@ use Modern::Perl; use C4::Context; use C4::Biblio; -use Test::More tests => 13; +use Test::More tests => 27; use Test::MockModule; use Test::Warn; use DateTime; use XML::Simple; use t::lib::Mocks; +use t::lib::TestBuilder; +use YAML; BEGIN { @@ -47,48 +49,117 @@ BEGIN { # Mocked CGI module in order to be able to send CGI parameters to OAI Server my %param; my $module = Test::MockModule->new('CGI'); -$module->mock('Vars', sub { %param; }); + $module->mock('Vars', sub { %param; }); +my $schema = Koha::Database->schema; +$schema->storage->txn_begin; my $dbh = C4::Context->dbh; -$dbh->{AutoCommit} = 0; -$dbh->{RaiseError} = 1; -$dbh->do('DELETE FROM issues'); -$dbh->do('DELETE FROM biblio'); -$dbh->do('DELETE FROM biblioitems'); -$dbh->do('DELETE FROM items'); + +my $builder = t::lib::TestBuilder->new; + +$dbh->do('SET FOREIGN_KEY_CHECKS = 0'); +$dbh->do('TRUNCATE biblio'); +$dbh->do('TRUNCATE biblioitems'); +$dbh->do('TRUNCATE issues'); # Add 10 biblio records -my @bibs = map { +our $tz = DateTime::TimeZone->new( name => 'local' ); +my $date_added = DateTime->now(time_zone =>$tz) . 'Z'; +my $date_to = substr($date_added, 0, 10) . 'T23:59:59Z'; + +my (@header, @marcxml, @oaidc); +map { my $record = MARC::Record->new(); $record->append_fields( MARC::Field->new('245', '', '', 'a' => "Title $_" ) ); my ($biblionumber) = AddBiblio($record, ''); - $biblionumber; + $record = GetMarcBiblio($biblionumber); + $record = XMLin($record->as_xml_record); + $header[$biblionumber] = { datestamp => $date_added, identifier => "TEST:$biblionumber" }; + delete $record->{$_} for (('xmlns','xmlns:xsi','xsi:schemaLocation')); + $oaidc[$biblionumber] = { + header => $header[$biblionumber], + metadata => { + 'oai_dc:dcCollection' => { + 'oai_dc:dc' => { + 'dc:title' => { + 'content' => "Title $biblionumber", + 'xmlns:dc' => 'http://purl.org/dc/elements/1.1/' + }, + 'dc:language' => { + 'xmlns:dc' => 'http://purl.org/dc/elements/1.1/' + }, + 'dc:type' => { + 'xmlns:dc' => 'http://purl.org/dc/elements/1.1/' + }, + }, + "xmlns:oai_dc" => "http://www.openarchives.org/OAI/2.0/oai_dc/", + "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", + "xsi:schemaLocation" => "http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd", + }, + }, + }; + $marcxml[$biblionumber] = { + header => $header[$biblionumber], + metadata => { + collection => { + record => $record, + "xmlns" => "http://www.loc.gov/MARC21/slim", + "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", + "xsi:schemaLocation" => "http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd", + }, + }, + }; + $biblionumber => undef; } (1..10); -t::lib::Mocks::mock_preference('LibraryName', 'My Library'); -t::lib::Mocks::mock_preference('OAI::PMH', 1); -t::lib::Mocks::mock_preference('OAI-PMH:archiveID', 'TEST'); -t::lib::Mocks::mock_preference('OAI-PMH:ConfFile', '' ); -t::lib::Mocks::mock_preference('OAI-PMH:MaxCount', 3); -t::lib::Mocks::mock_preference('OAI-PMH:DeletedRecord', 'persistent'); - -%param = ( verb => 'ListMetadataFormats' ); -my $response; -my $get_response = sub { - my $stdout; - local *STDOUT; - open STDOUT, '>', \$stdout; - Koha::OAI::Server::Repository->new(); - $response = XMLin($stdout); + +my $syspref = { + 'LibraryName' => 'My Library', + 'OAI::PMH' => 1, + 'OAI-PMH:archiveID' => 'TEST', + 'OAI-PMH:ConfFile' => '', + 'OAI-PMH:MaxCount' => 3, + 'OAI-PMH:DeletedRecord' => 'persistent', }; -$get_response->(); -my $now = DateTime->now . 'Z'; -my $expected = { - request => 'http://localhost', - responseDate => $now, - xmlns => 'http://www.openarchives.org/OAI/2.0/', - 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', - 'xsi:schemaLocation' => 'http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd', +while ( my ($name, $value) = each %$syspref ) { + t::lib::Mocks::mock_preference( $name => $value ); +} + + +sub test_query { + my ($test, $param, $expected) = @_; + + %param = %$param; + my %full_expected = ( + %$expected, + ( + request => 'http://localhost', + responseDate => DateTime->now . 'Z', + xmlns => 'http://www.openarchives.org/OAI/2.0/', + 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'xsi:schemaLocation' => 'http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd', + ) + ); + + my $response; + { + my $stdout; + local *STDOUT; + open STDOUT, '>', \$stdout; + Koha::OAI::Server::Repository->new(); + $response = XMLin($stdout); + } + + unless (is_deeply($response, \%full_expected, $test)) { + diag + "PARAM:" . Dump($param) . + "EXPECTED:" . Dump(\%full_expected) . + "RESPONSE:" . Dump($response); + } +} + + +test_query('ListMetadataFormats', {verb => 'ListMetadataFormats'}, { ListMetadataFormats => { metadataFormat => [ { @@ -103,23 +174,168 @@ my $expected = { }, ], }, -}; -is_deeply($response, $expected, "ListMetadataFormats"); - -%param = ( verb => 'ListIdentifiers' ); -$get_response->(); -$now = DateTime->now . 'Z'; -$expected = { - request => 'http://localhost', - responseDate => $now, - xmlns => 'http://www.openarchives.org/OAI/2.0/', - 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', - 'xsi:schemaLocation' => 'http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd', +} ); + +test_query('ListIdentifiers without metadataPrefix', {verb => 'ListIdentifiers'}, { error => { code => 'badArgument', content => "Required argument 'metadataPrefix' was undefined", }, -}; -is_deeply($response, $expected, "ListIdentifiers without metadaPrefix argument"); +}); + + +test_query('ListIdentifiers', {verb => 'ListIdentifiers', metadataPrefix => 'marcxml'}, { + ListIdentifiers => { + header => [ @header[1..3] ], + resumptionToken => { + content => "marcxml/3/1970-01-01T00:00:00Z/$date_to/", + cursor => 3, + }, + }, +}); + +test_query('ListIdentifiers', {verb => 'ListIdentifiers', metadataPrefix => 'marcxml'}, { + ListIdentifiers => { + header => [ @header[1..3] ], + resumptionToken => { + content => "marcxml/3/1970-01-01T00:00:00Z/$date_to/", + cursor => 3, + }, + }, +}); + +test_query( + 'ListIdentifiers with resumptionToken 1', + { verb => 'ListIdentifiers', resumptionToken => "marcxml/3/1970-01-01T00:00:00Z/$date_to/" }, + { + ListIdentifiers => { + header => [ @header[4..6] ], + resumptionToken => { + content => "marcxml/6/1970-01-01T00:00:00Z/$date_to/", + cursor => 6, + }, + }, + + }, +); + +test_query( + 'ListIdentifiers with resumptionToken 2', + { verb => 'ListIdentifiers', resumptionToken => "marcxml/6/1970-01-01T00:00:00Z/$date_to/" }, + { + ListIdentifiers => { + header => [ @header[7..9] ], + resumptionToken => { + content => "marcxml/9/1970-01-01T00:00:00Z/$date_to/", + cursor => 9, + }, + }, + + }, +); + +test_query( + 'ListIdentifiers with resumptionToken 3, response without resumption', + { verb => 'ListIdentifiers', resumptionToken => "marcxml/9/1970-01-01T00:00:00Z/$date_to/" }, + { + ListIdentifiers => { + header => $header[10], + }, + + }, +); + +test_query('ListRecords marcxml without metadataPrefix', {verb => 'ListRecords'}, { + error => { + code => 'badArgument', + content => "Required argument 'metadataPrefix' was undefined", + }, +}); + +test_query('ListRecords marcxml', {verb => 'ListRecords', metadataPrefix => 'marcxml'}, { + ListRecords => { + record => [ @marcxml[1..3] ], + resumptionToken => { + content => "marcxml/3/1970-01-01T00:00:00Z/$date_to/", + cursor => 3, + }, + }, +}); + +test_query( + 'ListRecords marcxml with resumptionToken 1', + { verb => 'ListRecords', resumptionToken => "marcxml/3/1970-01-01T00:00:00Z/$date_to/" }, + { ListRecords => { + record => [ @marcxml[4..6] ], + resumptionToken => { + content => "marcxml/6/1970-01-01T00:00:00Z/$date_to/", + cursor => 6, + }, + }, +}); + +test_query( + 'ListRecords marcxml with resumptionToken 2', + { verb => 'ListRecords', resumptionToken => "marcxml/6/1970-01-01T00:00:00Z/$date_to/" }, + { ListRecords => { + record => [ @marcxml[7..9] ], + resumptionToken => { + content => "marcxml/9/1970-01-01T00:00:00Z/$date_to/", + cursor => 9, + }, + }, +}); + +# Last record, so no resumption token +test_query( + 'ListRecords marcxml with resumptionToken 3, response without resumption', + { verb => 'ListRecords', resumptionToken => "marcxml/9/1970-01-01T00:00:00Z/$date_to/" }, + { ListRecords => { + record => $marcxml[10], + }, +}); + +test_query('ListRecords oai_dc', {verb => 'ListRecords', metadataPrefix => 'oai_dc'}, { + ListRecords => { + record => [ @oaidc[1..3] ], + resumptionToken => { + content => "oai_dc/3/1970-01-01T00:00:00Z/$date_to/", + cursor => 3, + }, + }, +}); + +test_query( + 'ListRecords oai_dc with resumptionToken 1', + { verb => 'ListRecords', resumptionToken => "oai_dc/3/1970-01-01T00:00:00Z/$date_to/" }, + { ListRecords => { + record => [ @oaidc[4..6] ], + resumptionToken => { + content => "oai_dc/6/1970-01-01T00:00:00Z/$date_to/", + cursor => 6, + }, + }, +}); + +test_query( + 'ListRecords oai_dc with resumptionToken 2', + { verb => 'ListRecords', resumptionToken => "oai_dc/6/1970-01-01T00:00:00Z/$date_to/" }, + { ListRecords => { + record => [ @oaidc[7..9] ], + resumptionToken => { + content => "oai_dc/9/1970-01-01T00:00:00Z/$date_to/", + cursor => 9, + }, + }, +}); + +# Last record, so no resumption token +test_query( + 'ListRecords oai_dc with resumptionToken 3, response without resumption', + { verb => 'ListRecords', resumptionToken => "oai_dc/9/1970-01-01T00:00:00Z/$date_to/" }, + { ListRecords => { + record => $oaidc[10], + }, +}); -$dbh->rollback; +$schema->storage->txn_rollback; -- 2.1.4