X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=t%2Fdb_dependent%2FKoha%2FREST%2FPlugin%2FObjects.t;h=21f89f063955a4348328d43e5dc62f64a66a498d;hb=8dd24dab223375d49592f68b8c6ab01273e4e005;hp=5a2b207c64cbb98e1feb6f95b9a76b6ee3991397;hpb=b1af5a62cb74aa7dd000ae41c4be07dd6d3aa330;p=koha-ffzg.git diff --git a/t/db_dependent/Koha/REST/Plugin/Objects.t b/t/db_dependent/Koha/REST/Plugin/Objects.t old mode 100644 new mode 100755 index 5a2b207c64..21f89f0639 --- a/t/db_dependent/Koha/REST/Plugin/Objects.t +++ b/t/db_dependent/Koha/REST/Plugin/Objects.t @@ -18,9 +18,13 @@ use Modern::Perl; use Koha::Acquisition::Orders; +use Koha::AuthorisedValueCategories; +use Koha::AuthorisedValues; use Koha::Cities; -use Koha::Holds; use Koha::Biblios; +use Koha::Patrons; + +use Mojo::JSON qw(encode_json); # Dummy app for testing the plugin use Mojolicious::Lite; @@ -38,6 +42,13 @@ get '/cities' => sub { $c->render( status => 200, json => $cities ); }; +get '/cities/:city_id' => sub { + my $c = shift; + my $id = $c->stash("city_id"); + my $city = $c->objects->find(Koha::Cities->new, $id); + $c->render( status => 200, json => $city ); +}; + get '/orders' => sub { my $c = shift; $c->stash('koha.embed', ( { fund => {} } ) ); @@ -46,14 +57,12 @@ get '/orders' => sub { $c->render( status => 200, json => $orders ); }; -get '/patrons/:patron_id/holds' => sub { +get '/orders/:order_id' => sub { my $c = shift; - my $params = $c->req->params->to_hash; - $params->{patron_id} = $c->stash("patron_id"); - $c->validation->output($params); - my $holds_set = Koha::Holds->new; - my $holds = $c->objects->search( $holds_set ); - $c->render( status => 200, json => {count => scalar(@$holds)} ); + $c->stash('koha.embed', ( { fund => {} } ) ); + my $id = $c->stash("order_id"); + my $order = $c->objects->find(Koha::Acquisition::Orders->new, $id); + $c->render( status => 200, json => $order ); }; get '/biblios' => sub { @@ -75,22 +84,54 @@ get '/biblios' => sub { $c->render( status => 200, json => {count => scalar(@$biblios), biblios => $biblios} ); }; +get '/libraries/:library_id_1/:library_id_2' => sub { + + my $c = shift; + + # Emulate a public route by stashing the is_public value + $c->stash( 'is_public' => 1 ); + + my $library_id_1 = $c->param('library_id_1'); + my $library_id_2 = $c->param('library_id_2'); + + my $libraries_rs = Koha::Libraries->search( + { branchcode => [ $library_id_1, $library_id_2 ] }, + { order_by => 'branchname' } + ); + my $libraries = $c->objects->search( $libraries_rs ); + + $c->render( + status => 200, + json => $libraries + ); +}; + +get '/my_patrons' => sub { + + my $c = shift; + + my $patrons = $c->objects->search( scalar Koha::Patrons->search( {}, { order_by => 'borrowernumber' }) ); + + $c->render( + status => 200, + json => $patrons + ); +}; # The tests -use Test::More tests => 10; +use Test::More tests => 16; use Test::Mojo; +use t::lib::Mocks; use t::lib::TestBuilder; use Koha::Database; -my $t = Test::Mojo->new; - my $schema = Koha::Database->new()->schema(); my $builder = t::lib::TestBuilder->new; subtest 'objects.search helper' => sub { - plan tests => 38; + plan tests => 50; $schema->storage->txn_begin; @@ -118,6 +159,7 @@ subtest 'objects.search helper' => sub { } }); + my $t = Test::Mojo->new; $t->get_ok('/cities?name=manuel&_per_page=1&_page=1') ->status_is(200) ->header_like( 'Link' => qr/; rel="next",/ ) @@ -172,12 +214,43 @@ subtest 'objects.search helper' => sub { ->json_is('/2/name' => 'Manuelab') ->json_is('/3/name' => 'Emanuel'); + # Add 20 more cities + for ( 1..20 ) { + $builder->build_object({ class => 'Koha::Cities' }); + } + + t::lib::Mocks::mock_preference('RESTdefaultPageSize', 20 ); + $t->get_ok('/cities') + ->status_is(200); + + my $response_count = scalar @{ $t->tx->res->json }; + is( $response_count, 20, 'RESTdefaultPageSize is honoured by default (20)' ); + + t::lib::Mocks::mock_preference('RESTdefaultPageSize', 5 ); + $t->get_ok('/cities') + ->status_is(200); + + $response_count = scalar @{ $t->tx->res->json }; + is( $response_count, 5, 'RESTdefaultPageSize is honoured by default (5)' ); + + $t->get_ok('/cities?_page=1&_per_page=-1') + ->status_is(200); + + $response_count = scalar @{ $t->tx->res->json }; + is( $response_count, 24, '_per_page=-1 means all resources' ); + + $t->get_ok('/cities?_page=100&_per_page=-1') + ->status_is(200); + + $response_count = scalar @{ $t->tx->res->json }; + is( $response_count, 24, 'When _per_page=-1 the page param is not considered' ); + $schema->storage->txn_rollback; }; subtest 'objects.search helper, sorting on mapped column' => sub { - plan tests => 14; + plan tests => 42; $schema->storage->txn_begin; @@ -186,22 +259,59 @@ subtest 'objects.search helper, sorting on mapped column' => sub { $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'A', city_country => 'Argentina' } }); $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'B', city_country => 'Argentina' } }); + $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'C', city_country => 'Argentina' } }); + $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'C', city_country => 'Belarus' } }); - $t->get_ok('/cities?_order_by=%2Bname&_order_by=+country') + my $t = Test::Mojo->new; + # CSV-param + $t->get_ok('/cities?_order_by=%2Bname,-country') ->status_is(200) ->json_has('/0') ->json_has('/1') - ->json_hasnt('/2') ->json_is('/0/name' => 'A') - ->json_is('/1/name' => 'B'); - + ->json_is('/1/name' => 'B') + ->json_is('/2/name' => 'C') + ->json_is('/2/country' => 'Belarus') + ->json_is('/3/name' => 'C') + ->json_is('/3/country' => 'Argentina') + ->json_hasnt('/4'); + + # Multi-param: traditional + $t->get_ok('/cities?_order_by=%2Bname&_order_by=-country') + ->status_is(200) + ->json_has('/0') + ->json_has('/1') + ->json_is('/0/name' => 'A') + ->json_is('/1/name' => 'B') + ->json_is('/2/name' => 'C') + ->json_is('/2/country' => 'Belarus') + ->json_is('/3/name' => 'C') + ->json_is('/3/country' => 'Argentina') + ->json_hasnt('/4'); + + # Multi-param: PHP Style, Passes validation as above, subsequntly explodes + $t->get_ok('/cities?_order_by[]=%2Bname&_order_by[]=-country') + ->status_is(200) + ->json_has('/0') + ->json_has('/1') + ->json_is('/0/name' => 'A') + ->json_is('/1/name' => 'B') + ->json_is('/2/name' => 'C') + ->json_is('/2/country' => 'Belarus') + ->json_is('/3/name' => 'C') + ->json_is('/3/country' => 'Argentina') + ->json_hasnt('/4'); + + # Single-param $t->get_ok('/cities?_order_by=-name') ->status_is(200) ->json_has('/0') ->json_has('/1') - ->json_hasnt('/2') - ->json_is('/0/name' => 'B') - ->json_is('/1/name' => 'A'); + ->json_is('/0/name' => 'C') + ->json_is('/1/name' => 'C') + ->json_is('/2/name' => 'B') + ->json_is('/3/name' => 'A') + ->json_hasnt('/4'); $schema->storage->txn_rollback; }; @@ -217,6 +327,7 @@ subtest 'objects.search helper, encoding' => sub { $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'A', city_country => 'Argentina' } }); $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'B', city_country => '❤Argentina❤' } }); + my $t = Test::Mojo->new; $t->get_ok('/cities?q={"country": "❤Argentina❤"}') ->status_is(200) ->json_has('/0') @@ -226,54 +337,57 @@ subtest 'objects.search helper, encoding' => sub { $schema->storage->txn_rollback; }; -subtest 'objects.search helper, embed' => sub { +subtest 'objects.search helper, X-Total-Count and X-Base-Total-Count' => sub { - plan tests => 2; + plan tests => 8; $schema->storage->txn_begin; - my $order = $builder->build_object({ class => 'Koha::Acquisition::Orders' }); - - $t->get_ok('/orders?order_id=' . $order->ordernumber) - ->json_is('/0',$order->to_api({ embed => ( { fund => {} } ) })); + Koha::Cities->delete; - $schema->storage->txn_rollback; -}; + my $long_city_name = 'Llanfairpwllgwyngyll'; + for my $i ( 1 .. length($long_city_name) ) { + $builder->build_object( + { + class => 'Koha::Cities', + value => { + city_name => substr( $long_city_name, 0, $i ), + city_country => 'Wales' + } + } + ); + } -subtest 'objects.search helper, with path parameters and _match' => sub { - plan tests => 8; + my $t = Test::Mojo->new; + $t->get_ok('/cities?name=L&_per_page=10&_page=1&_match=starts_with') + ->status_is(200) + ->header_is( 'X-Total-Count' => 20, 'X-Total-Count header present' ) + ->header_is( 'X-Base-Total-Count' => 20, 'X-Base-Total-Count header present' ); - $schema->storage->txn_begin; + $t->get_ok('/cities?name=Llan&_per_page=10&_page=1&_match=starts_with') + ->status_is(200) + ->header_is( 'X-Total-Count' => 17, 'X-Total-Count header present' ) + ->header_is('X-Base-Total-Count' => 20, 'X-Base-Total-Count header present' ); - Koha::Holds->search()->delete; + $schema->storage->txn_rollback; +}; - my $patron = Koha::Patrons->find(10); - $patron->delete if $patron; - $patron = $builder->build_object( { class => "Koha::Patrons" } ); - $patron->borrowernumber(10)->store; - $builder->build_object( - { - class => "Koha::Holds", - value => { borrowernumber => $patron->borrowernumber } - } - ); +subtest 'objects.search helper, embed' => sub { - $t->get_ok('/patrons/1/holds?_match=exact') - ->json_is('/count' => 0, 'there should be no holds for borrower 1 with _match=exact'); + plan tests => 2; - $t->get_ok('/patrons/1/holds?_match=contains') - ->json_is('/count' => 0, 'there should be no holds for borrower 1 with _match=contains'); + $schema->storage->txn_begin; - $t->get_ok('/patrons/10/holds?_match=exact') - ->json_is('/count' => 1, 'there should be 1 hold for borrower 10 with _match=exact'); + my $order = $builder->build_object({ class => 'Koha::Acquisition::Orders' }); - $t->get_ok('/patrons/10/holds?_match=contains') - ->json_is('/count' => 1, 'there should be 1 hold for borrower 10 with _match=contains'); + my $t = Test::Mojo->new; + $t->get_ok('/orders?order_id=' . $order->ordernumber) + ->json_is('/0',$order->to_api({ embed => ( { fund => {} } ) })); $schema->storage->txn_rollback; }; -subtest 'object.search helper with query parameter' => sub { +subtest 'objects.search helper with query parameter' => sub { plan tests => 4; $schema->storage->txn_begin; @@ -287,6 +401,7 @@ subtest 'object.search helper with query parameter' => sub { my $suggestion2 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio2->biblionumber} } ); my $suggestion3 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio3->biblionumber} } ); + my $t = Test::Mojo->new; $t->get_ok('/biblios' => json => {"suggestions.suggester.patron_id" => $patron1->borrowernumber }) ->json_is('/count' => 1, 'there should be 1 biblio with suggestions of patron 1'); @@ -296,7 +411,7 @@ subtest 'object.search helper with query parameter' => sub { $schema->storage->txn_rollback; }; -subtest 'object.search helper with q parameter' => sub { +subtest 'objects.search helper with q parameter' => sub { plan tests => 4; $schema->storage->txn_begin; @@ -310,6 +425,7 @@ subtest 'object.search helper with q parameter' => sub { my $suggestion2 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio2->biblionumber} } ); my $suggestion3 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio3->biblionumber} } ); + my $t = Test::Mojo->new; $t->get_ok('/biblios?q={"suggestions.suggester.patron_id": "'.$patron1->borrowernumber.'"}') ->json_is('/count' => 1, 'there should be 1 biblio with suggestions of patron 1'); @@ -319,7 +435,7 @@ subtest 'object.search helper with q parameter' => sub { $schema->storage->txn_rollback; }; -subtest 'object.search helper with x-koha-query header' => sub { +subtest 'objects.search helper with x-koha-query header' => sub { plan tests => 4; $schema->storage->txn_begin; @@ -333,6 +449,7 @@ subtest 'object.search helper with x-koha-query header' => sub { my $suggestion2 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio2->biblionumber} } ); my $suggestion3 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio3->biblionumber} } ); + my $t = Test::Mojo->new; $t->get_ok('/biblios' => {'x-koha-query' => '{"suggestions.suggester.patron_id": "'.$patron1->borrowernumber.'"}'}) ->json_is('/count' => 1, 'there should be 1 biblio with suggestions of patron 1'); @@ -342,7 +459,7 @@ subtest 'object.search helper with x-koha-query header' => sub { $schema->storage->txn_rollback; }; -subtest 'object.search helper with all query methods' => sub { +subtest 'objects.search helper with all query methods' => sub { plan tests => 6; $schema->storage->txn_begin; @@ -356,6 +473,7 @@ subtest 'object.search helper with all query methods' => sub { my $suggestion2 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio2->biblionumber} } ); my $suggestion3 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio3->biblionumber} } ); + my $t = Test::Mojo->new; $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}) ->json_is('/count' => 1, 'there should be 1 biblio with suggestions of patron 1'); @@ -368,9 +486,11 @@ subtest 'object.search helper with all query methods' => sub { $schema->storage->txn_rollback; }; -subtest 'object.search helper order by embedded columns' => sub { +subtest 'objects.search helper order by embedded columns' => sub { plan tests => 3; + $schema->storage->txn_begin; + my $patron1 = $builder->build_object( { class => "Koha::Patrons" , value => {firstname=>'patron1'} } ); my $patron2 = $builder->build_object( { class => "Koha::Patrons" , value => {firstname=>'patron2'} } ); my $biblio1 = $builder->build_sample_biblio; @@ -378,9 +498,354 @@ subtest 'object.search helper order by embedded columns' => sub { my $suggestion1 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron1->borrowernumber, biblionumber => $biblio1->biblionumber} } ); my $suggestion2 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio2->biblionumber} } ); + my $t = Test::Mojo->new; $t->get_ok('/biblios?_order_by=-suggestions.suggester.firstname' => json => [{"me.biblio_id" => $biblio1->biblionumber}, {"me.biblio_id" => $biblio2->biblionumber}]) ->json_is('/biblios/0/biblio_id' => $biblio2->biblionumber, 'Biblio 2 should be first') ->json_is('/biblios/1/biblio_id' => $biblio1->biblionumber, 'Biblio 1 should be second'); + $schema->storage->txn_rollback; +}; + +subtest 'objects.find helper' => sub { + + plan tests => 9; + + my $t = Test::Mojo->new; + + $schema->storage->txn_begin; + + my $city_1 = $builder->build_object( { class => 'Koha::Cities' } ); + my $city_2 = $builder->build_object( { class => 'Koha::Cities' } ); + + $t->get_ok( '/cities/' . $city_1->id ) + ->status_is(200) + ->json_is( $city_1->to_api ); + + $t->get_ok( '/cities/' . $city_2->id ) + ->status_is(200) + ->json_is( $city_2->to_api ); + + # Remove the city + my $city_2_id = $city_2->id; + $city_2->delete; + $t->get_ok( '/cities/' . $city_2_id ) + ->status_is(200) + ->json_is( undef ); + + $schema->storage->txn_rollback; +}; + +subtest 'objects.find helper, embed' => sub { + + plan tests => 2; + + my $t = Test::Mojo->new; + + $schema->storage->txn_begin; + + my $order = $builder->build_object({ class => 'Koha::Acquisition::Orders' }); + + $t->get_ok( '/orders/' . $order->ordernumber ) + ->json_is( $order->to_api( { embed => ( { fund => {} } ) } ) ); + + $schema->storage->txn_rollback; +}; + +subtest 'objects.search helper, public requests' => sub { + + plan tests => 3; + + $schema->storage->txn_begin; + + my $library_1 = $builder->build_object({ class => 'Koha::Libraries', value => { branchname => 'A' } }); + my $library_2 = $builder->build_object({ class => 'Koha::Libraries', value => { branchname => 'B' } }); + + my $t = Test::Mojo->new; + + $t->get_ok( '/libraries/'.$library_1->id.'/'.$library_2->id ) + ->json_is('/0' => $library_1->to_api({ public => 1 }), 'Public representation of $library_1 is retrieved') + ->json_is('/1' => $library_2->to_api({ public => 1 }), 'Public representation of $library_2 is retrieved'); + + $schema->storage->txn_rollback; +}; + +subtest 'objects.search helper, search_limited() tests' => sub { + + plan tests => 9; + + $schema->storage->txn_begin; + + my $library_1 = $builder->build_object({ class => 'Koha::Libraries' }); + my $library_2 = $builder->build_object({ class => 'Koha::Libraries' }); + + my $patron_1 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $library_1->id } }); + my $patron_2 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $library_1->id } }); + my $patron_3 = $builder->build_object({ class => 'Koha::Patrons', value => { branchcode => $library_2->id } }); + + my @libraries_where_can_see_patrons = ( $library_1->id, $library_2->id ); + + my $t = Test::Mojo->new; + + my $mocked_patron = Test::MockModule->new('Koha::Patron'); + $mocked_patron->mock( 'libraries_where_can_see_patrons', sub + { + return @libraries_where_can_see_patrons; + } + ); + + my $patron = $builder->build_object( + { + class => 'Koha::Patrons', + value => { flags => 2**4 } # borrowers flag = 4 + } + ); + + t::lib::Mocks::mock_userenv({ patron => $patron }); + + $t->get_ok( "/my_patrons?q=" . encode_json( { library_id => [ $library_1->id, $library_2->id ] } ) ) + ->status_is(200) + ->json_is( '/0/patron_id' => $patron_1->id ) + ->json_is( '/1/patron_id' => $patron_2->id ) + ->json_is( '/2/patron_id' => $patron_3->id ); + + @libraries_where_can_see_patrons = ( $library_2->id ); + + my $res = $t->get_ok( "/my_patrons?q=" . encode_json( { library_id => [ $library_1->id, $library_2->id ] } ) ) + ->status_is(200) + ->json_is( '/0/patron_id' => $patron_3->id, 'Returns the only allowed patron' ) + ->tx->res->json; + + is( scalar @{$res}, 1, 'Only one patron returned' ); + + $schema->storage->txn_rollback; +}; + +subtest 'objects.find helper with expanded authorised values' => sub { + + plan tests => 18; + + $schema->storage->txn_begin; + + my $t = Test::Mojo->new; + + Koha::AuthorisedValues->search( { category => 'Countries' } )->delete; + Koha::AuthorisedValueCategories->search( { category_name => 'Countries' } ) + ->delete; + + my $cat = $builder->build_object( + { + class => 'Koha::AuthorisedValueCategories', + value => { category_name => 'Countries' } + } + ); + my $fr = $builder->build_object( + { + class => 'Koha::AuthorisedValues', + value => { + authorised_value => 'FR', + lib => 'France', + category => $cat->category_name + } + } + ); + my $us = $builder->build_object( + { + class => 'Koha::AuthorisedValues', + value => { + authorised_value => 'US', + lib => 'United States of America', + category => $cat->category_name + } + } + ); + my $ar = $builder->build_object( + { + class => 'Koha::AuthorisedValues', + value => { + authorised_value => 'AR', + lib => 'Argentina', + category => $cat->category_name + } + } + ); + + my $city_class = Test::MockModule->new('Koha::City'); + $city_class->mock( + 'api_av_mapping', + sub { + my ($self, $params) = @_; + use Koha::AuthorisedValues; + + my $av = Koha::AuthorisedValues->find( + { + authorised_value => $self->city_country, + category => 'Countries' + } + ); + + return { + city_country => { + category => $av->category, + str => ( $params->{public} ) ? $av->lib_opac : $av->lib, + type => 'av', + } + }; + } + ); + + my $manuel = $builder->build_object( + { + class => 'Koha::Cities', + value => { + city_name => 'Manuel', + city_country => 'AR' + } + } + ); + my $manuela = $builder->build_object( + { + class => 'Koha::Cities', + value => { + city_name => 'Manuela', + city_country => 'US' + } + } + ); + + $t->get_ok( '/cities/' . $manuel->id => { 'x-koha-av-expand' => 1 } ) + ->status_is(200)->json_is( '/name' => 'Manuel' ) + ->json_has('/_str') + ->json_is( '/_str/country/type' => 'av' ) + ->json_is( '/_str/country/category' => $cat->category_name ) + ->json_is( '/_str/country/str' => $ar->lib ); + + $t->get_ok( '/cities/' . $manuel->id => { 'x-koha-av-expand' => 0 } ) + ->status_is(200)->json_is( '/name' => 'Manuel' ) + ->json_hasnt('/_str'); + + $t->get_ok( '/cities/' . $manuela->id => { 'x-koha-av-expand' => 1 } ) + ->status_is(200)->json_is( '/name' => 'Manuela' ) + ->json_has('/_str') + ->json_is( '/_str/country/type' => 'av' ) + ->json_is( '/_str/country/category' => $cat->category_name ) + ->json_is( '/_str/country/str' => $us->lib ); + + $schema->storage->txn_rollback; +}; + +subtest 'objects.search helper with expanded authorised values' => sub { + + plan tests => 24; + + my $t = Test::Mojo->new; + $schema->storage->txn_begin; -} + + Koha::AuthorisedValues->search( { category => 'Countries' } )->delete; + Koha::AuthorisedValueCategories->search( { category_name => 'Countries' } ) + ->delete; + + my $cat = $builder->build_object( + { + class => 'Koha::AuthorisedValueCategories', + value => { category_name => 'Countries' } + } + ); + my $fr = $builder->build_object( + { + class => 'Koha::AuthorisedValues', + value => { + authorised_value => 'FR', + lib => 'France', + category => $cat->category_name + } + } + ); + my $us = $builder->build_object( + { + class => 'Koha::AuthorisedValues', + value => { + authorised_value => 'US', + lib => 'United States of America', + category => $cat->category_name + } + } + ); + my $ar = $builder->build_object( + { + class => 'Koha::AuthorisedValues', + value => { + authorised_value => 'AR', + lib => 'Argentina', + category => $cat->category_name + } + } + ); + + my $city_class = Test::MockModule->new('Koha::City'); + $city_class->mock( + 'api_av_mapping', + sub { + my ($self, $params) = @_; + use Koha::AuthorisedValues; + + my $av = Koha::AuthorisedValues->find( + { + authorised_value => $self->city_country, + category => 'Countries' + } + ); + + return { + city_country => { + category => $av->category, + str => ( $params->{public} ) ? $av->lib_opac : $av->lib, + type => 'av', + } + }; + } + ); + + + $builder->build_object( + { + class => 'Koha::Cities', + value => { + city_name => 'Manuel', + city_country => 'AR' + } + } + ); + $builder->build_object( + { + class => 'Koha::Cities', + value => { + city_name => 'Manuela', + city_country => 'US' + } + } + ); + + $t->get_ok( '/cities?name=manuel&_per_page=4&_page=1&_match=starts_with' => + { 'x-koha-av-expand' => 1 } )->status_is(200) + ->json_has('/0')->json_has('/1')->json_hasnt('/2') + ->json_is( '/0/name' => 'Manuel' ) + ->json_has('/0/_str') + ->json_is( '/0/_str/country/str' => $ar->lib ) + ->json_is( '/0/_str/country/type' => 'av' ) + ->json_is( '/0/_str/country/category' => $cat->category_name ) + ->json_is( '/1/name' => 'Manuela' ) + ->json_has('/1/_str') + ->json_is( '/1/_str/country/str' => $us->lib ) + ->json_is( '/1/_str/country/type' => 'av' ) + ->json_is( '/1/_str/country/category' => $cat->category_name ); + + $t->get_ok( '/cities?name=manuel&_per_page=4&_page=1&_match=starts_with' => + { 'x-koha-av-expand' => 0 } )->status_is(200) + ->json_has('/0')->json_has('/1')->json_hasnt('/2') + ->json_is( '/0/name' => 'Manuel' )->json_hasnt('/0/_str') + ->json_is( '/1/name' => 'Manuela' )->json_hasnt('/1/_str'); + + + $schema->storage->txn_rollback; +};