Bug 24545: Fix license statements
[koha.git] / t / db_dependent / api / v1 / libraries.t
1 #!/usr/bin/env perl
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18 use Modern::Perl;
19
20 use Test::More tests => 5;
21 use Test::Mojo;
22 use Test::Warn;
23
24 use t::lib::TestBuilder;
25 use t::lib::Mocks;
26
27 use Koha::Libraries;
28 use Koha::Database;
29
30 my $schema  = Koha::Database->new->schema;
31 my $builder = t::lib::TestBuilder->new;
32
33 t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
34
35 my $t = Test::Mojo->new('Koha::REST::V1');
36
37 subtest 'list() tests' => sub {
38     plan tests => 8;
39
40     $schema->storage->txn_begin;
41
42     my $patron = $builder->build_object({
43         class => 'Koha::Patrons',
44         value => { flags => 4 }
45     });
46     my $password = 'thePassword123';
47     $patron->set_password({ password => $password, skip_validation => 1 });
48     my $userid = $patron->userid;
49
50     # Create test context
51     my $library = $builder->build_object({ class => 'Koha::Libraries' });
52     my $another_library = $library->unblessed; # create a copy of $library but make
53     delete $another_library->{branchcode};     # sure branchcode will be regenerated
54     $another_library = $builder->build_object({ class => 'Koha::Libraries', value => $another_library });
55
56     ## Authorized user tests
57     my $count_of_libraries = Koha::Libraries->search->count;
58     # Make sure we are returned with the correct amount of libraries
59     $t->get_ok( "//$userid:$password@/api/v1/libraries" )
60       ->status_is( 200, 'SWAGGER3.2.2' )
61       ->json_has('/'.($count_of_libraries-1).'/library_id')
62       ->json_hasnt('/'.($count_of_libraries).'/library_id');
63
64     subtest 'query parameters' => sub {
65
66         my $fields = {
67             name              => 'branchname',
68             address1          => 'branchaddress1',
69             address2          => 'branchaddress2',
70             address3          => 'branchaddress3',
71             postal_code       => 'branchzip',
72             city              => 'branchcity',
73             state             => 'branchstate',
74             country           => 'branchcountry',
75             phone             => 'branchphone',
76             fax               => 'branchfax',
77             email             => 'branchemail',
78             reply_to_email    => 'branchreplyto',
79             return_path_email => 'branchreturnpath',
80             url               => 'branchurl',
81             ip                => 'branchip',
82             notes             => 'branchnotes',
83             opac_info         => 'opac_info',
84         };
85
86         my $size = keys %{$fields};
87
88         plan tests => $size * 3;
89
90         foreach my $field ( keys %{$fields} ) {
91             my $model_field = $fields->{ $field };
92             my $result =
93             $t->get_ok("//$userid:$password@/api/v1/libraries?$field=" . $library->$model_field)
94               ->status_is(200)
95               ->json_has( [ $library, $another_library ] );
96         }
97     };
98
99     # Warn on unsupported query parameter
100     $t->get_ok( "//$userid:$password@/api/v1/libraries?library_blah=blah" )
101       ->status_is(400)
102       ->json_is( [{ path => '/query/library_blah', message => 'Malformed query string'}] );
103
104     $schema->storage->txn_rollback;
105 };
106
107 subtest 'get() tests' => sub {
108
109     plan tests => 6;
110
111     $schema->storage->txn_begin;
112
113     my $library = $builder->build_object( { class => 'Koha::Libraries' } );
114     my $patron = $builder->build_object({
115         class => 'Koha::Patrons',
116         value => { flags => 4 }
117     });
118     my $password = 'thePassword123';
119     $patron->set_password({ password => $password, skip_validation => 1 });
120     my $userid = $patron->userid;
121
122     $t->get_ok( "//$userid:$password@/api/v1/libraries/" . $library->branchcode )
123       ->status_is( 200, 'SWAGGER3.2.2' )
124       ->json_is( '' => $library->to_api, 'SWAGGER3.3.2' );
125
126     my $non_existent_code = $library->branchcode;
127     $library->delete;
128
129     $t->get_ok( "//$userid:$password@/api/v1/libraries/" . $non_existent_code )
130       ->status_is(404)
131       ->json_is( '/error' => 'Library not found' );
132
133     $schema->storage->txn_rollback;
134 };
135
136 subtest 'add() tests' => sub {
137
138     plan tests => 17;
139
140     $schema->storage->txn_begin;
141
142     my $authorized_patron = $builder->build_object({
143         class => 'Koha::Patrons',
144         value => { flags => 1 }
145     });
146     my $password = 'thePassword123';
147     $authorized_patron->set_password({ password => $password, skip_validation => 1 });
148     my $auth_userid = $authorized_patron->userid;
149
150     my $unauthorized_patron = $builder->build_object({
151         class => 'Koha::Patrons',
152         value => { flags => 4 }
153     });
154     $unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
155     my $unauth_userid = $unauthorized_patron->userid;
156
157     my $library_obj = $builder->build_object({ class => 'Koha::Libraries' });
158     my $library     = $library_obj->to_api;
159     $library_obj->delete;
160
161     # Unauthorized attempt to write
162     $t->post_ok( "//$unauth_userid:$password@/api/v1/libraries" => json => $library )
163       ->status_is(403);
164
165     # Authorized attempt to write invalid data
166     my $library_with_invalid_field = { %$library };
167     $library_with_invalid_field->{'branchinvalid'} = 'Library invalid';
168
169     $t->post_ok( "//$auth_userid:$password@/api/v1/libraries" => json => $library_with_invalid_field )
170       ->status_is(400)
171       ->json_is(
172         "/errors" => [
173             {
174                 message => "Properties not allowed: branchinvalid.",
175                 path    => "/body"
176             }
177         ]
178     );
179
180     # Authorized attempt to write
181     $t->post_ok( "//$auth_userid:$password@/api/v1/libraries" => json => $library )
182       ->status_is( 201, 'SWAGGER3.2.1' )
183       ->json_is( '' => $library, 'SWAGGER3.3.1' )
184       ->header_is( Location => '/api/v1/libraries/' . $library->{library_id}, 'SWAGGER3.4.1' );
185
186     # save the library_id
187     my $library_id = $library->{library_id};
188     # Authorized attempt to create with null id
189     $library->{library_id} = undef;
190
191     $t->post_ok( "//$auth_userid:$password@/api/v1/libraries" => json => $library )
192       ->status_is(400)
193       ->json_has('/errors');
194
195     # Authorized attempt to create with existing id
196     $library->{library_id} = $library_id;
197
198     warning_like {
199         $t->post_ok( "//$auth_userid:$password@/api/v1/libraries" => json => $library )
200           ->status_is(409)
201           ->json_has( '/error' => "Fails when trying to add an existing library_id")
202           ->json_like( '/conflict' => qr/(branches\.)?PRIMARY/ ); }
203         qr/^DBD::mysql::st execute failed: Duplicate entry '(.*)' for key '(branches\.)?PRIMARY'/;
204
205     $schema->storage->txn_rollback;
206 };
207
208 subtest 'update() tests' => sub {
209     plan tests => 13;
210
211     $schema->storage->txn_begin;
212
213     my $authorized_patron = $builder->build_object({
214         class => 'Koha::Patrons',
215         value => { flags => 1 }
216     });
217     my $password = 'thePassword123';
218     $authorized_patron->set_password({ password => $password, skip_validation => 1 });
219     my $auth_userid = $authorized_patron->userid;
220
221     my $unauthorized_patron = $builder->build_object({
222         class => 'Koha::Patrons',
223         value => { flags => 4 }
224     });
225     $unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
226     my $unauth_userid = $unauthorized_patron->userid;
227
228     my $library    = $builder->build_object({ class => 'Koha::Libraries' });
229     my $library_id = $library->branchcode;
230
231     # Unauthorized attempt to update
232     $t->put_ok( "//$unauth_userid:$password@/api/v1/libraries/$library_id"
233                     => json => { name => 'New unauthorized name change' } )
234       ->status_is(403);
235
236     # Attempt partial update on a PUT
237     my $library_with_missing_field = {
238         address1 => "New library address",
239     };
240
241     $t->put_ok( "//$auth_userid:$password@/api/v1/libraries/$library_id" => json => $library_with_missing_field )
242       ->status_is(400)
243       ->json_has( "/errors" =>
244           [ { message => "Missing property.", path => "/body/address2" } ]
245       );
246
247     my $deleted_library = $builder->build_object( { class => 'Koha::Libraries' } );
248     my $library_with_updated_field = $deleted_library->to_api;
249     $library_with_updated_field->{library_id} = $library_id;
250     $deleted_library->delete;
251
252     $t->put_ok( "//$auth_userid:$password@/api/v1/libraries/$library_id" => json => $library_with_updated_field )
253       ->status_is(200, 'SWAGGER3.2.1')
254       ->json_is( '' => $library_with_updated_field, 'SWAGGER3.3.3' );
255
256     # Authorized attempt to write invalid data
257     my $library_with_invalid_field = { %$library_with_updated_field };
258     $library_with_invalid_field->{'branchinvalid'} = 'Library invalid';
259
260     $t->put_ok( "//$auth_userid:$password@/api/v1/libraries/$library_id" => json => $library_with_invalid_field )
261       ->status_is(400)
262       ->json_is(
263         "/errors" => [
264             {
265                 message => "Properties not allowed: branchinvalid.",
266                 path    => "/body"
267             }
268         ]
269     );
270
271     my $non_existent_code = 'nope'.int(rand(10000));
272     $t->put_ok("//$auth_userid:$password@/api/v1/libraries/$non_existent_code" => json => $library_with_updated_field)
273       ->status_is(404);
274
275     $schema->storage->txn_rollback;
276 };
277
278 subtest 'delete() tests' => sub {
279     plan tests => 7;
280
281     $schema->storage->txn_begin;
282
283     my $authorized_patron = $builder->build_object({
284         class => 'Koha::Patrons',
285         value => { flags => 1 }
286     });
287     my $password = 'thePassword123';
288     $authorized_patron->set_password({ password => $password, skip_validation => 1 });
289     my $auth_userid = $authorized_patron->userid;
290
291     my $unauthorized_patron = $builder->build_object({
292         class => 'Koha::Patrons',
293         value => { flags => 4 }
294     });
295     $unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
296     my $unauth_userid = $unauthorized_patron->userid;
297
298     my $library_id = $builder->build( { source => 'Branch' } )->{branchcode};
299
300     # Unauthorized attempt to delete
301     $t->delete_ok( "//$unauth_userid:$password@/api/v1/libraries/$library_id" )
302       ->status_is(403);
303
304     $t->delete_ok( "//$auth_userid:$password@/api/v1/libraries/$library_id" )
305       ->status_is(204, 'SWAGGER3.2.4')
306       ->content_is('', 'SWAGGER3.3.4');
307
308     $t->delete_ok( "//$auth_userid:$password@/api/v1/libraries/$library_id" )
309       ->status_is(404);
310
311     $schema->storage->txn_rollback;
312 };