Bug 11319: Add UT for the fields management
[koha.git] / t / SimpleMARC.t
1 use Modern::Perl;
2
3 use Test::More tests => 9;
4
5 use_ok("MARC::Field");
6 use_ok("MARC::Record");
7 use_ok("Koha::SimpleMARC");
8
9 sub new_record {
10     my $record = MARC::Record->new;
11     $record->leader('03174nam a2200445 a 4500');
12     my @fields = (
13         MARC::Field->new(
14             100, '1', ' ',
15             a => 'Knuth, Donald Ervin',
16             d => '1938',
17         ),
18         MARC::Field->new(
19             245, '1', '4',
20             a => 'The art of computer programming',
21             c => 'Donald E. Knuth.',
22         ),
23         MARC::Field->new(
24             650, ' ', '0',
25             a => 'Computer programming.',
26             9 => '462',
27         ),
28         MARC::Field->new(
29             952, ' ', ' ',
30             p => '3010023917',
31             y => 'BK',
32             c => 'GEN',
33             d => '2001-06-25',
34         ),
35     );
36     $record->append_fields(@fields);
37     return $record;
38 }
39
40 # field_exists
41 subtest 'field_exists' => sub {
42     plan tests => 3;
43     my $record = new_record;
44     is(
45         field_exists( { record => $record, field => '650', subfield => 'a' } ),
46         'Computer programming.',
47         '650$a exists'
48     );
49     is(
50         field_exists( { record => $record, field => '650', subfield => 'b' } ),
51         undef,
52         '650$b does not exist'
53     );
54
55     $record->append_fields(
56         MARC::Field->new(
57             650, ' ', '0',
58             a => 'Computer algorithms.',
59             9 => '463',
60         )
61     );
62
63     is(
64         field_exists( { record => $record, field => '650', subfield => 'a' } ),
65         'Computer programming.',
66         '650$a exists, field_exists returns the first one'
67     );
68 };
69
70 # read_field
71 subtest 'read_field' => sub {
72     plan tests              => 2;
73     subtest 'read subfield' => sub {
74         plan tests => 5;
75         my $record = new_record;
76         $record->append_fields(
77             MARC::Field->new(
78                 650, ' ', '0',
79                 a => 'Computer algorithms.',
80                 9 => '463',
81             )
82         );
83
84         my @fields_650a =
85           read_field( { record => $record, field => '650', subfield => 'a' } );
86         is( $fields_650a[0], 'Computer programming.', 'first 650$a' );
87         is( $fields_650a[1], 'Computer algorithms.',  'second 650$a' );
88         is(
89             read_field(
90                 {
91                     record   => $record,
92                     field    => '650',
93                     subfield => 'a',
94                     n        => 1
95                 }
96             ),
97             'Computer programming.',
98             'first 650$a bis'
99         );
100         is(
101             read_field(
102                 {
103                     record   => $record,
104                     field    => '650',
105                     subfield => 'a',
106                     n        => 2
107                 }
108             ),
109             'Computer algorithms.',
110             'second 650$a bis'
111         );
112         is(
113             read_field(
114                 {
115                     record   => $record,
116                     field    => '650',
117                     subfield => 'a',
118                     n        => 3
119                 }
120             ),
121             undef,
122             'There is no 3 650$a'
123         );
124     };
125     subtest 'read field' => sub {
126         plan tests => 4;
127         my $record = new_record;
128         $record->append_fields(
129             MARC::Field->new(
130                 650, ' ', '0',
131                 a => 'Computer algorithms.',
132                 9 => '463',
133             )
134         );
135         is_deeply(
136             [
137                 read_field(
138                     {
139                         record => $record,
140                         field  => '650'
141                     }
142                 )
143             ],
144             [ 'Computer programming.', '462', 'Computer algorithms.', '463' ],
145             'Get the all subfield values for field 650'
146         );
147         is_deeply(
148             [
149                 read_field(
150                     {
151                         record => $record,
152                         field  => '650',
153                         n      => 1
154                     }
155                 )
156             ],
157             [ 'Computer programming.', '462' ],
158             'Get the all subfield values for the first field 650'
159         );
160         is_deeply(
161             [ read_field( { record => $record, field => '650', n => 2 } ) ],
162             [ 'Computer algorithms.', '463' ],
163             'Get the all subfield values for the second field 650'
164         );
165         is_deeply(
166             [ read_field( { record => $record, field => '650', n => 3 } ) ],
167             [],
168 'Get the all subfield values for the third field 650 which does not exist'
169         );
170     };
171 };
172
173 # update_field
174 subtest 'update_field' => sub {
175     plan tests                => 1;
176     subtest 'update subfield' => sub {
177         plan tests => 5;
178         my $record = new_record;
179
180         update_field(
181             {
182                 record   => $record,
183                 field    => '952',
184                 subfield => 'p',
185                 values   => ['3010023918']
186             }
187         );
188         is_deeply(
189             read_field(
190                 { record => $record, field => '952', subfield => 'p' }
191             ),
192             '3010023918',
193             'update existing subfield 952$p'
194         );
195         delete_field( { record => $record, field => '952' } );
196         update_field(
197             {
198                 record   => $record,
199                 field    => '952',
200                 subfield => 'p',
201                 values   => ['3010023918']
202             }
203         );
204         update_field(
205             {
206                 record   => $record,
207                 field    => '952',
208                 subfield => 'y',
209                 values   => ['BK']
210             }
211         );
212         is_deeply(
213             read_field(
214                 { record => $record, field => '952', subfield => 'p' }
215             ),
216             '3010023918',
217             'create subfield 952$p'
218         );
219         is_deeply(
220             read_field(
221                 { record => $record, field => '952', subfield => 'y' }
222             ),
223             'BK',
224             'create subfield 952$k on existing 952 field'
225         );
226
227         $record->append_fields(
228             MARC::Field->new(
229                 952, ' ', ' ',
230                 p => '3010023917',
231                 y => 'BK',
232             ),
233         );
234         update_field(
235             {
236                 record   => $record,
237                 field    => '952',
238                 subfield => 'p',
239                 values   => ['3010023919']
240             }
241         );
242         my @fields_952p =
243           read_field( { record => $record, field => '952', subfield => 'p' } );
244         is_deeply(
245             \@fields_952p,
246             [ '3010023919', '3010023919' ],
247             'update all subfields 952$p with the same value'
248         );
249
250         update_field(
251             {
252                 record   => $record,
253                 field    => '952',
254                 subfield => 'p',
255                 values   => [ '3010023917', '3010023918' ]
256             }
257         );
258         @fields_952p =
259           read_field( { record => $record, field => '952', subfield => 'p' } );
260         is_deeply(
261             \@fields_952p,
262             [ '3010023917', '3010023918' ],
263             'update all subfields 952$p with the different values'
264         );
265     };
266 };
267
268 # copy_field - subfield
269 subtest 'copy_field' => sub {
270     plan tests              => 2;
271     subtest 'copy subfield' => sub {
272         plan tests => 15;
273         my $record = new_record;
274         $record->append_fields(
275             MARC::Field->new(
276                 650, ' ', '0',
277                 a => 'Computer algorithms.',
278                 9 => '463',
279             )
280         );
281         copy_field(
282             {
283                 record        => $record,
284                 from_field    => '245',
285                 from_subfield => 'a',
286                 to_field      => '246',
287                 to_subfield   => 'a'
288             }
289         );
290         is_deeply(
291             read_field(
292                 { record => $record, field => '245', subfield => 'a' }
293             ),
294             'The art of computer programming',
295             'After copy 245$a still exists'
296         );
297         is_deeply(
298             read_field(
299                 { record => $record, field => '246', subfield => 'a' }
300             ),
301             'The art of computer programming',
302             '246$a is a new field'
303         );
304         delete_field( { record => $record, field => '246' } );
305         is(
306             field_exists(
307                 { record => $record, field => '246', subfield => 'a' }
308             ),
309             undef,
310             '246$a does not exist anymore'
311         );
312
313         copy_field(
314             {
315                 record        => $record,
316                 from_field    => '650',
317                 from_subfield => 'a',
318                 to_field      => '651',
319                 to_subfield   => 'a'
320             }
321         );
322         my @fields_651a =
323           read_field( { record => $record, field => '651', subfield => 'a' } );
324         is_deeply(
325             \@fields_651a,
326             [ 'Computer programming.', 'Computer algorithms.' ],
327             'Copy multivalued field'
328         );
329         delete_field( { record => $record, field => '651' } );
330
331         copy_field(
332             {
333                 record        => $record,
334                 from_field    => '650',
335                 from_subfield => 'a',
336                 to_field      => '651',
337                 to_subfield   => 'a',
338                 n             => 1
339             }
340         );
341         is_deeply(
342             read_field(
343                 { record => $record, field => '651', subfield => 'a' }
344             ),
345             'Computer programming.',
346             'Copy first field 650$a'
347         );
348         delete_field( { record => $record, field => '652' } );
349
350         copy_field(
351             {
352                 record        => $record,
353                 from_field    => '650',
354                 from_subfield => 'a',
355                 to_field      => '651',
356                 to_subfield   => 'a',
357                 n             => 2
358             }
359         );
360         is_deeply(
361             read_field(
362                 { record => $record, field => '651', subfield => 'a' }
363             ),
364             'Computer algorithms.',
365             'Copy second field 650$a'
366         );
367         delete_field( { record => $record, field => '651' } );
368
369         copy_field(
370             {
371                 record        => $record,
372                 from_field    => '650',
373                 from_subfield => 'a',
374                 to_field      => '651',
375                 to_subfield   => 'a',
376                 regex => { search => 'Computer', replace => 'The art of' }
377             }
378         );
379         @fields_651a =
380           read_field( { record => $record, field => '651', subfield => 'a' } );
381         is_deeply(
382             \@fields_651a,
383             [ 'The art of programming.', 'The art of algorithms.' ],
384             'Copy field using regex'
385         );
386
387         copy_field(
388             {
389                 record        => $record,
390                 from_field    => '650',
391                 from_subfield => 'a',
392                 to_field      => '651',
393                 to_subfield   => 'a',
394                 regex => { search => 'Computer', replace => 'The mistake of' }
395             }
396         );
397         @fields_651a =
398           read_field( { record => $record, field => '651', subfield => 'a' } );
399         is_deeply(
400             \@fields_651a,
401             [ 'The mistake of programming.', 'The mistake of algorithms.' ],
402             'Copy fields using regex on existing fields'
403         );
404         delete_field( { record => $record, field => '651' } );
405
406         copy_field(
407             {
408                 record        => $record,
409                 from_field    => '650',
410                 from_subfield => 'a',
411                 to_field      => '651',
412                 to_subfield   => 'a',
413                 regex => { search => 'Computer', replace => 'The art of' }
414             }
415         );
416         @fields_651a =
417           read_field( { record => $record, field => '651', subfield => 'a' } );
418         is_deeply(
419             \@fields_651a,
420             [ 'The art of programming.', 'The art of algorithms.', ],
421             'Copy all fields using regex'
422         );
423         delete_field( { record => $record, field => '651' } );
424
425         copy_field(
426             {
427                 record        => $record,
428                 from_field    => '650',
429                 from_subfield => 'a',
430                 to_field      => '651',
431                 to_subfield   => 'a',
432                 regex => { search => 'Computer', replace => 'The art of' },
433                 n     => 1
434             }
435         );
436         @fields_651a =
437           read_field( { record => $record, field => '651', subfield => 'a' } );
438         is_deeply(
439             \@fields_651a,
440             [ 'The art of programming.', ],
441             'Copy first field using regex'
442         );
443         delete_field( { record => $record, field => '651' } );
444
445         # Copy with regex modifiers
446         $record = new_record;
447         $record->append_fields(
448             MARC::Field->new(
449                 650, ' ', '0',
450                 a => 'Computer algorithms.',
451                 9 => '463',
452             )
453         );
454         copy_field(
455             {
456                 record        => $record,
457                 from_field    => '650',
458                 from_subfield => 'a',
459                 to_field      => '652',
460                 to_subfield   => 'a',
461                 regex         => { search => 'o', replace => 'foo' }
462             }
463         );
464         my @fields_652a =
465           read_field( { record => $record, field => '652', subfield => 'a' } );
466         is_deeply(
467             \@fields_652a,
468             [ 'Cfoomputer programming.', 'Cfoomputer algorithms.' ],
469             'Copy field using regex'
470         );
471
472         copy_field(
473             {
474                 record        => $record,
475                 from_field    => '650',
476                 from_subfield => 'a',
477                 to_field      => '653',
478                 to_subfield   => 'a',
479                 regex => { search => 'o', replace => 'foo', modifiers => 'g' }
480             }
481         );
482         my @fields_653a =
483           read_field( { record => $record, field => '653', subfield => 'a' } );
484         is_deeply(
485             \@fields_653a,
486             [ 'Cfoomputer prfoogramming.', 'Cfoomputer algfoorithms.' ],
487             'Copy field using regex'
488         );
489
490         copy_field(
491             {
492                 record        => $record,
493                 from_field    => '650',
494                 from_subfield => 'a',
495                 to_field      => '654',
496                 to_subfield   => 'a',
497                 regex => { search => 'O', replace => 'foo', modifiers => 'i' }
498             }
499         );
500         my @fields_654a =
501           read_field( { record => $record, field => '654', subfield => 'a' } );
502         is_deeply(
503             \@fields_654a,
504             [ 'Cfoomputer programming.', 'Cfoomputer algorithms.' ],
505             'Copy field using regex'
506         );
507
508         copy_field(
509             {
510                 record        => $record,
511                 from_field    => '650',
512                 from_subfield => 'a',
513                 to_field      => '655',
514                 to_subfield   => 'a',
515                 regex => { search => 'O', replace => 'foo', modifiers => 'gi' }
516             }
517         );
518         my @fields_655a =
519           read_field( { record => $record, field => '655', subfield => 'a' } );
520         is_deeply(
521             \@fields_655a,
522             [ 'Cfoomputer prfoogramming.', 'Cfoomputer algfoorithms.' ],
523             'Copy field using regex'
524         );
525
526         $record->append_fields(
527             MARC::Field->new(
528                 952, ' ', ' ',
529                 p => '3010023917',
530                 y => 'BK',
531             ),
532         );
533
534         copy_field(
535             {
536                 record        => $record,
537                 from_field    => '952',
538                 from_subfield => 'd',
539                 to_field      => '952',
540                 to_subfield   => 'd'
541             }
542         );
543         my @fields_952d =
544           read_field( { record => $record, field => '952', subfield => 'd' } );
545         is_deeply(
546             \@fields_952d,
547             [ '2001-06-25', '2001-06-25' ],
548             'copy 952$d into others 952 field'
549         );
550     };
551
552     subtest 'copy field' => sub {
553         plan tests => 11;
554         my $record = new_record;
555         $record->append_fields(
556             MARC::Field->new(
557                 952, ' ', ' ',
558                 p => '3010023918',
559                 y => 'CD',
560             ),
561         );
562
563         #- copy all fields
564         copy_field(
565             { record => $record, from_field => '952', to_field => '953' } );
566         my @fields_952 = read_field( { record => $record, field => '952' } );
567         is_deeply(
568             [ read_field( { record => $record, field => '952', n => 1 } ) ],
569             [ '3010023917', 'BK', 'GEN', '2001-06-25' ],
570             "copy all: original first field still exists"
571         );
572         is_deeply(
573             [ read_field( { record => $record, field => '952', n => 2 } ) ],
574             [ '3010023918', 'CD' ],
575             "copy all: original second field still exists"
576         );
577         is_deeply(
578             [ read_field( { record => $record, field => '953', n => 1 } ) ],
579             [ '3010023917', 'BK', 'GEN', '2001-06-25' ],
580             "copy all: first original fields has been copied"
581         );
582         is_deeply(
583             [ read_field( { record => $record, field => '953', n => 2 } ) ],
584             [ '3010023918', 'CD' ],
585             "copy all: second original fields has been copied"
586         );
587
588         #- copy only the first field
589         copy_field(
590             {
591                 record     => $record,
592                 from_field => '953',
593                 to_field   => '954',
594                 n          => 1
595             }
596         );
597         is_deeply(
598             [ read_field( { record => $record, field => '953', n => 1 } ) ],
599             [ '3010023917', 'BK', 'GEN', '2001-06-25' ],
600             "copy first: first original fields has been copied"
601         );
602         is_deeply(
603             [ read_field( { record => $record, field => '953', n => 2 } ) ],
604             [ '3010023918', 'CD' ],
605             "copy first: second original fields has been copied"
606         );
607         is_deeply(
608             [ read_field( { record => $record, field => '954' } ) ],
609             [ '3010023917', 'BK', 'GEN', '2001-06-25' ],
610             "copy first: only first, first 953 has been copied"
611         );
612
613         $record = new_record;
614         $record->append_fields(
615             MARC::Field->new(
616                 952, ' ', ' ',
617                 p => '3010023918',
618                 y => 'CD',
619             ),
620         );
621
622         #- copy all fields and modify values using a regex
623         copy_field(
624             {
625                 record     => $record,
626                 from_field => '952',
627                 to_field   => '953',
628                 regex      => { search => '30100', replace => '42424' }
629             }
630         );
631         is_deeply(
632             [ read_field( { record => $record, field => '952', n => 1 } ) ],
633             [ '3010023917', 'BK', 'GEN', '2001-06-25' ],
634             "copy all with regex: original first field still exists"
635         );
636         is_deeply(
637             [ read_field( { record => $record, field => '952', n => 2 } ) ],
638             [ '3010023918', 'CD' ],
639             "copy all with regex: original second field still exists"
640         );
641         is_deeply(
642             [ read_field( { record => $record, field => '953', n => 1 } ) ],
643             [ '4242423917', 'BK', 'GEN', '2001-06-25' ],
644             "copy all wirh regex: first original fields has been copied"
645         );
646         is_deeply(
647             [ read_field( { record => $record, field => '953', n => 2 } ) ],
648             [ '4242423918', 'CD' ],
649             "copy all with regex: second original fields has been copied"
650         );
651     };
652 };
653
654 # move_field - subfields
655 subtest 'move_field' => sub {
656     plan tests              => 2;
657     subtest 'move subfield' => sub {
658         plan tests => 6;
659         my $record = new_record;
660         my ( @fields_952d, @fields_952c, @fields_954c, @fields_954p );
661         $record->append_fields(
662             MARC::Field->new(
663                 952, ' ', ' ',
664                 p => '3010023917',
665                 y => 'BK',
666             ),
667         );
668         move_field(
669             {
670                 record        => $record,
671                 from_field    => '952',
672                 from_subfield => 'c',
673                 to_field      => '954',
674                 to_subfield   => 'c'
675             }
676         );
677         @fields_952c =
678           read_field( { record => $record, field => '952', subfield => 'c' } );
679         @fields_954c =
680           read_field( { record => $record, field => '954', subfield => 'c' } );
681         is_deeply( \@fields_952c, [],      'The 952$c has moved' );
682         is_deeply( \@fields_954c, ['GEN'], 'Now 954$c exists' );
683
684         move_field(
685             {
686                 record        => $record,
687                 from_field    => '952',
688                 from_subfield => 'p',
689                 to_field      => '954',
690                 to_subfield   => 'p',
691                 n             => 1
692             }
693         );    # Move the first field
694         my @fields_952p =
695           read_field( { record => $record, field => '952', subfield => 'p' } );
696         @fields_954p =
697           read_field( { record => $record, field => '954', subfield => 'p' } );
698         is_deeply( \@fields_952p, ['3010023917'], 'One of 952$p has moved' );
699         is_deeply( \@fields_954p, ['3010023917'], 'Now 954$p exists' );
700
701         $record = new_record;
702         $record->append_fields(
703             MARC::Field->new(
704                 952, ' ', ' ',
705                 p => '3010023917',
706                 y => 'BK',
707             ),
708         );
709
710         move_field(
711             {
712                 record        => $record,
713                 from_field    => '952',
714                 from_subfield => 'p',
715                 to_field      => '954',
716                 to_subfield   => 'p'
717             }
718         );    # Move all field
719         @fields_952p =
720           read_field( { record => $record, field => '952', subfield => 'p' } );
721         @fields_954p =
722           read_field( { record => $record, field => '954', subfield => 'p' } );
723         is_deeply( \@fields_952p, [], 'All 952$p have moved' );
724         is_deeply(
725             \@fields_954p,
726             [ '3010023917', '3010023917' ],
727             'Now 2 954$p exist'
728         );
729     };
730
731     subtest 'move field' => sub {
732         plan tests => 8;
733
734         # move_field - fields
735         my $record = new_record;
736         $record->append_fields(
737             MARC::Field->new(
738                 952, ' ', ' ',
739                 p => '3010023917',
740                 y => 'BK',
741             ),
742         );
743
744         #- Move all fields
745         move_field(
746             { record => $record, from_field => '952', to_field => '953' } );
747         is_deeply( [ read_field( { record => $record, field => '952' } ) ],
748             [], "original fields don't exist" );
749         is_deeply(
750             [ read_field( { record => $record, field => '953', n => 1 } ) ],
751             [ '3010023917', 'BK', 'GEN', '2001-06-25' ],
752             "first original fields has been copied"
753         );
754         is_deeply(
755             [ read_field( { record => $record, field => '953', n => 2 } ) ],
756             [ '3010023917', 'BK' ],
757             "second original fields has been copied"
758         );
759
760         #- Move only the first field
761         move_field(
762             {
763                 record     => $record,
764                 from_field => '953',
765                 to_field   => '954',
766                 n          => 1
767             }
768         );
769         is_deeply(
770             [ read_field( { record => $record, field => '953' } ) ],
771             [ '3010023917', 'BK' ],
772             "only first, the second 953 still exists"
773         );
774         is_deeply(
775             [ read_field( { record => $record, field => '954' } ) ],
776             [ '3010023917', 'BK', 'GEN', '2001-06-25' ],
777             "only first, first 953 has been copied"
778         );
779
780         $record = new_record;
781         $record->append_fields(
782             MARC::Field->new(
783                 952, ' ', ' ',
784                 p => '3010023917',
785                 y => 'BK',
786             ),
787         );
788
789         #- Move all fields and modify values using a regex
790         move_field(
791             {
792                 record     => $record,
793                 from_field => '952',
794                 to_field   => '953',
795                 regex      => { search => 'BK', replace => 'DVD' }
796             }
797         );
798         is_deeply( [ read_field( { record => $record, field => '952' } ) ],
799             [], "use a regex, original fields don't exist" );
800         is_deeply(
801             [ read_field( { record => $record, field => '953', n => 1 } ) ],
802             [ '3010023917', 'DVD', 'GEN', '2001-06-25' ],
803             "use a regex, first original fields has been copied"
804         );
805         is_deeply(
806             [ read_field( { record => $record, field => '953', n => 2 } ) ],
807             [ '3010023917', 'DVD' ],
808             "use a regex, second original fields has been copied"
809         );
810     };
811 };
812
813 # delete_field
814 subtest 'delete_field' => sub {
815     plan tests                => 2;
816     subtest 'delete subfield' => sub {
817         plan tests => 2;
818         my $record = new_record;
819         $record->append_fields(
820             MARC::Field->new(
821                 952, ' ', ' ',
822                 p => '3010023917',
823                 y => 'BK',
824             ),
825         );
826
827         delete_field(
828             { record => $record, field => '952', subfield => 'p', n => 1 } );
829         my @fields_952p =
830           read_field( { record => $record, field => '952', subfield => 'p' } );
831         is_deeply( \@fields_952p, ['3010023917'], 'Delete first 952$p' );
832
833         $record = new_record;
834         $record->append_fields(
835             MARC::Field->new(
836                 952, ' ', ' ',
837                 p => '3010023917',
838                 y => 'BK',
839             ),
840         );
841         delete_field( { record => $record, field => '952', subfield => 'p' } );
842         @fields_952p =
843           read_field( { record => $record, field => '952', subfield => 'p' } );
844         is_deeply( \@fields_952p, [], 'Delete all 952$p' );
845     };
846
847     subtest 'delete field' => sub {
848         plan tests => 2;
849         my $record = new_record;
850         delete_field( { record => $record, field => '952' } );
851         my @fields_952 = read_field( { record => $record, field => '952' } );
852         is_deeply( \@fields_952, [], 'Delete all 952, 1 deleted' );
853
854         $record = new_record;
855         $record->append_fields(
856             MARC::Field->new(
857                 952, ' ', ' ',
858                 p => '3010023917',
859                 y => 'BK',
860             ),
861         );
862         delete_field( { record => $record, field => '952' } );
863         @fields_952 = read_field( { record => $record, field => '952' } );
864         is_deeply( \@fields_952, [], 'Delete all 952, 2 deleted' );
865     };
866 };