Bug 22522: Add support for current Mojolicious and related packages
[srvgit] / t / db_dependent / Koha / REST / Plugin / Objects.t
1 #!/usr/bin/perl
2
3 # This file is part of Koha.
4 #
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.
9 #
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.
14 #
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>.
17
18 use Modern::Perl;
19
20 use Koha::Acquisition::Orders;
21 use Koha::Cities;
22 use Koha::Holds;
23
24 # Dummy app for testing the plugin
25 use Mojolicious::Lite;
26
27 app->log->level('error');
28
29 plugin 'Koha::REST::Plugin::Objects';
30 plugin 'Koha::REST::Plugin::Query';
31 plugin 'Koha::REST::Plugin::Pagination';
32
33 get '/cities' => sub {
34     my $c = shift;
35     $c->validation->output($c->req->params->to_hash);
36     my $cities = $c->objects->search(Koha::Cities->new);
37     $c->render( status => 200, json => $cities );
38 };
39
40 get '/orders' => sub {
41     my $c = shift;
42     $c->stash('koha.embed', ( { fund => {} } ) );
43     $c->validation->output($c->req->params->to_hash);
44     my $orders = $c->objects->search(Koha::Acquisition::Orders->new);
45     $c->render( status => 200, json => $orders );
46 };
47
48 get '/patrons/:patron_id/holds' => sub {
49     my $c = shift;
50     my $params = $c->req->params->to_hash;
51     $params->{patron_id} = $c->stash("patron_id");
52     $c->validation->output($params);
53     my $holds_set = Koha::Holds->new;
54     my $holds     = $c->objects->search( $holds_set );
55     $c->render( status => 200, json => {count => scalar(@$holds)} );
56 };
57
58 # The tests
59 use Test::More tests => 4;
60 use Test::Mojo;
61
62 use t::lib::TestBuilder;
63 use Koha::Database;
64
65 my $t = Test::Mojo->new;
66
67 my $schema  = Koha::Database->new()->schema();
68 my $builder = t::lib::TestBuilder->new;
69
70 subtest 'objects.search helper' => sub {
71
72     plan tests => 38;
73
74     $schema->storage->txn_begin;
75
76     # Remove existing cities to have more control on the search results
77     Koha::Cities->delete;
78
79     # Create three sample cities that match the query. This makes sure we
80     # always have a "next" link regardless of Mojolicious::Plugin::OpenAPI version.
81     $builder->build_object({
82         class => 'Koha::Cities',
83         value => {
84             city_name => 'Manuel'
85         }
86     });
87     $builder->build_object({
88         class => 'Koha::Cities',
89         value => {
90             city_name => 'Manuela'
91         }
92     });
93     $builder->build_object({
94         class => 'Koha::Cities',
95         value => {
96             city_name => 'Manuelab'
97         }
98     });
99
100     $t->get_ok('/cities?name=manuel&_per_page=1&_page=1')
101         ->status_is(200)
102         ->header_like( 'Link' => qr/<http:\/\/.*[\?&]_page=2.*>; rel="next",/ )
103         ->json_has('/0')
104         ->json_hasnt('/1')
105         ->json_is('/0/name' => 'Manuel');
106
107     $builder->build_object({
108         class => 'Koha::Cities',
109         value => {
110             city_name => 'Emanuel'
111         }
112     });
113
114     # _match=starts_with
115     $t->get_ok('/cities?name=manuel&_per_page=4&_page=1&_match=starts_with')
116         ->status_is(200)
117         ->json_has('/0')
118         ->json_has('/1')
119         ->json_has('/2')
120         ->json_hasnt('/3')
121         ->json_is('/0/name' => 'Manuel')
122         ->json_is('/1/name' => 'Manuela')
123         ->json_is('/2/name' => 'Manuelab');
124
125     # _match=ends_with
126     $t->get_ok('/cities?name=manuel&_per_page=4&_page=1&_match=ends_with')
127         ->status_is(200)
128         ->json_has('/0')
129         ->json_has('/1')
130         ->json_hasnt('/2')
131         ->json_is('/0/name' => 'Manuel')
132         ->json_is('/1/name' => 'Emanuel');
133
134     # _match=exact
135     $t->get_ok('/cities?name=manuel&_per_page=4&_page=1&_match=exact')
136         ->status_is(200)
137         ->json_has('/0')
138         ->json_hasnt('/1')
139         ->json_is('/0/name' => 'Manuel');
140
141     # _match=contains
142     $t->get_ok('/cities?name=manuel&_per_page=4&_page=1&_match=contains')
143         ->status_is(200)
144         ->json_has('/0')
145         ->json_has('/1')
146         ->json_has('/2')
147         ->json_has('/3')
148         ->json_hasnt('/4')
149         ->json_is('/0/name' => 'Manuel')
150         ->json_is('/1/name' => 'Manuela')
151         ->json_is('/2/name' => 'Manuelab')
152         ->json_is('/3/name' => 'Emanuel');
153
154     $schema->storage->txn_rollback;
155 };
156
157 subtest 'objects.search helper, sorting on mapped column' => sub {
158
159     plan tests => 14;
160
161     $schema->storage->txn_begin;
162
163     # Have complete control over the existing cities to ease testing
164     Koha::Cities->delete;
165
166     $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'A', city_country => 'Argentina' } });
167     $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'B', city_country => 'Argentina' } });
168
169     $t->get_ok('/cities?_order_by=%2Bname&_order_by=+country')
170       ->status_is(200)
171       ->json_has('/0')
172       ->json_has('/1')
173       ->json_hasnt('/2')
174       ->json_is('/0/name' => 'A')
175       ->json_is('/1/name' => 'B');
176
177     $t->get_ok('/cities?_order_by=-name')
178       ->status_is(200)
179       ->json_has('/0')
180       ->json_has('/1')
181       ->json_hasnt('/2')
182       ->json_is('/0/name' => 'B')
183       ->json_is('/1/name' => 'A');
184
185     $schema->storage->txn_rollback;
186 };
187
188 subtest 'objects.search helper, embed' => sub {
189
190     plan tests => 2;
191
192     $schema->storage->txn_begin;
193
194     my $order = $builder->build_object({ class => 'Koha::Acquisition::Orders' });
195
196     $t->get_ok('/orders?order_id=' . $order->ordernumber)
197       ->json_is('/0',$order->to_api({ embed => ( { fund => {} } ) }));
198
199     $schema->storage->txn_rollback;
200 };
201
202 subtest 'objects.search helper, with path parameters and _match' => sub {
203     plan tests => 8;
204
205     $schema->storage->txn_begin;
206
207     Koha::Holds->search()->delete;
208
209     my $patron = Koha::Patrons->find(10);
210     $patron->delete if $patron;
211     $patron = $builder->build_object( { class => "Koha::Patrons" } );
212     $patron->borrowernumber(10)->store;
213     $builder->build_object(
214         {
215             class => "Koha::Holds",
216             value => { borrowernumber => $patron->borrowernumber }
217         }
218     );
219
220     $t->get_ok('/patrons/1/holds?_match=exact')
221       ->json_is('/count' => 0, 'there should be no holds for borrower 1 with _match=exact');
222
223     $t->get_ok('/patrons/1/holds?_match=contains')
224       ->json_is('/count' => 0, 'there should be no holds for borrower 1 with _match=contains');
225
226     $t->get_ok('/patrons/10/holds?_match=exact')
227       ->json_is('/count' => 1, 'there should be 1 hold for borrower 10 with _match=exact');
228
229     $t->get_ok('/patrons/10/holds?_match=contains')
230       ->json_is('/count' => 1, 'there should be 1 hold for borrower 10 with _match=contains');
231
232     $schema->storage->txn_rollback;
233 };