3 # This file is part of Koha.
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.
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.
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>.
20 use Test
::More tests
=> 6;
24 use t
::lib
::TestBuilder
;
30 use List
::Util
qw( any );
32 use Koha
::SearchEngine
::Elasticsearch
;
33 use Koha
::SearchEngine
::Elasticsearch
::Search
;
35 my $schema = Koha
::Database
->new->schema;
36 $schema->storage->txn_begin;
38 subtest
'_read_configuration() tests' => sub {
43 t
::lib
::Mocks
::mock_config
( 'elasticsearch', undef );
45 # 'elasticsearch' missing in configuration
47 $configuration = Koha
::SearchEngine
::Elasticsearch
::_read_configuration
;
49 'Koha::Exceptions::Config::MissingEntry',
50 'Configuration problem, exception thrown';
53 "Missing <elasticsearch> entry in koha-conf.xml",
54 'Exception message is correct'
57 # 'elasticsearch' present but no 'server' entry
58 t
::lib
::Mocks
::mock_config
( 'elasticsearch', {} );
60 $configuration = Koha
::SearchEngine
::Elasticsearch
::_read_configuration
;
62 'Koha::Exceptions::Config::MissingEntry',
63 'Configuration problem, exception thrown';
66 "Missing <elasticsearch>/<server> entry in koha-conf.xml",
67 'Exception message is correct'
70 # 'elasticsearch' and 'server' entries present, but no 'index_name'
71 t
::lib
::Mocks
::mock_config
( 'elasticsearch', { server
=> 'a_server' } );
73 $configuration = Koha
::SearchEngine
::Elasticsearch
::_read_configuration
;
75 'Koha::Exceptions::Config::MissingEntry',
76 'Configuration problem, exception thrown';
79 "Missing <elasticsearch>/<index_name> entry in koha-conf.xml",
80 'Exception message is correct'
83 # Correct configuration, only one server
84 t
::lib
::Mocks
::mock_config
( 'elasticsearch', { server
=> 'a_server', index_name
=> 'index' } );
86 $configuration = Koha
::SearchEngine
::Elasticsearch
::_read_configuration
;
87 is
( $configuration->{index_name
}, 'index', 'Index configuration parsed correctly' );
88 is_deeply
( $configuration->{nodes
}, ['a_server'], 'Server configuration parsed correctly' );
90 # Correct configuration, two servers
91 my @servers = ('a_server', 'another_server');
92 t
::lib
::Mocks
::mock_config
( 'elasticsearch', { server
=> \
@servers, index_name
=> 'index' } );
94 $configuration = Koha
::SearchEngine
::Elasticsearch
::_read_configuration
;
95 is
( $configuration->{index_name
}, 'index', 'Index configuration parsed correctly' );
96 is
( $configuration->{cxn_pool
}, 'Static', 'cxn_pool configuration set correctly to Static if not specified' );
97 is_deeply
( $configuration->{nodes
}, \
@servers , 'Server configuration parsed correctly' );
99 t
::lib
::Mocks
::mock_config
( 'elasticsearch', { server
=> \
@servers, index_name
=> 'index', cxn_pool
=> 'Fluid' } );
101 $configuration = Koha
::SearchEngine
::Elasticsearch
::_read_configuration
;
102 is
( $configuration->{cxn_pool
}, 'Fluid', 'cxn_pool configuration parsed correctly' );
104 my $params = Koha
::SearchEngine
::Elasticsearch
::get_elasticsearch_params
;
105 is_deeply
( $configuration->{nodes
}, \
@servers , 'get_elasticsearch_params is just a wrapper for _read_configuration' );
109 subtest
'get_elasticsearch_settings() tests' => sub {
115 # test reading index settings
116 my $es = Koha
::SearchEngine
::Elasticsearch
->new( {index => $Koha::SearchEngine
::Elasticsearch
::BIBLIOS_INDEX
} );
117 $settings = $es->get_elasticsearch_settings();
118 is
( $settings->{index}{analysis
}{analyzer
}{analyzer_phrase
}{tokenizer
}, 'keyword', 'Index settings parsed correctly' );
121 subtest
'get_elasticsearch_mappings() tests' => sub {
127 # test reading mappings
128 my $es = Koha
::SearchEngine
::Elasticsearch
->new( {index => $Koha::SearchEngine
::Elasticsearch
::BIBLIOS_INDEX
} );
129 $mappings = $es->get_elasticsearch_mappings();
130 is
( $mappings->{data
}{properties
}{isbn__sort
}{index}, 'false', 'Field mappings parsed correctly' );
133 subtest
'Koha::SearchEngine::Elasticsearch::marc_records_to_documents () tests' => sub {
137 t
::lib
::Mocks
::mock_preference
('marcflavour', 'MARC21');
138 t
::lib
::Mocks
::mock_preference
('ElasticsearchMARCFormat', 'ISO2709');
142 name
=> 'control_number',
148 marc_type
=> 'marc21',
158 marc_type
=> 'marc21',
159 marc_field
=> '020a',
168 marc_type
=> 'marc21',
169 marc_field
=> '100a',
178 marc_type
=> 'marc21',
179 marc_field
=> '110a',
188 marc_type
=> 'marc21',
189 marc_field
=> '245(ab)ab',
192 name
=> 'unimarc_title',
198 marc_type
=> 'unimarc',
199 marc_field
=> '245a',
205 suggestible
=> undef,
208 marc_type
=> 'marc21',
212 name
=> 'uniform_title',
218 marc_type
=> 'marc21',
219 marc_field
=> '240a',
222 name
=> 'title_wildcard',
228 marc_type
=> 'marc21',
232 name
=> 'sum_item_price',
238 marc_type
=> 'marc21',
239 marc_field
=> '952g',
242 name
=> 'items_withdrawn_status',
248 marc_type
=> 'marc21',
249 marc_field
=> '9520',
252 name
=> 'local_classification',
258 marc_type
=> 'marc21',
259 marc_field
=> '952o',
262 name
=> 'type_of_record',
268 marc_type
=> 'marc21',
269 marc_field
=> 'leader_/6',
272 name
=> 'type_of_record_and_bib_level',
278 marc_type
=> 'marc21',
279 marc_field
=> 'leader_/6-7',
288 marc_type
=> 'marc21',
289 marc_field
=> '007_/0',
298 marc_type
=> 'marc21',
299 marc_field
=> '952l',
308 marc_type
=> 'marc21',
309 marc_field
=> '260c',
312 name
=> 'date-of-publication',
318 marc_type
=> 'marc21',
319 marc_field
=> '008_/7-10',
324 my $se = Test
::MockModule
->new('Koha::SearchEngine::Elasticsearch');
325 $se->mock('_foreach_mapping', sub {
326 my ($self, $sub) = @_;
328 foreach my $map (@mappings) {
342 my $see = Koha
::SearchEngine
::Elasticsearch
::Search
->new({ index => $Koha::SearchEngine
::Elasticsearch
::BIBLIOS_INDEX
});
344 my $callno = 'ABC123';
345 my $callno2 = 'ABC456';
346 my $long_callno = '1234567890' x
30;
348 my $marc_record_1 = MARC
::Record
->new();
349 $marc_record_1->leader(' cam 22 a 4500');
350 $marc_record_1->append_fields(
351 MARC
::Field
->new('001', '123'),
352 MARC
::Field
->new('007', 'ku'),
353 MARC
::Field
->new('008', '901111s1962 xxk|||| |00| ||eng c'),
354 MARC
::Field
->new('020', '', '', a
=> '1-56619-909-3'),
355 MARC
::Field
->new('100', '', '', a
=> 'Author 1'),
356 MARC
::Field
->new('110', '', '', a
=> 'Corp Author'),
357 MARC
::Field
->new('210', '', '', a
=> 'Title 1'),
358 MARC
::Field
->new('240', '', '4', a
=> 'The uniform title with nonfiling indicator'),
359 MARC
::Field
->new('245', '', '', a
=> 'Title:', b
=> 'first record'),
360 MARC
::Field
->new('260', '', '', a
=> 'New York :', b
=> 'Ace ,', c
=> 'c1962'),
361 MARC
::Field
->new('999', '', '', c
=> '1234567'),
362 # ' ' for testing trimming of white space in boolean value callback:
363 MARC
::Field
->new('952', '', '', 0 => ' ', g
=> '123.30', o
=> $callno, l
=> 3),
364 MARC
::Field
->new('952', '', '', 0 => 0, g
=> '127.20', o
=> $callno2, l
=> 2),
365 MARC
::Field
->new('952', '', '', 0 => 1, g
=> '0.00', o
=> $long_callno, l
=> 1),
367 my $marc_record_2 = MARC
::Record
->new();
368 $marc_record_2->leader(' cam 22 a 4500');
369 $marc_record_2->append_fields(
370 MARC
::Field
->new('008', '901111s19uu xxk|||| |00| ||eng c'),
371 MARC
::Field
->new('100', '', '', a
=> 'Author 2'),
372 # MARC::Field->new('210', '', '', a => 'Title 2'),
373 # MARC::Field->new('245', '', '', a => 'Title: second record'),
374 MARC
::Field
->new('260', '', '', a
=> 'New York :', b
=> 'Ace ,', c
=> '1963-2003'),
375 MARC
::Field
->new('999', '', '', c
=> '1234568'),
376 MARC
::Field
->new('952', '', '', 0 => 1, g
=> 'string where should be numeric', o
=> $long_callno),
379 my $marc_record_3 = MARC
::Record
->new();
380 $marc_record_3->leader(' cam 22 a 4500');
381 $marc_record_3->append_fields(
382 MARC
::Field
->new('008', '901111s19uu xxk|||| |00| ||eng c'),
383 MARC
::Field
->new('100', '', '', a
=> 'Author 2'),
384 # MARC::Field->new('210', '', '', a => 'Title 3'),
385 # MARC::Field->new('245', '', '', a => 'Title: third record'),
386 MARC
::Field
->new('260', '', '', a
=> 'New York :', b
=> 'Ace ,', c
=> ' 89 '),
387 MARC
::Field
->new('999', '', '', c
=> '1234568'),
388 MARC
::Field
->new('952', '', '', 0 => 1, g
=> 'string where should be numeric', o
=> $long_callno),
390 my $records = [$marc_record_1, $marc_record_2, $marc_record_3];
392 $see->get_elasticsearch_mappings(); #sort_fields will call this and use the actual db values unless we call it first
394 my $docs = $see->marc_records_to_documents($records);
397 is
(scalar @
{$docs}, 3, 'Two records converted to documents');
399 is_deeply
($docs->[0]->{control_number
}, ['123'], 'First record control number should be set correctly');
401 is_deeply
($docs->[0]->{'ff7-00'}, ['k'], 'First record ff7-00 should be set correctly');
403 is
(scalar @
{$docs->[0]->{author
}}, 2, 'First document author field should contain two values');
404 is_deeply
($docs->[0]->{author
}, ['Author 1', 'Corp Author'], 'First document author field should be set correctly');
406 is
(scalar @
{$docs->[0]->{author__sort
}}, 1, 'First document author__sort field should have a single value');
407 is_deeply
($docs->[0]->{author__sort
}, ['Author 1 Corp Author'], 'First document author__sort field should be set correctly');
409 is
(scalar @
{$docs->[0]->{title__sort
}}, 1, 'First document title__sort field should have a single');
410 is_deeply
($docs->[0]->{title__sort
}, ['Title: first record Title: first record'], 'First document title__sort field should be set correctly');
412 is
($docs->[0]->{issues
}, 6, 'Issues field should be sum of the issues for each item');
413 is
($docs->[0]->{issues__sort
}, 6, 'Issues sort field should also be a sum of the issues');
415 is
(scalar @
{$docs->[0]->{title_wildcard
}}, 2, 'First document title_wildcard field should have two values');
416 is_deeply
($docs->[0]->{title_wildcard
}, ['Title:', 'first record'], 'First document title_wildcard field should be set correctly');
419 is
(scalar @
{$docs->[0]->{author__suggestion
}}, 2, 'First document author__suggestion field should contain two values');
421 $docs->[0]->{author__suggestion
},
424 'input' => 'Author 1'
427 'input' => 'Corp Author'
430 'First document author__suggestion field should be set correctly'
433 is
(scalar @
{$docs->[0]->{title__suggestion
}}, 3, 'First document title__suggestion field should contain three values');
435 $docs->[0]->{title__suggestion
},
437 { 'input' => 'Title:' },
438 { 'input' => 'first record' },
439 { 'input' => 'Title: first record' }
441 'First document title__suggestion field should be set correctly'
444 ok
(!(defined $docs->[0]->{title__facet
}), 'First document should have no title__facet field');
446 is
(scalar @
{$docs->[0]->{author__facet
}}, 2, 'First document author__facet field should have two values');
448 $docs->[0]->{author__facet
},
449 ['Author 1', 'Corp Author'],
450 'First document author__facet field should be set correctly'
453 is
(scalar @
{$docs->[0]->{items_withdrawn_status
}}, 2, 'First document items_withdrawn_status field should have two values');
455 $docs->[0]->{items_withdrawn_status
},
457 'First document items_withdrawn_status field should be set correctly'
461 $docs->[0]->{sum_item_price
},
463 'First document sum_item_price field should be set correctly'
466 ok
(defined $docs->[0]->{marc_data
}, 'First document marc_data field should be set');
467 ok
(defined $docs->[0]->{marc_format
}, 'First document marc_format field should be set');
468 is
($docs->[0]->{marc_format
}, 'base64ISO2709', 'First document marc_format should be set correctly');
470 my $decoded_marc_record = $see->decode_record_from_result($docs->[0]);
472 ok
($decoded_marc_record->isa('MARC::Record'), "base64ISO2709 record successfully decoded from result");
473 is
($decoded_marc_record->as_usmarc(), $marc_record_1->as_usmarc(), "Decoded base64ISO2709 record has same data as original record");
475 is
(scalar @
{$docs->[0]->{type_of_record
}}, 1, 'First document type_of_record field should have one value');
477 $docs->[0]->{type_of_record
},
479 'First document type_of_record field should be set correctly'
482 is
(scalar @
{$docs->[0]->{type_of_record_and_bib_level
}}, 1, 'First document type_of_record_and_bib_level field should have one value');
484 $docs->[0]->{type_of_record_and_bib_level
},
486 'First document type_of_record_and_bib_level field should be set correctly'
489 is
(scalar @
{$docs->[0]->{isbn
}}, 4, 'First document isbn field should contain four values');
490 is_deeply
($docs->[0]->{isbn
}, ['978-1-56619-909-4', '9781566199094', '1-56619-909-3', '1566199093'], 'First document isbn field should be set correctly');
493 $docs->[0]->{'local_classification'},
494 [$callno, $callno2, $long_callno],
495 'First document local_classification field should be set correctly'
498 # Nonfiling characters for sort fields
500 $docs->[0]->{uniform_title
},
501 ['The uniform title with nonfiling indicator'],
502 'First document uniform_title field should contain the title verbatim'
505 $docs->[0]->{uniform_title__sort
},
506 ['uniform title with nonfiling indicator'],
507 'First document uniform_title__sort field should contain the title with the first four initial characters removed'
510 # Tests for 'year' type
511 is
(scalar @
{$docs->[0]->{'date-of-publication'}}, 1, 'First document date-of-publication field should contain one value');
512 is_deeply
($docs->[0]->{'date-of-publication'}, ['1962'], 'First document date-of-publication field should be set correctly');
515 $docs->[0]->{'copydate'},
517 'First document copydate field should be set correctly'
522 is
(scalar @
{$docs->[1]->{author
}}, 1, 'Second document author field should contain one value');
523 is_deeply
($docs->[1]->{author
}, ['Author 2'], 'Second document author field should be set correctly');
525 is
(scalar @
{$docs->[1]->{items_withdrawn_status
}}, 1, 'Second document items_withdrawn_status field should have one value');
527 $docs->[1]->{items_withdrawn_status
},
529 'Second document items_withdrawn_status field should be set correctly'
533 $docs->[1]->{sum_item_price
},
535 'Second document sum_item_price field should be set correctly'
539 $docs->[1]->{local_classification__sort
},
540 [substr($long_callno, 0, 255)],
541 'Second document local_classification__sort field should be set correctly'
544 # Tests for 'year' type
546 $docs->[1]->{'copydate'},
548 'Second document copydate field should be set correctly'
551 $docs->[1]->{'date-of-publication'},
553 'Second document date-of-publication field should be set correctly'
559 $docs->[2]->{'copydate'},
561 'Third document copydate field should be set correctly'
564 # Mappings marc_type:
566 ok
(!(defined $docs->[0]->{unimarc_title
}), "No mapping when marc_type doesn't match marc flavour");
568 # Marc serialization format fallback for records exceeding ISO2709 max record size
570 my $large_marc_record = MARC
::Record
->new();
571 $large_marc_record->leader(' cam 22 a 4500');
573 $large_marc_record->append_fields(
574 MARC
::Field
->new('100', '', '', a
=> 'Author 1'),
575 MARC
::Field
->new('110', '', '', a
=> 'Corp Author'),
576 MARC
::Field
->new('210', '', '', a
=> 'Title 1'),
577 MARC
::Field
->new('245', '', '', a
=> 'Title:', b
=> 'large record'),
578 MARC
::Field
->new('999', '', '', c
=> '1234567'),
581 my $item_field = MARC
::Field
->new('952', '', '', o
=> '123456789123456789123456789', p
=> '123456789', z
=> 'test');
582 my $items_count = 1638;
583 while(--$items_count) {
584 $large_marc_record->append_fields($item_field);
587 $docs = $see->marc_records_to_documents([$large_marc_record]);
589 is
($docs->[0]->{marc_format
}, 'MARCXML', 'For record exceeding max record size marc_format should be set correctly');
591 $decoded_marc_record = $see->decode_record_from_result($docs->[0]);
593 ok
($decoded_marc_record->isa('MARC::Record'), "MARCXML record successfully decoded from result");
594 is
($decoded_marc_record->as_xml_record(), $large_marc_record->as_xml_record(), "Decoded MARCXML record has same data as original record");
602 marc_type
=> 'marc21',
603 marc_field
=> '245((ab)ab',
606 my $exception = try
{
607 $see->marc_records_to_documents($records);
613 ok
(defined $exception, "Exception has been thrown when processing mapping with unmatched opening parenthesis");
614 ok
($exception->isa("Koha::Exceptions::Elasticsearch::MARCFieldExprParseError"), "Exception is of correct class");
615 ok
($exception->message =~ /Unmatched opening parenthesis/, "Exception has the correct message");
624 marc_type
=> 'marc21',
625 marc_field
=> '245(ab))ab',
629 $see->marc_records_to_documents($records);
635 ok
(defined $exception, "Exception has been thrown when processing mapping with unmatched closing parenthesis");
636 ok
($exception->isa("Koha::Exceptions::Elasticsearch::MARCFieldExprParseError"), "Exception is of correct class");
637 ok
($exception->message =~ /Unmatched closing parenthesis/, "Exception has the correct message");
640 my $marc_record_with_blank_field = MARC
::Record
->new();
641 $marc_record_with_blank_field->leader(' cam 22 a 4500');
643 $marc_record_with_blank_field->append_fields(
644 MARC
::Field
->new('100', '', '', a
=> ''),
645 MARC
::Field
->new('210', '', '', a
=> 'Title 1'),
646 MARC
::Field
->new('245', '', '', a
=> 'Title:', b
=> 'large record'),
647 MARC
::Field
->new('999', '', '', c
=> '1234567'),
649 $docs = $see->marc_records_to_documents([$marc_record_with_blank_field]);
650 is_deeply
( $docs->[0]->{author
},[],'No value placed into field if mapped marc field is blank');
651 is_deeply
( $docs->[0]->{author__suggestion
},[],'No value placed into suggestion if mapped marc field is blank');
655 subtest
'Koha::SearchEngine::Elasticsearch::marc_records_to_documents_array () tests' => sub {
659 t
::lib
::Mocks
::mock_preference
('marcflavour', 'MARC21');
660 t
::lib
::Mocks
::mock_preference
('ElasticsearchMARCFormat', 'ARRAY');
664 name
=> 'control_number',
670 marc_type
=> 'marc21',
675 my $se = Test
::MockModule
->new('Koha::SearchEngine::Elasticsearch');
676 $se->mock('_foreach_mapping', sub {
677 my ($self, $sub) = @_;
679 foreach my $map (@mappings) {
693 my $see = Koha
::SearchEngine
::Elasticsearch
::Search
->new({ index => $Koha::SearchEngine
::Elasticsearch
::BIBLIOS_INDEX
});
695 my $marc_record_1 = MARC
::Record
->new();
696 $marc_record_1->leader(' cam 22 a 4500');
697 $marc_record_1->append_fields(
698 MARC
::Field
->new('001', '123'),
699 MARC
::Field
->new('020', '', '', a
=> '1-56619-909-3'),
700 MARC
::Field
->new('100', '', '', a
=> 'Author 1'),
701 MARC
::Field
->new('110', '', '', a
=> 'Corp Author'),
702 MARC
::Field
->new('210', '', '', a
=> 'Title 1'),
703 MARC
::Field
->new('245', '', '', a
=> 'Title:', b
=> 'first record'),
704 MARC
::Field
->new('999', '', '', c
=> '1234567'),
706 my $marc_record_2 = MARC
::Record
->new();
707 $marc_record_2->leader(' cam 22 a 4500');
708 $marc_record_2->append_fields(
709 MARC
::Field
->new('100', '', '', a
=> 'Author 2'),
710 # MARC::Field->new('210', '', '', a => 'Title 2'),
711 # MARC::Field->new('245', '', '', a => 'Title: second record'),
712 MARC
::Field
->new('999', '', '', c
=> '1234568'),
713 MARC
::Field
->new('952', '', '', 0 => 1, g
=> 'string where should be numeric'),
715 my $records = [ $marc_record_1, $marc_record_2 ];
717 $see->get_elasticsearch_mappings(); #sort_fields will call this and use the actual db values unless we call it first
719 my $docs = $see->marc_records_to_documents($records);
722 is
(scalar @
{$docs}, 2, 'Two records converted to documents');
724 is_deeply
($docs->[0]->{control_number
}, ['123'], 'First record control number should be set correctly');
726 is
($docs->[0]->{marc_format
}, 'ARRAY', 'First document marc_format should be set correctly');
728 my $decoded_marc_record = $see->decode_record_from_result($docs->[0]);
730 ok
($decoded_marc_record->isa('MARC::Record'), "ARRAY record successfully decoded from result");
731 is
($decoded_marc_record->as_usmarc(), $marc_record_1->as_usmarc(), "Decoded ARRAY record has same data as original record");
734 subtest
'Koha::SearchEngine::Elasticsearch::marc_records_to_documents () authority tests' => sub {
738 t
::lib
::Mocks
::mock_preference
('marcflavour', 'MARC21');
739 t
::lib
::Mocks
::mock_preference
('ElasticsearchMARCFormat', 'ISO2709');
741 my $builder = t
::lib
::TestBuilder
->new;
742 my $auth_type = $builder->build_object({ class => 'Koha::Authority::Types', value
=>{
743 auth_tag_to_report
=> '150'
755 marc_type
=> 'marc21',
756 marc_field
=> '150(ae)',
760 my $se = Test
::MockModule
->new('Koha::SearchEngine::Elasticsearch');
761 $se->mock('_foreach_mapping', sub {
762 my ($self, $sub) = @_;
764 foreach my $map (@mappings) {
778 my $see = Koha
::SearchEngine
::Elasticsearch
::Search
->new({ index => $Koha::SearchEngine
::Elasticsearch
::AUTHORITIES_INDEX
});
779 my $marc_record_1 = MARC
::Record
->new();
780 $marc_record_1->append_fields(
781 MARC
::Field
->new('001', '123'),
782 MARC
::Field
->new('007', 'ku'),
783 MARC
::Field
->new('020', '', '', a
=> '1-56619-909-3'),
784 MARC
::Field
->new('150', '', '', a
=> 'Subject', v
=> 'Genresubdiv', x
=> 'Generalsubdiv', z
=> 'Geosubdiv'),
786 my $marc_record_2 = MARC
::Record
->new();
787 $marc_record_2->append_fields(
788 MARC
::Field
->new('150', '', '', a
=> 'Subject', v
=> 'Genresubdiv', z
=> 'Geosubdiv', x
=> 'Generalsubdiv', e
=> 'wrongsubdiv' ),
790 my $records = [ $marc_record_1, $marc_record_2 ];
792 $see->get_elasticsearch_mappings(); #sort_fields will call this and use the actual db values unless we call it first
794 my $docs = $see->marc_records_to_documents($records);
797 any
{ $_ eq "Subject formsubdiv Genresubdiv generalsubdiv Generalsubdiv geographicsubdiv Geosubdiv" }
798 @
{$docs->[0]->{'match-heading'}},
799 "First record match-heading should contain the correctly formatted heading"
802 any
{ $_ eq "Subject formsubdiv Genresubdiv geographicsubdiv Geosubdiv generalsubdiv Generalsubdiv" }
803 @
{$docs->[1]->{'match-heading'}},
804 "Second record match-heading should contain the correctly formatted heading without wrong subfield"
808 $schema->storage->txn_rollback;