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);
42 my $cities = $c->objects->search(Koha::Cities->new);
43 $c->render( status => 200, json => $cities );
46 get '/cities/:city_id' => sub {
48 my $id = $c->stash("city_id");
50 my $city = $c->objects->find(Koha::Cities->new, $id);
51 $c->render( status => 200, json => $city );
54 get '/orders' => sub {
56 $c->stash('koha.embed', ( { fund => {} } ) );
57 $c->validation->output($c->req->params->to_hash);
58 my $orders = $c->objects->search(Koha::Acquisition::Orders->new);
59 $c->render( status => 200, json => $orders );
62 get '/orders/:order_id' => sub {
64 $c->stash('koha.embed', ( { fund => {} } ) );
65 my $id = $c->stash("order_id");
66 my $order = $c->objects->find(Koha::Acquisition::Orders->new, $id);
67 $c->render( status => 200, json => $order );
70 get '/biblios' => sub {
72 my $output = $c->req->params->to_hash;
73 $output->{query} = $c->req->json if defined $c->req->json;
74 my $headers = $c->req->headers->to_hash;
75 $output->{'x-koha-query'} = $headers->{'x-koha-query'} if defined $headers->{'x-koha-query'};
76 $c->validation->output($output);
77 my $biblios_set = Koha::Biblios->new;
78 $c->stash("koha.embed", {
85 my $biblios = $c->objects->search($biblios_set);
86 $c->render( status => 200, json => {count => scalar(@$biblios), biblios => $biblios} );
89 get '/libraries/:library_id_1/:library_id_2' => sub {
93 # Emulate a public route by stashing the is_public value
94 $c->stash( 'is_public' => 1 );
96 my $library_id_1 = $c->param('library_id_1');
97 my $library_id_2 = $c->param('library_id_2');
99 my $libraries_rs = Koha::Libraries->search(
100 { branchcode => [ $library_id_1, $library_id_2 ] },
101 { order_by => 'branchname' }
103 my $libraries = $c->objects->search( $libraries_rs );
111 get '/my_patrons' => sub {
115 my $patrons = $c->objects->search( scalar Koha::Patrons->search( {}, { order_by => 'borrowernumber' }) );
124 use Test::More tests => 16;
128 use t::lib::TestBuilder;
131 my $schema = Koha::Database->new()->schema();
132 my $builder = t::lib::TestBuilder->new;
134 subtest 'objects.search helper' => sub {
138 $schema->storage->txn_begin;
140 # Remove existing cities to have more control on the search results
141 Koha::Cities->delete;
143 # Create three sample cities that match the query. This makes sure we
144 # always have a "next" link regardless of Mojolicious::Plugin::OpenAPI version.
145 $builder->build_object({
146 class => 'Koha::Cities',
148 city_name => 'Manuel'
151 $builder->build_object({
152 class => 'Koha::Cities',
154 city_name => 'Manuela'
157 $builder->build_object({
158 class => 'Koha::Cities',
160 city_name => 'Manuelab'
164 my $t = Test::Mojo->new;
165 $t->get_ok('/cities?name=manuel&_per_page=1&_page=1')
167 ->header_like( 'Link' => qr/<http:\/\/.*[\?&]_page=2.*>; rel="next",/ )
170 ->json_is('/0/name' => 'Manuel');
172 $builder->build_object({
173 class => 'Koha::Cities',
175 city_name => 'Emanuel'
180 $t->get_ok('/cities?name=manuel&_per_page=4&_page=1&_match=starts_with')
186 ->json_is('/0/name' => 'Manuel')
187 ->json_is('/1/name' => 'Manuela')
188 ->json_is('/2/name' => 'Manuelab');
191 $t->get_ok('/cities?name=manuel&_per_page=4&_page=1&_match=ends_with')
196 ->json_is('/0/name' => 'Manuel')
197 ->json_is('/1/name' => 'Emanuel');
200 $t->get_ok('/cities?name=manuel&_per_page=4&_page=1&_match=exact')
204 ->json_is('/0/name' => 'Manuel');
207 $t->get_ok('/cities?name=manuel&_per_page=4&_page=1&_match=contains')
214 ->json_is('/0/name' => 'Manuel')
215 ->json_is('/1/name' => 'Manuela')
216 ->json_is('/2/name' => 'Manuelab')
217 ->json_is('/3/name' => 'Emanuel');
221 $builder->build_object({ class => 'Koha::Cities' });
224 t::lib::Mocks::mock_preference('RESTdefaultPageSize', 20 );
225 $t->get_ok('/cities')
228 my $response_count = scalar @{ $t->tx->res->json };
229 is( $response_count, 20, 'RESTdefaultPageSize is honoured by default (20)' );
231 t::lib::Mocks::mock_preference('RESTdefaultPageSize', 5 );
232 $t->get_ok('/cities')
235 $response_count = scalar @{ $t->tx->res->json };
236 is( $response_count, 5, 'RESTdefaultPageSize is honoured by default (5)' );
238 $t->get_ok('/cities?_page=1&_per_page=-1')
241 $response_count = scalar @{ $t->tx->res->json };
242 is( $response_count, 24, '_per_page=-1 means all resources' );
244 $t->get_ok('/cities?_page=100&_per_page=-1')
247 $response_count = scalar @{ $t->tx->res->json };
248 is( $response_count, 24, 'When _per_page=-1 the page param is not considered' );
250 $schema->storage->txn_rollback;
253 subtest 'objects.search helper, sorting on mapped column' => sub {
257 $schema->storage->txn_begin;
259 # Have complete control over the existing cities to ease testing
260 Koha::Cities->delete;
262 $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'A', city_country => 'Argentina' } });
263 $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'B', city_country => 'Argentina' } });
264 $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'C', city_country => 'Argentina' } });
265 $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'C', city_country => 'Belarus' } });
267 my $t = Test::Mojo->new;
269 $t->get_ok('/cities?_order_by=%2Bname,-country')
273 ->json_is('/0/name' => 'A')
274 ->json_is('/1/name' => 'B')
275 ->json_is('/2/name' => 'C')
276 ->json_is('/2/country' => 'Belarus')
277 ->json_is('/3/name' => 'C')
278 ->json_is('/3/country' => 'Argentina')
281 # Multi-param: traditional
282 $t->get_ok('/cities?_order_by=%2Bname&_order_by=-country')
286 ->json_is('/0/name' => 'A')
287 ->json_is('/1/name' => 'B')
288 ->json_is('/2/name' => 'C')
289 ->json_is('/2/country' => 'Belarus')
290 ->json_is('/3/name' => 'C')
291 ->json_is('/3/country' => 'Argentina')
294 # Multi-param: PHP Style, Passes validation as above, subsequntly explodes
295 $t->get_ok('/cities?_order_by[]=%2Bname&_order_by[]=-country')
299 ->json_is('/0/name' => 'A')
300 ->json_is('/1/name' => 'B')
301 ->json_is('/2/name' => 'C')
302 ->json_is('/2/country' => 'Belarus')
303 ->json_is('/3/name' => 'C')
304 ->json_is('/3/country' => 'Argentina')
308 $t->get_ok('/cities?_order_by=-name')
312 ->json_is('/0/name' => 'C')
313 ->json_is('/1/name' => 'C')
314 ->json_is('/2/name' => 'B')
315 ->json_is('/3/name' => 'A')
318 $schema->storage->txn_rollback;
321 subtest 'objects.search helper, encoding' => sub {
325 $schema->storage->txn_begin;
327 Koha::Cities->delete;
329 $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'A', city_country => 'Argentina' } });
330 $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'B', city_country => '❤Argentina❤' } });
332 my $t = Test::Mojo->new;
333 $t->get_ok('/cities?q={"country": "❤Argentina❤"}')
337 ->json_is('/0/name' => 'B');
339 $schema->storage->txn_rollback;
342 subtest 'objects.search helper, X-Total-Count and X-Base-Total-Count' => sub {
346 $schema->storage->txn_begin;
348 Koha::Cities->delete;
350 my $long_city_name = 'Llanfairpwllgwyngyll';
351 for my $i ( 1 .. length($long_city_name) ) {
352 $builder->build_object(
354 class => 'Koha::Cities',
356 city_name => substr( $long_city_name, 0, $i ),
357 city_country => 'Wales'
363 my $t = Test::Mojo->new;
364 $t->get_ok('/cities?name=L&_per_page=10&_page=1&_match=starts_with')
366 ->header_is( 'X-Total-Count' => 20, 'X-Total-Count header present' )
367 ->header_is( 'X-Base-Total-Count' => 20, 'X-Base-Total-Count header present' );
369 $t->get_ok('/cities?name=Llan&_per_page=10&_page=1&_match=starts_with')
371 ->header_is( 'X-Total-Count' => 17, 'X-Total-Count header present' )
372 ->header_is('X-Base-Total-Count' => 20, 'X-Base-Total-Count header present' );
374 $schema->storage->txn_rollback;
377 subtest 'objects.search helper, embed' => sub {
381 $schema->storage->txn_begin;
383 my $order = $builder->build_object({ class => 'Koha::Acquisition::Orders' });
385 my $t = Test::Mojo->new;
386 $t->get_ok('/orders?order_id=' . $order->ordernumber)
387 ->json_is('/0',$order->to_api({ embed => ( { fund => {} } ) }));
389 $schema->storage->txn_rollback;
392 subtest 'objects.search helper with query parameter' => sub {
395 $schema->storage->txn_begin;
397 my $patron1 = $builder->build_object( { class => "Koha::Patrons" } );
398 my $patron2 = $builder->build_object( { class => "Koha::Patrons" } );
399 my $biblio1 = $builder->build_sample_biblio;
400 my $biblio2 = $builder->build_sample_biblio;
401 my $biblio3 = $builder->build_sample_biblio;
402 my $suggestion1 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron1->borrowernumber, biblionumber => $biblio1->biblionumber} } );
403 my $suggestion2 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio2->biblionumber} } );
404 my $suggestion3 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio3->biblionumber} } );
406 my $t = Test::Mojo->new;
407 $t->get_ok('/biblios' => json => {"suggestions.suggester.patron_id" => $patron1->borrowernumber })
408 ->json_is('/count' => 1, 'there should be 1 biblio with suggestions of patron 1');
410 $t->get_ok('/biblios' => json => {"suggestions.suggester.patron_id" => $patron2->borrowernumber })
411 ->json_is('/count' => 2, 'there should be 2 biblios with suggestions of patron 2');
413 $schema->storage->txn_rollback;
416 subtest 'objects.search helper with q parameter' => sub {
419 $schema->storage->txn_begin;
421 my $patron1 = $builder->build_object( { class => "Koha::Patrons" } );
422 my $patron2 = $builder->build_object( { class => "Koha::Patrons" } );
423 my $biblio1 = $builder->build_sample_biblio;
424 my $biblio2 = $builder->build_sample_biblio;
425 my $biblio3 = $builder->build_sample_biblio;
426 my $suggestion1 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron1->borrowernumber, biblionumber => $biblio1->biblionumber} } );
427 my $suggestion2 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio2->biblionumber} } );
428 my $suggestion3 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio3->biblionumber} } );
430 my $t = Test::Mojo->new;
431 $t->get_ok('/biblios?q={"suggestions.suggester.patron_id": "'.$patron1->borrowernumber.'"}')
432 ->json_is('/count' => 1, 'there should be 1 biblio with suggestions of patron 1');
434 $t->get_ok('/biblios?q={"suggestions.suggester.patron_id": "'.$patron2->borrowernumber.'"}')
435 ->json_is('/count' => 2, 'there should be 2 biblios with suggestions of patron 2');
437 $schema->storage->txn_rollback;
440 subtest 'objects.search helper with x-koha-query header' => sub {
443 $schema->storage->txn_begin;
445 my $patron1 = $builder->build_object( { class => "Koha::Patrons" } );
446 my $patron2 = $builder->build_object( { class => "Koha::Patrons" } );
447 my $biblio1 = $builder->build_sample_biblio;
448 my $biblio2 = $builder->build_sample_biblio;
449 my $biblio3 = $builder->build_sample_biblio;
450 my $suggestion1 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron1->borrowernumber, biblionumber => $biblio1->biblionumber} } );
451 my $suggestion2 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio2->biblionumber} } );
452 my $suggestion3 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio3->biblionumber} } );
454 my $t = Test::Mojo->new;
455 $t->get_ok('/biblios' => {'x-koha-query' => '{"suggestions.suggester.patron_id": "'.$patron1->borrowernumber.'"}'})
456 ->json_is('/count' => 1, 'there should be 1 biblio with suggestions of patron 1');
458 $t->get_ok('/biblios' => {'x-koha-query' => '{"suggestions.suggester.patron_id": "'.$patron2->borrowernumber.'"}'})
459 ->json_is('/count' => 2, 'there should be 2 biblios with suggestions of patron 2');
461 $schema->storage->txn_rollback;
464 subtest 'objects.search helper with all query methods' => sub {
467 $schema->storage->txn_begin;
469 my $patron1 = $builder->build_object( { class => "Koha::Patrons" , value => {firstname=>'patron1'} } );
470 my $patron2 = $builder->build_object( { class => "Koha::Patrons" , value => {firstname=>'patron2'} } );
471 my $biblio1 = $builder->build_sample_biblio;
472 my $biblio2 = $builder->build_sample_biblio;
473 my $biblio3 = $builder->build_sample_biblio;
474 my $suggestion1 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron1->borrowernumber, biblionumber => $biblio1->biblionumber} } );
475 my $suggestion2 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio2->biblionumber} } );
476 my $suggestion3 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio3->biblionumber} } );
478 my $t = Test::Mojo->new;
479 $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})
480 ->json_is('/count' => 1, 'there should be 1 biblio with suggestions of patron 1');
482 $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})
483 ->json_is('/count' => 2, 'there should be 2 biblios with suggestions of patron 2');
485 $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})
486 ->json_is('/count' => 0, 'there shouldn\'t be biblios where suggester has patron1 fistname and patron2 id');
488 $schema->storage->txn_rollback;
491 subtest 'objects.search helper order by embedded columns' => sub {
494 $schema->storage->txn_begin;
496 my $patron1 = $builder->build_object( { class => "Koha::Patrons" , value => {firstname=>'patron1'} } );
497 my $patron2 = $builder->build_object( { class => "Koha::Patrons" , value => {firstname=>'patron2'} } );
498 my $biblio1 = $builder->build_sample_biblio;
499 my $biblio2 = $builder->build_sample_biblio;
500 my $suggestion1 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron1->borrowernumber, biblionumber => $biblio1->biblionumber} } );
501 my $suggestion2 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio2->biblionumber} } );
503 my $t = Test::Mojo->new;
504 $t->get_ok('/biblios?_order_by=-suggestions.suggester.firstname' => json => [{"me.biblio_id" => $biblio1->biblionumber}, {"me.biblio_id" => $biblio2->biblionumber}])
505 ->json_is('/biblios/0/biblio_id' => $biblio2->biblionumber, 'Biblio 2 should be first')
506 ->json_is('/biblios/1/biblio_id' => $biblio1->biblionumber, 'Biblio 1 should be second');
508 $schema->storage->txn_rollback;
511 subtest 'objects.find helper' => sub {
515 my $t = Test::Mojo->new;
517 $schema->storage->txn_begin;
519 my $city_1 = $builder->build_object( { class => 'Koha::Cities' } );
520 my $city_2 = $builder->build_object( { class => 'Koha::Cities' } );
522 $t->get_ok( '/cities/' . $city_1->id )
524 ->json_is( $city_1->to_api );
526 $t->get_ok( '/cities/' . $city_2->id )
528 ->json_is( $city_2->to_api );
531 my $city_2_id = $city_2->id;
533 $t->get_ok( '/cities/' . $city_2_id )
537 $schema->storage->txn_rollback;
540 subtest 'objects.find helper, embed' => sub {
544 my $t = Test::Mojo->new;
546 $schema->storage->txn_begin;
548 my $order = $builder->build_object({ class => 'Koha::Acquisition::Orders' });
550 $t->get_ok( '/orders/' . $order->ordernumber )
551 ->json_is( $order->to_api( { embed => ( { fund => {} } ) } ) );
553 $schema->storage->txn_rollback;
556 subtest 'objects.search helper, public requests' => sub {
560 $schema->storage->txn_begin;
562 my $library_1 = $builder->build_object({ class => 'Koha::Libraries', value => { branchname => 'A' } });
563 my $library_2 = $builder->build_object({ class => 'Koha::Libraries', value => { branchname => 'B' } });
565 my $t = Test::Mojo->new;
567 $t->get_ok( '/libraries/'.$library_1->id.'/'.$library_2->id )
568 ->json_is('/0' => $library_1->to_api({ public => 1 }), 'Public representation of $library_1 is retrieved')
569 ->json_is('/1' => $library_2->to_api({ public => 1 }), 'Public representation of $library_2 is retrieved');
571 $schema->storage->txn_rollback;
574 subtest 'objects.search helper, search_limited() tests' => sub {
578 $schema->storage->txn_begin;
580 my $library_1 = $builder->build_object({ class => 'Koha::Libraries' });
581 my $library_2 = $builder->build_object({ class => 'Koha::Libraries' });
583 my $patron_1 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $library_1->id } });
584 my $patron_2 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $library_1->id } });
585 my $patron_3 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $library_2->id } });
587 my @libraries_where_can_see_patrons = ( $library_1->id, $library_2->id );
589 my $t = Test::Mojo->new;
591 my $mocked_patron = Test::MockModule->new('Koha::Patron');
592 $mocked_patron->mock( 'libraries_where_can_see_patrons', sub
594 return @libraries_where_can_see_patrons;
598 my $patron = $builder->build_object(
600 class => 'Koha::Patrons',
601 value => { flags => 2**4 } # borrowers flag = 4
605 t::lib::Mocks::mock_userenv({ patron => $patron });
607 $t->get_ok( "/my_patrons?q=" . encode_json( { library_id => [ $library_1->id, $library_2->id ] } ) )
609 ->json_is( '/0/patron_id' => $patron_1->id )
610 ->json_is( '/1/patron_id' => $patron_2->id )
611 ->json_is( '/2/patron_id' => $patron_3->id );
613 @libraries_where_can_see_patrons = ( $library_2->id );
615 my $res = $t->get_ok( "/my_patrons?q=" . encode_json( { library_id => [ $library_1->id, $library_2->id ] } ) )
617 ->json_is( '/0/patron_id' => $patron_3->id, 'Returns the only allowed patron' )
620 is( scalar @{$res}, 1, 'Only one patron returned' );
622 $schema->storage->txn_rollback;
625 subtest 'objects.find helper with expanded authorised values' => sub {
629 $schema->storage->txn_begin;
631 my $t = Test::Mojo->new;
633 Koha::AuthorisedValues->search( { category => 'Countries' } )->delete;
634 Koha::AuthorisedValueCategories->search( { category_name => 'Countries' } )
637 my $cat = $builder->build_object(
639 class => 'Koha::AuthorisedValueCategories',
640 value => { category_name => 'Countries' }
643 my $fr = $builder->build_object(
645 class => 'Koha::AuthorisedValues',
647 authorised_value => 'FR',
649 category => $cat->category_name
653 my $us = $builder->build_object(
655 class => 'Koha::AuthorisedValues',
657 authorised_value => 'US',
658 lib => 'United States of America',
659 category => $cat->category_name
663 my $ar = $builder->build_object(
665 class => 'Koha::AuthorisedValues',
667 authorised_value => 'AR',
669 category => $cat->category_name
674 my $city_class = Test::MockModule->new('Koha::City');
678 my ($self, $params) = @_;
679 use Koha::AuthorisedValues;
681 my $av = Koha::AuthorisedValues->find(
683 authorised_value => $self->city_country,
684 category => 'Countries'
690 category => $av->category,
691 str => ( $params->{public} ) ? $av->lib_opac : $av->lib,
698 my $manuel = $builder->build_object(
700 class => 'Koha::Cities',
702 city_name => 'Manuel',
707 my $manuela = $builder->build_object(
709 class => 'Koha::Cities',
711 city_name => 'Manuela',
717 $t->get_ok( '/cities/' . $manuel->id => { 'x-koha-embed' => '+av_expand' } )
718 ->status_is(200)->json_is( '/name' => 'Manuel' )
720 ->json_is( '/_str/country/type' => 'av' )
721 ->json_is( '/_str/country/category' => $cat->category_name )
722 ->json_is( '/_str/country/str' => $ar->lib );
724 $t->get_ok( '/cities/' . $manuel->id => { 'x-koha-av-expand' => 0 } )
725 ->status_is(200)->json_is( '/name' => 'Manuel' )
726 ->json_hasnt('/_str');
728 $t->get_ok( '/cities/' . $manuela->id => { 'x-koha-embed' => '+av_expand' } )
729 ->status_is(200)->json_is( '/name' => 'Manuela' )
731 ->json_is( '/_str/country/type' => 'av' )
732 ->json_is( '/_str/country/category' => $cat->category_name )
733 ->json_is( '/_str/country/str' => $us->lib );
735 $schema->storage->txn_rollback;
738 subtest 'objects.search helper with expanded authorised values' => sub {
742 my $t = Test::Mojo->new;
744 $schema->storage->txn_begin;
746 Koha::AuthorisedValues->search( { category => 'Countries' } )->delete;
747 Koha::AuthorisedValueCategories->search( { category_name => 'Countries' } )
750 my $cat = $builder->build_object(
752 class => 'Koha::AuthorisedValueCategories',
753 value => { category_name => 'Countries' }
756 my $fr = $builder->build_object(
758 class => 'Koha::AuthorisedValues',
760 authorised_value => 'FR',
762 category => $cat->category_name
766 my $us = $builder->build_object(
768 class => 'Koha::AuthorisedValues',
770 authorised_value => 'US',
771 lib => 'United States of America',
772 category => $cat->category_name
776 my $ar = $builder->build_object(
778 class => 'Koha::AuthorisedValues',
780 authorised_value => 'AR',
782 category => $cat->category_name
787 my $city_class = Test::MockModule->new('Koha::City');
791 my ($self, $params) = @_;
792 use Koha::AuthorisedValues;
794 my $av = Koha::AuthorisedValues->find(
796 authorised_value => $self->city_country,
797 category => 'Countries'
803 category => $av->category,
804 str => ( $params->{public} ) ? $av->lib_opac : $av->lib,
812 $builder->build_object(
814 class => 'Koha::Cities',
816 city_name => 'Manuel',
821 $builder->build_object(
823 class => 'Koha::Cities',
825 city_name => 'Manuela',
831 $t->get_ok( '/cities?name=manuel&_per_page=4&_page=1&_match=starts_with' =>
832 { 'x-koha-embed' => '+av_expand' } )->status_is(200)
833 ->json_has('/0')->json_has('/1')->json_hasnt('/2')
834 ->json_is( '/0/name' => 'Manuel' )
835 ->json_has('/0/_str')
836 ->json_is( '/0/_str/country/str' => $ar->lib )
837 ->json_is( '/0/_str/country/type' => 'av' )
838 ->json_is( '/0/_str/country/category' => $cat->category_name )
839 ->json_is( '/1/name' => 'Manuela' )
840 ->json_has('/1/_str')
841 ->json_is( '/1/_str/country/str' => $us->lib )
842 ->json_is( '/1/_str/country/type' => 'av' )
843 ->json_is( '/1/_str/country/category' => $cat->category_name );
845 $t->get_ok( '/cities?name=manuel&_per_page=4&_page=1&_match=starts_with' )->status_is(200)
846 ->json_has('/0')->json_has('/1')->json_hasnt('/2')
847 ->json_is( '/0/name' => 'Manuel' )->json_hasnt('/0/_str')
848 ->json_is( '/1/name' => 'Manuela' )->json_hasnt('/1/_str');
851 $schema->storage->txn_rollback;