Bug 24757: (RM follow-up) Restore test count
[koha.git] / t / db_dependent / Koha / Authorities.t
1 #!/usr/bin/perl
2
3 # Copyright 2015 Koha Development team
4 #
5 # This file is part of Koha
6 #
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20 use Modern::Perl;
21
22 use Test::More tests => 7;
23 use MARC::Field;
24 use MARC::File::XML;
25 use MARC::Record;
26 use Test::Deep;
27 use Test::MockModule;
28 use Test::MockObject;
29 use Test::Warn;
30
31 use C4::Context;
32 use C4::AuthoritiesMarc;
33 use Koha::Authority;
34 use Koha::Authority::ControlledIndicators;
35 use Koha::Authorities;
36 use Koha::Authority::MergeRequest;
37 use Koha::Authority::Type;
38 use Koha::Authority::Types;
39 use Koha::Database;
40
41 use t::lib::Mocks;
42 use t::lib::TestBuilder;
43
44 BEGIN {
45     #TODO Helpful as long as we have issues here
46     my $mock = Test::MockObject->new();
47     $mock->fake_module( 'Catmandu::Store::ElasticSearch' );
48 }
49
50 my $schema = Koha::Database->new->schema;
51 $schema->storage->txn_begin;
52
53 # Globals
54 our $search_compat_pars;
55 our $builder              = t::lib::TestBuilder->new;
56
57 my $nb_of_authorities     = Koha::Authorities->search->count;
58 my $nb_of_authority_types = Koha::Authority::Types->search->count;
59 my $new_authority_type_1  = Koha::Authority::Type->new(
60     {   authtypecode       => 'my_ac_1',
61         authtypetext       => 'my authority type text 1',
62         auth_tag_to_report => '100',
63         summary            => 'my summary for authority 1',
64     }
65 )->store;
66 my $new_authority_1 = Koha::Authority->new( { authtypecode => $new_authority_type_1->authtypecode, marcxml => '' } )->store;
67 my $new_authority_2 = Koha::Authority->new( { authtypecode => $new_authority_type_1->authtypecode, marcxml => '' } )->store;
68
69 is( Koha::Authority::Types->search->count, $nb_of_authority_types + 1, 'The authority type should have been added' );
70 is( Koha::Authorities->search->count,      $nb_of_authorities + 2,     'The 2 authorities should have been added' );
71
72 $new_authority_1->delete;
73 is( Koha::Authorities->search->count, $nb_of_authorities + 1, 'Delete should have deleted the authority' );
74
75 subtest 'New merge request, method oldmarc' => sub {
76     plan tests => 4;
77
78     my $marc = MARC::Record->new;
79     $marc->append_fields(
80         MARC::Field->new( '100', '', '', a => 'a', b => 'b_findme' ),
81         MARC::Field->new( '200', '', '', a => 'aa' ),
82     );
83     my $req = Koha::Authority::MergeRequest->new({
84         authid => $new_authority_2->authid,
85         reportxml => 'Should be discarded',
86     });
87     is( $req->reportxml, undef, 'Reportxml is undef without oldrecord' );
88
89     $req = Koha::Authority::MergeRequest->new({
90         authid => $new_authority_2->authid,
91         oldrecord => $marc,
92     });
93     like( $req->reportxml, qr/b_findme/, 'Reportxml initialized' );
94
95     # Check if oldmarc is a MARC::Record and has one or two fields
96     is( ref( $req->oldmarc ), 'MARC::Record', 'Check oldmarc method' );
97     if( C4::Context->preference('marcflavour') eq 'UNIMARC' ) {
98         is( scalar $req->oldmarc->fields, 2, 'UNIMARC contains two fields' );
99     } else {
100         is( scalar $req->oldmarc->fields, 1, 'MARC21 contains one field' );
101     }
102 };
103
104 subtest 'Testing reporting_tag_xml in MergeRequest' => sub {
105     plan tests => 2;
106
107     my $record = MARC::Record->new;
108     $record->append_fields(
109         MARC::Field->new( '024', '', '', a => 'aaa' ),
110         MARC::Field->new( '110', '', '', a => 'Best author' ),
111         MARC::Field->new( '234', '', '', a => 'Just a field' ),
112     );
113     my $xml = Koha::Authority::MergeRequest->reporting_tag_xml({
114         record => $record, tag => '100',
115     });
116     is( $xml, undef, 'Expected no result for wrong tag' );
117     $xml = Koha::Authority::MergeRequest->reporting_tag_xml({
118         record => $record, tag => '110',
119     });
120     my $newrecord = MARC::Record->new_from_xml(
121         $xml, 'UTF-8',
122         C4::Context->preference('marcflavour') eq 'UNIMARC' ?
123         'UNIMARCAUTH' :
124         'MARC21',
125     );
126     cmp_deeply( $record->field('110')->subfields,
127         $newrecord->field('110')->subfields,
128         'Compare reporting tag in both records',
129     );
130 };
131
132 subtest 'Trivial tests for get_usage_count and linked_biblionumbers' => sub {
133     plan tests => 5;
134
135     # NOTE: We are not testing $searcher->simple_search_compat here. Suppose
136     # that should be done in t/db../Koha/SearchEngine?
137     # So we're just testing the 'wrapper' here.
138
139     my ( $mods, $koha_fields );
140     t::lib::Mocks::mock_preference('SearchEngine', 'Zebra');
141     $mods->{zebra} = Test::MockModule->new( 'Koha::SearchEngine::Zebra::Search' );
142     $mods->{elastic} = Test::MockModule->new( 'Koha::SearchEngine::Elasticsearch::Search' );
143     $mods->{biblio} = Test::MockModule->new( 'C4::Biblio' );
144     $mods->{zebra}->mock( 'simple_search_compat', \&simple_search_compat );
145     $mods->{elastic}->mock( 'simple_search_compat', \&simple_search_compat );
146     $mods->{biblio}->mock( 'GetMarcFromKohaField', sub { return @$koha_fields; });
147
148     my $auth1 = $builder->build({ source => 'AuthHeader' });
149     $auth1 = Koha::Authorities->find( $auth1->{authid} );
150
151     # Test error condition
152     my $count;
153     $search_compat_pars = [ 0, 'some_error' ];
154     warning_like { $count = $auth1->get_usage_count }
155         qr/some_error/, 'Catch warn of simple_search_compat';
156     is( $count, undef, 'Undef returned when error encountered' );
157
158     # Simple test with some results; one result discarded in the 2nd test
159     $search_compat_pars = [ 1 ];
160     $koha_fields = [ '001', '' ];
161     is(  $auth1->get_usage_count, 3, 'Three results expected (Zebra)' );
162     cmp_deeply( [ $auth1->linked_biblionumbers ], [ 1001, 3003 ],
163         'linked_biblionumbers should ignore record without biblionumber' );
164
165     # And a simple test with Elastic
166     t::lib::Mocks::mock_preference('SearchEngine', 'Elasticsearch');
167     cmp_deeply( [ $auth1->linked_biblionumbers ], [ 2001 ],
168         'linked_biblionumbers with Elasticsearch' );
169     t::lib::Mocks::mock_preference('SearchEngine', 'Zebra');
170 };
171
172 subtest 'Simple test for controlled_indicators' => sub {
173     plan tests => 4;
174
175     # NOTE: See more detailed tests in t/Koha/Authority/ControlledIndicators.t
176
177     # Mock pref so that authority indicators are swapped for marc21/unimarc
178     # The biblio tag is actually made irrelevant here
179     t::lib::Mocks::mock_preference('AuthorityControlledIndicators', q|marc21,*,ind1:auth2,ind2:auth1
180 unimarc,*,ind1:auth2,ind2:auth1|);
181     t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' );
182
183     my $record = MARC::Record->new;
184     $record->append_fields( MARC::Field->new( '100', '1', '2', a => 'Name' ) );
185     my $type = $builder->build({ source => 'AuthType', value => { auth_tag_to_report => '100'} });
186     my $authid = C4::AuthoritiesMarc::AddAuthority( $record, undef, $type->{authtypecode} );
187     my $auth = Koha::Authorities->find( $authid );
188     is( $auth->controlled_indicators({ biblio_tag => '123' })->{ind1}, '2', 'MARC21: Swapped ind2' );
189     is( $auth->controlled_indicators({ biblio_tag => '234' })->{ind2}, '1', 'MARC21: Swapped ind1' );
190
191     # try UNIMARC too
192     t::lib::Mocks::mock_preference( 'marcflavour', 'UNIMARC' );
193     $record = MARC::Record->new;
194     $record->append_fields( MARC::Field->new( '210', '1', '2', a => 'Name' ) );
195     $type = $builder->build({ source => 'AuthType', value => { auth_tag_to_report => '210'} });
196     $authid = C4::AuthoritiesMarc::AddAuthority( $record, undef, $type->{authtypecode} );
197     $auth = Koha::Authorities->find( $authid );
198     is( $auth->controlled_indicators({ biblio_tag => '345' })->{ind1}, '2', 'UNIMARC: Swapped ind2' );
199     is( $auth->controlled_indicators({ biblio_tag => '456' })->{ind2}, '1', 'UNIMARC: Swapped ind1' );
200 };
201
202 sub simple_search_compat {
203     if( $search_compat_pars->[0] == 0 ) {
204         return ( $search_compat_pars->[1], [], 0 );
205     } elsif( $search_compat_pars->[0] == 1 ) {
206         my $records = C4::Context->preference('SearchEngine') eq 'Zebra'
207             ? few_marcxml_records()
208             : few_marc_records();
209         return ( undef, $records, scalar @$records );
210     }
211 }
212
213 sub few_marcxml_records {
214     return [
215 q|<?xml version="1.0" encoding="UTF-8"?>
216 <record xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.loc.gov/MARC21/slim" xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd">
217     <controlfield tag="001">1001</controlfield>
218     <datafield tag="110" ind1=" " ind2=" ">
219         <subfield code="9">102</subfield>
220         <subfield code="a">My Corporation</subfield>
221     </datafield>
222 </record>|,
223 q|<?xml version="1.0" encoding="UTF-8"?>
224 <record xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.loc.gov/MARC21/slim" xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd">
225     <!-- No biblionumber here -->
226     <datafield tag="610" ind1=" " ind2=" ">
227         <subfield code="9">112</subfield>
228         <subfield code="a">Another Corporation</subfield>
229     </datafield>
230 </record>|,
231 q|<?xml version="1.0" encoding="UTF-8"?>
232 <record xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.loc.gov/MARC21/slim" xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd">
233     <controlfield tag="001">3003</controlfield>
234     <datafield tag="110" ind1=" " ind2=" ">
235         <subfield code="9">102</subfield>
236         <subfield code="a">My Corporation</subfield>
237     </datafield>
238 </record>|
239     ];
240 }
241
242 sub few_marc_records {
243     my $marc = MARC::Record->new;
244     $marc->append_fields(
245         MARC::Field->new( '001', '2001' ),
246         MARC::Field->new( '245', '', '', a => 'Title' ),
247     );
248     return [ $marc ];
249 }
250
251 $schema->storage->txn_rollback;