Bug 26384: Fix executable flags
[koha.git] / t / db_dependent / api / v1 / advanced_editor_macros.t
blobb95eeb2cb54a412340d9c0269e4744131a0d56d9
1 #!/usr/bin/env perl
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
8 # version.
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>.
17 use Modern::Perl;
19 use Test::More tests => 5;
20 use Test::Mojo;
21 use Test::Warn;
23 use t::lib::TestBuilder;
24 use t::lib::Mocks;
26 use Koha::AdvancedEditorMacros;
27 use Koha::Database;
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 {
39 plan tests => 8;
42 my $patron_1 = $builder->build_object({
43 class => 'Koha::Patrons',
44 value => { flags => 9 }
45 });
46 my $patron_2 = $builder->build_object({
47 class => 'Koha::Patrons',
48 });
49 my $password = 'thePassword123';
50 $patron_1->set_password({ password => $password, skip_validation => 1 });
51 my $userid = $patron_1->userid;
53 # Create test context
54 my $macro_1 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value =>
56 name => 'Test1',
57 macro => 'delete 100',
58 borrowernumber => $patron_1->borrowernumber,
59 shared => 0,
61 });
62 my $macro_2 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value =>
64 name => 'Test2',
65 macro => 'delete 100',
66 borrowernumber => $patron_1->borrowernumber,
67 shared => 1,
69 });
70 my $macro_3 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value =>
72 name => 'Test3',
73 macro => 'delete 100',
74 borrowernumber => $patron_2->borrowernumber,
75 shared => 0,
77 });
78 my $macro_4 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value =>
80 name => 'Test4',
81 macro => 'delete 100',
82 borrowernumber => $patron_2->borrowernumber,
83 shared => 1,
85 });
87 my $macros_index = Koha::AdvancedEditorMacros->search({ -or => { shared => 1, borrowernumber => $patron_1->borrowernumber } })->count-1;
88 ## Authorized user tests
89 # Make sure we are returned with the correct amount of macros
90 $t->get_ok( "//$userid:$password@/api/v1/advanced_editor/macros" )
91 ->status_is( 200, 'SWAGGER3.2.2' )
92 ->json_has('/' . $macros_index . '/macro_id')
93 ->json_hasnt('/' . ($macros_index + 1) . '/macro_id');
95 subtest 'query parameters' => sub {
97 plan tests => 15;
98 $t->get_ok("//$userid:$password@/api/v1/advanced_editor/macros?name=" . $macro_2->name)
99 ->status_is(200)
100 ->json_is( [ $macro_2->to_api ] );
101 $t->get_ok("//$userid:$password@/api/v1/advanced_editor/macros?name=" . $macro_3->name)
102 ->status_is(200)
103 ->json_is( [ ] );
104 $t->get_ok("//$userid:$password@/api/v1/advanced_editor/macros?macro_text=delete%20100")
105 ->status_is(200)
106 ->json_is( [ $macro_1->to_api, $macro_2->to_api, $macro_4->to_api ] );
107 $t->get_ok("//$userid:$password@/api/v1/advanced_editor/macros?patron_id=" . $patron_1->borrowernumber)
108 ->status_is(200)
109 ->json_is( [ $macro_1->to_api, $macro_2->to_api ] );
110 $t->get_ok("//$userid:$password@/api/v1/advanced_editor/macros?shared=1")
111 ->status_is(200)
112 ->json_is( [ $macro_2->to_api, $macro_4->to_api ] );
115 # Warn on unsupported query parameter
116 $t->get_ok( "//$userid:$password@/api/v1/advanced_editor/macros?macro_blah=blah" )
117 ->status_is(400)
118 ->json_is( [{ path => '/query/macro_blah', message => 'Malformed query string'}] );
122 subtest 'get() tests' => sub {
124 plan tests => 15;
126 my $patron = $builder->build_object({
127 class => 'Koha::Patrons',
128 value => { flags => 1 }
130 my $password = 'thePassword123';
131 $patron->set_password({ password => $password, skip_validation => 1 });
132 my $userid = $patron->userid;
134 my $macro_1 = $builder->build_object( { class => 'Koha::AdvancedEditorMacros', value => {
135 shared => 1,
138 my $macro_2 = $builder->build_object( { class => 'Koha::AdvancedEditorMacros', value => {
139 shared => 0,
142 my $macro_3 = $builder->build_object( { class => 'Koha::AdvancedEditorMacros', value => {
143 borrowernumber => $patron->borrowernumber,
144 shared => 0,
148 $t->get_ok( "//$userid:$password@/api/v1/advanced_editor/macros/" . $macro_1->id )
149 ->status_is( 403, 'Cannot get a shared macro via regular endpoint' )
150 ->json_is( '/error' => 'This macro is shared, you must access it via advanced_editor/macros/shared' );
152 $t->get_ok( "//$userid:$password@/api/v1/advanced_editor/macros/shared/" . $macro_1->id )
153 ->status_is( 200, 'Can get a shared macro via shared endpoint' )
154 ->json_is( $macro_1->to_api );
156 $t->get_ok( "//$userid:$password@/api/v1/advanced_editor/macros/" . $macro_2->id )
157 ->status_is( 403, 'Cannot access another users macro' )
158 ->json_is( '/error' => 'You do not have permission to access this macro' );
160 $t->get_ok( "//$userid:$password@/api/v1/advanced_editor/macros/" . $macro_3->id )
161 ->status_is( 200, 'Can get your own private macro' )
162 ->json_is( $macro_3->to_api );
164 my $non_existent_code = $macro_1->id;
165 $macro_1->delete;
167 $t->get_ok( "//$userid:$password@/api/v1/advanced_editor/macros/" . $non_existent_code )
168 ->status_is(404)
169 ->json_is( '/error' => 'Macro not found' );
173 subtest 'add() tests' => sub {
175 plan tests => 24;
177 my $authorized_patron = $builder->build_object({
178 class => 'Koha::Patrons',
179 value => { flags => 0 }
181 $builder->build({
182 source => 'UserPermission',
183 value => {
184 borrowernumber => $authorized_patron->borrowernumber,
185 module_bit => 9,
186 code => 'advanced_editor',
190 my $password = 'thePassword123';
191 $authorized_patron->set_password({ password => $password, skip_validation => 1 });
192 my $auth_userid = $authorized_patron->userid;
194 my $unauthorized_patron = $builder->build_object({
195 class => 'Koha::Patrons',
196 value => { flags => 0 }
198 $unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
199 my $unauth_userid = $unauthorized_patron->userid;
201 my $macro = $builder->build_object({
202 class => 'Koha::AdvancedEditorMacros',
203 value => { shared => 0 }
205 my $macro_values = $macro->to_api;
206 delete $macro_values->{macro_id};
207 $macro->delete;
209 # Unauthorized attempt to write
210 $t->post_ok( "//$unauth_userid:$password@/api/v1/advanced_editor/macros" => json => $macro_values )
211 ->status_is(403);
213 # Authorized attempt to write invalid data
214 my $macro_with_invalid_field = { %$macro_values };
215 $macro_with_invalid_field->{'big_mac_ro'} = 'Mac attack';
217 $t->post_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros" => json => $macro_with_invalid_field )
218 ->status_is(400)
219 ->json_is(
220 "/errors" => [
222 message => "Properties not allowed: big_mac_ro.",
223 path => "/body"
228 # Authorized attempt to write
229 $t->post_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros" => json => $macro_values )
230 ->status_is( 201, 'SWAGGER3.2.1' )
231 ->json_has( '/macro_id', 'We generated a new id' )
232 ->json_is( '/name' => $macro_values->{name}, 'The name matches what we supplied' )
233 ->json_is( '/macro_text' => $macro_values->{macro_text}, 'The text matches what we supplied' )
234 ->json_is( '/patron_id' => $macro_values->{patron_id}, 'The borrower matches the borrower who submitted' )
235 ->json_is( '/shared' => Mojo::JSON->false, 'The macro is not shared' )
236 ->header_like( Location => qr|^\/api\/v1\/advanced_editor/macros\/d*|, 'Correct location' );
238 # save the library_id
239 my $macro_id = 999;
241 # Authorized attempt to create with existing id
242 $macro_values->{macro_id} = $macro_id;
244 $t->post_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros" => json => $macro_values )
245 ->status_is(400)
246 ->json_is( '/errors' => [
248 message => "Read-only.",
249 path => "/body/macro_id"
254 $macro_values->{shared} = Mojo::JSON->true;
255 delete $macro_values->{macro_id};
257 # Unauthorized attempt to write a shared macro on private endpoint
258 $t->post_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros" => json => $macro_values )
259 ->status_is(403);
260 # Unauthorized attempt to write a private macro on shared endpoint
261 $t->post_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros/shared" => json => $macro_values )
262 ->status_is(403);
264 $builder->build({
265 source => 'UserPermission',
266 value => {
267 borrowernumber => $authorized_patron->borrowernumber,
268 module_bit => 9,
269 code => 'create_shared_macros',
273 # Authorized attempt to write a shared macro on private endpoint
274 $t->post_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros" => json => $macro_values )
275 ->status_is(403);
277 # Authorized attempt to write a shared macro on shared endpoint
278 $t->post_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros/shared" => json => $macro_values )
279 ->status_is(201);
283 subtest 'update() tests' => sub {
284 plan tests => 32;
286 my $authorized_patron = $builder->build_object({
287 class => 'Koha::Patrons',
288 value => { flags => 0 }
290 $builder->build({
291 source => 'UserPermission',
292 value => {
293 borrowernumber => $authorized_patron->borrowernumber,
294 module_bit => 9,
295 code => 'advanced_editor',
299 my $password = 'thePassword123';
300 $authorized_patron->set_password({ password => $password, skip_validation => 1 });
301 my $auth_userid = $authorized_patron->userid;
303 my $unauthorized_patron = $builder->build_object({
304 class => 'Koha::Patrons',
305 value => { flags => 0 }
307 $unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
308 my $unauth_userid = $unauthorized_patron->userid;
310 my $macro = $builder->build_object({
311 class => 'Koha::AdvancedEditorMacros',
312 value => { borrowernumber => $authorized_patron->borrowernumber, shared => 0 }
314 my $macro_2 = $builder->build_object({
315 class => 'Koha::AdvancedEditorMacros',
316 value => { borrowernumber => $unauthorized_patron->borrowernumber, shared => 0 }
318 my $macro_id = $macro->id;
319 my $macro_2_id = $macro_2->id;
320 my $macro_values = $macro->to_api;
321 delete $macro_values->{macro_id};
323 # Unauthorized attempt to update
324 $t->put_ok( "//$unauth_userid:$password@/api/v1/advanced_editor/macros/$macro_id"
325 => json => { name => 'New unauthorized name change' } )
326 ->status_is(403);
328 # Attempt partial update on a PUT
329 my $macro_with_missing_field = {
330 name => "Call it macro-roni",
333 $t->put_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros/$macro_id" => json => $macro_with_missing_field )
334 ->status_is(400)
335 ->json_has( "/errors" =>
336 [ { message => "Missing property.", path => "/body/macro_text" } ]
339 my $macro_update = {
340 name => "Macro-update",
341 macro_text => "delete 100",
342 patron_id => $authorized_patron->borrowernumber,
343 shared => Mojo::JSON->false,
346 my $test = $t->put_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros/$macro_id" => json => $macro_update )
347 ->status_is(200, 'Authorized user can update a macro')
348 ->json_is( '/macro_id' => $macro_id, 'We get the id back' )
349 ->json_is( '/name' => $macro_update->{name}, 'We get the name back' )
350 ->json_is( '/macro_text' => $macro_update->{macro_text}, 'We get the text back' )
351 ->json_is( '/patron_id' => $macro_update->{patron_id}, 'We get the patron_id back' )
352 ->json_is( '/shared' => $macro_update->{shared}, 'It should still not be shared' );
354 # Now try to make the macro shared
355 $macro_update->{shared} = Mojo::JSON->true;
357 $t->put_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros/shared/$macro_id" => json => $macro_update )
358 ->status_is(403, 'Cannot make your macro shared on private endpoint');
359 $t->put_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros/shared/$macro_id" => json => $macro_update )
360 ->status_is(403, 'Cannot make your macro shared without permission');
362 $builder->build({
363 source => 'UserPermission',
364 value => {
365 borrowernumber => $authorized_patron->borrowernumber,
366 module_bit => 9,
367 code => 'create_shared_macros',
371 $t->put_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros/$macro_id" => json => $macro_update )
372 ->status_is(403, 'Cannot make your macro shared on the private endpoint');
374 $t->put_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros/shared/$macro_id" => json => $macro_update )
375 ->status_is(200, 'Can update macro to shared with permission')
376 ->json_is( '/macro_id' => $macro_id, 'We get back the id' )
377 ->json_is( '/name' => $macro_update->{name}, 'We get back the name' )
378 ->json_is( '/macro_text' => $macro_update->{macro_text}, 'We get back the text' )
379 ->json_is( '/patron_id' => $macro_update->{patron_id}, 'We get back our patron id' )
380 ->json_is( '/shared' => Mojo::JSON->true, 'It is shared' );
382 # Authorized attempt to write invalid data
383 my $macro_with_invalid_field = { %$macro_update };
384 $macro_with_invalid_field->{'big_mac_ro'} = 'Mac attack';
386 $t->put_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros/$macro_id" => json => $macro_with_invalid_field )
387 ->status_is(400)
388 ->json_is(
389 "/errors" => [
391 message => "Properties not allowed: big_mac_ro.",
392 path => "/body"
397 my $non_existent_macro = $builder->build_object({class => 'Koha::AdvancedEditorMacros'});
398 my $non_existent_code = $non_existent_macro->id;
399 $non_existent_macro->delete;
401 $t->put_ok("//$auth_userid:$password@/api/v1/advanced_editor/macros/$non_existent_code" => json => $macro_update)
402 ->status_is(404);
404 $t->put_ok("//$auth_userid:$password@/api/v1/advanced_editor/macros/$macro_2_id" => json => $macro_update)
405 ->status_is(403, "Cannot update other borrowers private macro");
408 subtest 'delete() tests' => sub {
409 plan tests => 12;
411 my $authorized_patron = $builder->build_object({
412 class => 'Koha::Patrons',
413 value => { flags => 0 }
415 $builder->build({
416 source => 'UserPermission',
417 value => {
418 borrowernumber => $authorized_patron->borrowernumber,
419 module_bit => 9,
420 code => 'advanced_editor',
424 my $password = 'thePassword123';
425 $authorized_patron->set_password({ password => $password, skip_validation => 1 });
426 my $auth_userid = $authorized_patron->userid;
428 my $unauthorized_patron = $builder->build_object({
429 class => 'Koha::Patrons',
430 value => { flags => 0 }
432 $unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
433 my $unauth_userid = $unauthorized_patron->userid;
435 my $macro = $builder->build_object({
436 class => 'Koha::AdvancedEditorMacros',
437 value => { borrowernumber => $authorized_patron->borrowernumber, shared => 0 }
439 my $macro_2 = $builder->build_object({
440 class => 'Koha::AdvancedEditorMacros',
441 value => { borrowernumber => $unauthorized_patron->borrowernumber, shared => 0 }
443 my $macro_id = $macro->id;
444 my $macro_2_id = $macro_2->id;
446 # Unauthorized attempt to delete
447 $t->delete_ok( "//$unauth_userid:$password@/api/v1/advanced_editor/macros/$macro_2_id")
448 ->status_is(403, "Cannot delete macro without permission");
450 $t->delete_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros/$macro_id")
451 ->status_is( 204, 'Can delete macro with permission');
453 $t->delete_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros/$macro_2_id")
454 ->status_is(403, 'Cannot delete other users macro with permission');
456 $macro_2->shared(1)->store();
458 $t->delete_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros/shared/$macro_2_id")
459 ->status_is(403, 'Cannot delete other users shared macro without permission');
461 $builder->build({
462 source => 'UserPermission',
463 value => {
464 borrowernumber => $authorized_patron->borrowernumber,
465 module_bit => 9,
466 code => 'delete_shared_macros',
469 $t->delete_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros/$macro_2_id")
470 ->status_is(403, 'Cannot delete other users shared macro with permission on private endpoint');
471 $t->delete_ok( "//$auth_userid:$password@/api/v1/advanced_editor/macros/shared/$macro_2_id")
472 ->status_is(204, 'Can delete other users shared macro with permission');
476 $schema->storage->txn_rollback;