Bug 32030: ERM - Add more API tests
[koha-ffzg.git] / t / db_dependent / api / v1 / clubs_holds.t
1
2 #!/usr/bin/env perl
3
4 # This file is part of Koha.
5 #
6 # Koha is free software; you can redistribute it and/or modify it
7 # under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
10 #
11 # Koha is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with Koha; if not, see <http://www.gnu.org/licenses>.
18
19 use Modern::Perl;
20
21 use Test::More tests => 2;
22 use Test::Mojo;
23 use Test::Warn;
24
25 use t::lib::TestBuilder;
26 use t::lib::Mocks;
27
28 use C4::Auth;
29 use C4::Context;
30 use Koha::Database;
31 use Koha::Holds;
32 use Koha::Patrons;
33 use JSON qw( decode_json );
34
35 my $schema  = Koha::Database->new->schema;
36 my $builder = t::lib::TestBuilder->new;
37 my $dbh = C4::Context->dbh;
38
39 my $t = Test::Mojo->new('Koha::REST::V1');
40 t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
41
42 subtest 'add() tests' => sub {
43
44     plan tests => 2;
45
46     $schema->storage->txn_begin;
47
48     my ($club_with_enrollments, $club_without_enrollments, $item, @enrollments) = create_test_data();
49
50     unauthorized_access_tests(
51         'POST',
52         "/api/v1/clubs/" . $club_with_enrollments->id . "/holds",
53         undef,
54         {
55             biblio_id         => $item->biblionumber,
56             pickup_library_id => $item->home_branch->branchcode
57         }
58     );
59
60     $schema->storage->txn_rollback;
61
62     subtest 'librarian access tests' => sub {
63
64         plan tests => 20;
65
66         $schema->storage->txn_begin;
67
68         my ($club_with_enrollments, $club_without_enrollments, $item, @enrollments) = create_test_data();
69         my $club_with_enrollments_id = $club_with_enrollments->id;
70
71         my $librarian = $builder->build_object(
72             {
73                 class => 'Koha::Patrons',
74                 value => { flags => 2 ** 6 }    # reserveforothers flag = 6
75             }
76         );
77         my $password = 'thePassword123';
78         $librarian->set_password( { password => $password, skip_validation => 1 } );
79         my $userid = $librarian->userid;
80
81         my $non_existent_item   = $builder->build_sample_item;
82         my $non_existent_biblio = $non_existent_item->biblio;
83
84         my $non_existent_item_id   = $non_existent_item->id;
85         my $non_existent_biblio_id = $non_existent_biblio->id;
86         my $non_existent_item_homebranch =
87           $non_existent_item->home_branch->branchcode;
88
89         $non_existent_item->delete;
90         $non_existent_biblio->delete;
91
92         my $biblio = $builder->build_sample_biblio;
93
94         $t->post_ok(
95                 "//$userid:$password@/api/v1/clubs/"
96               . $club_with_enrollments->id
97               . "/holds" => json => {
98                 biblio_id         => $biblio->id,
99                 item_id           => $item->id,
100                 pickup_library_id => $item->home_branch->branchcode
101               }
102         )->status_is(400)
103           ->json_is( '/error' => "Item "
104               . $item->id
105               . " doesn't belong to biblio "
106               . $biblio->id );
107
108         $t->post_ok(
109                 "//$userid:$password@/api/v1/clubs/"
110               . $club_with_enrollments->id
111               . "/holds" => json => {
112                 pickup_library_id => $non_existent_item_homebranch
113               }
114         )->status_is(400)
115           ->json_is(
116             '/error' => 'At least one of biblio_id, item_id should be given' );
117
118         $t->post_ok(
119                 "//$userid:$password@/api/v1/clubs/"
120               . $club_with_enrollments->id
121               . "/holds" => json => {
122                 biblio_id         => $non_existent_biblio_id,
123                 pickup_library_id => $non_existent_item_homebranch
124               }
125         )->status_is(404)->json_is( '/error' => 'Biblio not found' );
126
127         $t->post_ok(
128                 "//$userid:$password@/api/v1/clubs/"
129               . $club_with_enrollments->id
130               . "/holds" => json => {
131                 item_id           => $non_existent_item_id,
132                 pickup_library_id => $non_existent_item_homebranch
133               }
134         )->status_is(404)->json_is( '/error' => 'Item not found' );
135
136         my $data = {
137             biblio_id         => $item->biblionumber,
138             pickup_library_id => $item->home_branch->branchcode
139         };
140
141         $t->post_ok( "//$userid:$password@/api/v1/clubs/"
142               . $club_without_enrollments->id
143               . "/holds" => json => $data )
144           ->status_is(409)
145           ->json_is( '/error' => "Cannot place a hold on a club without patrons." );
146
147         $t->post_ok( "//$userid:$password@/api/v1/clubs/"
148               . $club_with_enrollments->id
149               . "/holds" => json => $data )
150           ->status_is( 201, 'Created Hold' )
151           ->json_has( '/club_hold_id', 'got a club hold id' )
152           ->json_is( '/club_id'   => $club_with_enrollments->id )
153           ->json_is( '/biblio_id' => $item->biblionumber );
154
155         $schema->storage->txn_rollback;
156     };
157 };
158
159 subtest "default patron home" => sub {
160
161     plan tests => 8;
162
163     $schema->storage->txn_begin;
164
165     my ($club_with_enrollments, $club_without_enrollments, $item, @enrollments) = create_test_data();
166     my $club_with_enrollments_id = $club_with_enrollments->id;
167
168     my $librarian = $builder->build_object(
169         {
170             class => 'Koha::Patrons',
171             value => { flags => 2**6 }    # reserveforothers flag = 6
172         }
173     );
174     my $password = 'thePassword123';
175     $librarian->set_password( { password => $password, skip_validation => 1 } );
176     my $userid = $librarian->userid;
177
178     my $data = {
179         biblio_id           => $item->biblionumber,
180         pickup_library_id   => $item->home_branch->branchcode,
181         default_patron_home => 1
182     };
183
184     $t->post_ok( "//$userid:$password@/api/v1/clubs/"
185           . $club_with_enrollments->id
186           . "/holds" => json => $data )
187       ->status_is( 201, 'Created Hold' );
188
189     my $json_response = decode_json $t->tx->res->content->get_body_chunk;
190
191     my $sth = $dbh->prepare(
192         "select patron_id, hold_id from club_holds_to_patron_holds where club_hold_id = ?"
193     );
194     $sth->execute($json_response->{club_hold_id});
195     while (my $test = $sth->fetchrow_hashref()) {
196         my $hold = Koha::Holds->find($test->{hold_id});
197         my $patron = Koha::Patrons->find($test->{patron_id});
198         is($hold->branchcode, $patron->branchcode, 'Pickup location should be patrons home branch');
199     }
200     $schema->storage->txn_rollback;
201 };
202
203 sub unauthorized_access_tests {
204     my ($verb, $endpoint, $club_hold_id, $json) = @_;
205
206     $endpoint .= ($club_hold_id) ? "/$club_hold_id" : '';
207
208     subtest 'unauthorized access tests' => sub {
209         plan tests => 5;
210
211         my $verb_ok = lc($verb) . '_ok';
212
213         $t->$verb_ok($endpoint => json => $json)
214           ->status_is(401);
215
216         my $unauthorized_patron = $builder->build_object(
217             {
218                 class => 'Koha::Patrons',
219                 value => { flags => 0 }
220             }
221         );
222         my $password = "thePassword123!";
223         $unauthorized_patron->set_password(
224             { password => $password, skip_validation => 1 } );
225         my $unauth_userid = $unauthorized_patron->userid;
226
227         $t->$verb_ok( "//$unauth_userid:$password\@$endpoint" => json => $json )
228           ->status_is(403)
229           ->json_has('/required_permissions');
230     };
231 }
232
233 sub create_test_data {
234     my $club_with_enrollments = $builder->build_object( { class => 'Koha::Clubs' } );
235     my $club_without_enrollments = $builder->build_object( { class => 'Koha::Clubs' } );
236     my $lib = $builder->build_object({ class => 'Koha::Libraries', value => {pickup_location => 1}});
237     my $patron = $builder->build_object({ class => 'Koha::Patrons', value => {branchcode => $lib->branchcode}});
238     my $enrollment1 = $builder->build_object( { class => 'Koha::Club::Enrollments', value => { club_id => $club_with_enrollments->id, date_canceled => undef, borrowernumber => $patron->borrowernumber } } );
239     $lib = $builder->build_object({ class => 'Koha::Libraries', value => {pickup_location => 1}});
240     $patron = $builder->build_object({ class => 'Koha::Patrons', value => {branchcode => $lib->branchcode}});
241     my $enrollment2 = $builder->build_object( { class => 'Koha::Club::Enrollments', value => { club_id => $club_with_enrollments->id, date_canceled => undef, borrowernumber => $patron->borrowernumber } } );
242     $lib = $builder->build_object({ class => 'Koha::Libraries', value => {pickup_location => 1}});
243     $patron = $builder->build_object({ class => 'Koha::Patrons', value => {branchcode => $lib->branchcode}});
244     my $enrollment3 = $builder->build_object( { class => 'Koha::Club::Enrollments', value => { club_id => $club_with_enrollments->id, date_canceled => undef, borrowernumber => $patron->borrowernumber } } );
245     $lib = $builder->build_object({ class => 'Koha::Libraries', value => {pickup_location => 1}});
246     $patron = $builder->build_object({ class => 'Koha::Patrons', value => {branchcode => $lib->branchcode}});
247     my $enrollment4 = $builder->build_object( { class => 'Koha::Club::Enrollments', value => { club_id => $club_with_enrollments->id, date_canceled => undef, borrowernumber => $patron->borrowernumber } } );
248     $lib = $builder->build_object({ class => 'Koha::Libraries', value => {pickup_location => 1}});
249     $patron = $builder->build_object({ class => 'Koha::Patrons', value => {branchcode => $lib->branchcode}});
250     my $enrollment5 = $builder->build_object( { class => 'Koha::Club::Enrollments', value => { club_id => $club_with_enrollments->id, date_canceled => undef, borrowernumber => $patron->borrowernumber } } );
251     $lib = $builder->build_object({ class => 'Koha::Libraries', value => {pickup_location => 1}});
252     $patron = $builder->build_object({ class => 'Koha::Patrons', value => {branchcode => $lib->branchcode}});
253     my $enrollment6 = $builder->build_object( { class => 'Koha::Club::Enrollments', value => { club_id => $club_with_enrollments->id, date_canceled => undef, borrowernumber => $patron->borrowernumber } } );
254     $lib = $builder->build_object({ class => 'Koha::Libraries', value => {pickup_location => 1}});
255     my $item        = $builder->build_sample_item({homebranch => $lib->branchcode});
256     return ( $club_with_enrollments, $club_without_enrollments, $item, [ $enrollment1, $enrollment2, $enrollment3, $enrollment4, $enrollment5, $enrollment6 ] );
257 }