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
15 # along with Koha; if not, see <http://www.gnu.org/licenses>.
19 use Test
::More tests
=> 5;
23 use t
::lib
::TestBuilder
;
26 use Koha
::AdvancedEditorMacros
;
29 my $schema = Koha
::Database
->new->schema;
30 my $builder = t
::lib
::TestBuilder
->new;
32 t
::lib
::Mocks
::mock_preference
( 'RESTBasicAuth', 1 );
34 my $t = Test
::Mojo
->new('Koha::REST::V1');
36 $schema->storage->txn_begin;
38 subtest
'list() tests' => sub {
42 my $patron_1 = $builder->build_object({
43 class => 'Koha::Patrons',
44 value
=> { flags
=> 9 }
46 my $patron_2 = $builder->build_object({
47 class => 'Koha::Patrons',
49 my $password = 'thePassword123';
50 $patron_1->set_password({ password
=> $password, skip_validation
=> 1 });
51 my $userid = $patron_1->userid;
54 my $macro_1 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value
=>
57 macro
=> 'delete 100',
58 borrowernumber
=> $patron_1->borrowernumber,
61 my $macro_2 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value
=>
64 macro
=> 'delete 100',
65 borrowernumber
=> $patron_1->borrowernumber,
69 my $macro_3 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value
=>
72 macro
=> 'delete 100',
73 borrowernumber
=> $patron_2->borrowernumber,
76 my $macro_4 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value
=>
79 macro
=> 'delete 100',
80 borrowernumber
=> $patron_2->borrowernumber,
85 my $macros_index = Koha
::AdvancedEditorMacros
->search({ -or => { shared
=> 1, borrowernumber
=> $patron_1->borrowernumber } })->count-1;
86 ## Authorized user tests
87 # Make sure we are returned with the correct amount of macros
88 $t->get_ok( "//$userid:$password@/api/v1/advancededitormacros" )
89 ->status_is( 200, 'SWAGGER3.2.2' )
90 ->json_has('/' . $macros_index . '/macro_id')
91 ->json_hasnt('/' . ($macros_index + 1) . '/macro_id');
93 subtest
'query parameters' => sub {
96 $t->get_ok("//$userid:$password@/api/v1/advancededitormacros?name=" . $macro_2->name)
98 ->json_has( [ $macro_2 ] );
99 $t->get_ok("//$userid:$password@/api/v1/advancededitormacros?name=" . $macro_3->name)
102 $t->get_ok("//$userid:$password@/api/v1/advancededitormacros?macro_text=delete 100")
104 ->json_has( [ $macro_1, $macro_2, $macro_4 ] );
105 $t->get_ok("//$userid:$password@/api/v1/advancededitormacros?patron_id=" . $patron_1->borrowernumber)
107 ->json_has( [ $macro_1, $macro_2 ] );
108 $t->get_ok("//$userid:$password@/api/v1/advancededitormacros?shared=1")
110 ->json_has( [ $macro_2, $macro_4 ] );
113 # Warn on unsupported query parameter
114 $t->get_ok( "//$userid:$password@/api/v1/advancededitormacros?macro_blah=blah" )
116 ->json_is( [{ path
=> '/query/macro_blah', message
=> 'Malformed query string'}] );
120 subtest
'get() tests' => sub {
124 my $patron = $builder->build_object({
125 class => 'Koha::Patrons',
126 value
=> { flags
=> 1 }
128 my $password = 'thePassword123';
129 $patron->set_password({ password
=> $password, skip_validation
=> 1 });
130 my $userid = $patron->userid;
132 my $macro_1 = $builder->build_object( { class => 'Koha::AdvancedEditorMacros', value
=> {
136 my $macro_2 = $builder->build_object( { class => 'Koha::AdvancedEditorMacros', value
=> {
140 my $macro_3 = $builder->build_object( { class => 'Koha::AdvancedEditorMacros', value
=> {
141 borrowernumber
=> $patron->borrowernumber,
146 $t->get_ok( "//$userid:$password@/api/v1/advancededitormacros/" . $macro_1->id )
147 ->status_is( 403, 'Cannot get a shared macro via regular endpoint' )
148 ->json_is( '/error' => 'This macro is shared, you must access it via advancededitormacros/shared' );
150 $t->get_ok( "//$userid:$password@/api/v1/advancededitormacros/shared/" . $macro_1->id )
151 ->status_is( 200, 'Can get a shared macro via shared endpoint' )
152 ->json_is( '' => Koha
::REST
::V1
::AdvancedEditorMacro
::_to_api
( $macro_1->TO_JSON ), 'Macro correctly retrieved' );
154 $t->get_ok( "//$userid:$password@/api/v1/advancededitormacros/" . $macro_2->id )
155 ->status_is( 403, 'Cannot access another users macro' )
156 ->json_is( '/error' => 'You do not have permission to access this macro' );
158 $t->get_ok( "//$userid:$password@/api/v1/advancededitormacros/" . $macro_3->id )
159 ->status_is( 200, 'Can get your own private macro' )
160 ->json_is( '' => Koha
::REST
::V1
::AdvancedEditorMacro
::_to_api
( $macro_3->TO_JSON ), 'Macro correctly retrieved' );
162 my $non_existent_code = $macro_1->id;
165 $t->get_ok( "//$userid:$password@/api/v1/advancededitormacros/" . $non_existent_code )
167 ->json_is( '/error' => 'Macro not found' );
171 subtest
'add() tests' => sub {
175 my $authorized_patron = $builder->build_object({
176 class => 'Koha::Patrons',
177 value
=> { flags
=> 0 }
180 source
=> 'UserPermission',
182 borrowernumber
=> $authorized_patron->borrowernumber,
184 code
=> 'advanced_editor',
188 my $password = 'thePassword123';
189 $authorized_patron->set_password({ password
=> $password, skip_validation
=> 1 });
190 my $auth_userid = $authorized_patron->userid;
192 my $unauthorized_patron = $builder->build_object({
193 class => 'Koha::Patrons',
194 value
=> { flags
=> 0 }
196 $unauthorized_patron->set_password({ password
=> $password, skip_validation
=> 1 });
197 my $unauth_userid = $unauthorized_patron->userid;
199 my $macro = $builder->build_object({
200 class => 'Koha::AdvancedEditorMacros',
201 value
=> { shared
=> 0 }
203 my $macro_values = Koha
::REST
::V1
::AdvancedEditorMacro
::_to_api
( $macro->TO_JSON );
204 delete $macro_values->{macro_id
};
207 # Unauthorized attempt to write
208 $t->post_ok( "//$unauth_userid:$password@/api/v1/advancededitormacros" => json
=> $macro_values )
211 # Authorized attempt to write invalid data
212 my $macro_with_invalid_field = { %$macro_values };
213 $macro_with_invalid_field->{'big_mac_ro'} = 'Mac attack';
215 $t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros" => json
=> $macro_with_invalid_field )
220 message
=> "Properties not allowed: big_mac_ro.",
226 # Authorized attempt to write
227 $t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros" => json
=> $macro_values )
228 ->status_is( 201, 'SWAGGER3.2.1' )
229 ->json_has( '/macro_id', 'We generated a new id' )
230 ->json_is( '/name' => $macro_values->{name
}, 'The name matches what we supplied' )
231 ->json_is( '/macro_text' => $macro_values->{macro_text
}, 'The text matches what we supplied' )
232 ->json_is( '/patron_id' => $macro_values->{patron_id
}, 'The borrower matches the borrower who submitted' )
233 ->json_is( '/shared' => 0, 'The macro is not shared' )
234 ->header_like( Location
=> qr
|^\
/api\/v1\
/advancededitormacros\/d*|, 'Correct location' );
236 # save the library_id
239 # Authorized attempt to create with existing id
240 $macro_values->{macro_id
} = $macro_id;
242 $t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros" => json
=> $macro_values )
244 ->json_is( '/errors' => [
246 message
=> "Read-only.",
247 path
=> "/body/macro_id"
252 $macro_values->{shared
} = 1;
253 delete $macro_values->{macro_id
};
255 # Unauthorized attempt to write a shared macro on private endpoint
256 $t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros" => json
=> $macro_values )
258 # Unauthorized attempt to write a private macro on shared endpoint
259 $t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/shared" => json
=> $macro_values )
263 source
=> 'UserPermission',
265 borrowernumber
=> $authorized_patron->borrowernumber,
267 code
=> 'create_shared_macros',
271 # Authorized attempt to write a shared macro on private endpoint
272 $t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros" => json
=> $macro_values )
275 # Authorized attempt to write a shared macro on shared endpoint
276 $t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/shared" => json
=> $macro_values )
281 subtest
'update() tests' => sub {
284 my $authorized_patron = $builder->build_object({
285 class => 'Koha::Patrons',
286 value
=> { flags
=> 0 }
289 source
=> 'UserPermission',
291 borrowernumber
=> $authorized_patron->borrowernumber,
293 code
=> 'advanced_editor',
297 my $password = 'thePassword123';
298 $authorized_patron->set_password({ password
=> $password, skip_validation
=> 1 });
299 my $auth_userid = $authorized_patron->userid;
301 my $unauthorized_patron = $builder->build_object({
302 class => 'Koha::Patrons',
303 value
=> { flags
=> 0 }
305 $unauthorized_patron->set_password({ password
=> $password, skip_validation
=> 1 });
306 my $unauth_userid = $unauthorized_patron->userid;
308 my $macro = $builder->build_object({
309 class => 'Koha::AdvancedEditorMacros',
310 value
=> { borrowernumber
=> $authorized_patron->borrowernumber, shared
=> 0 }
312 my $macro_2 = $builder->build_object({
313 class => 'Koha::AdvancedEditorMacros',
314 value
=> { borrowernumber
=> $unauthorized_patron->borrowernumber, shared
=> 0 }
316 my $macro_id = $macro->id;
317 my $macro_2_id = $macro_2->id;
318 my $macro_values = Koha
::REST
::V1
::AdvancedEditorMacro
::_to_api
( $macro->TO_JSON );
319 delete $macro_values->{macro_id
};
321 # Unauthorized attempt to update
322 $t->put_ok( "//$unauth_userid:$password@/api/v1/advancededitormacros/$macro_id"
323 => json
=> { name
=> 'New unauthorized name change' } )
326 # Attempt partial update on a PUT
327 my $macro_with_missing_field = {
328 name
=> "Call it macro-roni",
331 $t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_id" => json
=> $macro_with_missing_field )
333 ->json_has( "/errors" =>
334 [ { message
=> "Missing property.", path
=> "/body/macro_text" } ]
338 name
=> "Macro-update",
339 macro_text
=> "delete 100",
340 patron_id
=> $authorized_patron->borrowernumber,
344 my $test = $t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_id" => json
=> $macro_update )
345 ->status_is(200, 'Authorized user can update a macro')
346 ->json_is( '/macro_id' => $macro_id, 'We get the id back' )
347 ->json_is( '/name' => $macro_update->{name
}, 'We get the name back' )
348 ->json_is( '/macro_text' => $macro_update->{macro_text
}, 'We get the text back' )
349 ->json_is( '/patron_id' => $macro_update->{patron_id
}, 'We get the patron_id back' )
350 ->json_is( '/shared' => $macro_update->{shared
}, 'It should still not be shared' );
352 # Now try to make the macro shared
353 $macro_update->{shared
} = 1;
355 $t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/shared/$macro_id" => json
=> $macro_update )
356 ->status_is(403, 'Cannot make your macro shared on private endpoint');
357 $t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/shared/$macro_id" => json
=> $macro_update )
358 ->status_is(403, 'Cannot make your macro shared without permission');
361 source
=> 'UserPermission',
363 borrowernumber
=> $authorized_patron->borrowernumber,
365 code
=> 'create_shared_macros',
369 $t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_id" => json
=> $macro_update )
370 ->status_is(403, 'Cannot make your macro shared on the private endpoint');
372 $t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/shared/$macro_id" => json
=> $macro_update )
373 ->status_is(200, 'Can update macro to shared with permission')
374 ->json_is( '/macro_id' => $macro_id, 'We get back the id' )
375 ->json_is( '/name' => $macro_update->{name
}, 'We get back the name' )
376 ->json_is( '/macro_text' => $macro_update->{macro_text
}, 'We get back the text' )
377 ->json_is( '/patron_id' => $macro_update->{patron_id
}, 'We get back our patron id' )
378 ->json_is( '/shared' => 1, 'It is shared' );
380 # Authorized attempt to write invalid data
381 my $macro_with_invalid_field = { %$macro_update };
382 $macro_with_invalid_field->{'big_mac_ro'} = 'Mac attack';
384 $t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_id" => json
=> $macro_with_invalid_field )
389 message
=> "Properties not allowed: big_mac_ro.",
395 my $non_existent_macro = $builder->build_object({class => 'Koha::AdvancedEditorMacros'});
396 my $non_existent_code = $non_existent_macro->id;
397 $non_existent_macro->delete;
399 $t->put_ok("//$auth_userid:$password@/api/v1/advancededitormacros/$non_existent_code" => json
=> $macro_update)
402 $t->put_ok("//$auth_userid:$password@/api/v1/advancededitormacros/$macro_2_id" => json
=> $macro_update)
403 ->status_is(403, "Cannot update other borrowers private macro");
406 subtest
'delete() tests' => sub {
409 my $authorized_patron = $builder->build_object({
410 class => 'Koha::Patrons',
411 value
=> { flags
=> 0 }
414 source
=> 'UserPermission',
416 borrowernumber
=> $authorized_patron->borrowernumber,
418 code
=> 'advanced_editor',
422 my $password = 'thePassword123';
423 $authorized_patron->set_password({ password
=> $password, skip_validation
=> 1 });
424 my $auth_userid = $authorized_patron->userid;
426 my $unauthorized_patron = $builder->build_object({
427 class => 'Koha::Patrons',
428 value
=> { flags
=> 0 }
430 $unauthorized_patron->set_password({ password
=> $password, skip_validation
=> 1 });
431 my $unauth_userid = $unauthorized_patron->userid;
433 my $macro = $builder->build_object({
434 class => 'Koha::AdvancedEditorMacros',
435 value
=> { borrowernumber
=> $authorized_patron->borrowernumber, shared
=> 0 }
437 my $macro_2 = $builder->build_object({
438 class => 'Koha::AdvancedEditorMacros',
439 value
=> { borrowernumber
=> $unauthorized_patron->borrowernumber, shared
=> 0 }
441 my $macro_id = $macro->id;
442 my $macro_2_id = $macro_2->id;
444 # Unauthorized attempt to delete
445 $t->delete_ok( "//$unauth_userid:$password@/api/v1/advancededitormacros/$macro_2_id")
446 ->status_is(403, "Cannot delete macro without permission");
448 $t->delete_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_id")
449 ->status_is(200, 'Can delete macro with permission');
451 $t->delete_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_2_id")
452 ->status_is(403, 'Cannot delete other users macro with permission');
454 $macro_2->shared(1)->store();
456 $t->delete_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/shared/$macro_2_id")
457 ->status_is(403, 'Cannot delete other users shared macro without permission');
460 source
=> 'UserPermission',
462 borrowernumber
=> $authorized_patron->borrowernumber,
464 code
=> 'delete_shared_macros',
467 $t->delete_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_2_id")
468 ->status_is(403, 'Cannot delete other users shared macro with permission on private endpoint');
469 $t->delete_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/shared/$macro_2_id")
470 ->status_is(200, 'Can delete other users shared macro with permission');
474 $schema->storage->txn_rollback;