3 # This file is part of Koha.
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.
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.
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>.
20 use Test
::More tests
=> 5;
24 use t
::lib
::TestBuilder
;
27 use Koha
::Acquisition
::Orders
;
30 my $schema = Koha
::Database
->new->schema;
31 my $builder = t
::lib
::TestBuilder
->new;
33 t
::lib
::Mocks
::mock_preference
( 'RESTBasicAuth', 1 );
35 my $t = Test
::Mojo
->new('Koha::REST::V1');
37 subtest
'list() tests' => sub {
40 $schema->storage->txn_begin;
42 my $patron = $builder->build_object({
43 class => 'Koha::Patrons',
44 value
=> { flags
=> 1 }
46 my $password = 'thePassword123';
47 $patron->set_password({ password
=> $password, skip_validation
=> 1 });
48 my $userid = $patron->userid;
50 my $basket = $builder->build_object({ class => 'Koha::Acquisition::Baskets' });
52 my $order = $builder->build_object(
54 class => 'Koha::Acquisition::Orders',
55 value
=> { basketno
=> $basket->basketno, orderstatus
=> 'new' }
58 my $another_order = $order->unblessed; # create a copy of $order but make
59 delete $another_order->{ordernumber
}; # sure ordernumber will be regenerated
60 $another_order = $builder->build_object({ class => 'Koha::Acquisition::Orders', value
=> $another_order });
62 ## Authorized user tests
63 my $count_of_orders = Koha
::Acquisition
::Orders
->search->count;
64 # Make sure we are returned with the correct amount of orders
65 $t->get_ok( "//$userid:$password@/api/v1/acquisitions/orders" )
66 ->status_is( 200, 'SWAGGER3.2.2' )
67 ->json_has('/'.($count_of_orders-1).'/order_id')
68 ->json_hasnt('/'.($count_of_orders).'/order_id');
70 subtest
'query parameters' => sub {
73 biblio_id
=> 'biblionumber',
74 basket_id
=> 'basketno',
75 fund_id
=> 'budget_id',
78 my $size = keys %{$fields};
80 plan tests
=> $size * (2 + 2 * $size);
82 foreach my $field ( keys %{$fields} ) {
83 my $model_field = $fields->{ $field };
84 my $result = $t->get_ok("//$userid:$password@/api/v1/acquisitions/orders?$field=" . $order->$model_field)
87 foreach my $key ( keys %{$fields} ) {
88 my $key_field = $fields->{ $key };
89 # Check the result order first since it's not predefined.
90 if ($result->tx->res->json->[0]->{$key} eq $order->$key_field) {
91 $result->json_is( "/0/$key", $order->$key_field );
92 $result->json_is( "/1/$key", $another_order->$key_field );
94 $result->json_is( "/0/$key", $another_order->$key_field );
95 $result->json_is( "/1/$key", $order->$key_field );
101 # Warn on unsupported query parameter
102 $t->get_ok( "//$userid:$password@/api/v1/acquisitions/orders?order_blah=blah" )
104 ->json_is( [{ path
=> '/query/order_blah', message
=> 'Malformed query string'}] );
106 $schema->storage->txn_rollback;
109 subtest
'get() tests' => sub {
113 $schema->storage->txn_begin;
115 my $order = $builder->build_object(
117 class => 'Koha::Acquisition::Orders',
118 value
=> { orderstatus
=> 'new' }
121 my $patron = $builder->build_object({
122 class => 'Koha::Patrons',
123 value
=> { flags
=> 2048 }
125 my $password = 'thePassword123';
126 $patron->set_password({ password
=> $password, skip_validation
=> 1 });
127 my $userid = $patron->userid;
129 $t->get_ok( "//$userid:$password@/api/v1/acquisitions/orders/" . $order->ordernumber )
130 ->status_is( 200, 'SWAGGER3.2.2' )
131 ->json_is( '' => $order->to_api, 'SWAGGER3.3.2' );
133 my $non_existent_order_id = $order->ordernumber;
136 $t->get_ok( "//$userid:$password@/api/v1/acquisitions/orders/" . $non_existent_order_id )
138 ->json_is( '/error' => 'Order not found' );
140 # FIXME This does not work on all the OS we support
141 ## Regression tests for bug 25513
142 ## Pick a high value that could be transformed into exponential
143 ## representation and not considered a number by buggy DBD::mysql versions
144 #$order = $builder->build_object(
146 # class => 'Koha::Acquisition::Orders',
148 # orderstatus => 'new',
149 # ecost_tax_excluded => 9963405519357589504,
150 # unitprice => 10177559957753600000
155 #$t->get_ok( "//$userid:$password@/api/v1/acquisitions/orders/" . $order->ordernumber )
156 # ->json_is( '' => $order->to_api, 'Number representation should be consistent' );
158 $schema->storage->txn_rollback;
161 subtest
'add() tests' => sub {
165 $schema->storage->txn_begin;
167 my $authorized_patron = $builder->build_object({
168 class => 'Koha::Patrons',
169 value
=> { flags
=> 1 }
171 my $password = 'thePassword123';
172 $authorized_patron->set_password({ password
=> $password, skip_validation
=> 1 });
173 my $auth_userid = $authorized_patron->userid;
175 my $unauthorized_patron = $builder->build_object({
176 class => 'Koha::Patrons',
177 value
=> { flags
=> 4 }
179 $unauthorized_patron->set_password({ password
=> $password, skip_validation
=> 1 });
180 my $unauth_userid = $unauthorized_patron->userid;
182 my $order_obj = $builder->build_object(
184 class => 'Koha::Acquisition::Orders',
186 orderstatus
=> 'new',
188 replacementprice
=> 10,
190 quantityreceived
=> 0,
191 datecancellationprinted
=> undef,
192 order_internalnote
=> 'This is a dummy note for testing'
196 my $order = $order_obj->to_api;
198 delete $order->{ordernumber
};
199 $order->{uncertain_price
} = Mojo
::JSON
->false;
201 # Unauthorized attempt to write
202 $t->post_ok( "//$unauth_userid:$password@/api/v1/acquisitions/orders" => json
=> $order )
205 # Authorized attempt to write invalid data
206 my $order_with_invalid_field = { %$order };
207 $order_with_invalid_field->{'orderinvalid'} = 'Order invalid';
209 $t->post_ok( "//$auth_userid:$password@/api/v1/acquisitions/orders" => json
=> $order_with_invalid_field )
214 message
=> "Properties not allowed: orderinvalid.",
220 # Authorized attempt to write
221 $t->post_ok( "//$auth_userid:$password@/api/v1/acquisitions/orders" => json
=> $order )
222 ->status_is( 201, 'SWAGGER3.2.1' )
223 ->json_is( '/internal_note' => $order->{internal_note
}, 'SWAGGER3.3.1' )
224 ->header_like( Location
=> qr/\/api\
/v1\/acquisitions\
/orders\/\d
*/, 'SWAGGER3.4.1' );
227 my $order_id = $order->{order_id
};
228 # Authorized attempt to create with null id
229 $order->{order_id
} = undef;
231 $t->post_ok( "//$auth_userid:$password@/api/v1/acquisitions/orders" => json
=> $order )
233 ->json_has('/errors');
235 # Authorized attempt to create with existing id
236 $order->{order_id
} = $order_id;
239 $t->post_ok( "//$auth_userid:$password@/api/v1/acquisitions/orders" => json
=> $order )
241 ->json_has( '/error' => "Fails when trying to add an existing order_id")
242 ->json_like( '/conflict' => qr
/(aqorders\
.)?PRIMARY
/ ); }
243 qr/DBD::mysql::st execute failed: Duplicate entry '(.*)' for key '(aqorders\.)?PRIMARY'/;
245 $schema->storage->txn_rollback;
248 subtest
'update() tests' => sub {
251 $schema->storage->txn_begin;
253 my $authorized_patron = $builder->build_object({
254 class => 'Koha::Patrons',
255 value
=> { flags
=> 1 }
257 my $password = 'thePassword123';
258 $authorized_patron->set_password({ password
=> $password, skip_validation
=> 1 });
259 my $auth_userid = $authorized_patron->userid;
261 my $unauthorized_patron = $builder->build_object({
262 class => 'Koha::Patrons',
263 value
=> { flags
=> 4 }
265 $unauthorized_patron->set_password({ password
=> $password, skip_validation
=> 1 });
266 my $unauth_userid = $unauthorized_patron->userid;
268 my $library = $builder->build_object({ class => 'Koha::Libraries' });
269 my $library_id = $library->branchcode;
271 # Unauthorized attempt to update
272 $t->put_ok( "//$unauth_userid:$password@/api/v1/libraries/$library_id"
273 => json
=> { name
=> 'New unauthorized name change' } )
276 # Attempt partial update on a PUT
277 my $library_with_missing_field = {
278 address1
=> "New library address",
281 my $result = $t->put_ok( "//$auth_userid:$password@/api/v1/libraries/$library_id" => json
=> $library_with_missing_field )
283 # Check the result order first since it's not predefined.
284 if ($result->tx->res->json->{errors
}->[0]->{path
} eq '/body/name') {
288 {message
=> "Missing property.", path
=> "/body/name"},
289 {message
=> "Missing property.", path
=> "/body/library_id"}
296 {message
=> "Missing property.", path
=> "/body/library_id"},
297 {message
=> "Missing property.", path
=> "/body/name"}
302 my $deleted_library = $builder->build_object( { class => 'Koha::Libraries' } );
303 my $library_with_updated_field = $deleted_library->to_api;
304 $library_with_updated_field->{library_id
} = $library_id;
305 $deleted_library->delete;
307 $t->put_ok( "//$auth_userid:$password@/api/v1/libraries/$library_id" => json
=> $library_with_updated_field )
308 ->status_is(200, 'SWAGGER3.2.1')
309 ->json_is( '' => $library_with_updated_field, 'SWAGGER3.3.3' );
311 # Authorized attempt to write invalid data
312 my $library_with_invalid_field = { %$library_with_updated_field };
313 $library_with_invalid_field->{'branchinvalid'} = 'Library invalid';
315 $t->put_ok( "//$auth_userid:$password@/api/v1/libraries/$library_id" => json
=> $library_with_invalid_field )
320 message
=> "Properties not allowed: branchinvalid.",
326 my $non_existent_code = 'nope'.int(rand(10000));
327 $t->put_ok("//$auth_userid:$password@/api/v1/libraries/$non_existent_code" => json
=> $library_with_updated_field)
330 $schema->storage->txn_rollback;
333 subtest
'delete() tests' => sub {
336 $schema->storage->txn_begin;
338 my $authorized_patron = $builder->build_object({
339 class => 'Koha::Patrons',
340 value
=> { flags
=> 1 }
342 my $password = 'thePassword123';
343 $authorized_patron->set_password({ password
=> $password, skip_validation
=> 1 });
344 my $auth_userid = $authorized_patron->userid;
346 my $unauthorized_patron = $builder->build_object({
347 class => 'Koha::Patrons',
348 value
=> { flags
=> 4 }
350 $unauthorized_patron->set_password({ password
=> $password, skip_validation
=> 1 });
351 my $unauth_userid = $unauthorized_patron->userid;
353 my $order = $builder->build_object( { class => 'Koha::Acquisition::Orders' } );
355 # Unauthorized attempt to delete
356 $t->delete_ok( "//$unauth_userid:$password@/api/v1/acquisitions/orders/" . $order->ordernumber )
359 $t->delete_ok( "//$auth_userid:$password@/api/v1/acquisitions/orders/" . $order->ordernumber )
360 ->status_is(204, 'SWAGGER3.2.4')
361 ->content_is('', 'SWAGGER3.3.4');
363 $t->delete_ok( "//$auth_userid:$password@/api/v1/acquisitions/orders/" . $order->ordernumber )
366 $schema->storage->txn_rollback;