Bug 17268: (follow-up) Fix licenses
[koha.git] / t / db_dependent / api / v1 / advanced_editor_macros.t
blob9df48fdb368faad915dc5fcb74e03266b0bf3d94
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,
60 });
61 my $macro_2 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value =>
63 name => 'Test2',
64 macro => 'delete 100',
65 borrowernumber => $patron_1->borrowernumber,
66 shared=> 1,
68 });
69 my $macro_3 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value =>
71 name => 'Test3',
72 macro => 'delete 100',
73 borrowernumber => $patron_2->borrowernumber,
75 });
76 my $macro_4 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value =>
78 name => 'Test4',
79 macro => 'delete 100',
80 borrowernumber => $patron_2->borrowernumber,
81 shared => 1,
83 });
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 {
95 plan tests => 15;
96 $t->get_ok("//$userid:$password@/api/v1/advancededitormacros?name=" . $macro_2->name)
97 ->status_is(200)
98 ->json_has( [ $macro_2 ] );
99 $t->get_ok("//$userid:$password@/api/v1/advancededitormacros?name=" . $macro_3->name)
100 ->status_is(200)
101 ->json_has( [ ] );
102 $t->get_ok("//$userid:$password@/api/v1/advancededitormacros?macro_text=delete 100")
103 ->status_is(200)
104 ->json_has( [ $macro_1, $macro_2, $macro_4 ] );
105 $t->get_ok("//$userid:$password@/api/v1/advancededitormacros?patron_id=" . $patron_1->borrowernumber)
106 ->status_is(200)
107 ->json_has( [ $macro_1, $macro_2 ] );
108 $t->get_ok("//$userid:$password@/api/v1/advancededitormacros?shared=1")
109 ->status_is(200)
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" )
115 ->status_is(400)
116 ->json_is( [{ path => '/query/macro_blah', message => 'Malformed query string'}] );
120 subtest 'get() tests' => sub {
122 plan tests => 15;
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 => {
133 shared => 1,
136 my $macro_2 = $builder->build_object( { class => 'Koha::AdvancedEditorMacros', value => {
137 shared => 0,
140 my $macro_3 = $builder->build_object( { class => 'Koha::AdvancedEditorMacros', value => {
141 borrowernumber => $patron->borrowernumber,
142 shared => 0,
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;
163 $macro_1->delete;
165 $t->get_ok( "//$userid:$password@/api/v1/advancededitormacros/" . $non_existent_code )
166 ->status_is(404)
167 ->json_is( '/error' => 'Macro not found' );
171 subtest 'add() tests' => sub {
173 plan tests => 24;
175 my $authorized_patron = $builder->build_object({
176 class => 'Koha::Patrons',
177 value => { flags => 0 }
179 $builder->build({
180 source => 'UserPermission',
181 value => {
182 borrowernumber => $authorized_patron->borrowernumber,
183 module_bit => 9,
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};
205 $macro->delete;
207 # Unauthorized attempt to write
208 $t->post_ok( "//$unauth_userid:$password@/api/v1/advancededitormacros" => json => $macro_values )
209 ->status_is(403);
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 )
216 ->status_is(400)
217 ->json_is(
218 "/errors" => [
220 message => "Properties not allowed: big_mac_ro.",
221 path => "/body"
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
237 my $macro_id = 999;
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 )
243 ->status_is(400)
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 )
257 ->status_is(403);
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 )
260 ->status_is(403);
262 $builder->build({
263 source => 'UserPermission',
264 value => {
265 borrowernumber => $authorized_patron->borrowernumber,
266 module_bit => 9,
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 )
273 ->status_is(403);
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 )
277 ->status_is(201);
281 subtest 'update() tests' => sub {
282 plan tests => 32;
284 my $authorized_patron = $builder->build_object({
285 class => 'Koha::Patrons',
286 value => { flags => 0 }
288 $builder->build({
289 source => 'UserPermission',
290 value => {
291 borrowernumber => $authorized_patron->borrowernumber,
292 module_bit => 9,
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' } )
324 ->status_is(403);
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 )
332 ->status_is(400)
333 ->json_has( "/errors" =>
334 [ { message => "Missing property.", path => "/body/macro_text" } ]
337 my $macro_update = {
338 name => "Macro-update",
339 macro_text => "delete 100",
340 patron_id => $authorized_patron->borrowernumber,
341 shared => 0,
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');
360 $builder->build({
361 source => 'UserPermission',
362 value => {
363 borrowernumber => $authorized_patron->borrowernumber,
364 module_bit => 9,
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 )
385 ->status_is(400)
386 ->json_is(
387 "/errors" => [
389 message => "Properties not allowed: big_mac_ro.",
390 path => "/body"
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)
400 ->status_is(404);
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 {
407 plan tests => 12;
409 my $authorized_patron = $builder->build_object({
410 class => 'Koha::Patrons',
411 value => { flags => 0 }
413 $builder->build({
414 source => 'UserPermission',
415 value => {
416 borrowernumber => $authorized_patron->borrowernumber,
417 module_bit => 9,
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');
459 $builder->build({
460 source => 'UserPermission',
461 value => {
462 borrowernumber => $authorized_patron->borrowernumber,
463 module_bit => 9,
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;