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;
23 use t::lib::TestBuilder;
26 use Koha::Suggestions;
29 my $schema = Koha::Database->new->schema;
30 my $builder = t::lib::TestBuilder->new;
32 my $t = Test::Mojo->new('Koha::REST::V1');
33 t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
35 subtest 'list() tests' => sub {
39 $schema->storage->txn_begin;
41 my $librarian = $builder->build_object(
43 class => 'Koha::Patrons',
44 value => { flags => 2 ** 12 } # suggestions flag = 12
47 my $password = 'thePassword123';
48 $librarian->set_password( { password => $password, skip_validation => 1 } );
49 my $userid = $librarian->userid;
51 my $patron = $builder->build_object(
53 class => 'Koha::Patrons',
54 value => { flags => 0 }
58 $patron->set_password( { password => $password, skip_validation => 1 } );
60 my $unauth_userid = $patron->userid;
61 my $patron_id = $patron->id;
63 ## Authorized user tests
64 # No suggestions by patron, so empty array should be returned
65 $t->get_ok("//$userid:$password@/api/v1/suggestions?q={\"suggested_by\":\"$patron_id\"}")
66 ->status_is(200)->json_is( [] );
68 my $suggestion_1 = $builder->build_object(
70 class => 'Koha::Suggestions',
71 value => { suggestedby => $patron_id, STATUS => 'ASKED' }
75 # One suggestion created, should get returned
76 $t->get_ok("//$userid:$password@/api/v1/suggestions?q={\"suggested_by\":\"$patron_id\"}")
77 ->status_is(200)->json_is( [ $suggestion_1->to_api ] );
79 my $suggestion_2 = $builder->build_object(
81 class => 'Koha::Suggestions',
82 value => { suggestedby => $patron_id, STATUS => 'ASKED' }
86 # Two SMTP servers created, they should both be returned
87 $t->get_ok("//$userid:$password@/api/v1/suggestions?q={\"suggested_by\":\"$patron_id\"}")
89 ->json_is( [ $suggestion_1->to_api, $suggestion_2->to_api, ] );
92 $t->get_ok("//$unauth_userid:$password@/api/v1/suggestions")
95 $schema->storage->txn_rollback;
98 subtest 'get() tests' => sub {
102 $schema->storage->txn_begin;
104 my $librarian = $builder->build_object(
106 class => 'Koha::Patrons',
107 value => { flags => 2 ** 12 } # suggestions flag = 12
110 my $password = 'thePassword123';
111 $librarian->set_password( { password => $password, skip_validation => 1 } );
112 my $userid = $librarian->userid;
114 my $patron = $builder->build_object(
116 class => 'Koha::Patrons',
117 value => { flags => 0 }
121 $patron->set_password( { password => $password, skip_validation => 1 } );
122 my $unauth_userid = $patron->userid;
123 my $patron_id = $patron->id;
125 my $suggestion = $builder->build_object(
127 class => 'Koha::Suggestions',
128 value => { suggestedby => $patron_id, STATUS => 'ASKED' }
133 "//$userid:$password@/api/v1/suggestions/" . $suggestion->id )
134 ->status_is(200)->json_is( $suggestion->to_api );
136 my $authorised_value = Koha::AuthorisedValue->new(
138 category => 'SUGGEST_STATUS',
139 authorised_value => 'FREDERIC'
142 $suggestion->STATUS('FREDERIC')->store->discard_changes;
144 $t->get_ok( "//$userid:$password@/api/v1/suggestions/" . $suggestion->id )->status_is(200)
145 ->json_is( $suggestion->to_api );
147 $t->get_ok( "//$unauth_userid:$password@/api/v1/suggestions/"
148 . $suggestion->id )->status_is(403);
150 my $suggestion_to_delete = $builder->build_object( { class => 'Koha::Suggestions' } );
151 my $non_existent_id = $suggestion_to_delete->id;
152 $suggestion_to_delete->delete;
155 "//$userid:$password@/api/v1/suggestions/$non_existent_id")
156 ->status_is(404)->json_is( '/error' => 'Suggestion not found.' );
158 $schema->storage->txn_rollback;
161 subtest 'add() tests' => sub {
165 $schema->storage->txn_begin;
167 my $librarian = $builder->build_object(
169 class => 'Koha::Patrons',
170 value => { flags => 2 ** 12 } # suggestions flag = 12
173 my $password = 'thePassword123';
174 $librarian->set_password( { password => $password, skip_validation => 1 } );
175 my $userid = $librarian->userid;
177 my $patron = $builder->build_object(
179 class => 'Koha::Patrons',
180 value => { flags => 0 }
184 $patron->set_password( { password => $password, skip_validation => 1 } );
186 my $unauth_userid = $patron->userid;
187 my $patron_id = $patron->id;
189 my $suggestion = $builder->build_object(
191 class => 'Koha::Suggestions',
192 value => { suggestedby => $patron_id, STATUS => 'ASKED' }
195 my $suggestion_data = $suggestion->to_api;
196 delete $suggestion_data->{suggestion_id};
199 # Unauthorized attempt to write
201 "//$unauth_userid:$password@/api/v1/suggestions" => json =>
202 $suggestion_data )->status_is(403);
204 # Authorized attempt to write invalid data
205 my $suggestion_with_invalid_field = {
209 $t->post_ok( "//$userid:$password@/api/v1/suggestions" => json =>
210 $suggestion_with_invalid_field )->status_is(400)->json_is(
213 message => "Properties not allowed: blah.",
219 # Authorized attempt to write
220 my $generated_suggestion =
221 $t->post_ok( "//$userid:$password@/api/v1/suggestions" => json =>
222 $suggestion_data )->status_is( 201, 'SWAGGER3.2.1' )->header_like(
223 Location => qr|^\/api\/v1\/suggestions\/\d*|,
227 my $suggestion_id = $generated_suggestion->{suggestion_id};
229 $generated_suggestion,
230 Koha::Suggestions->find($suggestion_id)->to_api,
231 'The object is returned'
234 # Authorized attempt to create with null id
235 $suggestion_data->{suggestion_id} = undef;
236 $t->post_ok( "//$userid:$password@/api/v1/suggestions" => json =>
237 $suggestion_data )->status_is(400)->json_has('/errors');
239 # Authorized attempt to create with existing id
240 $suggestion_data->{suggestion_id} = $suggestion_id;
241 $t->post_ok( "//$userid:$password@/api/v1/suggestions" => json =>
242 $suggestion_data )->status_is(400)->json_is(
245 message => "Read-only.",
246 path => "/body/suggestion_id"
251 subtest 'x-koha-override tests' => sub {
255 my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
257 t::lib::Mocks::mock_preference( 'MaxTotalSuggestions', 4 );
258 t::lib::Mocks::mock_preference( 'MaxOpenSuggestions', 2 );
259 t::lib::Mocks::mock_preference( 'NumberOfSuggestionDays', 2 );
261 my $suggestion = $builder->build_object(
262 { class => 'Koha::Suggestions',
263 value => { suggestedby => $patron->id, STATUS => 'ACCEPTED' }
267 my $suggestion_data = $suggestion->to_api;
268 delete $suggestion_data->{suggestion_id};
269 delete $suggestion_data->{status};
271 $t->post_ok( "//$userid:$password@/api/v1/suggestions" => json => $suggestion_data )
272 ->status_is( 201, 'First pending suggestion' );
274 $t->post_ok( "//$userid:$password@/api/v1/suggestions" => json => $suggestion_data )
275 ->status_is( 201, 'Second pending suggestion' );
277 $t->post_ok( "//$userid:$password@/api/v1/suggestions" => json => $suggestion_data )
279 ->json_is( '/error_code' => 'max_pending_reached' );
281 $t->post_ok( "//$userid:$password@/api/v1/suggestions"
282 => { 'x-koha-override' => 'max_pending' }
283 => json => $suggestion_data )
284 ->status_is( 201, 'max_pending override does the job' );
286 $t->post_ok( "//$userid:$password@/api/v1/suggestions" => json => $suggestion_data )
288 ->json_is( '/error_code' => 'max_total_reached' );
291 "//$userid:$password@/api/v1/suggestions" => { 'x-koha-override' => 'any' } => json => $suggestion_data )
292 ->status_is( 201, 'any overrides anything' );
295 $schema->storage->txn_rollback;
298 subtest 'update() tests' => sub {
302 $schema->storage->txn_begin;
304 my $librarian = $builder->build_object(
306 class => 'Koha::Patrons',
307 value => { flags => 2 ** 12 } # suggestions flag = 12
310 my $password = 'thePassword123';
311 $librarian->set_password( { password => $password, skip_validation => 1 } );
312 my $userid = $librarian->userid;
314 my $patron = $builder->build_object(
316 class => 'Koha::Patrons',
317 value => { flags => 0 }
321 $patron->set_password( { password => $password, skip_validation => 1 } );
322 my $unauth_userid = $patron->userid;
324 my $suggestion_id = $builder->build_object(
326 class => 'Koha::Suggestions',
327 value => { STATUS => 'ASKED' }
331 # Unauthorized attempt to update
333 "//$unauth_userid:$password@/api/v1/suggestions/$suggestion_id"
334 => json => { name => 'New unauthorized name change' } )
337 # Full object update on PUT
338 my $suggestion_with_updated_field = { reason => "Some reason", };
341 "//$userid:$password@/api/v1/suggestions/$suggestion_id" =>
342 json => $suggestion_with_updated_field )->status_is(200)
343 ->json_is( '/reason' => 'Some reason' );
345 # Authorized attempt to write invalid data
346 my $suggestion_with_invalid_field = {
348 reason => 'Some reason'
352 "//$userid:$password@/api/v1/suggestions/$suggestion_id" =>
353 json => $suggestion_with_invalid_field )->status_is(400)->json_is(
356 message => "Properties not allowed: blah.",
362 my $suggestion_to_delete = $builder->build_object({ class => 'Koha::Suggestions' });
363 my $non_existent_id = $suggestion_to_delete->id;
364 $suggestion_to_delete->delete;
367 "//$userid:$password@/api/v1/suggestions/$non_existent_id" =>
368 json => $suggestion_with_updated_field )->status_is(404);
370 # Wrong method (POST)
371 $suggestion_with_updated_field->{smtp_server_id} = 2;
374 "//$userid:$password@/api/v1/suggestions/$suggestion_id" =>
375 json => $suggestion_with_updated_field )->status_is(404);
377 $schema->storage->txn_rollback;
380 subtest 'delete() tests' => sub {
384 $schema->storage->txn_begin;
386 my $librarian = $builder->build_object(
388 class => 'Koha::Patrons',
389 value => { flags => 2 ** 12 } # suggestions flag = 12
392 my $password = 'thePassword123';
393 $librarian->set_password( { password => $password, skip_validation => 1 } );
394 my $userid = $librarian->userid;
396 my $patron = $builder->build_object(
398 class => 'Koha::Patrons',
399 value => { flags => 0 }
403 $patron->set_password( { password => $password, skip_validation => 1 } );
404 my $unauth_userid = $patron->userid;
406 my $suggestion_id = $builder->build_object({ class => 'Koha::Suggestions' } )->id;
408 # Unauthorized attempt to delete
410 "//$unauth_userid:$password@/api/v1/suggestions/$suggestion_id"
414 "//$userid:$password@/api/v1/suggestions/$suggestion_id")
415 ->status_is( 204, 'SWAGGER3.2.4' )->content_is( q{}, 'SWAGGER3.3.4' );
418 "//$userid:$password@/api/v1/suggestions/$suggestion_id")
421 $schema->storage->txn_rollback;