View | Details | Raw Unified | Return to bug 27205
Collapse All | Expand All

(-)a/Koha/REST/V1/Holds.pm (-1 / +25 lines)
Lines 27-32 use Koha::Patrons; Link Here
27
use Koha::Holds;
27
use Koha::Holds;
28
use Koha::DateUtils;
28
use Koha::DateUtils;
29
29
30
use List::MoreUtils qw(any);
30
use Try::Tiny;
31
use Try::Tiny;
31
32
32
=head1 API
33
=head1 API
Lines 65-70 sub add { Link Here
65
        my $body = $c->validation->param('body');
66
        my $body = $c->validation->param('body');
66
67
67
        my $biblio;
68
        my $biblio;
69
        my $item;
68
70
69
        my $biblio_id         = $body->{biblio_id};
71
        my $biblio_id         = $body->{biblio_id};
70
        my $pickup_library_id = $body->{pickup_library_id};
72
        my $pickup_library_id = $body->{pickup_library_id};
Lines 99-105 sub add { Link Here
99
            }
101
            }
100
        }
102
        }
101
        elsif ($item_id) {
103
        elsif ($item_id) {
102
            my $item = Koha::Items->find($item_id);
104
            $item = Koha::Items->find($item_id);
103
105
104
            unless ($item) {
106
            unless ($item) {
105
                return $c->render(
107
                return $c->render(
Lines 136-141 sub add { Link Here
136
            );
138
            );
137
        }
139
        }
138
140
141
        # Validate pickup location
142
        my $valid_pickup_location;
143
        if ($item) {    # item-level hold
144
            $valid_pickup_location =
145
              any { $_->branchcode eq $pickup_library_id }
146
            $item->pickup_locations(
147
                { patron => $patron } );
148
        }
149
        else {
150
            $valid_pickup_location =
151
              any { $_->branchcode eq $pickup_library_id }
152
            $biblio->pickup_locations(
153
                { patron => $patron } );
154
        }
155
156
        return $c->render(
157
            status  => 400,
158
            openapi => {
159
                error => 'The supplied pickup location is not valid'
160
            }
161
        ) unless $valid_pickup_location;
162
139
        my $can_place_hold
163
        my $can_place_hold
140
            = $item_id
164
            = $item_id
141
            ? C4::Reserves::CanItemBeReserved( $patron_id, $item_id )
165
            ? C4::Reserves::CanItemBeReserved( $patron_id, $item_id )
(-)a/t/db_dependent/api/v1/holds.t (-3 / +135 lines)
Lines 17-23 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 11;
20
use Test::More tests => 12;
21
use Test::MockModule;
21
use Test::MockModule;
22
use Test::Mojo;
22
use Test::Mojo;
23
use t::lib::TestBuilder;
23
use t::lib::TestBuilder;
Lines 238-246 subtest "Test endpoints with permission" => sub { Link Here
238
      ->status_is(204, 'SWAGGER3.2.4')
238
      ->status_is(204, 'SWAGGER3.2.4')
239
      ->content_is('', 'SWAGGER3.3.4');
239
      ->content_is('', 'SWAGGER3.3.4');
240
240
241
    # Make sure pickup location checks doesn't get in the middle
242
    my $mock_biblio = Test::MockModule->new('Koha::Biblio');
243
    $mock_biblio->mock( 'pickup_locations', sub { return Koha::Libraries->search; });
244
    my $mock_item   = Test::MockModule->new('Koha::Item');
245
    $mock_item->mock( 'pickup_locations', sub { return Koha::Libraries->search });
246
241
    $t->post_ok( "//$userid_3:$password@/api/v1/holds" => json => $post_data )
247
    $t->post_ok( "//$userid_3:$password@/api/v1/holds" => json => $post_data )
242
      ->status_is(201)
248
      ->status_is(201)
243
      ->json_has('/hold_id');
249
      ->json_has('/hold_id');
250
244
    # Get id from response
251
    # Get id from response
245
    $reserve_id = $t->tx->res->json->{hold_id};
252
    $reserve_id = $t->tx->res->json->{hold_id};
246
253
Lines 290-295 subtest 'Reserves with itemtype' => sub { Link Here
290
      ->status_is(204, 'SWAGGER3.2.4')
297
      ->status_is(204, 'SWAGGER3.2.4')
291
      ->content_is('', 'SWAGGER3.3.4');
298
      ->content_is('', 'SWAGGER3.3.4');
292
299
300
    # Make sure pickup location checks doesn't get in the middle
301
    my $mock_biblio = Test::MockModule->new('Koha::Biblio');
302
    $mock_biblio->mock( 'pickup_locations', sub { return Koha::Libraries->search; });
303
    my $mock_item   = Test::MockModule->new('Koha::Item');
304
    $mock_item->mock( 'pickup_locations', sub { return Koha::Libraries->search });
305
293
    $t->post_ok( "//$userid_3:$password@/api/v1/holds" => json => $post_data )
306
    $t->post_ok( "//$userid_3:$password@/api/v1/holds" => json => $post_data )
294
      ->status_is(201)
307
      ->status_is(201)
295
      ->json_has('/hold_id');
308
      ->json_has('/hold_id');
Lines 329-334 subtest 'test AllowHoldDateInFuture' => sub { Link Here
329
342
330
    t::lib::Mocks::mock_preference( 'AllowHoldDateInFuture', 1 );
343
    t::lib::Mocks::mock_preference( 'AllowHoldDateInFuture', 1 );
331
344
345
    # Make sure pickup location checks doesn't get in the middle
346
    my $mock_biblio = Test::MockModule->new('Koha::Biblio');
347
    $mock_biblio->mock( 'pickup_locations', sub { return Koha::Libraries->search; });
348
    my $mock_item   = Test::MockModule->new('Koha::Item');
349
    $mock_item->mock( 'pickup_locations', sub { return Koha::Libraries->search });
350
332
    $t->post_ok( "//$userid_3:$password@/api/v1/holds" => json => $post_data )
351
    $t->post_ok( "//$userid_3:$password@/api/v1/holds" => json => $post_data )
333
      ->status_is(201)
352
      ->status_is(201)
334
      ->json_is('/hold_date', output_pref({ dt => $future_hold_date, dateformat => 'rfc3339', dateonly => 1 }));
353
      ->json_is('/hold_date', output_pref({ dt => $future_hold_date, dateformat => 'rfc3339', dateonly => 1 }));
Lines 345-357 subtest 'test AllowHoldPolicyOverride' => sub { Link Here
345
            itemtype     => undef,
364
            itemtype     => undef,
346
            branchcode   => undef,
365
            branchcode   => undef,
347
            rules        => {
366
            rules        => {
348
                holdallowed              => 1
367
                holdallowed => 1
349
            }
368
            }
350
        }
369
        }
351
    );
370
    );
352
371
353
    t::lib::Mocks::mock_preference( 'AllowHoldPolicyOverride', 0 );
372
    t::lib::Mocks::mock_preference( 'AllowHoldPolicyOverride', 0 );
354
373
374
    # Make sure pickup location checks doesn't get in the middle
375
    my $mock_biblio = Test::MockModule->new('Koha::Biblio');
376
    $mock_biblio->mock( 'pickup_locations', sub { return Koha::Libraries->search; });
377
    my $mock_item   = Test::MockModule->new('Koha::Item');
378
    $mock_item->mock( 'pickup_locations', sub { return Koha::Libraries->search });
379
355
    $t->post_ok( "//$userid_3:$password@/api/v1/holds" => json => $post_data )
380
    $t->post_ok( "//$userid_3:$password@/api/v1/holds" => json => $post_data )
356
      ->status_is(403)
381
      ->status_is(403)
357
      ->json_has('/error');
382
      ->json_has('/error');
Lines 606-611 subtest 'add() tests (maxreserves behaviour)' => sub { Link Here
606
    my $biblio_3 = $builder->build_sample_biblio;
631
    my $biblio_3 = $builder->build_sample_biblio;
607
    my $item_3   = $builder->build_sample_item({ biblionumber => $biblio_3->biblionumber });
632
    my $item_3   = $builder->build_sample_item({ biblionumber => $biblio_3->biblionumber });
608
633
634
    # Make sure pickup location checks doesn't get in the middle
635
    my $mock_biblio = Test::MockModule->new('Koha::Biblio');
636
    $mock_biblio->mock( 'pickup_locations', sub { return Koha::Libraries->search; });
637
    my $mock_item   = Test::MockModule->new('Koha::Item');
638
    $mock_item->mock( 'pickup_locations', sub { return Koha::Libraries->search });
639
609
    # Disable logging
640
    # Disable logging
610
    t::lib::Mocks::mock_preference( 'HoldsLog',      0 );
641
    t::lib::Mocks::mock_preference( 'HoldsLog',      0 );
611
    t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
642
    t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
Lines 868-870 subtest 'edit() tests' => sub { Link Here
868
899
869
    $schema->storage->txn_rollback;
900
    $schema->storage->txn_rollback;
870
};
901
};
871
- 
902
903
subtest 'add() tests' => sub {
904
905
    plan tests => 10;
906
907
    $schema->storage->txn_begin;
908
909
    my $password = 'AbcdEFG123';
910
911
    my $library  = $builder->build_object({ class => 'Koha::Libraries' });
912
    my $patron = $builder->build_object(
913
        { class => 'Koha::Patrons', value => { flags => 1 } } );
914
    $patron->set_password( { password => $password, skip_validation => 1 } );
915
    my $userid = $patron->userid;
916
    $builder->build(
917
        {
918
            source => 'UserPermission',
919
            value  => {
920
                borrowernumber => $patron->borrowernumber,
921
                module_bit     => 6,
922
                code           => 'modify_holds_priority',
923
            },
924
        }
925
    );
926
927
    # Disable logging
928
    t::lib::Mocks::mock_preference( 'HoldsLog',      0 );
929
    t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
930
931
    my $mock_biblio = Test::MockModule->new('Koha::Biblio');
932
    my $mock_item   = Test::MockModule->new('Koha::Item');
933
934
    my $library_1 = $builder->build_object({ class => 'Koha::Libraries' });
935
    my $library_2 = $builder->build_object({ class => 'Koha::Libraries' });
936
    my $library_3 = $builder->build_object({ class => 'Koha::Libraries' });
937
938
    # let's control what Koha::Biblio->pickup_locations returns, for testing
939
    $mock_biblio->mock( 'pickup_locations', sub {
940
        return Koha::Libraries->search( { branchcode => [ $library_2->branchcode, $library_3->branchcode ] } );
941
    });
942
    # let's mock what Koha::Item->pickup_locations returns, for testing
943
    $mock_item->mock( 'pickup_locations', sub {
944
        return Koha::Libraries->search( { branchcode => [ $library_2->branchcode, $library_3->branchcode ] } );
945
    });
946
947
    my $biblio = $builder->build_sample_biblio;
948
    my $item   = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
949
950
    # Test biblio-level holds
951
    my $biblio_hold = $builder->build_object(
952
        {
953
            class => "Koha::Holds",
954
            value => {
955
                biblionumber => $biblio->biblionumber,
956
                branchcode   => $library_3->branchcode,
957
                itemnumber   => undef,
958
                priority     => 1,
959
            }
960
        }
961
    );
962
963
    my $biblio_hold_data = $biblio_hold->to_api;
964
    $biblio_hold->delete;
965
    $biblio_hold_data->{pickup_library_id} = $library_1->branchcode;
966
    delete $biblio_hold_data->{hold_id};
967
968
    $t->post_ok( "//$userid:$password@/api/v1/holds" => json => $biblio_hold_data )
969
      ->status_is(400)
970
      ->json_is({ error => 'The supplied pickup location is not valid' });
971
972
    $biblio_hold_data->{pickup_library_id} = $library_2->branchcode;
973
    $t->post_ok( "//$userid:$password@/api/v1/holds"  => json => $biblio_hold_data )
974
      ->status_is(201);
975
976
    # Test item-level holds
977
    my $item_hold = $builder->build_object(
978
        {
979
            class => "Koha::Holds",
980
            value => {
981
                biblionumber => $biblio->biblionumber,
982
                branchcode   => $library_3->branchcode,
983
                itemnumber   => $item->itemnumber,
984
                priority     => 1,
985
            }
986
        }
987
    );
988
989
    my $item_hold_data = $item_hold->to_api;
990
    $item_hold->delete;
991
    $item_hold_data->{pickup_library_id} = $library_1->branchcode;
992
    delete $item_hold->{hold_id};
993
994
    $t->post_ok( "//$userid:$password@/api/v1/holds" => json => $item_hold_data )
995
      ->status_is(400)
996
      ->json_is({ error => 'The supplied pickup location is not valid' });
997
998
    $item_hold_data->{pickup_library_id} = $library_2->branchcode;
999
    $t->post_ok( "//$userid:$password@/api/v1/holds" => json => $item_hold_data )
1000
      ->status_is(201);
1001
1002
    $schema->storage->txn_rollback;
1003
};

Return to bug 27205