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