3 # This file is part of Koha.
5 # Koha is free software; you can redistribute it and/or modify it under the
6 # terms of the GNU General Public License as published by the Free Software
7 # Foundation; either version 3 of the License, or (at your option) any later
10 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License along
15 # with Koha; if not, write to the Free Software Foundation, Inc.,
16 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 use Test::More tests => 5;
24 use t::lib::TestBuilder;
31 my $schema = Koha::Database->new->schema;
32 my $builder = t::lib::TestBuilder->new;
34 # FIXME: sessionStorage defaults to mysql, but it seems to break transaction handling
35 # this affects the other REST api tests
36 t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' );
38 my $remote_address = '127.0.0.1';
39 my $t = Test::Mojo->new('Koha::REST::V1');
41 subtest 'list() tests' => sub {
44 $schema->storage->txn_begin;
47 my $library = $builder->build( { source => 'Branch' } );
48 my $another_library = { %$library }; # create a copy of $library but make
49 delete $another_library->{branchcode}; # sure branchcode will be regenerated
50 $another_library = $builder->build(
51 { source => 'Branch', value => $another_library } );
52 my ( $borrowernumber, $session_id ) =
53 create_user_and_session( { authorized => 0 } );
55 ## Authorized user tests
56 my $count_of_libraries = Koha::Libraries->search->count;
57 # Make sure we are returned with the correct amount of libraries
58 my $tx = $t->ua->build_tx( GET => '/api/v1/libraries' );
59 $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
60 $tx->req->env( { REMOTE_ADDR => $remote_address } );
63 ->json_has('/'.($count_of_libraries-1).'/branchcode')
64 ->json_hasnt('/'.($count_of_libraries).'/branchcode');
66 subtest 'query parameters' => sub {
68 branchname branchaddress1 branchaddress2 branchaddress3
69 branchzip branchcity branchstate branchcountry
70 branchphone branchfax branchemail branchreplyto
71 branchreturnpath branchurl issuing branchip
72 branchprinter branchnotes opac_info
74 plan tests => scalar(@fields)*3;
76 foreach my $field (@fields) {
77 $tx = $t->ua->build_tx( GET =>
78 "/api/v1/libraries?$field=$library->{$field}" );
79 $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
80 $tx->req->env( { REMOTE_ADDR => $remote_address } );
84 ->json_has( [ $library, $another_library ] );
88 # Warn on unsupported query parameter
89 $tx = $t->ua->build_tx( GET => '/api/v1/libraries?library_blah=blah' );
90 $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
91 $tx->req->env( { REMOTE_ADDR => $remote_address } );
94 ->json_is( [{ path => '/query/library_blah', message => 'Malformed query string'}] );
96 $schema->storage->txn_rollback;
99 subtest 'get() tests' => sub {
103 $schema->storage->txn_begin;
105 my $library = $builder->build( { source => 'Branch' } );
106 my ( $borrowernumber, $session_id ) =
107 create_user_and_session( { authorized => 0 } );
109 my $tx = $t->ua->build_tx( GET => "/api/v1/libraries/" . $library->{branchcode} );
110 $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
111 $tx->req->env( { REMOTE_ADDR => $remote_address } );
116 my $non_existent_code = 'non_existent'.int(rand(10000));
117 $tx = $t->ua->build_tx( GET => "/api/v1/libraries/" . $non_existent_code );
118 $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
119 $tx->req->env( { REMOTE_ADDR => $remote_address } );
122 ->json_is( '/error' => 'Library not found' );
124 $schema->storage->txn_rollback;
127 subtest 'add() tests' => sub {
130 $schema->storage->txn_begin;
132 my ( $unauthorized_borrowernumber, $unauthorized_session_id ) =
133 create_user_and_session( { authorized => 0 } );
134 my ( $authorized_borrowernumber, $authorized_session_id ) =
135 create_user_and_session( { authorized => 1 } );
137 branchcode => "LIBRARYBR1",
138 branchname => "Library Name",
139 branchaddress1 => "Library Address1",
140 branchaddress2 => "Library Address2",
141 branchaddress3 => "Library Address3",
142 branchzip => "Library Zipcode",
143 branchcity => "Library City",
144 branchstate => "Library State",
145 branchcountry => "Library Country",
146 branchphone => "Library Phone",
147 branchfax => "Library Fax",
148 branchemail => "Library Email",
149 branchreplyto => "Library Reply-To",
150 branchreturnpath => "Library Return-Path",
151 branchurl => "http://library.url",
152 issuing => undef, # unused in Koha
153 branchip => "127.0.0.1",
154 branchprinter => "Library Printer", # unused in Koha
155 branchnotes => "Library Notes",
156 opac_info => "<p>Library OPAC info</p>",
159 # Unauthorized attempt to write
160 my $tx = $t->ua->build_tx( POST => "/api/v1/libraries" => json => $library );
162 { name => 'CGISESSID', value => $unauthorized_session_id } );
163 $tx->req->env( { REMOTE_ADDR => $remote_address } );
167 # Authorized attempt to write invalid data
168 my $library_with_invalid_field = { %$library };
169 $library_with_invalid_field->{'branchinvalid'} = 'Library invalid';
171 $tx = $t->ua->build_tx(
172 POST => "/api/v1/libraries" => json => $library_with_invalid_field );
174 { name => 'CGISESSID', value => $authorized_session_id } );
175 $tx->req->env( { REMOTE_ADDR => $remote_address } );
181 message => "Properties not allowed: branchinvalid.",
187 # Authorized attempt to write
188 $tx = $t->ua->build_tx( POST => "/api/v1/libraries" => json => $library );
190 { name => 'CGISESSID', value => $authorized_session_id } );
191 $tx->req->env( { REMOTE_ADDR => $remote_address } );
192 my $branchcode = $t->request_ok($tx)
194 ->json_is( '/branchname' => $library->{branchname} )
195 ->json_is( '/branchaddress1' => $library->{branchaddress1} )
196 ->json_is( '/branchaddress2' => $library->{branchaddress2} )
197 ->json_is( '/branchaddress3' => $library->{branchaddress3} )
198 ->json_is( '/branchzip' => $library->{branchzip} )
199 ->json_is( '/branchcity' => $library->{branchcity} )
200 ->json_is( '/branchstate' => $library->{branchstate} )
201 ->json_is( '/branchcountry' => $library->{branchcountry} )
202 ->json_is( '/branchphone' => $library->{branchphone} )
203 ->json_is( '/branchfax' => $library->{branchfax} )
204 ->json_is( '/branchemail' => $library->{branchemail} )
205 ->json_is( '/branchreplyto' => $library->{branchreplyto} )
206 ->json_is( '/branchreturnpath' => $library->{branchreturnpath} )
207 ->json_is( '/branchurl' => $library->{branchurl} )
208 ->json_is( '/branchip' => $library->{branchip} )
209 ->json_is( '/branchnotes' => $library->{branchnotes} )
210 ->json_is( '/opac_info' => $library->{opac_info} )
211 ->header_is(Location => "/api/v1/libraries/$library->{branchcode}")
212 ->tx->res->json->{branchcode};
214 # Authorized attempt to create with null id
215 $library->{branchcode} = undef;
216 $tx = $t->ua->build_tx(
217 POST => "/api/v1/libraries" => json => $library );
219 { name => 'CGISESSID', value => $authorized_session_id } );
220 $tx->req->env( { REMOTE_ADDR => $remote_address } );
223 ->json_has('/errors');
225 # Authorized attempt to create with existing id
226 $library->{branchcode} = $branchcode;
227 $tx = $t->ua->build_tx(
228 POST => "/api/v1/libraries" => json => $library );
230 { name => 'CGISESSID', value => $authorized_session_id } );
231 $tx->req->env( { REMOTE_ADDR => $remote_address } );
234 ->json_is('/error' => 'Library already exists');
236 $schema->storage->txn_rollback;
239 subtest 'update() tests' => sub {
242 $schema->storage->txn_begin;
244 my ( $unauthorized_borrowernumber, $unauthorized_session_id ) =
245 create_user_and_session( { authorized => 0 } );
246 my ( $authorized_borrowernumber, $authorized_session_id ) =
247 create_user_and_session( { authorized => 1 } );
249 my $branchcode = $builder->build( { source => 'Branch' } )->{branchcode};
251 # Unauthorized attempt to update
252 my $tx = $t->ua->build_tx( PUT => "/api/v1/libraries/$branchcode"
253 => json => { branchname => 'New unauthorized name change' } );
255 { name => 'CGISESSID', value => $unauthorized_session_id } );
256 $tx->req->env( { REMOTE_ADDR => $remote_address } );
260 # Attempt partial update on a PUT
261 my $library_with_missing_field = {
262 branchaddress1 => "New library address",
265 $tx = $t->ua->build_tx( PUT => "/api/v1/libraries/$branchcode" =>
266 json => $library_with_missing_field );
268 { name => 'CGISESSID', value => $authorized_session_id } );
269 $tx->req->env( { REMOTE_ADDR => $remote_address } );
272 ->json_has( "/errors" =>
273 [ { message => "Missing property.", path => "/body/branchaddress2" } ]
276 # Full object update on PUT
277 my $library_with_updated_field = {
278 branchcode => "LIBRARYBR2",
279 branchname => "Library Name",
280 branchaddress1 => "Library Address1",
281 branchaddress2 => "Library Address2",
282 branchaddress3 => "Library Address3",
283 branchzip => "Library Zipcode",
284 branchcity => "Library City",
285 branchstate => "Library State",
286 branchcountry => "Library Country",
287 branchphone => "Library Phone",
288 branchfax => "Library Fax",
289 branchemail => "Library Email",
290 branchreplyto => "Library Reply-To",
291 branchreturnpath => "Library Return-Path",
292 branchurl => "http://library.url",
293 issuing => undef, # unused in Koha
294 branchip => "127.0.0.1",
295 branchprinter => "Library Printer", # unused in Koha
296 branchnotes => "Library Notes",
297 opac_info => "<p>Library OPAC info</p>",
300 $tx = $t->ua->build_tx(
301 PUT => "/api/v1/libraries/$branchcode" => json => $library_with_updated_field );
303 { name => 'CGISESSID', value => $authorized_session_id } );
304 $tx->req->env( { REMOTE_ADDR => $remote_address } );
307 ->json_is( '/branchname' => 'Library Name' );
309 # Authorized attempt to write invalid data
310 my $library_with_invalid_field = { %$library_with_updated_field };
311 $library_with_invalid_field->{'branchinvalid'} = 'Library invalid';
313 $tx = $t->ua->build_tx(
314 PUT => "/api/v1/libraries/$branchcode" => json => $library_with_invalid_field );
316 { name => 'CGISESSID', value => $authorized_session_id } );
317 $tx->req->env( { REMOTE_ADDR => $remote_address } );
323 message => "Properties not allowed: branchinvalid.",
329 my $non_existent_code = 'nope'.int(rand(10000));
331 $t->ua->build_tx( PUT => "/api/v1/libraries/$non_existent_code" => json =>
332 $library_with_updated_field );
334 { name => 'CGISESSID', value => $authorized_session_id } );
335 $tx->req->env( { REMOTE_ADDR => $remote_address } );
339 $schema->storage->txn_rollback;
342 subtest 'delete() tests' => sub {
345 $schema->storage->txn_begin;
347 my ( $unauthorized_borrowernumber, $unauthorized_session_id ) =
348 create_user_and_session( { authorized => 0 } );
349 my ( $authorized_borrowernumber, $authorized_session_id ) =
350 create_user_and_session( { authorized => 1 } );
352 my $branchcode = $builder->build( { source => 'Branch' } )->{branchcode};
354 # Unauthorized attempt to delete
355 my $tx = $t->ua->build_tx( DELETE => "/api/v1/libraries/$branchcode" );
357 { name => 'CGISESSID', value => $unauthorized_session_id } );
358 $tx->req->env( { REMOTE_ADDR => $remote_address } );
362 $tx = $t->ua->build_tx( DELETE => "/api/v1/libraries/$branchcode" );
364 { name => 'CGISESSID', value => $authorized_session_id } );
365 $tx->req->env( { REMOTE_ADDR => $remote_address } );
370 $tx = $t->ua->build_tx( DELETE => "/api/v1/libraries/$branchcode" );
372 { name => 'CGISESSID', value => $authorized_session_id } );
373 $tx->req->env( { REMOTE_ADDR => $remote_address } );
377 $schema->storage->txn_rollback;
380 sub create_user_and_session {
383 my $flags = ( $args->{authorized} ) ? $args->{authorized} : 0;
384 my $dbh = C4::Context->dbh;
386 my $user = $builder->build(
388 source => 'Borrower',
395 # Create a session for the authorized user
396 my $session = C4::Auth::get_session('');
397 $session->param( 'number', $user->{borrowernumber} );
398 $session->param( 'id', $user->{userid} );
399 $session->param( 'ip', '127.0.0.1' );
400 $session->param( 'lasttime', time() );
403 if ( $args->{authorized} ) {
405 INSERT INTO user_permissions (borrowernumber,module_bit,code)
406 VALUES (?,3,'parameters_remaining_permissions')", undef,
407 $user->{borrowernumber} );
410 return ( $user->{borrowernumber}, $session->id );