]> git.koha-community.org Git - koha.git/blob - t/db_dependent/Koha/Z3950Responder/GenericSession.t
Bug 13937: Add SRU tests
[koha.git] / t / db_dependent / Koha / Z3950Responder / GenericSession.t
1 #!/usr/bin/perl
2
3 use Modern::Perl;
4
5 use Test::More tests => 3;
6 use Test::WWW::Mechanize;
7 use t::lib::Mocks qw(mock_preference);
8
9 use File::Basename;
10 use XML::LibXML;
11 use YAML;
12 use ZOOM;
13
14 BEGIN {
15     use_ok('Koha::Z3950Responder');
16     use_ok('Koha::Z3950Responder::GenericSession');
17 }
18
19 our $child;
20
21 subtest 'test_search' => sub {
22
23     plan tests => 20;
24
25     t::lib::Mocks::mock_preference('SearchEngine', 'Elasticsearch');
26
27     my $marc_record_1 = MARC::Record->new();
28     $marc_record_1->leader('     cam  22      a 4500');
29     $marc_record_1->append_fields(
30         MARC::Field->new('001', '123'),
31         MARC::Field->new('020', '', '', a => '1-56619-909-3'),
32         MARC::Field->new('100', '', '', a => 'Author 1'),
33         MARC::Field->new('110', '', '', a => 'Corp Author'),
34         MARC::Field->new('210', '', '', a => 'Title 1'),
35         MARC::Field->new('245', '', '', a => 'Title:', b => 'first record'),
36         MARC::Field->new('999', '', '', c => '1234567'),
37     );
38
39     my $marc_record_2 = MARC::Record->new();
40     $marc_record_2->leader('     cam  22      a 4500');
41     $marc_record_2->append_fields(
42         MARC::Field->new('001', '234'),
43         MARC::Field->new('020', '', '', a => '1-56619-909-3'),
44         MARC::Field->new('100', '', '', a => 'Author 2'),
45         MARC::Field->new('110', '', '', a => 'Corp Author'),
46         MARC::Field->new('210', '', '', a => 'Title 2'),
47         MARC::Field->new('245', '', '', a => 'Title:', b => 'second record'),
48         MARC::Field->new('999', '', '', c => '1234567'),
49     );
50
51     my $yaml = new Test::MockModule('YAML');
52     $yaml->mock('LoadFile', sub {
53         return {
54             biblios => {
55                 use => {
56                     1 => 'author',
57                     4 => 'title',
58                     1003 => 'author'
59                 }
60             }
61         };
62     });
63
64     my $builder = new Test::MockModule('Koha::SearchEngine::Elasticsearch::QueryBuilder');
65     $builder->mock('build_query_compat', sub {
66         my ( $self, $operators, $operands ) = @_;
67
68         return (undef, $operands->[0]);
69     });
70
71     my $search = new Test::MockModule('Koha::SearchEngine::Elasticsearch::Search');
72     $search->mock('simple_search_compat', sub {
73         my ( $self, $query ) = @_;
74
75         return ('unexpected query', undef, 0) unless $query eq '((author:(author)) AND ((title:(title\(s\))) OR (title:(another))))';
76
77         my @records = ($marc_record_1, $marc_record_2);
78         return (undef, \@records, 2);
79     });
80
81     $child = fork();
82     if ($child == 0) {
83         my $config_dir = dirname(__FILE__) . '/';
84         my $z = Koha::Z3950Responder->new( {
85             config_dir => $config_dir
86         });
87         $z->start();
88         exit;
89     }
90     sleep(1);
91
92     # Z39.50 protocol tests
93     my $o = new ZOOM::Options();
94     $o->option(preferredRecordSyntax => 'xml');
95     $o->option(elementSetName => 'marcxml');
96     $o->option(databaseName => 'biblios');
97
98     my $Zconn = ZOOM::Connection->create($o);
99     ok($Zconn, 'ZOOM connection created');
100
101     $Zconn->connect('localhost:42111', 0);
102     is($Zconn->errcode(), 0, 'Connection is successful: ' . $Zconn->errmsg());
103
104     my $rs = $Zconn->search_pqf('@and @attr 1=1 @attr 4=1 author @or @attr 1=4 title(s) @attr 1=4 another');
105     is($Zconn->errcode(), 0, 'Search is successful: ' . $Zconn->errmsg());
106
107     is($rs->size(), 2, 'Two results returned');
108
109     my $returned1 = MARC::Record->new_from_xml($rs->record(0)->raw());
110     ok($returned1, 'Record 1 returned as MARCXML');
111     is($returned1->as_xml, $marc_record_1->as_xml, 'Record 1 returned properly');
112
113     my $returned2= MARC::Record->new_from_xml($rs->record(1)->raw());
114     ok($returned2, 'Record 2 returned as MARCXML');
115     is($returned2->as_xml, $marc_record_2->as_xml, 'Record 2 returned properly');
116
117     is($rs->record(2), undef, 'Record 3 does not exist');
118
119     # SRU protocol tests
120     my $base = 'http://localhost:42111';
121     my $ns = 'http://docs.oasis-open.org/ns/search-ws/sruResponse';
122     my $marc_ns = 'http://www.loc.gov/MARC21/slim';
123     my $agent = Test::WWW::Mechanize->new( autocheck => 1 );
124
125     $agent->get_ok("$base", 'Retrieve explain response');
126     my $dom = XML::LibXML->load_xml(string => $agent->content());
127     my @nodes = $dom->getElementsByTagNameNS($ns, 'explainResponse');
128     is(scalar(@nodes), 1, 'explainResponse returned');
129
130     $agent->get_ok("$base/biblios?operation=searchRetrieve&recordSchema=marcxml&maximumRecords=10&query=", 'Try bad search query');
131     $dom = XML::LibXML->load_xml(string => $agent->content());
132     @nodes = $dom->getElementsByTagNameNS($ns, 'diagnostics');
133     is(scalar(@nodes), 1, 'diagnostics returned for bad query');
134
135     $agent->get_ok("$base/biblios?operation=searchRetrieve&recordSchema=marcxml&maximumRecords=10&query=(dc.author%3dauthor AND (dc.title%3d\"title(s)\" OR dc.title%3danother))", 'Retrieve search results');
136     $dom = XML::LibXML->load_xml(string => $agent->content());
137     @nodes = $dom->getElementsByTagNameNS($ns, 'searchRetrieveResponse');
138     is(scalar(@nodes), 1, 'searchRetrieveResponse returned');
139     my @records = $nodes[0]->getElementsByTagNameNS($marc_ns, 'record');
140     is(scalar(@records), 2, 'Two results returned');
141
142     $returned1 = MARC::Record->new_from_xml($records[0]->toString());
143     ok($returned1, 'Record 1 returned as MARCXML');
144     is($returned1->as_xml, $marc_record_1->as_xml, 'Record 1 returned properly');
145
146     $returned2= MARC::Record->new_from_xml($records[1]->toString());
147     ok($returned2, 'Record 2 returned as MARCXML');
148     is($returned2->as_xml, $marc_record_2->as_xml, 'Record 2 returned properly');
149
150     cleanup();
151 };
152
153 sub cleanup {
154     if ($child) {
155         kill 9, $child;
156         $child = undef;
157     }
158 }
159
160 # Fall back to make sure that the server process gets cleaned up
161 END {
162     cleanup();
163 }