Martin Renvoize
66466e5d86
This patch adds some mock data for pickup_items getting included in the pickup locations response. Signed-off-by: Nick Clemens <nick@bywatersolutions.com> Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
2240 lines
69 KiB
Perl
Executable file
2240 lines
69 KiB
Perl
Executable file
#!/usr/bin/env 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 <http://www.gnu.org/licenses>.
|
||
|
||
use Modern::Perl;
|
||
|
||
use utf8;
|
||
use Encode;
|
||
|
||
use Test::More tests => 15;
|
||
use Test::MockModule;
|
||
use Test::Mojo;
|
||
use Test::Warn;
|
||
|
||
use t::lib::Mocks;
|
||
use t::lib::TestBuilder;
|
||
|
||
use Mojo::JSON qw(encode_json);
|
||
|
||
use C4::Auth;
|
||
use C4::Circulation qw( AddIssue AddReturn );
|
||
|
||
use Koha::Biblios;
|
||
use Koha::Database;
|
||
use Koha::DateUtils qw (dt_from_string output_pref);
|
||
use Koha::Checkouts;
|
||
use Koha::Old::Checkouts;
|
||
|
||
use Mojo::JSON qw(encode_json);
|
||
|
||
my $schema = Koha::Database->new->schema;
|
||
my $builder = t::lib::TestBuilder->new;
|
||
|
||
t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
|
||
|
||
my $t = Test::Mojo->new('Koha::REST::V1');
|
||
|
||
subtest 'get() tests' => sub {
|
||
|
||
plan tests => 22;
|
||
|
||
$schema->storage->txn_begin;
|
||
|
||
my $patron = $builder->build_object(
|
||
{
|
||
class => 'Koha::Patrons',
|
||
value => { flags => 0 }
|
||
}
|
||
);
|
||
my $password = 'thePassword123';
|
||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||
$patron->discard_changes;
|
||
my $userid = $patron->userid;
|
||
|
||
my $biblio = $builder->build_sample_biblio({
|
||
title => 'The unbearable lightness of being',
|
||
author => 'Milan Kundera'
|
||
});
|
||
$t->get_ok("//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber)
|
||
->status_is(403);
|
||
|
||
$patron->flags(4)->store;
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'application/weird+format' } )
|
||
->status_is(400);
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'application/json' } )
|
||
->status_is(200)
|
||
->json_is( '/title', 'The unbearable lightness of being' )
|
||
->json_is( '/author', 'Milan Kundera' );
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'application/marcxml+xml' } )
|
||
->status_is(200);
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'application/marc-in-json' } )
|
||
->status_is(200);
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'application/marc' } )
|
||
->status_is(200);
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'text/plain' } )
|
||
->status_is(200)
|
||
->content_is($biblio->metadata->record->as_formatted);
|
||
|
||
$biblio->delete;
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'application/marc' } )
|
||
->status_is(404)
|
||
->json_is( '/error', 'Bibliographic record not found' );
|
||
|
||
subtest 'marc-in-json encoding tests' => sub {
|
||
|
||
plan tests => 3;
|
||
|
||
my $title_with_diacritics = "L'insoutenable légèreté de l'être";
|
||
|
||
my $biblio = $builder->build_sample_biblio(
|
||
{
|
||
title => $title_with_diacritics,
|
||
author => "Milan Kundera"
|
||
}
|
||
);
|
||
|
||
my $result = $t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'application/marc-in-json' } )
|
||
->status_is(200)->tx->res->body;
|
||
|
||
my $encoded_title = Encode::encode( "UTF-8", $title_with_diacritics );
|
||
|
||
like( $result, qr/\Q$encoded_title/, "The title is not double encoded" );
|
||
};
|
||
|
||
subtest 'marcxml encoding tests' => sub {
|
||
plan tests => 3;
|
||
|
||
my $marcflavour = C4::Context->preference('marcflavour');
|
||
t::lib::Mocks::mock_preference('marcflavour', 'UNIMARC');
|
||
|
||
|
||
my $title_with_diacritics = "L'insoutenable légèreté de l'être";
|
||
|
||
my $biblio = $builder->build_sample_biblio(
|
||
{
|
||
title => $title_with_diacritics,
|
||
author => "Milan Kundera"
|
||
}
|
||
);
|
||
|
||
my $record = $biblio->metadata->record;
|
||
$record->leader(' nam 3 4500');
|
||
$biblio->metadata->metadata($record->as_xml_record('UNIMARC'));
|
||
$biblio->metadata->store;
|
||
|
||
my $result = $t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'application/marcxml+xml' } )
|
||
->status_is(200)->tx->res->body;
|
||
|
||
my $encoded_title = Encode::encode( "UTF-8", $title_with_diacritics );
|
||
|
||
like( $result, qr/\Q$encoded_title/, "The title is not double encoded" );
|
||
t::lib::Mocks::mock_preference('marcflavour', $marcflavour);
|
||
};
|
||
|
||
$schema->storage->txn_rollback;
|
||
};
|
||
|
||
subtest 'get_items() tests' => sub {
|
||
|
||
plan tests => 12;
|
||
|
||
$schema->storage->txn_begin;
|
||
|
||
my $patron = $builder->build_object(
|
||
{
|
||
class => 'Koha::Patrons',
|
||
value => { flags => 0 }
|
||
}
|
||
);
|
||
my $password = 'thePassword123';
|
||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||
$patron->discard_changes;
|
||
my $userid = $patron->userid;
|
||
|
||
my $biblio = $builder->build_sample_biblio();
|
||
$t->get_ok("//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber . "/items")
|
||
->status_is(403);
|
||
|
||
$patron->flags(4)->store;
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber . "/items")
|
||
->status_is(200)
|
||
->json_is( '' => [], 'No items on the biblio' );
|
||
|
||
my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
|
||
my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber . "/items?_order_by=item_id" )
|
||
->status_is(200)
|
||
->json_is( '' => [ $item_1->to_api, $item_2->to_api ], 'The items are returned' );
|
||
|
||
$t->get_ok(
|
||
"//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber . "/items" => { "x-koha-embed" => "+strings" } )
|
||
->status_is(200)
|
||
->json_has( '/0/_strings/home_library_id/str' => $item_1->holding_branch->branchname, '_strings are embedded' );
|
||
|
||
subtest 'first_hold+strings' => sub {
|
||
|
||
plan tests => 6;
|
||
|
||
my $patron = $builder->build_object(
|
||
{
|
||
class => 'Koha::Patrons',
|
||
value => {
|
||
flags => 1,
|
||
}
|
||
}
|
||
);
|
||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||
my $userid = $patron->userid;
|
||
my $pickup_library =
|
||
$builder->build_object( { class => 'Koha::Libraries', value => { pickup_location => 1 } } );
|
||
|
||
my $item = $builder->build_sample_item;
|
||
my $data = {
|
||
patron_id => $patron->borrowernumber,
|
||
biblio_id => $item->biblionumber,
|
||
item_id => $item->itemnumber,
|
||
pickup_library_id => $pickup_library->branchcode,
|
||
expiration_date => output_pref(
|
||
{
|
||
dt => dt_from_string()->add( days => "3" )->truncate( to => 'day' ), dateformat => 'iso',
|
||
dateonly => 1
|
||
}
|
||
),
|
||
};
|
||
$t->post_ok( "//$userid:$password@/api/v1/holds" => json => $data )->status_is(201)->json_has('/hold_id');
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/"
|
||
. $item->biblionumber
|
||
. "/items" => { "x-koha-embed" => "first_hold+strings" } )->status_is(200)
|
||
->json_is(
|
||
'/0/first_hold/_strings/pickup_library_id' => { type => 'library', str => $pickup_library->branchname } );
|
||
};
|
||
|
||
$schema->storage->txn_rollback;
|
||
};
|
||
|
||
subtest 'delete() tests' => sub {
|
||
|
||
plan tests => 9;
|
||
|
||
$schema->storage->txn_begin;
|
||
|
||
my $patron = $builder->build_object(
|
||
{
|
||
class => 'Koha::Patrons',
|
||
value => { flags => 0 } # no permissions
|
||
}
|
||
);
|
||
my $password = 'thePassword123';
|
||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||
my $userid = $patron->userid;
|
||
|
||
my $item = $builder->build_sample_item();
|
||
my $biblio_id = $item->biblionumber;
|
||
|
||
$t->delete_ok("//$userid:$password@/api/v1/biblios/$biblio_id")
|
||
->status_is(403, 'Not enough permissions makes it return the right code');
|
||
|
||
# Add permissions
|
||
$builder->build(
|
||
{
|
||
source => 'UserPermission',
|
||
value => {
|
||
borrowernumber => $patron->borrowernumber,
|
||
module_bit => 9,
|
||
code => 'edit_catalogue'
|
||
}
|
||
}
|
||
);
|
||
|
||
|
||
# Bibs with items cannot be deleted
|
||
$t->delete_ok("//$userid:$password@/api/v1/biblios/$biblio_id")
|
||
->status_is(409);
|
||
|
||
$item->delete();
|
||
|
||
# Bibs with no items can be deleted
|
||
$t->delete_ok("//$userid:$password@/api/v1/biblios/$biblio_id")
|
||
->status_is(204, 'SWAGGER3.2.4')
|
||
->content_is('', 'SWAGGER3.3.4');
|
||
|
||
$t->delete_ok("//$userid:$password@/api/v1/biblios/$biblio_id")
|
||
->status_is(404);
|
||
|
||
$schema->storage->txn_rollback;
|
||
};
|
||
|
||
subtest 'get_public() tests' => sub {
|
||
|
||
plan tests => 25;
|
||
|
||
$schema->storage->txn_begin;
|
||
|
||
my $category = $builder->build_object({ class => 'Koha::Patron::Categories' });
|
||
my $patron = $builder->build_object(
|
||
{
|
||
class => 'Koha::Patrons',
|
||
value => {
|
||
flags => undef, # opac user
|
||
categorycode => $category->categorycode
|
||
}
|
||
}
|
||
);
|
||
my $password = 'thePassword123';
|
||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||
$patron->discard_changes;
|
||
my $userid = $patron->userid;
|
||
|
||
my $biblio = $builder->build_sample_biblio({
|
||
title => 'The unbearable lightness of being',
|
||
author => 'Milan Kundera'
|
||
});
|
||
|
||
# Make sure author in shown in the OPAC
|
||
my $subfields = Koha::MarcSubfieldStructures->search({ tagfield => '100' });
|
||
while ( my $subfield = $subfields->next ) {
|
||
$subfield->set({ hidden => -1 })->store;
|
||
}
|
||
Koha::Caches->get_instance()->flush_all;
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'application/weird+format' } )
|
||
->status_is(400);
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'text/plain' } )
|
||
->status_is(200)
|
||
->content_like( qr{100\s+_aMilan Kundera} )
|
||
->content_like( qr{245\s+_aThe unbearable lightness of being} );
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'application/marcxml+xml' } )
|
||
->status_is(200);
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'application/marc-in-json' } )
|
||
->status_is(200);
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'application/marc' } )
|
||
->status_is(200);
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'text/plain' } )
|
||
->status_is(200)
|
||
->content_is($biblio->metadata->record->as_formatted);
|
||
|
||
subtest 'anonymous access' => sub {
|
||
plan tests => 9;
|
||
|
||
$t->get_ok( "/api/v1/public/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'application/marcxml+xml' } )
|
||
->status_is(200);
|
||
|
||
$t->get_ok( "/api/v1/public/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'application/marc-in-json' } )
|
||
->status_is(200);
|
||
|
||
$t->get_ok( "/api/v1/public/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'application/marc' } )
|
||
->status_is(200);
|
||
|
||
$t->get_ok( "/api/v1/public/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'text/plain' } )
|
||
->status_is(200)
|
||
->content_is($biblio->metadata->record->as_formatted);
|
||
};
|
||
|
||
subtest 'marc-in-json encoding tests' => sub {
|
||
|
||
plan tests => 3;
|
||
|
||
my $title_with_diacritics = "L'insoutenable légèreté de l'être";
|
||
|
||
my $biblio = $builder->build_sample_biblio(
|
||
{
|
||
title => $title_with_diacritics,
|
||
author => "Milan Kundera"
|
||
}
|
||
);
|
||
|
||
my $result = $t->get_ok( "/api/v1/public/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'application/marc-in-json' } )
|
||
->status_is(200)->tx->res->body;
|
||
|
||
my $encoded_title = Encode::encode( "UTF-8", $title_with_diacritics );
|
||
|
||
like( $result, qr/\Q$encoded_title/, "The title is not double encoded" );
|
||
};
|
||
|
||
# Hide author in OPAC
|
||
$subfields = Koha::MarcSubfieldStructures->search({ tagfield => '100' });
|
||
while ( my $subfield = $subfields->next ) {
|
||
$subfield->set({ hidden => 1 })->store;
|
||
}
|
||
|
||
Koha::Caches->get_instance()->flush_all;
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'text/plain' } )
|
||
->status_is(200)
|
||
->content_unlike( qr{100\s+_aMilan Kundera} )
|
||
->content_like( qr{245\s+_aThe unbearable lightness of being} );
|
||
|
||
subtest 'hidden_in_opac tests' => sub {
|
||
|
||
plan tests => 6;
|
||
|
||
my $biblio_hidden_in_opac = 1;
|
||
|
||
my $biblio_class = Test::MockModule->new('Koha::Biblio');
|
||
# force biblio hidden in OPAC
|
||
$biblio_class->mock( 'hidden_in_opac', sub { return $biblio_hidden_in_opac; } );
|
||
|
||
$t->get_ok( "/api/v1/public/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'text/plain' } )
|
||
->status_is(404, 'hidden_in_opac + anonymous => hidden');
|
||
|
||
my $category_override_hidden_items = 0;
|
||
my $category_class = Test::MockModule->new('Koha::Patron::Category');
|
||
$category_class->mock( 'override_hidden_items', sub { return $category_override_hidden_items; } );
|
||
$t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'text/plain' } )
|
||
->status_is(404, "hidden_in_opac + patron whose category doesn't override => hidden");
|
||
|
||
# Make the category override
|
||
$category_override_hidden_items = 1;
|
||
$t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'text/plain' } )
|
||
->status_is(200, "hidden_in_opac + patron whose category that overrides => displayed");
|
||
|
||
t::lib::Mocks::mock_preference('OpacHiddenItems');
|
||
};
|
||
|
||
$biblio->delete;
|
||
$t->get_ok( "//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber
|
||
=> { Accept => 'application/marc' } )
|
||
->status_is(404)
|
||
->json_is( '/error', 'Bibliographic record not found' );
|
||
|
||
$schema->storage->txn_rollback;
|
||
};
|
||
|
||
subtest 'pickup_locations() tests' => sub {
|
||
|
||
plan tests => 16;
|
||
|
||
$schema->storage->txn_begin;
|
||
|
||
t::lib::Mocks::mock_preference( 'AllowHoldPolicyOverride', 0 );
|
||
|
||
# Small trick to ease testing
|
||
Koha::Libraries->search->update({ pickup_location => 0 });
|
||
|
||
my $library_1 = $builder->build_object({ class => 'Koha::Libraries', value => { marcorgcode => 'A', pickup_location => 1 } });
|
||
my $library_2 = $builder->build_object({ class => 'Koha::Libraries', value => { marcorgcode => 'B', pickup_location => 1 } });
|
||
my $library_3 = $builder->build_object({ class => 'Koha::Libraries', value => { marcorgcode => 'C', pickup_location => 1 } });
|
||
|
||
my $library_1_api = $library_1->to_api();
|
||
my $library_2_api = $library_2->to_api();
|
||
my $library_3_api = $library_3->to_api();
|
||
|
||
$library_1_api->{needs_override} = Mojo::JSON->false;
|
||
$library_2_api->{needs_override} = Mojo::JSON->false;
|
||
$library_3_api->{needs_override} = Mojo::JSON->true;
|
||
|
||
$library_1_api->{pickup_items} = [];
|
||
$library_2_api->{pickup_items} = [];
|
||
$library_3_api->{pickup_items} = [];
|
||
|
||
my $patron = $builder->build_object(
|
||
{
|
||
class => 'Koha::Patrons',
|
||
value => { userid => 'tomasito', flags => 0 }
|
||
}
|
||
);
|
||
my $password = 'thePassword123';
|
||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||
my $userid = $patron->userid;
|
||
$builder->build(
|
||
{
|
||
source => 'UserPermission',
|
||
value => {
|
||
borrowernumber => $patron->borrowernumber,
|
||
module_bit => 6,
|
||
code => 'place_holds',
|
||
},
|
||
}
|
||
);
|
||
|
||
my $biblio_class = Test::MockModule->new('Koha::Biblio');
|
||
$biblio_class->mock(
|
||
'pickup_locations',
|
||
sub {
|
||
my ( $self, $params ) = @_;
|
||
my $mock_patron = $params->{patron};
|
||
is( $mock_patron->borrowernumber,
|
||
$patron->borrowernumber, 'Patron passed correctly' );
|
||
return Koha::Libraries->search(
|
||
{
|
||
branchcode => {
|
||
'-in' => [
|
||
$library_1->branchcode,
|
||
$library_2->branchcode
|
||
]
|
||
}
|
||
},
|
||
{ # we make sure no surprises in the order of the result
|
||
order_by => { '-asc' => 'marcorgcode' }
|
||
}
|
||
);
|
||
}
|
||
);
|
||
|
||
my $biblio = $builder->build_sample_biblio;
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/"
|
||
. $biblio->id
|
||
. "/pickup_locations?patron_id=" . $patron->id )
|
||
->json_is( [ $library_1_api, $library_2_api ] );
|
||
|
||
# filtering works!
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/"
|
||
. $biblio->id
|
||
. '/pickup_locations?'
|
||
. 'patron_id=' . $patron->id . '&q={"marc_org_code": { "-like": "A%" }}' )
|
||
->json_is( [ $library_1_api ] );
|
||
|
||
t::lib::Mocks::mock_preference( 'AllowHoldPolicyOverride', 1 );
|
||
|
||
my $library_4 = $builder->build_object({ class => 'Koha::Libraries', value => { pickup_location => 0, marcorgcode => 'X' } });
|
||
my $library_5 = $builder->build_object({ class => 'Koha::Libraries', value => { pickup_location => 1, marcorgcode => 'Y' } });
|
||
|
||
my $library_5_api = $library_5->to_api();
|
||
$library_5_api->{needs_override} = Mojo::JSON->true;
|
||
$library_5_api->{pickup_items} = [];
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/"
|
||
. $biblio->id
|
||
. "/pickup_locations?"
|
||
. "patron_id=" . $patron->id . "&_order_by=marc_org_code" )
|
||
->json_is( [ $library_1_api, $library_2_api, $library_3_api, $library_5_api ] );
|
||
|
||
subtest 'Pagination and AllowHoldPolicyOverride tests' => sub {
|
||
|
||
plan tests => 27;
|
||
|
||
t::lib::Mocks::mock_preference( 'AllowHoldPolicyOverride', 1 );
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->id . "/pickup_locations?" . "patron_id=" . $patron->id . "&_order_by=marc_org_code" . "&_per_page=1" )
|
||
->json_is( [$library_1_api] )
|
||
->header_is( 'X-Total-Count', '4', '4 is the count for libraries with pickup_location=1' )
|
||
->header_is( 'X-Base-Total-Count', '4', '4 is the count for libraries with pickup_location=1' )
|
||
->header_unlike( 'Link', qr|rel="prev"| )
|
||
->header_like( 'Link', qr#(_per_page=1.*\&_page=2.*|_page=2.*\&_per_page=1.*)>\; rel="next"# )
|
||
->header_like( 'Link', qr#(_per_page=1.*\&_page=1.*|_page=1.*\&_per_page=1).*>\; rel="first"# )
|
||
->header_like( 'Link', qr#(_per_page=1.*\&_page=4.*|_page=4.*\&_per_page=1).*>\; rel="last"# );
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/"
|
||
. $biblio->id
|
||
. "/pickup_locations?"
|
||
. "patron_id="
|
||
. $patron->id
|
||
. "&_order_by=marc_org_code"
|
||
. "&_per_page=1&_page=3" ) # force the needs_override=1 check
|
||
->json_is( [$library_3_api] )
|
||
->header_is( 'X-Total-Count', '4', '4 is the count for libraries with pickup_location=1' )
|
||
->header_is( 'X-Base-Total-Count', '4', '4 is the count for libraries with pickup_location=1' )
|
||
->header_like( 'Link', qr#(_per_page=1.*\&_page=2.*|_page=2.*\&_per_page=1.*)>\; rel="prev"# )
|
||
->header_like( 'Link', qr#(_per_page=1.*\&_page=4.*|_page=4.*\&_per_page=1.*)>\; rel="next"# )
|
||
->header_like( 'Link', qr#(_per_page=1.*\&_page=1.*|_page=1.*\&_per_page=1).*>\; rel="first"# )
|
||
->header_like( 'Link', qr#(_per_page=1.*\&_page=4.*|_page=4.*\&_per_page=1).*>\; rel="last"# );
|
||
|
||
t::lib::Mocks::mock_preference( 'AllowHoldPolicyOverride', 0 );
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->id . "/pickup_locations?" . "patron_id=" . $patron->id . "&_order_by=marc_org_code" . "&_per_page=1" )
|
||
->json_is( [$library_1_api] )
|
||
->header_is( 'X-Total-Count', '2' )
|
||
->header_is( 'X-Base-Total-Count', '2' )
|
||
->header_unlike( 'Link', qr|rel="prev"| )
|
||
->header_like( 'Link', qr#(_per_page=1.*\&_page=2.*|_page=2.*\&_per_page=1.*)>\; rel="next"# )
|
||
->header_like( 'Link', qr#(_per_page=1.*\&_page=1.*|_page=1.*\&_per_page=1).*>\; rel="first"# )
|
||
->header_like( 'Link', qr#(_per_page=1.*\&_page=2.*|_page=2.*\&_per_page=1).*>\; rel="last"# );
|
||
};
|
||
|
||
my $deleted_patron = $builder->build_object({ class => 'Koha::Patrons' });
|
||
my $deleted_patron_id = $deleted_patron->id;
|
||
$deleted_patron->delete;
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/"
|
||
. $biblio->id
|
||
. "/pickup_locations?"
|
||
. "patron_id=" . $deleted_patron_id )
|
||
->status_is( 400 )
|
||
->json_is( '/error' => 'Patron not found' );
|
||
|
||
$biblio->delete;
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/"
|
||
. $biblio->id
|
||
. "/pickup_locations?"
|
||
. "patron_id=" . $patron->id )
|
||
->status_is( 404 )
|
||
->json_is( '/error' => 'Bibliographic record not found' );
|
||
|
||
$schema->storage->txn_rollback;
|
||
};
|
||
|
||
subtest 'get_items_public() tests' => sub {
|
||
|
||
plan tests => 15;
|
||
|
||
$schema->storage->txn_begin;
|
||
|
||
my $override_hidden_items = 0;
|
||
|
||
my $mocked_category = Test::MockModule->new('Koha::Patron::Category');
|
||
$mocked_category->mock(
|
||
'override_hidden_items',
|
||
sub {
|
||
return $override_hidden_items;
|
||
}
|
||
);
|
||
|
||
my $rules = undef;
|
||
|
||
my $mocked_context = Test::MockModule->new('C4::Context');
|
||
$mocked_context->mock(
|
||
'yaml_preference',
|
||
sub {
|
||
return $rules;
|
||
}
|
||
);
|
||
|
||
my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
|
||
my $password = 'thePassword123';
|
||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||
$patron->discard_changes;
|
||
my $userid = $patron->userid;
|
||
|
||
my $biblio = $builder->build_sample_biblio();
|
||
|
||
$t->get_ok(
|
||
"//$userid:$password@/api/v1/public/biblios/" . $biblio->id . "/items" )
|
||
->status_is(200)->json_is( '' => [], 'No items on the biblio' );
|
||
|
||
my $item_1 = $builder->build_sample_item( { biblionumber => $biblio->id } );
|
||
my $item_2 = $builder->build_sample_item(
|
||
{ biblionumber => $biblio->id, withdrawn => 1 } );
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/public/biblios/"
|
||
. $biblio->biblionumber
|
||
. "/items" )->status_is(200)->json_is(
|
||
'' => [
|
||
$item_1->to_api( { public => 1 } ),
|
||
$item_2->to_api( { public => 1 } )
|
||
],
|
||
'The items are returned'
|
||
);
|
||
|
||
$rules = { withdrawn => ['1'] };
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/public/biblios/"
|
||
. $biblio->biblionumber
|
||
. "/items" )->status_is(200)->json_is(
|
||
'' => [ $item_1->to_api( { public => 1 } ) ],
|
||
'The items are returned, hidden one is not returned'
|
||
);
|
||
|
||
$t->get_ok( "/api/v1/public/biblios/"
|
||
. $biblio->biblionumber
|
||
. "/items" )->status_is(200)->json_is(
|
||
'' => [ $item_1->to_api( { public => 1 } ) ],
|
||
'Anonymous user, items are returned, hidden one is not returned'
|
||
);
|
||
|
||
|
||
$override_hidden_items = 1;
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/public/biblios/"
|
||
. $biblio->biblionumber
|
||
. "/items" )->status_is(200)->json_is(
|
||
'' => [
|
||
$item_1->to_api( { public => 1 } ),
|
||
$item_2->to_api( { public => 1 } )
|
||
],
|
||
'The items are returned, the patron category has an override'
|
||
);
|
||
|
||
$schema->storage->txn_rollback;
|
||
};
|
||
|
||
subtest 'get_bookings() tests' => sub {
|
||
|
||
plan tests => 8;
|
||
|
||
$schema->storage->txn_begin;
|
||
|
||
my $librarian = $builder->build_object(
|
||
{
|
||
class => 'Koha::Patrons',
|
||
value => { flags => 0 } # no additional permissions
|
||
}
|
||
);
|
||
$builder->build(
|
||
{
|
||
source => 'UserPermission',
|
||
value => {
|
||
borrowernumber => $librarian->borrowernumber,
|
||
module_bit => 1,
|
||
code => 'manage_bookings',
|
||
},
|
||
}
|
||
);
|
||
my $password = 'thePassword123';
|
||
$librarian->set_password( { password => $password, skip_validation => 1 } );
|
||
my $userid = $librarian->userid;
|
||
|
||
my $patron = $builder->build_object(
|
||
{
|
||
class => 'Koha::Patrons',
|
||
value => { flags => 0 }
|
||
}
|
||
);
|
||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||
my $unauth_userid = $patron->userid;
|
||
|
||
my $biblio = $builder->build_sample_biblio();
|
||
my $item1 = $builder->build_sample_item( { bookable => 1, biblionumber => $biblio->id } );
|
||
my $item2 = $builder->build_sample_item( { bookable => 1, biblionumber => $biblio->id } );
|
||
|
||
$t->get_ok( "//$unauth_userid:$password@/api/v1/biblios/" . $biblio->biblionumber . "/bookings" )->status_is(403);
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber . "/bookings" )->status_is(200)
|
||
->json_is( '' => [], 'No bookings on the biblio' );
|
||
|
||
# One booking
|
||
my $start_0 = dt_from_string->subtract( days => 2 )->truncate( to => 'day' );
|
||
my $end_0 = dt_from_string->add( days => 4 )->truncate( to => 'day' );
|
||
my $booking_0 = $builder->build_object(
|
||
{
|
||
class => 'Koha::Bookings',
|
||
value => {
|
||
biblio_id => $biblio->id,
|
||
item_id => $item1->id,
|
||
start_date => $start_0,
|
||
end_date => $end_0
|
||
}
|
||
}
|
||
);
|
||
|
||
my $ret = $t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber . "/bookings" )->status_is(200)
|
||
->tx->res->json;
|
||
|
||
is_deeply( $ret, [ $booking_0->to_api ] );
|
||
|
||
$schema->storage->txn_rollback;
|
||
};
|
||
|
||
subtest 'get_checkouts() tests' => sub {
|
||
|
||
plan tests => 17;
|
||
|
||
$schema->storage->txn_begin;
|
||
|
||
my $patron = $builder->build_object(
|
||
{
|
||
class => 'Koha::Patrons',
|
||
value => { flags => 0 }
|
||
}
|
||
);
|
||
my $password = 'thePassword123';
|
||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||
$patron->discard_changes;
|
||
my $userid = $patron->userid;
|
||
|
||
my $biblio = $builder->build_sample_biblio();
|
||
$t->get_ok("//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber . "/checkouts")
|
||
->status_is(403);
|
||
|
||
$builder->build(
|
||
{
|
||
source => 'UserPermission',
|
||
value => {
|
||
borrowernumber => $patron->borrowernumber,
|
||
module_bit => 1,
|
||
code => 'circulate_remaining_permissions',
|
||
},
|
||
}
|
||
);
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber . "/checkouts" )
|
||
->status_is( 200, 'circulate_remaining_permissions allows checkouts access' )
|
||
->json_is( '' => [], 'No checkouts on the biblio' );
|
||
|
||
my $bookings_librarian = $builder->build_object(
|
||
{
|
||
class => 'Koha::Patrons',
|
||
value => { flags => 0 } # no additional permissions
|
||
}
|
||
);
|
||
$builder->build(
|
||
{
|
||
source => 'UserPermission',
|
||
value => {
|
||
borrowernumber => $bookings_librarian->borrowernumber,
|
||
module_bit => 1,
|
||
code => 'manage_bookings',
|
||
},
|
||
}
|
||
);
|
||
$bookings_librarian->set_password( { password => $password, skip_validation => 1 } );
|
||
my $bookings_userid = $bookings_librarian->userid;
|
||
|
||
$t->get_ok( "//$bookings_userid:$password@/api/v1/biblios/" . $biblio->biblionumber . "/checkouts" )
|
||
->status_is( 200, 'manage_bookings allows checkouts access' )
|
||
->json_is( '' => [], 'No checkouts on the biblio' );
|
||
|
||
my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
|
||
my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
|
||
|
||
AddIssue( $patron, $item_1->barcode );
|
||
AddIssue( $patron, $item_2->barcode );
|
||
|
||
my $ret = $t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber . "/checkouts")
|
||
->status_is(200)
|
||
->tx->res->json;
|
||
|
||
my $checkout_1 = Koha::Checkouts->find({ itemnumber => $item_1->id });
|
||
my $checkout_2 = Koha::Checkouts->find({ itemnumber => $item_2->id });
|
||
|
||
is_deeply( $ret, [ $checkout_1->to_api, $checkout_2->to_api ] );
|
||
|
||
AddReturn( $item_1->barcode );
|
||
|
||
$ret = $t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber . "/checkouts")
|
||
->status_is(200)
|
||
->tx->res->json;
|
||
|
||
is_deeply( $ret, [ $checkout_2->to_api ] );
|
||
|
||
$ret = $t->get_ok( "//$userid:$password@/api/v1/biblios/" . $biblio->biblionumber . "/checkouts?checked_in=1")
|
||
->status_is(200)
|
||
->tx->res->json;
|
||
|
||
my $old_checkout_1 = Koha::Old::Checkouts->find( $checkout_1->id );
|
||
|
||
is_deeply( $ret, [ $old_checkout_1->to_api ] );
|
||
|
||
$schema->storage->txn_rollback;
|
||
};
|
||
|
||
subtest 'set_rating() tests' => sub {
|
||
|
||
plan tests => 12;
|
||
|
||
$schema->storage->txn_begin;
|
||
|
||
my $patron = $builder->build_object(
|
||
{
|
||
class => 'Koha::Patrons',
|
||
value => { flags => 0 }
|
||
}
|
||
);
|
||
my $password = 'thePassword123';
|
||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||
$patron->discard_changes;
|
||
my $userid = $patron->userid;
|
||
|
||
my $biblio = $builder->build_sample_biblio();
|
||
$t->post_ok("/api/v1/public/biblios/" . $biblio->biblionumber . "/ratings" => json => { rating => 3 })
|
||
->status_is(403);
|
||
|
||
$t->post_ok("//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber . "/ratings" => json => { rating => 3 })
|
||
->status_is(200)
|
||
->json_is( '/rating', '3' )
|
||
->json_is( '/average', '3' )
|
||
->json_is( '/count', '1' );
|
||
|
||
$t->post_ok("//$userid:$password@/api/v1/public/biblios/" . $biblio->biblionumber . "/ratings" => json => { rating => undef })
|
||
->status_is(200)
|
||
->json_is( '/rating', undef )
|
||
->json_is( '/average', '0' )
|
||
->json_is( '/count', '0' );
|
||
|
||
$schema->storage->txn_rollback;
|
||
|
||
};
|
||
|
||
|
||
subtest 'post() tests' => sub {
|
||
|
||
plan tests => 14;
|
||
|
||
$schema->storage->txn_begin;
|
||
|
||
my $patron = $builder->build_object(
|
||
{
|
||
class => 'Koha::Patrons',
|
||
value => { flags => 0 } # no permissions
|
||
}
|
||
);
|
||
my $password = 'thePassword123';
|
||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||
my $userid = $patron->userid;
|
||
|
||
my $frameworkcode = 'BKS';
|
||
my $marcxml = q|<?xml version="1.0" encoding="UTF-8"?>
|
||
<record
|
||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||
xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"
|
||
xmlns="http://www.loc.gov/MARC21/slim">
|
||
|
||
<leader>01102pam a2200289 a 7500</leader>
|
||
<controlfield tag="001">2504398</controlfield>
|
||
<controlfield tag="005">20200421093816.0</controlfield>
|
||
<controlfield tag="008">920610s1993 caub s001 0 eng </controlfield>
|
||
<datafield tag="010" ind1=" " ind2=" ">
|
||
<subfield code="a"> 92021731 </subfield>
|
||
</datafield>
|
||
<datafield tag="020" ind1=" " ind2=" ">
|
||
<subfield code="a">05200784381 (Test marcxml)</subfield>
|
||
</datafield>
|
||
<datafield tag="020" ind1=" " ind2=" ">
|
||
<subfield code="a">05200784461 (Test marcxml)</subfield>
|
||
</datafield>
|
||
<datafield tag="040" ind1=" " ind2=" ">
|
||
<subfield code="a">DLC</subfield>
|
||
<subfield code="c">DLC</subfield>
|
||
<subfield code="d">DLC</subfield>
|
||
</datafield>
|
||
<datafield tag="041" ind1="0" ind2=" ">
|
||
<subfield code="a">enggrc</subfield>
|
||
</datafield>
|
||
<datafield tag="050" ind1="0" ind2="0">
|
||
<subfield code="a">PA522</subfield>
|
||
<subfield code="b">.M38 1993</subfield>
|
||
</datafield>
|
||
<datafield tag="082" ind1="0" ind2="0">
|
||
<subfield code="a">480</subfield>
|
||
<subfield code="2">20</subfield>
|
||
</datafield>
|
||
<datafield tag="100" ind1="1" ind2=" ">
|
||
<subfield code="a">Mastronarde, Donald J.</subfield>
|
||
<subfield code="9">389</subfield>
|
||
</datafield>
|
||
<datafield tag="245" ind1="1" ind2="0">
|
||
<subfield code="a">Introduction to Attic Greek (Using marcxml) /</subfield>
|
||
<subfield code="c">Donald J. Mastronarde.</subfield>
|
||
</datafield>
|
||
<datafield tag="260" ind1=" " ind2=" ">
|
||
<subfield code="a">Berkeley :</subfield>
|
||
<subfield code="b">University of California Press,</subfield>
|
||
<subfield code="c">c1993.</subfield>
|
||
</datafield>
|
||
<datafield tag="300" ind1=" " ind2=" ">
|
||
<subfield code="a">ix, 425 p. :</subfield>
|
||
<subfield code="b">maps ;</subfield>
|
||
<subfield code="c">26 cm.</subfield>
|
||
</datafield>
|
||
<datafield tag="500" ind1=" " ind2=" ">
|
||
<subfield code="a">Includes index.</subfield>
|
||
</datafield>
|
||
<datafield tag="650" ind1=" " ind2="0">
|
||
<subfield code="a">Attic Greek dialect</subfield>
|
||
<subfield code="9">7</subfield>
|
||
</datafield>
|
||
<datafield tag="856" ind1="4" ind2="2">
|
||
<subfield code="3">Contributor biographical information</subfield>
|
||
<subfield code="u">http://www.loc.gov/catdir/bios/ucal051/92021731.html</subfield>
|
||
</datafield>
|
||
<datafield tag="856" ind1="4" ind2="2">
|
||
<subfield code="3">Publisher description</subfield>
|
||
<subfield code="u">http://www.loc.gov/catdir/description/ucal041/92021731.html</subfield>
|
||
</datafield>
|
||
<datafield tag="906" ind1=" " ind2=" ">
|
||
<subfield code="a">7</subfield>
|
||
<subfield code="b">cbc</subfield>
|
||
<subfield code="c">orignew</subfield>
|
||
<subfield code="d">1</subfield>
|
||
<subfield code="e">ocip</subfield>
|
||
<subfield code="f">19</subfield>
|
||
<subfield code="g">y-gencatlg</subfield>
|
||
</datafield>
|
||
<datafield tag="942" ind1=" " ind2=" ">
|
||
<subfield code="2">ddc</subfield>
|
||
<subfield code="c">BK</subfield>
|
||
</datafield>
|
||
<datafield tag="955" ind1=" " ind2=" ">
|
||
<subfield code="a">pc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93</subfield>
|
||
</datafield>
|
||
<datafield tag="999" ind1=" " ind2=" ">
|
||
<subfield code="c">3</subfield>
|
||
<subfield code="d">3</subfield>
|
||
</datafield>
|
||
</record>|;
|
||
|
||
my $mij = q|{
|
||
"fields": [
|
||
{
|
||
"001": "2504398"
|
||
},
|
||
{
|
||
"005": "20200421093816.0"
|
||
},
|
||
{
|
||
"008": "920610s1993 caub s001 0 eng "
|
||
},
|
||
{
|
||
"010": {
|
||
"ind1": " ",
|
||
"subfields": [
|
||
{
|
||
"a": " 92021731 "
|
||
}
|
||
],
|
||
"ind2": " "
|
||
}
|
||
},
|
||
{
|
||
"020": {
|
||
"subfields": [
|
||
{
|
||
"a": "05200784382 (Test mij)"
|
||
}
|
||
],
|
||
"ind2": " ",
|
||
"ind1": " "
|
||
}
|
||
},
|
||
{
|
||
"020": {
|
||
"subfields": [
|
||
{
|
||
"a": "05200784462 (Test mij)"
|
||
}
|
||
],
|
||
"ind1": " ",
|
||
"ind2": " "
|
||
}
|
||
},
|
||
{
|
||
"040": {
|
||
"subfields": [
|
||
{
|
||
"a": "DLC"
|
||
},
|
||
{
|
||
"c": "DLC"
|
||
},
|
||
{
|
||
"d": "DLC"
|
||
}
|
||
],
|
||
"ind2": " ",
|
||
"ind1": " "
|
||
}
|
||
},
|
||
{
|
||
"041": {
|
||
"ind2": " ",
|
||
"subfields": [
|
||
{
|
||
"a": "enggrc"
|
||
}
|
||
],
|
||
"ind1": "0"
|
||
}
|
||
},
|
||
{
|
||
"050": {
|
||
"subfields": [
|
||
{
|
||
"a": "PA522"
|
||
},
|
||
{
|
||
"b": ".M38 1993"
|
||
}
|
||
],
|
||
"ind1": "0",
|
||
"ind2": "0"
|
||
}
|
||
},
|
||
{
|
||
"082": {
|
||
"subfields": [
|
||
{
|
||
"a": "480"
|
||
},
|
||
{
|
||
"2": "20"
|
||
}
|
||
],
|
||
"ind2": "0",
|
||
"ind1": "0"
|
||
}
|
||
},
|
||
{
|
||
"100": {
|
||
"ind2": " ",
|
||
"subfields": [
|
||
{
|
||
"a": "Mastronarde, Donald J."
|
||
},
|
||
{
|
||
"9": "389"
|
||
}
|
||
],
|
||
"ind1": "1"
|
||
}
|
||
},
|
||
{
|
||
"245": {
|
||
"ind1": "1",
|
||
"subfields": [
|
||
{
|
||
"a": "Introduction to Attic Greek (Using mij) /"
|
||
},
|
||
{
|
||
"c": "Donald J. Mastronarde."
|
||
}
|
||
],
|
||
"ind2": "0"
|
||
}
|
||
},
|
||
{
|
||
"260": {
|
||
"subfields": [
|
||
{
|
||
"a": "Berkeley :"
|
||
},
|
||
{
|
||
"b": "University of California Press,"
|
||
},
|
||
{
|
||
"c": "c1993."
|
||
}
|
||
],
|
||
"ind2": " ",
|
||
"ind1": " "
|
||
}
|
||
},
|
||
{
|
||
"300": {
|
||
"ind1": " ",
|
||
"subfields": [
|
||
{
|
||
"a": "ix, 425 p. :"
|
||
},
|
||
{
|
||
"b": "maps ;"
|
||
},
|
||
{
|
||
"c": "26 cm."
|
||
}
|
||
],
|
||
"ind2": " "
|
||
}
|
||
},
|
||
{
|
||
"500": {
|
||
"subfields": [
|
||
{
|
||
"a": "Includes index."
|
||
}
|
||
],
|
||
"ind1": " ",
|
||
"ind2": " "
|
||
}
|
||
},
|
||
{
|
||
"650": {
|
||
"subfields": [
|
||
{
|
||
"a": "Attic Greek dialect"
|
||
},
|
||
{
|
||
"9": "7"
|
||
}
|
||
],
|
||
"ind2": "0",
|
||
"ind1": " "
|
||
}
|
||
},
|
||
{
|
||
"856": {
|
||
"subfields": [
|
||
{
|
||
"3": "Contributor biographical information"
|
||
},
|
||
{
|
||
"u": "http://www.loc.gov/catdir/bios/ucal051/92021731.html"
|
||
}
|
||
],
|
||
"ind2": "2",
|
||
"ind1": "4"
|
||
}
|
||
},
|
||
{
|
||
"856": {
|
||
"ind1": "4",
|
||
"subfields": [
|
||
{
|
||
"3": "Publisher description"
|
||
},
|
||
{
|
||
"u": "http://www.loc.gov/catdir/description/ucal041/92021731.html"
|
||
}
|
||
],
|
||
"ind2": "2"
|
||
}
|
||
},
|
||
{
|
||
"906": {
|
||
"subfields": [
|
||
{
|
||
"a": "7"
|
||
},
|
||
{
|
||
"b": "cbc"
|
||
},
|
||
{
|
||
"c": "orignew"
|
||
},
|
||
{
|
||
"d": "1"
|
||
},
|
||
{
|
||
"e": "ocip"
|
||
},
|
||
{
|
||
"f": "19"
|
||
},
|
||
{
|
||
"g": "y-gencatlg"
|
||
}
|
||
],
|
||
"ind1": " ",
|
||
"ind2": " "
|
||
}
|
||
},
|
||
{
|
||
"942": {
|
||
"subfields": [
|
||
{
|
||
"2": "ddc"
|
||
},
|
||
{
|
||
"c": "BK"
|
||
}
|
||
],
|
||
"ind2": " ",
|
||
"ind1": " "
|
||
}
|
||
},
|
||
{
|
||
"955": {
|
||
"subfields": [
|
||
{
|
||
"a": "pc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93"
|
||
}
|
||
],
|
||
"ind2": " ",
|
||
"ind1": " "
|
||
}
|
||
},
|
||
{
|
||
"999": {
|
||
"subfields": [
|
||
{
|
||
"c": "3"
|
||
},
|
||
{
|
||
"d": "3"
|
||
}
|
||
],
|
||
"ind1": " ",
|
||
"ind2": " "
|
||
}
|
||
}
|
||
],
|
||
"leader": "01102pam a2200289 a 8500"
|
||
}|;
|
||
my $marc = q|01102pam a2200289 a 9500001000800000005001700008008004100025010001700066020002800083020003500111040001800146041001100164050002100175082001200196100003200208245005800240260005600298300003300354500002000387650002700407856009500434856008700529906004500616942001200661955013000673999000900803250439820200421093816.0920610s1993 caub s001 0 eng a 92021731 a05200784383 (Test usmarc) a05200784463 (Test usmarc) aDLCcDLCdDLC0 aenggrc00aPA522b.M38 199300a4802201 aMastronarde, Donald J.938910aIntroduction to Attic Greek (Using usmarc) /cDonald J. Mastronarde. aBerkeley :bUniversity of California Press,cc1993. aix, 425 p. :bmaps ;c26 cm. aIncludes index. 0aAttic Greek dialect97423Contributor biographical informationuhttp://www.loc.gov/catdir/bios/ucal051/92021731.html423Publisher descriptionuhttp://www.loc.gov/catdir/description/ucal041/92021731.html a7bcbccorignewd1eocipf19gy-gencatlg 2ddccBK apc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93 c3d3|;
|
||
|
||
$t->post_ok("//$userid:$password@/api/v1/biblios")
|
||
->status_is(403, 'Not enough permissions makes it return the right code');
|
||
|
||
# Add permissions
|
||
$builder->build(
|
||
{
|
||
source => 'UserPermission',
|
||
value => {
|
||
borrowernumber => $patron->borrowernumber,
|
||
module_bit => 9,
|
||
code => 'edit_catalogue'
|
||
}
|
||
}
|
||
);
|
||
|
||
$t->post_ok("//$userid:$password@/api/v1/biblios" => {'Content-Type' => 'application/marcxml+xml', 'x-framework-id' => $frameworkcode, "x-record-schema" => 'INVALID'})
|
||
->status_is(400, 'Invalid header x-record-schema');
|
||
|
||
$t->post_ok("//$userid:$password@/api/v1/biblios" => {'Content-Type' => 'application/marcxml+xml', 'x-framework-id' => $frameworkcode} => $marcxml)
|
||
->status_is(200)
|
||
->json_has('/id');
|
||
|
||
$t->post_ok("//$userid:$password@/api/v1/biblios" => {'Content-Type' => 'application/marc-in-json', 'x-framework-id' => $frameworkcode, 'x-confirm-not-duplicate' => 1} => $mij)
|
||
->status_is(200)
|
||
->json_has('/id');
|
||
|
||
$t->post_ok("//$userid:$password@/api/v1/biblios" => {'Content-Type' => 'application/marc', 'x-framework-id' => $frameworkcode} => $marc)
|
||
->status_is(200)
|
||
->json_has('/id');
|
||
|
||
subtest 'x-record-source-id header tests' => sub {
|
||
|
||
plan tests => 5;
|
||
|
||
my $record_source =
|
||
$builder->build_object( { class => 'Koha::RecordSources', value => { can_be_edited => 0 } } );
|
||
|
||
$t->post_ok(
|
||
"//$userid:$password@/api/v1/biblios" => {
|
||
'Content-Type' => 'application/marc', 'x-framework-id' => $frameworkcode,
|
||
'x-record-source-id' => $record_source->id
|
||
} => $marc
|
||
)->status_is(403)->json_is( '/error' => 'You do not have permission to set the record source' );
|
||
|
||
# Add required subpermission
|
||
$builder->build(
|
||
{
|
||
source => 'UserPermission',
|
||
value => {
|
||
borrowernumber => $patron->id,
|
||
module_bit => 9,
|
||
code => 'set_record_sources'
|
||
}
|
||
}
|
||
);
|
||
|
||
$t->post_ok(
|
||
"//$userid:$password@/api/v1/biblios" => {
|
||
'Content-Type' => 'application/marc', 'x-framework-id' => $frameworkcode,
|
||
'x-record-source-id' => $record_source->id
|
||
} => $marc
|
||
)->status_is(200);
|
||
};
|
||
|
||
$schema->storage->txn_rollback;
|
||
};
|
||
|
||
subtest 'put() tests' => sub {
|
||
|
||
plan tests => 14;
|
||
|
||
$schema->storage->txn_begin;
|
||
|
||
my $patron = $builder->build_object(
|
||
{
|
||
class => 'Koha::Patrons',
|
||
value => { flags => 0 } # no permissions
|
||
}
|
||
);
|
||
my $password = 'thePassword123';
|
||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||
my $userid = $patron->userid;
|
||
|
||
my $frameworkcode = 'BKS';
|
||
my $biblio = $builder->build_sample_biblio({frameworkcode => $frameworkcode});
|
||
|
||
my $biblionumber = $biblio->biblionumber;
|
||
|
||
my $marcxml = q|<?xml version="1.0" encoding="UTF-8"?>
|
||
<record
|
||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||
xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"
|
||
xmlns="http://www.loc.gov/MARC21/slim">
|
||
|
||
<leader>01102pam a2200289 a 6500</leader>
|
||
<controlfield tag="001">2504398</controlfield>
|
||
<controlfield tag="005">20200421093816.0</controlfield>
|
||
<controlfield tag="008">920610s1993 caub s001 0 eng </controlfield>
|
||
<datafield tag="010" ind1=" " ind2=" ">
|
||
<subfield code="a"> 92021731 </subfield>
|
||
</datafield>
|
||
<datafield tag="020" ind1=" " ind2=" ">
|
||
<subfield code="a">05200784384 (Test json)</subfield>
|
||
</datafield>
|
||
<datafield tag="020" ind1=" " ind2=" ">
|
||
<subfield code="a">05200784464 (Test json)</subfield>
|
||
</datafield>
|
||
<datafield tag="040" ind1=" " ind2=" ">
|
||
<subfield code="a">DLC</subfield>
|
||
<subfield code="c">DLC</subfield>
|
||
<subfield code="d">DLC</subfield>
|
||
</datafield>
|
||
<datafield tag="041" ind1="0" ind2=" ">
|
||
<subfield code="a">enggrc</subfield>
|
||
</datafield>
|
||
<datafield tag="050" ind1="0" ind2="0">
|
||
<subfield code="a">PA522</subfield>
|
||
<subfield code="b">.M38 1993</subfield>
|
||
</datafield>
|
||
<datafield tag="082" ind1="0" ind2="0">
|
||
<subfield code="a">480</subfield>
|
||
<subfield code="2">20</subfield>
|
||
</datafield>
|
||
<datafield tag="100" ind1="1" ind2=" ">
|
||
<subfield code="a">Mastronarde, Donald J.</subfield>
|
||
<subfield code="9">389</subfield>
|
||
</datafield>
|
||
<datafield tag="245" ind1="1" ind2="0">
|
||
<subfield code="a">Introduction to Attic Greek (Using marcxml) /</subfield>
|
||
<subfield code="c">Donald J. Mastronarde.</subfield>
|
||
</datafield>
|
||
<datafield tag="260" ind1=" " ind2=" ">
|
||
<subfield code="a">Berkeley :</subfield>
|
||
<subfield code="b">University of California Press,</subfield>
|
||
<subfield code="c">c1993.</subfield>
|
||
</datafield>
|
||
<datafield tag="300" ind1=" " ind2=" ">
|
||
<subfield code="a">ix, 425 p. :</subfield>
|
||
<subfield code="b">maps ;</subfield>
|
||
<subfield code="c">26 cm.</subfield>
|
||
</datafield>
|
||
<datafield tag="500" ind1=" " ind2=" ">
|
||
<subfield code="a">Includes index.</subfield>
|
||
</datafield>
|
||
<datafield tag="650" ind1=" " ind2="0">
|
||
<subfield code="a">Attic Greek dialect</subfield>
|
||
<subfield code="9">7</subfield>
|
||
</datafield>
|
||
<datafield tag="856" ind1="4" ind2="2">
|
||
<subfield code="3">Contributor biographical information</subfield>
|
||
<subfield code="u">http://www.loc.gov/catdir/bios/ucal051/92021731.html</subfield>
|
||
</datafield>
|
||
<datafield tag="856" ind1="4" ind2="2">
|
||
<subfield code="3">Publisher description</subfield>
|
||
<subfield code="u">http://www.loc.gov/catdir/description/ucal041/92021731.html</subfield>
|
||
</datafield>
|
||
<datafield tag="906" ind1=" " ind2=" ">
|
||
<subfield code="a">7</subfield>
|
||
<subfield code="b">cbc</subfield>
|
||
<subfield code="c">orignew</subfield>
|
||
<subfield code="d">1</subfield>
|
||
<subfield code="e">ocip</subfield>
|
||
<subfield code="f">19</subfield>
|
||
<subfield code="g">y-gencatlg</subfield>
|
||
</datafield>
|
||
<datafield tag="942" ind1=" " ind2=" ">
|
||
<subfield code="2">ddc</subfield>
|
||
<subfield code="c">BK</subfield>
|
||
</datafield>
|
||
<datafield tag="955" ind1=" " ind2=" ">
|
||
<subfield code="a">pc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93</subfield>
|
||
</datafield>
|
||
<datafield tag="999" ind1=" " ind2=" ">
|
||
<subfield code="c">3</subfield>
|
||
<subfield code="d">3</subfield>
|
||
</datafield>
|
||
</record>|;
|
||
|
||
my $mij = q|{
|
||
"fields": [
|
||
{
|
||
"001": "2504398"
|
||
},
|
||
{
|
||
"005": "20200421093816.0"
|
||
},
|
||
{
|
||
"008": "920610s1993 caub s001 0 eng "
|
||
},
|
||
{
|
||
"010": {
|
||
"ind1": " ",
|
||
"subfields": [
|
||
{
|
||
"a": " 92021731 "
|
||
}
|
||
],
|
||
"ind2": " "
|
||
}
|
||
},
|
||
{
|
||
"020": {
|
||
"subfields": [
|
||
{
|
||
"a": "05200784382 (Test mij)"
|
||
}
|
||
],
|
||
"ind2": " ",
|
||
"ind1": " "
|
||
}
|
||
},
|
||
{
|
||
"020": {
|
||
"subfields": [
|
||
{
|
||
"a": "05200784462 (Test mij)"
|
||
}
|
||
],
|
||
"ind1": " ",
|
||
"ind2": " "
|
||
}
|
||
},
|
||
{
|
||
"040": {
|
||
"subfields": [
|
||
{
|
||
"a": "DLC"
|
||
},
|
||
{
|
||
"c": "DLC"
|
||
},
|
||
{
|
||
"d": "DLC"
|
||
}
|
||
],
|
||
"ind2": " ",
|
||
"ind1": " "
|
||
}
|
||
},
|
||
{
|
||
"041": {
|
||
"ind2": " ",
|
||
"subfields": [
|
||
{
|
||
"a": "enggrc"
|
||
}
|
||
],
|
||
"ind1": "0"
|
||
}
|
||
},
|
||
{
|
||
"050": {
|
||
"subfields": [
|
||
{
|
||
"a": "PA522"
|
||
},
|
||
{
|
||
"b": ".M38 1993"
|
||
}
|
||
],
|
||
"ind1": "0",
|
||
"ind2": "0"
|
||
}
|
||
},
|
||
{
|
||
"082": {
|
||
"subfields": [
|
||
{
|
||
"a": "480"
|
||
},
|
||
{
|
||
"2": "20"
|
||
}
|
||
],
|
||
"ind2": "0",
|
||
"ind1": "0"
|
||
}
|
||
},
|
||
{
|
||
"100": {
|
||
"ind2": " ",
|
||
"subfields": [
|
||
{
|
||
"a": "Mastronarde, Donald J."
|
||
},
|
||
{
|
||
"9": "389"
|
||
}
|
||
],
|
||
"ind1": "1"
|
||
}
|
||
},
|
||
{
|
||
"245": {
|
||
"ind1": "1",
|
||
"subfields": [
|
||
{
|
||
"a": "Introduction to Attic Greek (Using mij) /"
|
||
},
|
||
{
|
||
"c": "Donald J. Mastronarde."
|
||
}
|
||
],
|
||
"ind2": "0"
|
||
}
|
||
},
|
||
{
|
||
"260": {
|
||
"subfields": [
|
||
{
|
||
"a": "Berkeley :"
|
||
},
|
||
{
|
||
"b": "University of California Press,"
|
||
},
|
||
{
|
||
"c": "c1993."
|
||
}
|
||
],
|
||
"ind2": " ",
|
||
"ind1": " "
|
||
}
|
||
},
|
||
{
|
||
"300": {
|
||
"ind1": " ",
|
||
"subfields": [
|
||
{
|
||
"a": "ix, 425 p. :"
|
||
},
|
||
{
|
||
"b": "maps ;"
|
||
},
|
||
{
|
||
"c": "26 cm."
|
||
}
|
||
],
|
||
"ind2": " "
|
||
}
|
||
},
|
||
{
|
||
"500": {
|
||
"subfields": [
|
||
{
|
||
"a": "Includes index."
|
||
}
|
||
],
|
||
"ind1": " ",
|
||
"ind2": " "
|
||
}
|
||
},
|
||
{
|
||
"650": {
|
||
"subfields": [
|
||
{
|
||
"a": "Attic Greek dialect"
|
||
},
|
||
{
|
||
"9": "7"
|
||
}
|
||
],
|
||
"ind2": "0",
|
||
"ind1": " "
|
||
}
|
||
},
|
||
{
|
||
"856": {
|
||
"subfields": [
|
||
{
|
||
"3": "Contributor biographical information"
|
||
},
|
||
{
|
||
"u": "http://www.loc.gov/catdir/bios/ucal051/92021731.html"
|
||
}
|
||
],
|
||
"ind2": "2",
|
||
"ind1": "4"
|
||
}
|
||
},
|
||
{
|
||
"856": {
|
||
"ind1": "4",
|
||
"subfields": [
|
||
{
|
||
"3": "Publisher description"
|
||
},
|
||
{
|
||
"u": "http://www.loc.gov/catdir/description/ucal041/92021731.html"
|
||
}
|
||
],
|
||
"ind2": "2"
|
||
}
|
||
},
|
||
{
|
||
"906": {
|
||
"subfields": [
|
||
{
|
||
"a": "7"
|
||
},
|
||
{
|
||
"b": "cbc"
|
||
},
|
||
{
|
||
"c": "orignew"
|
||
},
|
||
{
|
||
"d": "1"
|
||
},
|
||
{
|
||
"e": "ocip"
|
||
},
|
||
{
|
||
"f": "19"
|
||
},
|
||
{
|
||
"g": "y-gencatlg"
|
||
}
|
||
],
|
||
"ind1": " ",
|
||
"ind2": " "
|
||
}
|
||
},
|
||
{
|
||
"942": {
|
||
"subfields": [
|
||
{
|
||
"2": "ddc"
|
||
},
|
||
{
|
||
"c": "BK"
|
||
}
|
||
],
|
||
"ind2": " ",
|
||
"ind1": " "
|
||
}
|
||
},
|
||
{
|
||
"955": {
|
||
"subfields": [
|
||
{
|
||
"a": "pc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93"
|
||
}
|
||
],
|
||
"ind2": " ",
|
||
"ind1": " "
|
||
}
|
||
},
|
||
{
|
||
"999": {
|
||
"subfields": [
|
||
{
|
||
"c": "3"
|
||
},
|
||
{
|
||
"d": "3"
|
||
}
|
||
],
|
||
"ind1": " ",
|
||
"ind2": " "
|
||
}
|
||
}
|
||
],
|
||
"leader": "01102pam a2200289 a 8500"
|
||
}|;
|
||
my $marc = q|01116pam a2200289 a 4500001000800000005001700008008004100025010001700066020002800083020002800111040001800139041001100157050002100168082001200189100003200201245007500233260005600308300003300364500002000397650002700417856009500444856008700539906004500626942001200671955013000683999001300813250439820221223213433.0920610s1993 caub s001 0 eng a 92021731 a05200784384 (Test json) a05200784464 (Test json) aDLCcDLCdDLC0 aenggrc00aPA522b.M38 199300a4802201 aMastronarde, Donald J.938910aIntroduction to Attic Greek (Using usmarc) /cDonald J. Mastronarde. aBerkeley :bUniversity of California Press,cc1993. aix, 425 p. :bmaps ;c26 cm. aIncludes index. 0aAttic Greek dialect97423Contributor biographical informationuhttp://www.loc.gov/catdir/bios/ucal051/92021731.html423Publisher descriptionuhttp://www.loc.gov/catdir/description/ucal041/92021731.html a7bcbccorignewd1eocipf19gy-gencatlg 2ddccBK apc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93 c715d715|;
|
||
|
||
$t->put_ok("//$userid:$password@/api/v1/biblios/$biblionumber")
|
||
->status_is(403, 'Not enough permissions makes it return the right code');
|
||
|
||
# Add permissions
|
||
$builder->build(
|
||
{
|
||
source => 'UserPermission',
|
||
value => {
|
||
borrowernumber => $patron->borrowernumber,
|
||
module_bit => 9,
|
||
code => 'edit_catalogue'
|
||
}
|
||
}
|
||
);
|
||
|
||
$t->put_ok("//$userid:$password@/api/v1/biblios/$biblionumber" => {'Content-Type' => 'application/marcxml+xml', 'x-framework-id' => $frameworkcode} => $marcxml)
|
||
->status_is(200)
|
||
->json_has('/id');
|
||
|
||
$biblio = Koha::Biblios->find($biblionumber);
|
||
|
||
is($biblio->title, 'Introduction to Attic Greek (Using marcxml) /');
|
||
|
||
$t->put_ok("//$userid:$password@/api/v1/biblios/$biblionumber" => {'Content-Type' => 'application/marc-in-json', 'x-framework-id' => $frameworkcode} => $mij)
|
||
->status_is(200)
|
||
->json_has('/id');
|
||
|
||
$biblio = Koha::Biblios->find($biblionumber);
|
||
|
||
is($biblio->title, 'Introduction to Attic Greek (Using mij) /');
|
||
|
||
$t->put_ok("//$userid:$password@/api/v1/biblios/$biblionumber" => {'Content-Type' => 'application/marc', 'x-framework-id' => $frameworkcode} => $marc)
|
||
->status_is(200)
|
||
->json_has('/id');
|
||
|
||
$biblio = Koha::Biblios->find($biblionumber);
|
||
|
||
is($biblio->title, 'Introduction to Attic Greek (Using usmarc) /');
|
||
|
||
$schema->storage->txn_rollback;
|
||
};
|
||
|
||
subtest 'list() tests' => sub {
|
||
|
||
plan tests => 17;
|
||
|
||
$schema->storage->txn_begin;
|
||
|
||
my $patron = $builder->build_object(
|
||
{
|
||
class => 'Koha::Patrons',
|
||
value => { flags => 0 }
|
||
}
|
||
);
|
||
my $password = 'thePassword123';
|
||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||
$patron->discard_changes;
|
||
my $userid = $patron->userid;
|
||
|
||
t::lib::Mocks::mock_preference('marcflavour', 'UNIMARC');
|
||
|
||
my $title_with_diacritics = "L'insoutenable légèreté de l'être";
|
||
my $biblio = $builder->build_sample_biblio(
|
||
{
|
||
title => $title_with_diacritics,
|
||
author => "Milan Kundera"
|
||
}
|
||
);
|
||
|
||
my $record = $biblio->metadata->record;
|
||
$record->leader(' nam 3 4500');
|
||
$biblio->metadata->metadata($record->as_xml_record('UNIMARC'))->store;
|
||
|
||
my $biblio_id_1 = $biblio->id;
|
||
|
||
t::lib::Mocks::mock_preference('marcflavour', 'MARC21');
|
||
my $biblio_id_2 = $builder->build_sample_biblio->id;
|
||
|
||
my $query = encode_json( [ { biblio_id => $biblio_id_1 }, { biblio_id => $biblio_id_2 } ] );
|
||
|
||
$t->get_ok("//$userid:$password@/api/v1/biblios?q=$query")->status_is(403);
|
||
|
||
$patron->flags(4)->store;
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios?q=$query" => { Accept => 'application/weird+format' } )
|
||
->status_is(400);
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios?q=$query" => { Accept => 'application/json' } )->status_is(200);
|
||
|
||
my $result = $t->get_ok( "//$userid:$password@/api/v1/biblios?q=$query" => { Accept => 'application/marcxml+xml' } )
|
||
->status_is(200)->tx->res->body;
|
||
|
||
my $encoded_title = Encode::encode( "UTF-8", $title_with_diacritics );
|
||
like( $result, qr/\Q$encoded_title/, "The title is not double encoded" );
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios?q=$query" => { Accept => 'application/marc-in-json' } )
|
||
->status_is(200);
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios?q=$query" => { Accept => 'application/marc' } )->status_is(200);
|
||
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios?q=$query" => { Accept => 'text/plain' } )->status_is(200);
|
||
|
||
# DELETE any biblio with ISBN = TOMAS
|
||
Koha::Biblios->search({ 'biblioitem.isbn' => 'TOMAS' }, { join => [ 'biblioitem' ] })
|
||
->delete;
|
||
|
||
|
||
my $isbn_query = encode_json({ isbn => 'TOMAS' });
|
||
$biblio->biblioitem->set({ isbn => 'TOMAS' })->store;
|
||
$t->get_ok( "//$userid:$password@/api/v1/biblios?q=$isbn_query" =>
|
||
{ Accept => 'text/plain' } )
|
||
->status_is(200);
|
||
|
||
$schema->storage->txn_rollback;
|
||
};
|
||
|
||
subtest 'add_item() tests' => sub {
|
||
plan tests => 7;
|
||
|
||
$schema->storage->txn_begin;
|
||
|
||
my $patron = $builder->build_object(
|
||
{
|
||
class => 'Koha::Patrons',
|
||
value => { flags => 0 }
|
||
}
|
||
);
|
||
my $password = 'thePassword123';
|
||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||
my $userid = $patron->userid;
|
||
|
||
my $biblio = $builder->build_sample_biblio();
|
||
my $biblio_id = $biblio->biblionumber;
|
||
|
||
my $barcode = 'mybarcode';
|
||
my $matching_items = Koha::Items->search({ barcode => $barcode });
|
||
|
||
while (my $item = $matching_items->next) {
|
||
$item->delete;
|
||
}
|
||
|
||
$t->post_ok("//$userid:$password@/api/v1/biblios/$biblio_id/items" => json => { external_id => $barcode })
|
||
->status_is(403, 'Not enough permissions to create an item');
|
||
|
||
# Add permissions
|
||
$builder->build(
|
||
{
|
||
source => 'UserPermission',
|
||
value => {
|
||
borrowernumber => $patron->borrowernumber,
|
||
module_bit => 9,
|
||
code => 'edit_catalogue'
|
||
}
|
||
}
|
||
);
|
||
|
||
$t->post_ok("//$userid:$password@/api/v1/biblios/$biblio_id/items" => json => {
|
||
external_id => $barcode,
|
||
})
|
||
->status_is(201, 'Item created')
|
||
->json_is('/biblio_id', $biblio_id);
|
||
|
||
my $item = $builder->build_sample_item();
|
||
|
||
$t->post_ok("//$userid:$password@/api/v1/biblios/$biblio_id/items" => json => {
|
||
external_id => $item->barcode,
|
||
})
|
||
->status_is(409, 'Duplicate barcode');
|
||
|
||
$schema->storage->txn_rollback;
|
||
};
|
||
|
||
subtest 'update_item() tests' => sub {
|
||
plan tests => 7;
|
||
|
||
$schema->storage->txn_begin;
|
||
|
||
my $patron = $builder->build_object(
|
||
{
|
||
class => 'Koha::Patrons',
|
||
value => { flags => 0 }
|
||
}
|
||
);
|
||
my $password = 'thePassword123';
|
||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||
my $userid = $patron->userid;
|
||
|
||
my $item = $builder->build_sample_item({ replacementprice => 5 });
|
||
my $biblio_id = $item->biblionumber;
|
||
my $item_id = $item->itemnumber;
|
||
|
||
my $biblio = Koha::Biblios->find($item->biblionumber);
|
||
|
||
my $matching_items = Koha::Items->search({ barcode => $item->barcode });
|
||
|
||
while (my $mbcitem = $matching_items->next) {
|
||
$mbcitem->delete if $mbcitem->biblionumber != $item->biblionumber;
|
||
}
|
||
|
||
$t->put_ok("//$userid:$password@/api/v1/biblios/$biblio_id/items/$item_id" => json => { external_id => 'something' })
|
||
->status_is(403, 'Not enough permissions to update an item');
|
||
|
||
# Add permissions
|
||
$builder->build(
|
||
{
|
||
source => 'UserPermission',
|
||
value => {
|
||
borrowernumber => $patron->borrowernumber,
|
||
module_bit => 9,
|
||
code => 'edit_catalogue'
|
||
}
|
||
}
|
||
);
|
||
|
||
my $other_item = $builder->build_sample_item();
|
||
|
||
$t->put_ok("//$userid:$password@/api/v1/biblios/$biblio_id/items/$item_id" => json => {
|
||
external_id => $other_item->barcode,
|
||
})
|
||
->status_is(409, 'Barcode not unique');
|
||
|
||
$t->put_ok("//$userid:$password@/api/v1/biblios/$biblio_id/items/$item_id" => json => {
|
||
replacement_price => 30,
|
||
})
|
||
->status_is(200, 'Item updated')
|
||
->json_is('/replacement_price', 30);
|
||
|
||
$schema->storage->txn_rollback;
|
||
};
|
||
|
||
subtest 'merge() tests' => sub {
|
||
plan tests => 12;
|
||
$schema->storage->txn_begin;
|
||
|
||
my $mij_rec = q|{
|
||
"fields": [
|
||
{
|
||
"001": "2504398"
|
||
},
|
||
{
|
||
"005": "20200421093816.0"
|
||
},
|
||
{
|
||
"008": "920610s1993 caub s001 0 eng "
|
||
},
|
||
{
|
||
"010": {
|
||
"ind1": " ",
|
||
"subfields": [
|
||
{
|
||
"a": " 92021731 "
|
||
}
|
||
],
|
||
"ind2": " "
|
||
}
|
||
},
|
||
{
|
||
"020": {
|
||
"subfields": [
|
||
{
|
||
"a": "05200784462 (Test mij)"
|
||
}
|
||
],
|
||
"ind1": " ",
|
||
"ind2": " "
|
||
}
|
||
},
|
||
{
|
||
"040": {
|
||
"subfields": [
|
||
{
|
||
"a": "DLC"
|
||
},
|
||
{
|
||
"c": "DLC"
|
||
},
|
||
{
|
||
"d": "DLC"
|
||
}
|
||
],
|
||
"ind2": " ",
|
||
"ind1": " "
|
||
}
|
||
},
|
||
{
|
||
"041": {
|
||
"ind2": " ",
|
||
"subfields": [
|
||
{
|
||
"a": "enggrc"
|
||
}
|
||
],
|
||
"ind1": "0"
|
||
}
|
||
},
|
||
{
|
||
"082": {
|
||
"subfields": [
|
||
{
|
||
"a": "480"
|
||
},
|
||
{
|
||
"2": "20"
|
||
}
|
||
],
|
||
"ind2": "0",
|
||
"ind1": "0"
|
||
}
|
||
},
|
||
{
|
||
"100": {
|
||
"ind2": " ",
|
||
"subfields": [
|
||
{
|
||
"a": "Mastronarde, Donald J."
|
||
},
|
||
{
|
||
"9": "389"
|
||
}
|
||
],
|
||
"ind1": "1"
|
||
}
|
||
},
|
||
{
|
||
"245": {
|
||
"ind1": "1",
|
||
"subfields": [
|
||
{
|
||
"a": "Introduction to Attic Greek (Using mij) /"
|
||
},
|
||
{
|
||
"c": "Donald J. Mastronarde."
|
||
}
|
||
],
|
||
"ind2": "0"
|
||
}
|
||
},
|
||
{
|
||
"260": {
|
||
"subfields": [
|
||
{
|
||
"a": "Berkeley :"
|
||
},
|
||
{
|
||
"b": "University of California Press,"
|
||
},
|
||
{
|
||
"c": "c1993."
|
||
}
|
||
],
|
||
"ind2": " ",
|
||
"ind1": " "
|
||
}
|
||
},
|
||
{
|
||
"300": {
|
||
"ind1": " ",
|
||
"subfields": [
|
||
{
|
||
"a": "ix, 425 p. :"
|
||
},
|
||
{
|
||
"b": "maps ;"
|
||
},
|
||
{
|
||
"c": "26 cm."
|
||
}
|
||
],
|
||
"ind2": " "
|
||
}
|
||
},
|
||
{
|
||
"650": {
|
||
"subfields": [
|
||
{
|
||
"a": "Attic Greek dialect"
|
||
},
|
||
{
|
||
"9": "7"
|
||
}
|
||
],
|
||
"ind2": "0",
|
||
"ind1": " "
|
||
}
|
||
},
|
||
{
|
||
"942": {
|
||
"subfields": [
|
||
{
|
||
"2": "ddc"
|
||
},
|
||
{
|
||
"c": "BK"
|
||
}
|
||
],
|
||
"ind2": " ",
|
||
"ind1": " "
|
||
}
|
||
},
|
||
{
|
||
"955": {
|
||
"subfields": [
|
||
{
|
||
"a": "pc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93"
|
||
}
|
||
],
|
||
"ind2": " ",
|
||
"ind1": " "
|
||
}
|
||
},
|
||
{
|
||
"999": {
|
||
"subfields": [
|
||
{
|
||
"c": "3"
|
||
},
|
||
{
|
||
"d": "3"
|
||
}
|
||
],
|
||
"ind1": " ",
|
||
"ind2": " "
|
||
}
|
||
}
|
||
],
|
||
"leader": "01102pam a2200289 a 8500"
|
||
}|;
|
||
|
||
my $patron = $builder->build_object(
|
||
{
|
||
class => 'Koha::Patrons',
|
||
value => { flags => 0 }
|
||
}
|
||
);
|
||
my $password = 'thePassword123';
|
||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||
my $userid = $patron->userid;
|
||
|
||
my $title_1 = 'Title number 1';
|
||
my $title_2 = 'Title number 2';
|
||
my $biblio1 = $builder->build_sample_biblio( { title => $title_1 } );
|
||
my $biblio2 = $builder->build_sample_biblio( { title => $title_2 } );
|
||
my $biblio_id1 = $biblio1->biblionumber;
|
||
my $biblio_id2 = $biblio2->biblionumber;
|
||
my $json_input1 = '{ "biblio_id_to_merge": "' . $biblio_id2 . '" }';
|
||
|
||
$t->post_ok( "//$userid:$password@/api/v1/biblios/$biblio_id1/merge" =>
|
||
{ 'Content-Type' => 'application/json', 'Accept' => 'application/marc-in-json' } => $json_input1 )
|
||
->status_is( 403, 'Not enough permissions to merge two bib records' );
|
||
|
||
# Add permissions
|
||
$patron->flags(516)->store;
|
||
|
||
$t->post_ok(
|
||
"//$userid:$password@/api/v1/biblios/$biblio_id1/merge" => { 'Content-Type' => 'application/weird+format' } =>
|
||
$json_input1 )->status_is( 400, 'Not correct headers' );
|
||
|
||
my $result =
|
||
$t->post_ok( "//$userid:$password@/api/v1/biblios/$biblio_id1/merge" =>
|
||
{ 'Content-Type' => 'application/json', 'Accept' => 'application/marc-in-json' } => $json_input1 )
|
||
->status_is(200)->tx->res->body;
|
||
like( $result, qr/$title_1/, "Merged record has the correct title" );
|
||
unlike( $result, qr/$title_2/, "Merged record doesn't have the wrong title" );
|
||
|
||
my $biblio3 = $builder->build_sample_biblio( { title => 'Title number 3' } );
|
||
my $biblio_id3 = $biblio3->biblionumber;
|
||
my $json_input2 = '{ "biblio_id_to_merge": "' . $biblio_id3 . '",
|
||
"rules": "override_ext",
|
||
"datarecord": ' . $mij_rec . ' }';
|
||
$result =
|
||
$t->post_ok( "//$userid:$password@/api/v1/biblios/$biblio_id1/merge" =>
|
||
{ 'Content-Type' => 'application/json', 'Accept' => 'application/marc-in-json' } => $json_input2 )
|
||
->status_is(200)->tx->res->body;
|
||
like( $result, qr/Using mij/, "Update with Marc-in-json record" );
|
||
unlike( $result, qr/$title_1/, "Change all record with dat in the 'datarecord' field" );
|
||
|
||
$schema->storage->txn_rollback;
|
||
}
|