#!/usr/bin/perl # This file is part of Koha. # # Koha is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # Koha is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Koha; if not, see . use Modern::Perl; use Test::NoWarnings; use Test::More tests => 6; use Test::Exception; use Test::MockModule; use Test::Warn; use t::lib::TestBuilder; use t::lib::Mocks; use C4::Biblio qw( AddBiblio ); use Koha::Database; BEGIN { use_ok('Koha::Biblio::Metadatas'); } my $schema = Koha::Database->new->schema; my $builder = t::lib::TestBuilder->new; subtest 'record() tests' => sub { plan tests => 11; $schema->storage->txn_begin; my $title = 'Oranges and Peaches'; # Create a valid record my $record = MARC::Record->new(); my $field = MARC::Field->new( '245', '', '', 'a' => $title ); my $f952_1 = MARC::Field->new( '952', '', '', 0 => '1', y => 'BK', c => 'GEN', d => '2001-06-25', ); my $f952_2 = MARC::Field->new( '952', '', '', 0 => '1', y => 'BK', c => 'GEN', d => '2001-06-25', ); $record->append_fields( $field, $f952_1, $f952_2 ); my ($biblio_id) = C4::Biblio::AddBiblio( $record, '' ); my @fields_952 = $record->field('952'); is( scalar @fields_952, 2, 'The record to be inserted contains 2 item fields' ); my $c4_biblio = Test::MockModule->new('C4::Biblio'); $c4_biblio->mock( 'GetMarcFromKohaField', sub { return '952'; } ); my $metadata = Koha::Biblios->find($biblio_id)->metadata; my $record2 = $metadata->record; @fields_952 = $record2->field('952'); is( scalar @fields_952, 0, 'Item fields stripped out then calling $metadata->record' ); is( ref $record2, 'MARC::Record', 'Method record() returned a MARC::Record object' ); is( $record2->field('245')->subfield("a"), $title, 'Title in 245$a matches title from original record object' ); my $bad_data = $builder->build_object( { class => 'Koha::Biblio::Metadatas', value => { format => 'marcxml', schema => 'MARC21', metadata => 'this_is_not_marcxml' } } ); warning_like { throws_ok { $bad_data->record; } 'Koha::Exceptions::Metadata::Invalid', 'Exception thrown on bad record'; } qr/parser error : Start tag expected, '<' not found/, 'Warning thrown excplicitly'; my $exception = $@; is( $exception->id, $bad_data->id, 'id passed correctly to exception' ); is( $exception->format, 'marcxml', 'format passed correctly to exception' ); is( $exception->schema, 'MARC21', 'schema passed correctly to exception' ); my $bad_format = $builder->build_object( { class => 'Koha::Biblio::Metadatas', value => { format => 'mij', schema => 'MARC21', metadata => 'something' } } ); throws_ok { $bad_format->record; } 'Koha::Exceptions::Metadata', 'Exception thrown on unhandled format'; is( "$@", 'Koha::Biblio::Metadata->record called on unhandled format: mij', 'Exception message built correctly' ); $schema->storage->txn_rollback; }; subtest 'record_strip_nonxml() tests' => sub { plan tests => 5; $schema->storage->txn_begin; my $title = 'Oranges and' . chr(31) . ' Peaches'; # Create a valid record my $record = MARC::Record->new(); my $field = MARC::Field->new( '245', '', '', 'a' => $title ); $record->append_fields($field); my ($biblio_id) = C4::Biblio::AddBiblio( $record, '' ); my $metadata = Koha::Biblios->find($biblio_id)->metadata; my $record2 = $metadata->record_strip_nonxml; is( ref $record2, 'MARC::Record', 'Method record() returned a MARC::Record object' ); is( $record2->field('245')->subfield("a"), "Oranges and Peaches", 'Title in 245$a matches title with control character removed' ); my $bad_data = $builder->build_object( { class => 'Koha::Biblio::Metadatas', value => { format => 'marcxml', schema => 'MARC21', metadata => 'this_is_not_marcxml' } } ); warning_like { $record2 = $bad_data->record_strip_nonxml; } qr/parser error : Start tag expected, '<' not found/, 'Warning thrown explicitly'; is( $record2, undef, "record_strip_nonxml returns undef when the record cannot be parsed after removing nonxml characters" ); my $builder = t::lib::TestBuilder->new; my $item = $builder->build_sample_item( { biblionumber => $metadata->biblionumber } ); # Emptied the OpacHiddenItems pref t::lib::Mocks::mock_preference( 'OpacHiddenItems', '' ); my ($itemfield) = C4::Biblio::GetMarcFromKohaField('items.itemnumber'); $record2 = $metadata->record_strip_nonxml( { embed_items => 1 } ); my @items = $record2->field($itemfield); is( scalar @items, 1, "We got back our item" ); $schema->storage->txn_rollback; }; subtest '_embed_items' => sub { plan tests => 10; $schema->storage->txn_begin(); my $builder = t::lib::TestBuilder->new; my $library1 = $builder->build( { source => 'Branch', } ); my $library2 = $builder->build( { source => 'Branch', } ); my $itemtype = $builder->build( { source => 'Itemtype', } ); my $biblio = $builder->build_sample_biblio(); my $item_infos = [ { homebranch => $library1->{branchcode}, holdingbranch => $library1->{branchcode} }, { homebranch => $library1->{branchcode}, holdingbranch => $library1->{branchcode} }, { homebranch => $library1->{branchcode}, holdingbranch => $library1->{branchcode} }, { homebranch => $library2->{branchcode}, holdingbranch => $library2->{branchcode} }, { homebranch => $library2->{branchcode}, holdingbranch => $library2->{branchcode} }, { homebranch => $library1->{branchcode}, holdingbranch => $library2->{branchcode} }, { homebranch => $library1->{branchcode}, holdingbranch => $library2->{branchcode} }, { homebranch => $library1->{branchcode}, holdingbranch => $library2->{branchcode} }, ]; my $number_of_items = scalar @$item_infos; my $number_of_items_with_homebranch_is_CPL = grep { $_->{homebranch} eq $library1->{branchcode} } @$item_infos; my @itemnumbers; for my $item_info (@$item_infos) { my $itemnumber = $builder->build_sample_item( { biblionumber => $biblio->biblionumber, homebranch => $item_info->{homebranch}, holdingbranch => $item_info->{holdingbranch}, itype => $itemtype->{itemtype} } )->itemnumber; push @itemnumbers, $itemnumber; } # Emptied the OpacHiddenItems pref t::lib::Mocks::mock_preference( 'OpacHiddenItems', '' ); throws_ok { Koha::Biblio::Metadata->record() } 'Koha::Exceptions::Metadata', 'Koha::Biblio::Metadata->record must be called on an instantiated object or like a class method with a record passed in parameter'; my ($itemfield) = C4::Biblio::GetMarcFromKohaField('items.itemnumber'); my $record = $biblio->metadata->record; Koha::Biblio::Metadata->record( { record => $record, embed_items => 1, biblionumber => $biblio->biblionumber } ); my @items = $record->field($itemfield); is( scalar @items, $number_of_items, 'Should return all items' ); my $marc_with_items = $biblio->metadata->record( { embed_items => 1 } ); is_deeply( $record, $marc_with_items, 'A direct call to GetMarcBiblio with items matches' ); $record = $biblio->metadata->record( { embed_items => 1, itemnumbers => [ $itemnumbers[1], $itemnumbers[3] ] } ); @items = $record->field($itemfield); is( scalar @items, 2, 'Should return all items present in the list' ); $record = $biblio->metadata->record( { embed_items => 1, opac => 1 } ); @items = $record->field($itemfield); is( scalar @items, $number_of_items, 'Should return all items for opac' ); my $opachiddenitems = " homebranch: ['$library1->{branchcode}']"; t::lib::Mocks::mock_preference( 'OpacHiddenItems', $opachiddenitems ); $record = $biblio->metadata->record( { embed_items => 1 } ); @items = $record->field($itemfield); is( scalar @items, $number_of_items, 'Even with OpacHiddenItems set, all items should have been embedded' ); $record = $biblio->metadata->record( { embed_items => 1, opac => 1 } ); @items = $record->field($itemfield); is( scalar @items, $number_of_items - $number_of_items_with_homebranch_is_CPL, 'For OPAC, the pref OpacHiddenItems should have been take into account. Only items with homebranch ne CPL should have been embedded' ); $opachiddenitems = " homebranch: ['$library1->{branchcode}', '$library2->{branchcode}']"; t::lib::Mocks::mock_preference( 'OpacHiddenItems', $opachiddenitems ); $record = $biblio->metadata->record( { embed_items => 1, opac => 1 } ); @items = $record->field($itemfield); is( scalar @items, 0, 'For OPAC, If all items are hidden, no item should have been embedded' ); # Check position of 952 in response of embed_items marc t::lib::Mocks::mock_preference( 'OpacHiddenItems', q{} ); $record = $biblio->metadata->record; $record->insert_fields_ordered( MARC::Field->new( '951', '', '', a => 'before items' ), MARC::Field->new( '953', '', '', a => 'after items' ), ); C4::Biblio::ModBiblio( $record, $biblio->biblionumber, q{} ); my $field_list = join ',', map { $_->tag } $record->fields; ok( $field_list =~ /951,953/, "951 and 953 in $field_list" ); $biblio->discard_changes; $record = $biblio->metadata->record( { embed_items => 1 } ); $field_list = join ',', map { $_->tag } $record->fields; ok( $field_list =~ /951,(952,)+953/, "951-952s-953 in $field_list" ); $schema->storage->txn_rollback; }; subtest 'record_source() and source_allows_editing() tests' => sub { plan tests => 7; $schema->storage->txn_begin; my $biblio = $builder->build_sample_biblio; my $metadata = $biblio->metadata; is( $metadata->record_source_id, undef, 'No record source defined for metadata object' ); ok( $metadata->source_allows_editing, 'No record source, can be edited' ); is( $metadata->record_source, undef ); my $source = $builder->build_object( { class => 'Koha::RecordSources', value => { can_be_edited => 1 } } ); $metadata->record_source_id( $source->id )->store(); my $retrieved_source = $metadata->record_source; ok( $metadata->source_allows_editing, 'Record source allows, can be edited' ); is( ref($retrieved_source), 'Koha::RecordSource' ); is( $retrieved_source->id, $source->id ); $source->can_be_edited(0)->store(); $metadata->discard_changes; ok( !$metadata->source_allows_editing, 'Record source does not allow, cannot be edited' ); $schema->storage->txn_rollback; };