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 Koha::Acquisition::Orders;
21 use Koha::AuthorisedValueCategories;
22 use Koha::AuthorisedValues;
27 use Mojo::JSON qw(encode_json);
29 # Dummy app for testing the plugin
30 use Mojolicious::Lite;
32 app->log->level('error');
34 plugin 'Koha::REST::Plugin::Objects';
35 plugin 'Koha::REST::Plugin::Query';
36 plugin 'Koha::REST::Plugin::Pagination';
38 get '/cities' => sub {
40 $c->validation->output($c->req->params->to_hash);
41 $c->stash_embed( { spec => { parameters => [ { name => 'x-koha-embed', items => { enum => ['+strings'] } } ] } } );
42 my $cities = $c->objects->search(Koha::Cities->new);
43 $c->render( status => 200, json => $cities );
46 get '/cities/rs' => sub {
48 $c->validation->output( $c->req->params->to_hash );
50 my $cities = $c->objects->search_rs( Koha::Cities->new );
52 $c->render( status => 200, json => { count => $cities->count } );
55 get '/cities/:city_id' => sub {
57 my $id = $c->stash("city_id");
58 $c->stash_embed( { spec => { parameters => [ { name => 'x-koha-embed', items => { enum => ['+strings'] } } ] } } );
59 my $city = $c->objects->find(Koha::Cities->new, $id);
60 $c->render( status => 200, json => $city );
63 get '/orders' => sub {
65 $c->stash('koha.embed', ( { fund => {} } ) );
66 $c->validation->output($c->req->params->to_hash);
67 my $orders = $c->objects->search(Koha::Acquisition::Orders->new);
68 $c->render( status => 200, json => $orders );
71 get '/orders/:order_id' => sub {
73 $c->stash('koha.embed', ( { fund => {} } ) );
74 my $id = $c->stash("order_id");
75 my $order = $c->objects->find(Koha::Acquisition::Orders->new, $id);
76 $c->render( status => 200, json => $order );
79 get '/biblios' => sub {
81 my $output = $c->req->params->to_hash;
82 $output->{query} = $c->req->json if defined $c->req->json;
83 my $headers = $c->req->headers->to_hash;
84 $output->{'x-koha-query'} = $headers->{'x-koha-query'} if defined $headers->{'x-koha-query'};
85 $c->validation->output($output);
86 my $biblios_set = Koha::Biblios->new;
87 $c->stash("koha.embed", {
94 my $biblios = $c->objects->search($biblios_set);
95 $c->render( status => 200, json => {count => scalar(@$biblios), biblios => $biblios} );
98 get '/libraries/:library_id_1/:library_id_2' => sub {
102 # Emulate a public route by stashing the is_public value
103 $c->stash( 'is_public' => 1 );
105 my $library_id_1 = $c->param('library_id_1');
106 my $library_id_2 = $c->param('library_id_2');
108 my $libraries_rs = Koha::Libraries->search(
109 { branchcode => [ $library_id_1, $library_id_2 ] },
110 { order_by => 'branchname' }
112 my $libraries = $c->objects->search( $libraries_rs );
120 get '/my_patrons' => sub {
124 my $patrons = $c->objects->search( scalar Koha::Patrons->search( {}, { order_by => 'borrowernumber' }) );
132 get '/cities/:city_id/rs' => sub {
134 $c->validation->output( $c->req->params->to_hash );
136 my $city_id = $c->param('city_id');
137 my $city = $c->objects->find_rs( Koha::Cities->new, $city_id );
139 $c->render( status => 200, json => { name => $city->city_name } );
142 get '/my_patrons/:patron_id' => sub {
146 my $patron_id = $c->param('patron_id');
147 my $patron = $c->objects->find( scalar Koha::Patrons->new, $patron_id );
156 use Test::More tests => 18;
160 use t::lib::TestBuilder;
163 my $schema = Koha::Database->new()->schema();
164 my $builder = t::lib::TestBuilder->new;
166 subtest 'objects.search helper' => sub {
170 $schema->storage->txn_begin;
172 # Remove existing cities to have more control on the search results
173 Koha::Cities->delete;
175 # Create three sample cities that match the query. This makes sure we
176 # always have a "next" link regardless of Mojolicious::Plugin::OpenAPI version.
177 $builder->build_object({
178 class => 'Koha::Cities',
180 city_name => 'Manuel'
183 $builder->build_object({
184 class => 'Koha::Cities',
186 city_name => 'Manuela'
189 $builder->build_object({
190 class => 'Koha::Cities',
192 city_name => 'Manuelab'
196 my $t = Test::Mojo->new;
197 $t->get_ok('/cities?name=manuel&_per_page=1&_page=1')
199 ->header_like( 'Link' => qr/<http:\/\/.*[\?&]_page=2.*>; rel="next",/ )
202 ->json_is('/0/name' => 'Manuel');
204 $builder->build_object({
205 class => 'Koha::Cities',
207 city_name => 'Emanuel'
212 $t->get_ok('/cities?name=manuel&_per_page=4&_page=1&_match=starts_with')
218 ->json_is('/0/name' => 'Manuel')
219 ->json_is('/1/name' => 'Manuela')
220 ->json_is('/2/name' => 'Manuelab');
223 $t->get_ok('/cities?name=manuel&_per_page=4&_page=1&_match=ends_with')
228 ->json_is('/0/name' => 'Manuel')
229 ->json_is('/1/name' => 'Emanuel');
232 $t->get_ok('/cities?name=manuel&_per_page=4&_page=1&_match=exact')
236 ->json_is('/0/name' => 'Manuel');
239 $t->get_ok('/cities?name=manuel&_per_page=4&_page=1&_match=contains')
246 ->json_is('/0/name' => 'Manuel')
247 ->json_is('/1/name' => 'Manuela')
248 ->json_is('/2/name' => 'Manuelab')
249 ->json_is('/3/name' => 'Emanuel');
253 $builder->build_object({ class => 'Koha::Cities' });
256 t::lib::Mocks::mock_preference('RESTdefaultPageSize', 20 );
257 $t->get_ok('/cities')
260 my $response_count = scalar @{ $t->tx->res->json };
261 is( $response_count, 20, 'RESTdefaultPageSize is honoured by default (20)' );
263 t::lib::Mocks::mock_preference('RESTdefaultPageSize', 5 );
264 $t->get_ok('/cities')
267 $response_count = scalar @{ $t->tx->res->json };
268 is( $response_count, 5, 'RESTdefaultPageSize is honoured by default (5)' );
270 $t->get_ok('/cities?_page=1&_per_page=-1')
273 $response_count = scalar @{ $t->tx->res->json };
274 is( $response_count, 24, '_per_page=-1 means all resources' );
276 $t->get_ok('/cities?_page=100&_per_page=-1')
279 $response_count = scalar @{ $t->tx->res->json };
280 is( $response_count, 24, 'When _per_page=-1 the page param is not considered' );
282 $schema->storage->txn_rollback;
285 subtest 'objects.search helper, sorting on mapped column' => sub {
289 $schema->storage->txn_begin;
291 # Have complete control over the existing cities to ease testing
292 Koha::Cities->delete;
294 $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'A', city_country => 'Argentina' } });
295 $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'B', city_country => 'Argentina' } });
296 $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'C', city_country => 'Argentina' } });
297 $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'C', city_country => 'Belarus' } });
299 my $t = Test::Mojo->new;
301 $t->get_ok('/cities?_order_by=%2Bname,-country')
305 ->json_is('/0/name' => 'A')
306 ->json_is('/1/name' => 'B')
307 ->json_is('/2/name' => 'C')
308 ->json_is('/2/country' => 'Belarus')
309 ->json_is('/3/name' => 'C')
310 ->json_is('/3/country' => 'Argentina')
313 # Multi-param: traditional
314 $t->get_ok('/cities?_order_by=%2Bname&_order_by=-country')
318 ->json_is('/0/name' => 'A')
319 ->json_is('/1/name' => 'B')
320 ->json_is('/2/name' => 'C')
321 ->json_is('/2/country' => 'Belarus')
322 ->json_is('/3/name' => 'C')
323 ->json_is('/3/country' => 'Argentina')
326 # Multi-param: PHP Style, Passes validation as above, subsequntly explodes
327 $t->get_ok('/cities?_order_by[]=%2Bname&_order_by[]=-country')
331 ->json_is('/0/name' => 'A')
332 ->json_is('/1/name' => 'B')
333 ->json_is('/2/name' => 'C')
334 ->json_is('/2/country' => 'Belarus')
335 ->json_is('/3/name' => 'C')
336 ->json_is('/3/country' => 'Argentina')
340 $t->get_ok('/cities?_order_by=-name')
344 ->json_is('/0/name' => 'C')
345 ->json_is('/1/name' => 'C')
346 ->json_is('/2/name' => 'B')
347 ->json_is('/3/name' => 'A')
350 $schema->storage->txn_rollback;
353 subtest 'objects.search helper, encoding' => sub {
357 $schema->storage->txn_begin;
359 Koha::Cities->delete;
361 $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'A', city_country => 'Argentina' } });
362 $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'B', city_country => '❤Argentina❤' } });
364 my $t = Test::Mojo->new;
365 $t->get_ok('/cities?q={"country": "❤Argentina❤"}')
369 ->json_is('/0/name' => 'B');
371 $schema->storage->txn_rollback;
374 subtest 'objects.search helper, X-Total-Count and X-Base-Total-Count' => sub {
378 $schema->storage->txn_begin;
380 Koha::Cities->delete;
382 my $long_city_name = 'Llanfairpwllgwyngyll';
383 for my $i ( 1 .. length($long_city_name) ) {
384 $builder->build_object(
386 class => 'Koha::Cities',
388 city_name => substr( $long_city_name, 0, $i ),
389 city_country => 'Wales'
395 my $t = Test::Mojo->new;
396 $t->get_ok('/cities?name=L&_per_page=10&_page=1&_match=starts_with')
398 ->header_is( 'X-Total-Count' => 20, 'X-Total-Count header present' )
399 ->header_is( 'X-Base-Total-Count' => 20, 'X-Base-Total-Count header present' );
401 $t->get_ok('/cities?name=Llan&_per_page=10&_page=1&_match=starts_with')
403 ->header_is( 'X-Total-Count' => 17, 'X-Total-Count header present' )
404 ->header_is('X-Base-Total-Count' => 20, 'X-Base-Total-Count header present' );
406 $schema->storage->txn_rollback;
409 subtest 'objects.search helper, embed' => sub {
413 $schema->storage->txn_begin;
415 my $order = $builder->build_object({ class => 'Koha::Acquisition::Orders' });
417 my $t = Test::Mojo->new;
418 $t->get_ok('/orders?order_id=' . $order->ordernumber)
419 ->json_is('/0',$order->to_api({ embed => ( { fund => {} } ) }));
421 $schema->storage->txn_rollback;
424 subtest 'objects.search helper with query parameter' => sub {
427 $schema->storage->txn_begin;
429 my $patron1 = $builder->build_object( { class => "Koha::Patrons" } );
430 my $patron2 = $builder->build_object( { class => "Koha::Patrons" } );
431 my $biblio1 = $builder->build_sample_biblio;
432 my $biblio2 = $builder->build_sample_biblio;
433 my $biblio3 = $builder->build_sample_biblio;
434 my $suggestion1 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron1->borrowernumber, biblionumber => $biblio1->biblionumber} } );
435 my $suggestion2 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio2->biblionumber} } );
436 my $suggestion3 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio3->biblionumber} } );
438 my $t = Test::Mojo->new;
439 $t->get_ok('/biblios' => json => {"suggestions.suggester.patron_id" => $patron1->borrowernumber })
440 ->json_is('/count' => 1, 'there should be 1 biblio with suggestions of patron 1');
442 $t->get_ok('/biblios' => json => {"suggestions.suggester.patron_id" => $patron2->borrowernumber })
443 ->json_is('/count' => 2, 'there should be 2 biblios with suggestions of patron 2');
445 $schema->storage->txn_rollback;
448 subtest 'objects.search helper with q parameter' => sub {
451 $schema->storage->txn_begin;
453 my $patron1 = $builder->build_object( { class => "Koha::Patrons" } );
454 my $patron2 = $builder->build_object( { class => "Koha::Patrons" } );
455 my $biblio1 = $builder->build_sample_biblio;
456 my $biblio2 = $builder->build_sample_biblio;
457 my $biblio3 = $builder->build_sample_biblio;
458 my $suggestion1 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron1->borrowernumber, biblionumber => $biblio1->biblionumber} } );
459 my $suggestion2 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio2->biblionumber} } );
460 my $suggestion3 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio3->biblionumber} } );
462 my $t = Test::Mojo->new;
463 $t->get_ok('/biblios?q={"suggestions.suggester.patron_id": "'.$patron1->borrowernumber.'"}')
464 ->json_is('/count' => 1, 'there should be 1 biblio with suggestions of patron 1');
466 $t->get_ok('/biblios?q={"suggestions.suggester.patron_id": "'.$patron2->borrowernumber.'"}')
467 ->json_is('/count' => 2, 'there should be 2 biblios with suggestions of patron 2');
469 $schema->storage->txn_rollback;
472 subtest 'objects.search helper with x-koha-query header' => sub {
475 $schema->storage->txn_begin;
477 my $patron1 = $builder->build_object( { class => "Koha::Patrons" } );
478 my $patron2 = $builder->build_object( { class => "Koha::Patrons" } );
479 my $biblio1 = $builder->build_sample_biblio;
480 my $biblio2 = $builder->build_sample_biblio;
481 my $biblio3 = $builder->build_sample_biblio;
482 my $suggestion1 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron1->borrowernumber, biblionumber => $biblio1->biblionumber} } );
483 my $suggestion2 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio2->biblionumber} } );
484 my $suggestion3 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio3->biblionumber} } );
486 my $t = Test::Mojo->new;
487 $t->get_ok('/biblios' => {'x-koha-query' => '{"suggestions.suggester.patron_id": "'.$patron1->borrowernumber.'"}'})
488 ->json_is('/count' => 1, 'there should be 1 biblio with suggestions of patron 1');
490 $t->get_ok('/biblios' => {'x-koha-query' => '{"suggestions.suggester.patron_id": "'.$patron2->borrowernumber.'"}'})
491 ->json_is('/count' => 2, 'there should be 2 biblios with suggestions of patron 2');
493 $schema->storage->txn_rollback;
496 subtest 'objects.search helper with all query methods' => sub {
499 $schema->storage->txn_begin;
501 my $patron1 = $builder->build_object( { class => "Koha::Patrons" , value => {firstname=>'patron1'} } );
502 my $patron2 = $builder->build_object( { class => "Koha::Patrons" , value => {firstname=>'patron2'} } );
503 my $biblio1 = $builder->build_sample_biblio;
504 my $biblio2 = $builder->build_sample_biblio;
505 my $biblio3 = $builder->build_sample_biblio;
506 my $suggestion1 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron1->borrowernumber, biblionumber => $biblio1->biblionumber} } );
507 my $suggestion2 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio2->biblionumber} } );
508 my $suggestion3 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio3->biblionumber} } );
510 my $t = Test::Mojo->new;
511 $t->get_ok('/biblios?q={"suggestions.suggester.firstname": "'.$patron1->firstname.'"}' => {'x-koha-query' => '{"suggestions.suggester.patron_id": "'.$patron1->borrowernumber.'"}'} => json => {"suggestions.suggester.cardnumber" => $patron1->cardnumber})
512 ->json_is('/count' => 1, 'there should be 1 biblio with suggestions of patron 1');
514 $t->get_ok('/biblios?q={"suggestions.suggester.firstname": "'.$patron2->firstname.'"}' => {'x-koha-query' => '{"suggestions.suggester.patron_id": "'.$patron2->borrowernumber.'"}'} => json => {"suggestions.suggester.cardnumber" => $patron2->cardnumber})
515 ->json_is('/count' => 2, 'there should be 2 biblios with suggestions of patron 2');
517 $t->get_ok('/biblios?q={"suggestions.suggester.firstname": "'.$patron1->firstname.'"}' => {'x-koha-query' => '{"suggestions.suggester.patron_id": "'.$patron2->borrowernumber.'"}'} => json => {"suggestions.suggester.cardnumber" => $patron2->cardnumber})
518 ->json_is('/count' => 0, 'there shouldn\'t be biblios where suggester has patron1 fistname and patron2 id');
520 $schema->storage->txn_rollback;
523 subtest 'objects.search helper order by embedded columns' => sub {
526 $schema->storage->txn_begin;
528 my $patron1 = $builder->build_object( { class => "Koha::Patrons" , value => {firstname=>'patron1'} } );
529 my $patron2 = $builder->build_object( { class => "Koha::Patrons" , value => {firstname=>'patron2'} } );
530 my $biblio1 = $builder->build_sample_biblio;
531 my $biblio2 = $builder->build_sample_biblio;
532 my $suggestion1 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron1->borrowernumber, biblionumber => $biblio1->biblionumber} } );
533 my $suggestion2 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio2->biblionumber} } );
535 my $t = Test::Mojo->new;
536 $t->get_ok('/biblios?_order_by=-suggestions.suggester.firstname' => json => [{"me.biblio_id" => $biblio1->biblionumber}, {"me.biblio_id" => $biblio2->biblionumber}])
537 ->json_is('/biblios/0/biblio_id' => $biblio2->biblionumber, 'Biblio 2 should be first')
538 ->json_is('/biblios/1/biblio_id' => $biblio1->biblionumber, 'Biblio 1 should be second');
540 $schema->storage->txn_rollback;
543 subtest 'objects.search_rs helper' => sub {
546 $schema->storage->txn_begin;
548 # Remove existing cities to have more control on the search results
549 Koha::Cities->delete;
551 # Create three sample cities that match the query. This makes sure we
552 # always have a "next" link regardless of Mojolicious::Plugin::OpenAPI version.
553 $builder->build_object(
555 class => 'Koha::Cities',
561 $builder->build_object(
563 class => 'Koha::Cities',
569 $builder->build_object(
571 class => 'Koha::Cities',
578 my $t = Test::Mojo->new;
579 $t->get_ok('/cities/rs')->status_is(200)->json_is( '/count' => 3 );
581 $schema->storage->txn_rollback;
584 subtest 'objects.find helper' => sub {
588 my $t = Test::Mojo->new;
590 $schema->storage->txn_begin;
592 my $city_1 = $builder->build_object( { class => 'Koha::Cities' } );
593 my $city_2 = $builder->build_object( { class => 'Koha::Cities' } );
595 $t->get_ok( '/cities/' . $city_1->id )
597 ->json_is( $city_1->to_api );
599 $t->get_ok( '/cities/' . $city_2->id )
601 ->json_is( $city_2->to_api );
604 my $city_2_id = $city_2->id;
606 $t->get_ok( '/cities/' . $city_2_id )
610 $schema->storage->txn_rollback;
613 subtest 'objects.find helper, embed' => sub {
617 my $t = Test::Mojo->new;
619 $schema->storage->txn_begin;
621 my $order = $builder->build_object({ class => 'Koha::Acquisition::Orders' });
623 $t->get_ok( '/orders/' . $order->ordernumber )
624 ->json_is( $order->to_api( { embed => ( { fund => {} } ) } ) );
626 $schema->storage->txn_rollback;
629 subtest 'objects.search helper, public requests' => sub {
633 $schema->storage->txn_begin;
635 my $library_1 = $builder->build_object({ class => 'Koha::Libraries', value => { branchname => 'A' } });
636 my $library_2 = $builder->build_object({ class => 'Koha::Libraries', value => { branchname => 'B' } });
638 my $t = Test::Mojo->new;
640 $t->get_ok( '/libraries/'.$library_1->id.'/'.$library_2->id )
641 ->json_is('/0' => $library_1->to_api({ public => 1 }), 'Public representation of $library_1 is retrieved')
642 ->json_is('/1' => $library_2->to_api({ public => 1 }), 'Public representation of $library_2 is retrieved');
644 $schema->storage->txn_rollback;
647 subtest 'objects.search helper, search_limited() tests' => sub {
651 $schema->storage->txn_begin;
653 my $library_1 = $builder->build_object({ class => 'Koha::Libraries' });
654 my $library_2 = $builder->build_object({ class => 'Koha::Libraries' });
656 my $patron_1 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $library_1->id } });
657 my $patron_2 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $library_1->id } });
658 my $patron_3 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $library_2->id } });
660 my @libraries_where_can_see_patrons = ( $library_1->id, $library_2->id );
662 my $t = Test::Mojo->new;
664 my $mocked_patron = Test::MockModule->new('Koha::Patron');
665 $mocked_patron->mock( 'libraries_where_can_see_patrons', sub
667 return @libraries_where_can_see_patrons;
671 my $patron = $builder->build_object(
673 class => 'Koha::Patrons',
674 value => { flags => 2**4 } # borrowers flag = 4
678 t::lib::Mocks::mock_userenv({ patron => $patron });
680 $t->get_ok( "/my_patrons?q=" . encode_json( { library_id => [ $library_1->id, $library_2->id ] } ) )
682 ->json_is( '/0/patron_id' => $patron_1->id )
683 ->json_is( '/1/patron_id' => $patron_2->id )
684 ->json_is( '/2/patron_id' => $patron_3->id );
686 @libraries_where_can_see_patrons = ( $library_2->id );
688 my $res = $t->get_ok( "/my_patrons?q=" . encode_json( { library_id => [ $library_1->id, $library_2->id ] } ) )
690 ->json_is( '/0/patron_id' => $patron_3->id, 'Returns the only allowed patron' )
693 is( scalar @{$res}, 1, 'Only one patron returned' );
695 $schema->storage->txn_rollback;
698 subtest 'objects.find helper with expanded authorised values' => sub {
702 $schema->storage->txn_begin;
704 my $t = Test::Mojo->new;
706 Koha::AuthorisedValues->search( { category => 'Countries' } )->delete;
707 Koha::AuthorisedValueCategories->search( { category_name => 'Countries' } )
710 my $cat = $builder->build_object(
712 class => 'Koha::AuthorisedValueCategories',
713 value => { category_name => 'Countries' }
716 my $fr = $builder->build_object(
718 class => 'Koha::AuthorisedValues',
720 authorised_value => 'FR',
722 category => $cat->category_name
726 my $us = $builder->build_object(
728 class => 'Koha::AuthorisedValues',
730 authorised_value => 'US',
731 lib => 'United States of America',
732 category => $cat->category_name
736 my $ar = $builder->build_object(
738 class => 'Koha::AuthorisedValues',
740 authorised_value => 'AR',
742 category => $cat->category_name
747 my $city_class = Test::MockModule->new('Koha::City');
751 my ($self, $params) = @_;
752 use Koha::AuthorisedValues;
754 my $av = Koha::AuthorisedValues->find(
756 authorised_value => $self->city_country,
757 category => 'Countries'
763 category => $av->category,
764 str => ( $params->{public} ) ? $av->lib_opac : $av->lib,
771 my $manuel = $builder->build_object(
773 class => 'Koha::Cities',
775 city_name => 'Manuel',
780 my $manuela = $builder->build_object(
782 class => 'Koha::Cities',
784 city_name => 'Manuela',
790 $t->get_ok( '/cities/' . $manuel->id => { 'x-koha-embed' => '+strings' } )
791 ->status_is(200)->json_is( '/name' => 'Manuel' )
792 ->json_has('/_strings')
793 ->json_is( '/_strings/country/type' => 'av' )
794 ->json_is( '/_strings/country/category' => $cat->category_name )
795 ->json_is( '/_strings/country/str' => $ar->lib );
797 $t->get_ok( '/cities/' . $manuel->id => { 'x-koha-embed' => '' } )
798 ->status_is(200)->json_is( '/name' => 'Manuel' )
799 ->json_hasnt('/_strings');
801 $t->get_ok( '/cities/' . $manuela->id => { 'x-koha-embed' => '+strings' } )
802 ->status_is(200)->json_is( '/name' => 'Manuela' )
803 ->json_has('/_strings')
804 ->json_is( '/_strings/country/type' => 'av' )
805 ->json_is( '/_strings/country/category' => $cat->category_name )
806 ->json_is( '/_strings/country/str' => $us->lib );
808 $schema->storage->txn_rollback;
811 subtest 'objects.search helper with expanded authorised values' => sub {
815 my $t = Test::Mojo->new;
817 $schema->storage->txn_begin;
819 Koha::AuthorisedValues->search( { category => 'Countries' } )->delete;
820 Koha::AuthorisedValueCategories->search( { category_name => 'Countries' } )
823 my $cat = $builder->build_object(
825 class => 'Koha::AuthorisedValueCategories',
826 value => { category_name => 'Countries' }
829 my $fr = $builder->build_object(
831 class => 'Koha::AuthorisedValues',
833 authorised_value => 'FR',
835 category => $cat->category_name
839 my $us = $builder->build_object(
841 class => 'Koha::AuthorisedValues',
843 authorised_value => 'US',
844 lib => 'United States of America',
845 category => $cat->category_name
849 my $ar = $builder->build_object(
851 class => 'Koha::AuthorisedValues',
853 authorised_value => 'AR',
855 category => $cat->category_name
860 my $city_class = Test::MockModule->new('Koha::City');
864 my ($self, $params) = @_;
865 use Koha::AuthorisedValues;
867 my $av = Koha::AuthorisedValues->find(
869 authorised_value => $self->city_country,
870 category => 'Countries'
876 category => $av->category,
877 str => ( $params->{public} ) ? $av->lib_opac : $av->lib,
885 $builder->build_object(
887 class => 'Koha::Cities',
889 city_name => 'Manuel',
894 $builder->build_object(
896 class => 'Koha::Cities',
898 city_name => 'Manuela',
904 $t->get_ok( '/cities?name=manuel&_per_page=4&_page=1&_match=starts_with' =>
905 { 'x-koha-embed' => '+strings' } )->status_is(200)
906 ->json_has('/0')->json_has('/1')->json_hasnt('/2')
907 ->json_is( '/0/name' => 'Manuel' )
908 ->json_has('/0/_strings')
909 ->json_is( '/0/_strings/country/str' => $ar->lib )
910 ->json_is( '/0/_strings/country/type' => 'av' )
911 ->json_is( '/0/_strings/country/category' => $cat->category_name )
912 ->json_is( '/1/name' => 'Manuela' )
913 ->json_has('/1/_strings')
914 ->json_is( '/1/_strings/country/str' => $us->lib )
915 ->json_is( '/1/_strings/country/type' => 'av' )
916 ->json_is( '/1/_strings/country/category' => $cat->category_name );
918 $t->get_ok( '/cities?name=manuel&_per_page=4&_page=1&_match=starts_with' )->status_is(200)
919 ->json_has('/0')->json_has('/1')->json_hasnt('/2')
920 ->json_is( '/0/name' => 'Manuel' )->json_hasnt('/0/_strings')
921 ->json_is( '/1/name' => 'Manuela' )->json_hasnt('/1/_strings');
923 $schema->storage->txn_rollback;
926 subtest 'objects.find_rs helper' => sub {
929 $schema->storage->txn_begin;
931 # Remove existing cities to have more control on the search results
932 Koha::Cities->delete;
934 # Create three sample cities that match the query. This makes sure we
935 # always have a "next" link regardless of Mojolicious::Plugin::OpenAPI version.
936 my $city1 = $builder->build_object(
938 class => 'Koha::Cities',
944 my $city2 = $builder->build_object(
946 class => 'Koha::Cities',
952 my $city3 = $builder->build_object(
954 class => 'Koha::Cities',
961 my $t = Test::Mojo->new;
963 $t->get_ok( '/cities/' . $city1->id . '/rs' )->status_is(200)
964 ->json_is( '/name' => 'city1' );
966 $t->get_ok( '/cities/' . $city2->id . '/rs' )->status_is(200)
967 ->json_is( '/name' => 'city2' );
969 $t->get_ok( '/cities/' . $city3->id . '/rs' )->status_is(200)
970 ->json_is( '/name' => 'city3' );
972 $schema->storage->txn_rollback;
975 subtest 'objects.find helper, search_limited() tests' => sub {
979 $schema->storage->txn_begin;
981 my $library_1 = $builder->build_object( { class => 'Koha::Libraries' } );
982 my $library_2 = $builder->build_object( { class => 'Koha::Libraries' } );
984 my $patron_1 = $builder->build_object( { class => 'Koha::Patrons', value => { branchcode => $library_1->id } } );
985 my $patron_2 = $builder->build_object( { class => 'Koha::Patrons', value => { branchcode => $library_2->id } } );
987 my @libraries_where_can_see_patrons = ( $library_1->id, $library_2->id );
989 my $t = Test::Mojo->new;
991 my $mocked_patron = Test::MockModule->new('Koha::Patron');
992 $mocked_patron->mock(
993 'libraries_where_can_see_patrons',
995 return @libraries_where_can_see_patrons;
999 my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
1001 t::lib::Mocks::mock_userenv( { patron => $patron } );
1003 $t->get_ok( "/my_patrons/" . $patron_1->id )->status_is(200)->json_is( '/patron_id' => $patron_1->id );
1005 $t->get_ok( "/my_patrons/" . $patron_2->id )->status_is(200)->json_is( '/patron_id' => $patron_2->id );
1007 @libraries_where_can_see_patrons = ( $library_2->id );
1009 $t->get_ok( "/my_patrons/" . $patron_1->id )->status_is(200)->json_is(undef);
1011 $t->get_ok( "/my_patrons/" . $patron_2->id )->status_is(200)->json_is( '/patron_id' => $patron_2->id );
1013 $schema->storage->txn_rollback;