Bug 30047: Unit tests
[koha.git] / t / db_dependent / AuthoritiesMarc.t
1 #!/usr/bin/perl
2 #
3 # This Koha test module is a stub!  
4 # Add more tests here!!!
5
6 use Modern::Perl;
7
8 use Test::More tests => 13;
9 use Test::MockModule;
10 use Test::Warn;
11 use MARC::Field;
12 use MARC::Record;
13
14 use t::lib::Mocks;
15 use t::lib::TestBuilder;
16 use Koha::Database;
17 use Koha::Authority::Types;
18
19 BEGIN {
20         use_ok('C4::AuthoritiesMarc', qw( GetHeaderAuthority AddAuthority AddAuthorityTrees GetAuthority BuildAuthHierarchies GenerateHierarchy BuildSummary DelAuthority CompareFieldWithAuthority ModAuthority merge ));
21 }
22
23 # We are now going to be testing the authorities hierarchy code, and
24 # therefore need to pretend that we have consistent data in our database
25 my $module = Test::MockModule->new('C4::AuthoritiesMarc');
26 $module->mock('GetHeaderAuthority', sub {
27     return {'authtrees' => ''};
28 });
29 $module->mock('AddAuthorityTrees', sub {
30     return;
31 });
32 $module->mock('GetAuthority', sub {
33     my ($authid) = @_;
34     my $record = MARC::Record->new();
35     if ($authid eq '1') {
36         $record->add_fields(
37             [ '001', '1' ],
38             [ '151', ' ', ' ', a => 'United States' ]
39             );
40     } elsif ($authid eq '2') {
41         $record->add_fields(
42             [ '001', '2' ],
43             [ '151', ' ', ' ', a => 'New York (State)' ],
44             [ '551', ' ', ' ', a => 'United States', w => 'g', 9 => '1' ]
45             );
46     } elsif ($authid eq '3') {
47         $record->add_fields(
48             [ '001', '3' ],
49             [ '151', ' ', ' ', a => 'New York (City)' ],
50             [ '551', ' ', ' ', a => 'New York (State)', w => 'g', 9 => '2' ]
51             );
52     } elsif ($authid eq '4') {
53         $record->add_fields(
54             [ '001', '4' ],
55             [ '151', ' ', ' ', a => 'New York (City)' ],
56             [ '551', ' ', ' ', a => 'New York (State)', w => 'g' ]
57             );
58     } elsif ($authid eq '5') {
59         $record->add_fields(
60             [ '001', '5' ],
61             [ '100', ' ', ' ', a => 'Lastname, Firstname', b => 'b', c => 'c', i => 'i' ]
62             );
63     } else {
64         undef $record;
65     }
66     return $record;
67 });
68
69 my $schema  = Koha::Database->new->schema;
70 $schema->storage->txn_begin;
71 my $dbh = C4::Context->dbh;
72 my $builder = t::lib::TestBuilder->new;
73
74 t::lib::Mocks::mock_preference('marcflavour', 'MARC21');
75
76 # Authority type GEOGR_NAME is hardcoded here
77 if( ! Koha::Authority::Types->find('GEOGR_NAME') ) {
78     $builder->build({ source => 'AuthType', value => { authtypecode => 'GEOGR_NAME' }});
79 };
80
81 is(BuildAuthHierarchies(3, 1), '1,2,3', "Built linked authtrees hierarchy string");
82
83 my $expectedhierarchy = [ [ {
84         'authid' => '1',
85         'value' => 'United States',
86         'class' => 'child0',
87         'children' => [ {
88             'authid' => '2',
89             'value' => 'New York (State)',
90             'class' => 'child1',
91             'children' => [ {
92                 'authid' => '3',
93                 'current_value' => 1,
94                 'value' => 'New York (City)',
95                 'class' => 'child2',
96                 'children' => [],
97                 'parents' => [ {
98                     'authid' => '2',
99                     'value' => 'New York (State)'
100                 } ]
101             } ],
102             'parents' => [ {
103                 'authid' => '1',
104                 'value' => 'United States'
105             } ]
106         } ],
107         'parents' => []
108 } ] ];
109
110 is_deeply(GenerateHierarchy(3), $expectedhierarchy, "Generated hierarchy data structure for linked hierarchy");
111
112 is(BuildAuthHierarchies(4, 1), '4', "Built unlinked authtrees hierarchy string");
113 $expectedhierarchy = [ [ {
114     'authid' => '4',
115     'current_value' => 1,
116     'value' => 'New York (City)',
117     'class' => 'child0',
118     'children' => [],
119     'parents' => []
120 } ] ];
121 is_deeply(GenerateHierarchy(4), $expectedhierarchy, "Generated hierarchy data structure for unlinked hierarchy");
122
123 # set up auth_types for next tests
124 $dbh->do('DELETE FROM auth_types');
125 $dbh->do(q{
126     INSERT INTO auth_types (authtypecode, authtypetext, auth_tag_to_report, summary)
127     VALUES ('GEOGR_NAME', 'Geographic Name', '151', 'Geographic Name')
128 });
129
130 t::lib::Mocks::mock_preference('marcflavour', 'MARC21');
131 my $expected_marc21_summary = {
132     'authorized' => [
133         {
134             'field'   => '151',
135             'heading' => 'New York (State)',
136             'hemain'  => 'New York (State)'
137         }
138     ],
139     'authtypecode'  => 'GEOGR_NAME',
140     'mainentry'     => 'New York (State)',
141     'mainmainentry' => 'New York (State)',
142     'notes'         => [],
143     'otherscript'   => [],
144     'seealso'       => [
145         {
146             'authid'  => '1',
147             'field'   => '551',
148             'heading' => 'United States',
149             'hemain'  => 'United States',
150             'search'  => 'United States',
151             'type'    => 'broader'
152         }
153     ],
154     'seefrom'   => [],
155     'label'     => 'Geographic Name',
156     'type'      => 'Geographic Name',
157     'equalterm' => []
158 };
159
160 is_deeply(
161     BuildSummary(C4::AuthoritiesMarc::GetAuthority(2), 2, 'GEOGR_NAME'),
162     $expected_marc21_summary,
163     'test BuildSummary for MARC21'
164 );
165
166 my $marc21_subdiv = MARC::Record->new();
167 $marc21_subdiv->add_fields(
168     [ '181', ' ', ' ', x => 'Political aspects' ]
169 );
170 warning_is { BuildSummary($marc21_subdiv, 99999, 'GEN_SUBDIV') } [],
171     'BuildSummary does not generate warning if main heading subfield not present';
172
173 t::lib::Mocks::mock_preference('marcflavour', 'UNIMARC');
174 $dbh->do(q{
175     INSERT INTO auth_types (authtypecode, authtypetext, auth_tag_to_report, summary)
176     VALUES ('NP', 'Auteur', '200', '[200a][, 200b][ 200d][ ; 200c][ (200f)]')
177 });
178 $dbh->do(
179     q{
180     INSERT INTO marc_subfield_structure (frameworkcode,authtypecode,tagfield)
181     VALUES ('','NP','200')
182 }
183 );
184
185 my $unimarc_name_auth = MARC::Record->new();
186 $unimarc_name_auth->add_fields(
187     ['100', ' ', ' ',  a => '20121025              frey50       '],
188     ['200', ' ', ' ',  a => 'Fossey', b => 'Brigitte' ],
189     ['152', ' ', ' ',  a => 'NP'],
190 );
191 my $expected_unimarc_name_summary = {
192     'authorized' => [
193         {
194             'field'   => '200',
195             'heading' => 'Fossey Brigitte',
196             'hemain'  => 'Fossey'
197         }
198     ],
199     'authtypecode'  => 'NP',
200     'mainentry'     => 'Fossey Brigitte',
201     'mainmainentry' => 'Fossey',
202     'notes'         => [],
203     'otherscript'   => [],
204     'seealso'       => [],
205     'seefrom'       => [],
206     'summary'       => 'Fossey, Brigitte',
207     'type'          => 'Auteur',
208     'equalterm'     => []
209 };
210
211 is_deeply(
212     BuildSummary($unimarc_name_auth, 99999, 'NP'),
213     $expected_unimarc_name_summary,
214     'test BuildSummary for UNIMARC'
215 );
216
217 subtest 'AddAuthority should respect AUTO_INCREMENT (BZ 18104)' => sub {
218     plan tests => 3;
219
220     t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' );
221     my $record = MARC::Record->new();
222     my $field  = MARC::Field->new( '151', ' ', ' ', a => 'Amsterdam (Netherlands)', 'x' => 'Economic conditions' );
223     $record->append_fields($field);
224     my $id1 = AddAuthority( $record, undef, 'GEOGR_NAME' );
225     DelAuthority( { authid => $id1 } );
226     $record = MARC::Record->new();
227     $record->append_fields($field);
228     my $id2 = AddAuthority( $record, undef, 'GEOGR_NAME' );
229     isnt( $id1, $id2, 'Do not return the same id again' );
230     t::lib::Mocks::mock_preference( 'marcflavour', 'UNIMARC' );
231     $record = MARC::Record->new();
232     $field  = MARC::Field->new( '200', ' ', ' ', a => 'Fossey', 'b' => 'Brigitte' );
233     $record->append_fields($field);
234     my $id3 = AddAuthority( $record, undef, 'NP' );
235     ok( $id3 > 0, 'Tested AddAuthority with UNIMARC' );
236     is( $record->field('001')->data, $id3, 'Check updated 001' );
237 };
238
239 subtest 'AddAuthority should create heading field with display form' => sub {
240     plan tests => 2;
241
242     t::lib::Mocks::mock_preference( 'marcflavour',    'MARC21' );
243     t::lib::Mocks::mock_preference( 'AuthoritiesLog', 0 );
244     my $record = MARC::Record->new();
245     my $field  = MARC::Field->new( '151', ' ', ' ', a => 'White River Junction (Vt.)' );
246     $record->append_fields($field);
247     my $id        = AddAuthority( $record, undef, 'GEOGR_NAME' );
248     my $authority = Koha::Authorities->find($id);
249     is(
250         $authority->heading, 'White River Junction (Vt.)',
251         'Heading field is formed as expected when adding authority'
252     );
253     $record = MARC::Record->new();
254     $field  = MARC::Field->new( '151', ' ', ' ', a => 'Lyon (France)', 'x' => 'Antiquities' );
255     $record->append_fields($field);
256     $id        = ModAuthority( $id, $record, 'GEOGR_NAME' );
257     $authority = Koha::Authorities->find($id);
258     is(
259         $authority->heading, 'Lyon (France)--Antiquities',
260         'Heading field is formed as expected when modding authority'
261     );
262
263 };
264
265 subtest 'CompareFieldWithAuthority tests' => sub {
266     plan tests => 3;
267
268     t::lib::Mocks::mock_preference('marcflavour', 'MARC21');
269
270     $builder->build({ source => 'AuthType', value => { authtypecode => 'PERSO_NAME' }});
271
272     my $field = MARC::Field->new('100', 0, 0, a => 'Lastname, Firstname', b => 'b', c => 'c');
273
274     ok(C4::AuthoritiesMarc::CompareFieldWithAuthority({'field' => $field, 'authid' => 5}), 'Authority matches');
275
276     $field->add_subfields(i => 'X');
277
278     ok(C4::AuthoritiesMarc::CompareFieldWithAuthority({'field' => $field, 'authid' => 5}), 'Compare ignores unlisted subfields');
279
280     $field->add_subfields(d => 'd');
281
282     ok(!C4::AuthoritiesMarc::CompareFieldWithAuthority({'field' => $field, 'authid' => 5}), 'Authority does not match');
283 };
284
285 $schema->storage->txn_rollback;
286
287 $module->unmock('GetAuthority');
288
289 subtest 'ModAuthority() tests' => sub {
290
291     plan tests => 2;
292
293     $schema->storage->txn_begin;
294
295     my $auth_type = 'GEOGR_NAME';
296     my $record  = MARC::Record->new;
297     $record->add_fields(
298             [ '001', '1' ],
299             [ '151', ' ', ' ', a => 'United States' ]
300             );
301 ;
302     my $auth_id = AddAuthority( $record, undef, $auth_type );
303
304     my $mocked_authorities_marc = Test::MockModule->new('C4::AuthoritiesMarc');
305     $mocked_authorities_marc->mock( 'merge', sub { warn 'merge called'; } );
306
307     warning_is
308         { ModAuthority( $auth_id, $record, $auth_type ); }
309         'merge called',
310         'No param, merge called';
311
312     warning_is
313         { ModAuthority( $auth_id, $record, $auth_type, { skip_merge => 1 } ); }
314         undef,
315         'skip_merge passed, merge not called';
316
317     $schema->storage->txn_rollback;
318 };
319
320 subtest 'DelAuthority() tests' => sub {
321
322     plan tests => 2;
323
324     $schema->storage->txn_begin;
325
326     my $auth_type = 'GEOGR_NAME';
327     my $record  = MARC::Record->new;
328     $record->add_fields(
329             [ '001', '1' ],
330             [ '151', ' ', ' ', a => 'United States' ]
331             );
332 ;
333     my $auth_id = AddAuthority( $record, undef, $auth_type );
334
335     my $mocked_authorities_marc = Test::MockModule->new('C4::AuthoritiesMarc');
336     $mocked_authorities_marc->mock( 'merge', sub { warn 'merge called'; } );
337
338     warning_is
339         { DelAuthority({ authid => $auth_id }); }
340         'merge called',
341         'No param, merge called';
342
343     $auth_id = AddAuthority( $record, undef, $auth_type );
344
345     warning_is
346         { DelAuthority({ authid => $auth_id, skip_merge => 1 }); }
347         undef,
348         'skip_merge passed, merge not called';
349
350     $schema->storage->txn_rollback;
351 };