Bug 29562: Adjust CanItemBeReserved and checkHighHolds to take objects
[koha.git] / t / db_dependent / Biblio / MarcOverlayRules.t
1 #!/usr/bin/perl
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18 use Modern::Perl;
19 use Try::Tiny;
20 use POSIX qw(floor);
21
22 use MARC::Record;
23
24 use C4::Context;
25 use C4::Biblio qw( AddBiblio ModBiblio DelBiblio GetMarcBiblio );
26 use Koha::Database;
27
28 use Test::More tests => 24;
29 use Test::MockModule;
30
31 use Koha::MarcOverlayRules;
32
33 use t::lib::Mocks;
34
35 my $schema = Koha::Database->schema;
36 $schema->storage->txn_begin;
37
38 t::lib::Mocks::mock_preference('MARCOverlayRules', '1');
39
40 Koha::MarcOverlayRules->search->delete;
41
42 sub build_record {
43     my ( $fields ) = @_;
44     my $record = MARC::Record->new;
45     my @marc_fields;
46     for my $f ( @$fields ) {
47         my $tag = $f->[0];
48         my @subfields;
49         for my $i ( 1 .. (scalar(@$f) / 2) ) {
50             my $ii = floor($i*2);
51             push @subfields, $f->[$ii - 1], $f->[$ii];
52         }
53         push @marc_fields, MARC::Field->new($tag, '','', @subfields);
54     }
55
56     $record->append_fields(@marc_fields);
57     return $record;
58 }
59
60
61 # Create a record
62 my $orig_record = build_record([
63     [ '250', 'a', '250 bottles of beer on the wall' ],
64     [ '250', 'a', '256 bottles of beer on the wall' ],
65     [ '500', 'a', 'One bottle of beer in the fridge' ],
66 ]
67 );
68
69 my $incoming_record = build_record(
70     [
71     ['250', 'a', '256 bottles of beer on the wall'], # Unchanged
72     ['250', 'a', '251 bottles of beer on the wall'], # Appended
73     #['250', 'a', '250 bottles of beer on the wall'], # Removed
74     #['500', 'a', 'One bottle of beer in the fridge'], # Deleted
75     ['501', 'a', 'One cold bottle of beer in the fridge'], # Added
76     ['501', 'a', 'Two cold bottles of beer in the fridge'], # Added
77 ]
78 );
79
80 # Test default behavior when MARCOverlayRules is enabled, but no rules defined (overwrite)
81 subtest 'No rule defined' => sub {
82     plan tests => 1;
83
84     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
85
86     is(
87         $merged_record->as_formatted,
88         $incoming_record->as_formatted,
89         'Incoming record used as it with no rules defined'
90     );
91
92 };
93
94 my $rule =  Koha::MarcOverlayRules->find_or_create({
95     tag => '*',
96     module => 'source',
97     filter => '*',
98     add => 0,
99     append => 0,
100     remove => 0,
101     delete => 0
102 });
103
104 subtest 'Record fields has been protected when matched merge all rule operations are set to "0"' => sub {
105     plan tests => 1;
106
107     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
108
109     is(
110         $merged_record->as_formatted,
111         $orig_record->as_formatted,
112         'Record not modified if all op=0'
113     );
114
115 };
116
117 subtest '"Add new" - Only new fields has been added when add = 1, append = 0, remove = 0, delete = 0' => sub {
118     plan tests => 1;
119
120     $rule->set(
121         {
122             'add' => 1,
123             'append' => 0,
124             'remove' => 0,
125             'delete' => 0,
126         }
127     )->store();
128
129     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
130
131     my $expected_record = build_record([
132             [ '250', 'a', '250 bottles of beer on the wall' ],        # original
133             [ '250', 'a', '256 bottles of beer on the wall' ],        # original
134             [ '500', 'a', 'One bottle of beer in the fridge' ],       # original
135             [ '501', 'a', 'One cold bottle of beer in the fridge' ],  # incoming
136             [ '501', 'a', 'Two cold bottles of beer in the fridge' ], # incoming
137     ]);
138     is(
139         $merged_record->as_formatted,
140         $expected_record->as_formatted,
141         'Add fields from the incoming record that are not in the original record'
142     );
143
144 };
145
146 subtest 'Only appended fields has been added when add = 0, append = 1, remove = 0, delete = 0' => sub {
147     plan tests => 1;
148
149     $rule->set(
150         {
151             'add' => 0,
152             'append' => 1,
153             'remove' => 0,
154             'delete' => 0,
155         }
156     )->store;
157
158     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
159
160     my $expected_record = build_record([
161             [ '250', 'a', '250 bottles of beer on the wall' ],        # original
162             [ '250', 'a', '256 bottles of beer on the wall' ],        # original
163             # "251" field has been appended
164             [ '250', 'a', '251 bottles of beer on the wall' ],        # incoming
165             # "500" field has retained its original value
166             [ '500', 'a', 'One bottle of beer in the fridge' ],       # original
167     ]);
168
169     is(
170         $merged_record->as_formatted,
171         $expected_record->as_formatted,
172         'Add fields from the incoming record that are in the original record'
173     );
174
175 };
176
177 subtest '"Add and append" - add = 1, append = 1, remove = 0, delete = 0' => sub {
178     plan tests => 1;
179
180     $rule->set(
181         {
182             'add' => 1,
183             'append' => 1,
184             'remove' => 0,
185             'delete' => 0,
186         }
187     )->store;
188
189     my $expected_record = build_record([
190             [ '250', 'a', '250 bottles of beer on the wall' ],        # original
191             [ '250', 'a', '256 bottles of beer on the wall' ],        # original
192             # "251" field has been appended
193             [ '250', 'a', '251 bottles of beer on the wall' ],        # incoming
194             # "500" field has retained its original value
195             [ '500', 'a', 'One bottle of beer in the fridge' ],       # original
196             # "501" fields have been added
197             [ '501', 'a', 'One cold bottle of beer in the fridge' ],  # incoming
198             [ '501', 'a', 'Two cold bottles of beer in the fridge' ], # incoming
199     ]);
200
201     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
202
203     is(
204         $merged_record->as_formatted,
205         $expected_record->as_formatted,
206         'Appended and added fields have been added'
207     );
208
209 };
210
211 subtest 'Record fields has been only removed when add = 0, append = 0, remove = 1, delete = 0' => sub {
212     plan tests => 1;
213
214     $rule->set(
215         {
216             'add' => 0,
217             'append' => 0,
218             'remove' => 1,
219             'delete' => 0,
220         }
221     )->store;
222
223     # Warning - not obvious as the 500 is untouched
224     my $expected_record = build_record([
225             # "250" field has been removed
226             [ '250', 'a', '256 bottles of beer on the wall' ],        # original and incoming
227             # "500" field has retained its original value
228             [ '500', 'a', 'One bottle of beer in the fridge' ],       # original
229     ]);
230
231     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
232
233     is(
234         $merged_record->as_formatted,
235         $expected_record->as_formatted,
236         'Fields not in the incoming record are removed'
237     );
238
239 };
240
241 subtest 'Record fields has been added and removed when add = 1, append = 0, remove = 1, delete = 0' => sub {
242     plan tests => 1;
243
244     $rule->set(
245         {
246             'add' => 1,
247             'append' => 0,
248             'remove' => 1,
249             'delete' => 0,
250         }
251     )->store();
252
253     my $expected_record = build_record([
254             # "250" field has been removed
255             [ '250', 'a', '256 bottles of beer on the wall' ],        # original and incoming
256             # "500" field has retained its original value
257             [ '500', 'a', 'One bottle of beer in the fridge' ],       # original
258             # "501" fields have been added
259             [ '501', 'a', 'One cold bottle of beer in the fridge' ],  # incoming
260             [ '501', 'a', 'Two cold bottles of beer in the fridge' ], # incoming
261     ]);
262
263     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
264
265     is(
266         $merged_record->as_formatted,
267         $expected_record->as_formatted,
268         'Fields not in the incoming record are removed, fields not in the original record have been added'
269     );
270
271 };
272
273 subtest 'Record fields has been appended and removed when add = 0, append = 1, remove = 1, delete = 0' => sub {
274     plan tests => 1;
275
276     $rule->set(
277         {
278             'add' => 0,
279             'append' => 1,
280             'remove' => 1,
281             'delete' => 0,
282         }
283     )->store();
284
285     my $expected_record = build_record([
286             # "250" field has been appended and removed
287             [ '250', 'a', '256 bottles of beer on the wall' ],        # incoming
288             [ '250', 'a', '251 bottles of beer on the wall' ],        # incoming
289             # "500" field has retained its original value
290             [ '500', 'a', 'One bottle of beer in the fridge' ],       # original
291     ]);
292
293     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
294
295     is(
296         $merged_record->as_formatted,
297         $expected_record->as_formatted,
298         'Fields in the incoming record replace fields from the original record, fields only in the original record has been kept, fields not in the original record have been skipped'
299     );
300
301 };
302
303 subtest 'Record fields has been added, appended and removed when add = 0, append = 1, remove = 1, delete = 0' => sub {
304     plan tests => 1;
305
306     $rule->set(
307         {
308             'add' => 1,
309             'append' => 1,
310             'remove' => 1,
311             'delete' => 0,
312         }
313     )->store();
314
315     my $expected_record = build_record([
316             # "250" field has been appended and removed
317             [ '250', 'a', '256 bottles of beer on the wall' ],        # incoming
318             [ '250', 'a', '251 bottles of beer on the wall' ],        # incoming
319             # "500" field has retained its original value
320             [ '500', 'a', 'One bottle of beer in the fridge' ],       # original
321             # "501" fields have been added
322             [ '501', 'a', 'One cold bottle of beer in the fridge' ],  # incoming
323             [ '501', 'a', 'Two cold bottles of beer in the fridge' ], # incoming
324     ]);
325
326     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
327
328     is(
329         $merged_record->as_formatted,
330         $expected_record->as_formatted,
331         'Fields in the incoming record replace fields from the original record, fields only in the original record has been kept, fields not in the original record have been added'
332     );
333
334 };
335
336 subtest 'Record fields has been deleted when add = 0, append = 0, remove = 0, delete = 1' => sub {
337     plan tests => 1;
338
339     $rule->set(
340         {
341             'add' => 0,
342             'append' => 0,
343             'remove' => 0,
344             'delete' => 1,
345         }
346     )->store();
347
348     # FIXME the tooltip for delete is saying
349     # "If the original record has fields matching the rule tag, but no fields with this are found in the incoming record"
350     # But it does not seem to do that
351     my $expected_record = build_record([
352             # "250" fields have retained their original value
353             [ '250', 'a', '250 bottles of beer on the wall' ],        # original
354             [ '250', 'a', '256 bottles of beer on the wall' ],        # original
355     ]);
356
357     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
358
359     is(
360         $merged_record->as_formatted,
361         $expected_record->as_formatted,
362         'Only fields in original and incoming are kept, but incoming values are ignored'
363     );
364
365 };
366
367 subtest 'Record fields has been added and deleted when add = 1, append = 0, remove = 0, delete = 1' => sub {
368     plan tests => 1;
369
370     $rule->set(
371         {
372             'add' => 1,
373             'append' => 0,
374             'remove' => 0,
375             'delete' => 1,
376         }
377     )->store();
378
379     # Warning - is there a use case in real-life for this combinaison?
380     my $expected_record = build_record([
381             # "250" field have retained their original value
382             [ '250', 'a', '250 bottles of beer on the wall' ],        # original
383             [ '250', 'a', '256 bottles of beer on the wall' ],        # original
384             # "500" field has been removed
385             # "501" fields have been added
386             [ '501', 'a', 'One cold bottle of beer in the fridge' ],  # incoming
387             [ '501', 'a', 'Two cold bottles of beer in the fridge' ], # incoming
388     ]);
389
390     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
391
392     is(
393         $merged_record->as_formatted,
394         $expected_record->as_formatted,
395         'Fields from the incoming records are kept, but keep the value from the original record if they already existed'
396     );
397
398 };
399
400 subtest 'Record fields has been appended and deleted when add = 0, append = 1, remove = 0, delete = 1' => sub {
401     plan tests => 1;
402
403     $rule->set(
404         {
405             'add' => 0,
406             'append' => 1,
407             'remove' => 0,
408             'delete' => 1,
409         }
410     )->store();
411
412     my $expected_record = build_record([
413             # "250" field has been appended
414             [ '250', 'a', '250 bottles of beer on the wall' ],        # original
415             [ '250', 'a', '256 bottles of beer on the wall' ],        # original and incoming
416             [ '250', 'a', '251 bottles of beer on the wall' ],        # incoming
417             # "500" field has been removed
418     ]);
419
420     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
421
422     is(
423         $merged_record->as_formatted,
424         $expected_record->as_formatted,
425         'Only fields that already existed are appended'
426     );
427
428 };
429
430 subtest 'Record fields has been added, appended and deleted when add = 1, append = 1, remove = 0, delete = 1' => sub {
431     plan tests => 1;
432
433     $rule->set(
434         {
435             'add' => 1,
436             'append' => 1,
437             'remove' => 0,
438             'delete' => 1,
439         }
440     )->store();
441
442     my $expected_record = build_record([
443             # "250" field has been appended
444             [ '250', 'a', '250 bottles of beer on the wall' ],        # original
445             [ '250', 'a', '256 bottles of beer on the wall' ],        # original and incoming
446             [ '250', 'a', '251 bottles of beer on the wall' ],        # incoming
447             # "500" field has been removed
448             # "501" fields have been added
449             [ '501', 'a', 'One cold bottle of beer in the fridge' ],  # incoming
450             [ '501', 'a', 'Two cold bottles of beer in the fridge' ], # incoming
451     ]);
452
453     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
454
455     is(
456         $merged_record->as_formatted,
457         $expected_record->as_formatted,
458         'Fields in the incoming record are added and appended, fields not in the original record are removed'
459     );
460
461 };
462
463 subtest 'Record fields has been removed and deleted when add = 0, append = 0, remove = 1, delete = 1' => sub {
464     plan tests => 1;
465
466     $rule->set(
467         {
468             'add' => 0,
469             'append' => 0,
470             'remove' => 1,
471             'delete' => 1,
472         }
473     )->store();
474
475     my $expected_record = build_record([
476             # "250" field has been removed
477             [ '250', 'a', '256 bottles of beer on the wall' ],        # original and incoming
478             # "500" field has been removed
479     ]);
480
481     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
482
483     is(
484         $merged_record->as_formatted,
485         $expected_record->as_formatted,
486         'Union'
487     );
488
489 };
490
491 subtest 'Record fields has been added, removed and deleted when add = 1, append = 0, remove = 1, delete = 1' => sub {
492     plan tests => 1;
493
494     $rule->set(
495         {
496             'add' => 1,
497             'append' => 0,
498             'remove' => 1,
499             'delete' => 1,
500         }
501     )->store();
502
503     my $expected_record = build_record([
504             # "250" field has been appended
505             [ '250', 'a', '256 bottles of beer on the wall' ],        # original and incoming
506             # "500" field has been removed
507             # "501" fields have been added
508             [ '501', 'a', 'One cold bottle of beer in the fridge' ],  # incoming
509             [ '501', 'a', 'Two cold bottles of beer in the fridge' ], # incoming
510     ]);
511
512     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
513
514     is(
515         $merged_record->as_formatted,
516         $expected_record->as_formatted,
517         'Union for existing fields, new fields are added'
518     );
519
520 };
521
522 subtest 'Record fields has been appended, removed and deleted when add = 0, append = 1, remove = 1, delete = 1' => sub {
523     plan tests => 1;
524
525     $rule->set(
526         {
527             'add' => 0,
528             'append' => 1,
529             'remove' => 1,
530             'delete' => 1,
531         }
532     )->store();
533
534     my $expected_record = build_record([
535             # "250" field has been appended and removed
536             [ '250', 'a', '256 bottles of beer on the wall' ],        # incoming
537             [ '250', 'a', '251 bottles of beer on the wall' ],        # incoming
538             # "500" field has been removed
539     ]);
540
541     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
542
543     is(
544         $merged_record->as_formatted,
545         $expected_record->as_formatted,
546         'Fields from incoming replace original record. Existing fields not in incoming are removed'
547     );
548
549 };
550
551 subtest 'Record fields has been overwritten when add = 1, append = 1, remove = 1, delete = 1' => sub {
552     plan tests => 1;
553
554     $rule->set(
555         {
556             'add' => 1,
557             'append' => 1,
558             'remove' => 1,
559             'delete' => 1,
560         }
561     )->store();
562
563     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
564
565     is(
566         $merged_record->as_formatted,
567         $incoming_record->as_formatted,
568         'Incoming record erase original record'
569     );
570
571 };
572
573 subtest 'subfields order' => sub {
574     plan tests => 2;
575
576     $rule->set(
577         {
578             'add' => 0,
579             'append' => 0,
580             'remove' => 0,
581             'delete' => 0,
582         }
583     )->store();
584
585     my $incoming_record = build_record(
586         [
587             [ '250', 'a', '256 bottles of beer on the wall' ],
588             [ '250', 'a', '250 bottles of beer on the wall' ],
589             [ '500', 'a', 'One bottle of beer in the fridge' ],
590         ]
591     );
592
593     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
594
595     is(
596         $merged_record->as_formatted,
597         $orig_record->as_formatted,
598         'Original record not modified - order of subfields not modified'
599     );
600
601     $rule->set(
602         {
603             'add' => 1,
604             'append' => 1,
605             'remove' => 1,
606             'delete' => 1,
607         }
608     )->store();
609
610     $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
611
612     is(
613         $merged_record->as_formatted,
614         $incoming_record->as_formatted,
615         'Original record modified - order of subfields has been modified'
616     );
617
618 };
619
620 # Test rule tag specificity
621
622 # Protect field 500 with more specific tag value
623 my $skip_all_rule = Koha::MarcOverlayRules->find_or_create({
624     tag => '500',
625     module => 'source',
626     filter => '*',
627     add => 0,
628     append => 0,
629     remove => 0,
630     delete => 0
631 });
632
633 subtest '"500" field has been protected when rule matching on tag "500" is add = 0, append = 0, remove = 0, delete = 0' => sub {
634     plan tests => 1;
635
636     my $expected_record = build_record([
637             # "250" field has been appended
638             [ '250', 'a', '256 bottles of beer on the wall' ],        # incoming
639             [ '250', 'a', '251 bottles of beer on the wall' ],        # incoming
640             # "500" field has retained its original value
641             [ '500', 'a', 'One bottle of beer in the fridge' ],       # original
642             # "501" fields have been added
643             [ '501', 'a', 'One cold bottle of beer in the fridge' ],  # incoming
644             [ '501', 'a', 'Two cold bottles of beer in the fridge' ], # incoming
645     ]);
646
647     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
648
649     is(
650         $merged_record->as_formatted,
651         $expected_record->as_formatted,
652         'All fields are erased by incoming record but 500 is protected'
653     );
654
655 };
656
657 # Test regexp matching
658 subtest '"5XX" fields has been protected when rule matching on regexp "5\d{2}" is add = 0, append = 0, remove = 0, delete = 0' => sub {
659     plan tests => 1;
660
661     $skip_all_rule->set(
662         {
663             'tag' => '5\d{2}',
664         }
665     )->store;
666
667     my $expected_record = build_record([
668             # "250" field has been appended
669             [ '250', 'a', '256 bottles of beer on the wall' ],        # incoming
670             [ '250', 'a', '251 bottles of beer on the wall' ],        # incoming
671             # "500" field has retained its original value
672             [ '500', 'a', 'One bottle of beer in the fridge' ],       # original
673     ]);
674
675     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
676
677     is(
678         $merged_record->as_formatted,
679         $expected_record->as_formatted,
680         'Fields are erased by incoming record but 500 is protected and 501 is not added'
681     );
682
683 };
684
685 $skip_all_rule->delete();
686
687 # Test module specificity, the 0 all rule should no longer be included in set of applied rules
688 subtest 'Record fields has been overwritten when non wild card rule with filter match is add = 1, append = 1, remove = 1, delete = 1' => sub {
689     plan tests => 1;
690
691     $rule->set(
692         {
693             'filter' => 'test',
694         }
695     )->store();
696
697     my $merged_record = Koha::MarcOverlayRules->merge_records($orig_record, $incoming_record, { 'source' => 'test' });
698
699     is(
700         $merged_record->as_formatted,
701         $incoming_record->as_formatted,
702         'Only existing rule is not for us, erasing' # FIXME Is this comment correct?
703     );
704
705 };
706
707 subtest 'An exception is thrown when append = 1, remove = 0 is set for control field rule' => sub {
708     plan tests => 2;
709     my $exception = try {
710         Koha::MarcOverlayRules->validate({
711             'tag' => '008',
712             'append' => 1,
713             'remove' => 0,
714         });
715     }
716     catch {
717         return $_;
718     };
719     ok(defined $exception, "Exception was caught");
720     ok($exception->isa('Koha::Exceptions::MarcOverlayRule::InvalidControlFieldActions'), "Exception is of correct class");
721 };
722
723 subtest 'An exception is thrown when rule tag is set to invalid regexp' => sub {
724     plan tests => 2;
725
726     my $exception = try {
727         Koha::MarcOverlayRules->validate({
728             'tag' => '**'
729         });
730     }
731     catch {
732         return $_;
733     };
734     ok(defined $exception, "Exception was caught");
735     ok($exception->isa('Koha::Exceptions::MarcOverlayRule::InvalidTagRegExp'), "Exception is of correct class");
736 };
737
738
739 subtest 'context option in ModBiblio is handled correctly' => sub {
740     plan tests => 2;
741
742     $rule->set(
743         {
744             tag => '250',
745             module => 'source',
746             filter => '*',
747             'add' => 0,
748             'append' => 0,
749             'remove' => 0,
750             'delete' => 0,
751         }
752     )->store();
753
754     my ($biblionumber, $biblioitemnumber) = AddBiblio($orig_record, '');
755
756     # Since marc merc rules are not run on save, only update
757     # saved record should be identical to orig_record
758     my $saved_record = GetMarcBiblio({ biblionumber => $biblionumber });
759
760     my @all_fields = $saved_record->fields();
761     # Koha also adds 999c field, therefore 4 not 3
762
763     my $expected_record = build_record([
764             # "250" field has been appended
765             [ '250', 'a', '250 bottles of beer on the wall' ],        # original
766             [ '250', 'a', '256 bottles of beer on the wall' ],        # incoming
767             [ '500', 'a', 'One bottle of beer in the fridge' ],       # original
768             [ '999', 'c', $biblionumber, 'd', $biblioitemnumber ],    # created by AddBiblio
769     ]);
770
771     # Make sure leader is equal after AddBiblio
772     $expected_record->leader($saved_record->leader());
773
774     is(
775         $saved_record->as_formatted,
776         $expected_record->as_formatted,
777     );
778
779     $saved_record->append_fields(
780         MARC::Field->new('250', '', '', 'a' => '251 bottles of beer on the wall'), # Appended
781         MARC::Field->new('500', '', '', 'a' => 'One cold bottle of beer in the fridge'), # Appended
782     );
783
784     ModBiblio($saved_record, $biblionumber, '', { overlay_context => { 'source' => 'test' } });
785
786     my $updated_record = GetMarcBiblio({ biblionumber => $biblionumber });
787
788     $expected_record = build_record([
789             # "250" field has been appended
790             [ '250', 'a', '250 bottles of beer on the wall' ],
791             [ '250', 'a', '256 bottles of beer on the wall' ],
792             [ '500', 'a', 'One bottle of beer in the fridge' ],
793             [ '500', 'a', 'One cold bottle of beer in the fridge' ],
794             [ '999', 'c', $biblionumber, 'd', $biblioitemnumber ],    # created by AddBiblio
795     ]);
796
797     # Make sure leader is equal after ModBiblio
798     $expected_record->leader($updated_record->leader());
799
800     is(
801         $updated_record->as_formatted,
802         $expected_record->as_formatted,
803     );
804
805     # To trigger removal from search index etc
806     DelBiblio($biblionumber);
807 };
808
809 # Explicityly delete rule to trigger clearing of cache
810 $rule->delete();
811
812 $schema->storage->txn_rollback;