View | Details | Raw Unified | Return to bug 24321
Collapse All | Expand All

(-)a/Koha/REST/Plugin/Objects.pm (-19 / +8 lines)
Lines 29-45 Koha::REST::Plugin::Objects Link Here
29
29
30
=head3 objects.search
30
=head3 objects.search
31
31
32
    my $patrons_set = Koha::Patrons->new;
32
    my $patrons_rs = Koha::Patrons->new;
33
    my $patrons = $c->objects->search( $patrons_set, [\&to_model, \&to_api] );
33
    my $patrons = $c->objects->search( $patrons_rs );
34
34
35
Performs a database search using given Koha::Objects object and query parameters.
35
Performs a database search using given Koha::Objects object and query parameters.
36
It (optionally) applies the I<$to_model> function reference before building the
37
query itself, and (optionally) applies I<$to_api> to the result.
38
36
39
Returns an arrayref of the hashrefs representing the resulting objects
37
Returns an arrayref of the hashrefs representing the resulting objects
40
for JSON rendering.
38
for API rendering.
41
42
Note: Make sure I<$to_model> and I<$to_api> don't autovivify keys.
43
39
44
=cut
40
=cut
45
41
Lines 48-54 sub register { Link Here
48
44
49
    $app->helper(
45
    $app->helper(
50
        'objects.search' => sub {
46
        'objects.search' => sub {
51
            my ( $c, $objects_set, $to_model, $to_api ) = @_;
47
            my ( $c, $result_set ) = @_;
52
48
53
            my $args = $c->validation->output;
49
            my $args = $c->validation->output;
54
            my $attributes = {};
50
            my $attributes = {};
Lines 61-67 sub register { Link Here
61
                {
57
                {
62
                    attributes => $attributes,
58
                    attributes => $attributes,
63
                    params     => $reserved_params,
59
                    params     => $reserved_params,
64
                    to_model   => $to_model
60
                    result_set => $result_set
65
                }
61
                }
66
            );
62
            );
67
63
Lines 77-89 sub register { Link Here
77
            if ( defined $filtered_params ) {
73
            if ( defined $filtered_params ) {
78
74
79
                # Apply the mapping function to the passed params
75
                # Apply the mapping function to the passed params
80
                $filtered_params = $to_model->($filtered_params)
76
                $filtered_params = $result_set->attributes_from_api($filtered_params);
81
                  if defined $to_model;
82
                $filtered_params = $c->build_query_params( $filtered_params, $reserved_params );
77
                $filtered_params = $c->build_query_params( $filtered_params, $reserved_params );
83
            }
78
            }
84
79
85
            # Perform search
80
            # Perform search
86
            my $objects = $objects_set->search( $filtered_params, $attributes );
81
            my $objects = $result_set->search( $filtered_params, $attributes );
87
82
88
            if ($objects->is_paged) {
83
            if ($objects->is_paged) {
89
                $c->add_pagination_headers({
84
                $c->add_pagination_headers({
Lines 92-104 sub register { Link Here
92
                });
87
                });
93
            }
88
            }
94
89
95
            my @objects_list = map {
90
            return $objects->to_api;
96
                ( defined $to_api )
97
                  ? $to_api->( $_->TO_JSON )
98
                  : $_->TO_JSON
99
            } $objects->as_list;
100
101
            return \@objects_list;
102
        }
91
        }
103
    );
92
    );
104
}
93
}
(-)a/t/db_dependent/Koha/REST/Plugin/Objects.t (-140 / +21 lines)
Lines 34-83 get '/cities' => sub { Link Here
34
    $c->render( status => 200, json => $cities );
34
    $c->render( status => 200, json => $cities );
35
};
35
};
36
36
37
get '/cities_to_model' => sub {
38
    my $c = shift;
39
    $c->validation->output($c->req->params->to_hash);
40
    my $cities_set = Koha::Cities->new;
41
    my $cities = $c->objects->search( $cities_set, \&to_model );
42
    $c->render( status => 200, json => $cities );
43
};
44
45
get '/cities_to_model_to_api' => sub {
46
    my $c = shift;
47
    $c->validation->output($c->req->params->to_hash);
48
    my $cities_set = Koha::Cities->new;
49
    my $cities = $c->objects->search( $cities_set, \&to_model, \&to_api );
50
    $c->render( status => 200, json => $cities );
51
};
52
53
get '/cities_sorted' => sub {
54
    my $c = shift;
55
    $c->validation->output($c->req->params->to_hash);
56
    my $cities_set = Koha::Cities->new;
57
    my $cities = $c->objects->search( $cities_set, \&to_model, \&to_api );
58
    $c->render( status => 200, json => $cities );
59
};
60
61
sub to_model {
62
    my $params = shift;
63
64
    if ( exists $params->{nombre} ) {
65
        $params->{city_name} = delete $params->{nombre};
66
    }
67
68
    return $params;
69
}
70
71
sub to_api {
72
    my $params = shift;
73
74
    if ( exists $params->{city_name} ) {
75
        $params->{nombre} = delete $params->{city_name};
76
    }
77
78
    return $params;
79
}
80
81
# The tests
37
# The tests
82
use Test::More tests => 2;
38
use Test::More tests => 2;
83
use Test::Mojo;
39
use Test::Mojo;
Lines 92-98 my $builder = t::lib::TestBuilder->new; Link Here
92
48
93
subtest 'objects.search helper' => sub {
49
subtest 'objects.search helper' => sub {
94
50
95
    plan tests => 90;
51
    plan tests => 34;
96
52
97
    my $t = Test::Mojo->new;
53
    my $t = Test::Mojo->new;
98
54
Lines 115-126 subtest 'objects.search helper' => sub { Link Here
115
        }
71
        }
116
    });
72
    });
117
73
118
    $t->get_ok('/cities?city_name=manuel&_per_page=1&_page=1')
74
    $t->get_ok('/cities?name=manuel&_per_page=1&_page=1')
119
        ->status_is(200)
75
        ->status_is(200)
120
        ->header_like( 'Link' => qr/<http:\/\/.*\?.*&_page=2.*>; rel="next",/ )
76
        ->header_like( 'Link' => qr/<http:\/\/.*\?.*&_page=2.*>; rel="next",/ )
121
        ->json_has('/0')
77
        ->json_has('/0')
122
        ->json_hasnt('/1')
78
        ->json_hasnt('/1')
123
        ->json_is('/0/city_name' => 'Manuel');
79
        ->json_is('/0/name' => 'Manuel');
124
80
125
    $builder->build_object({
81
    $builder->build_object({
126
        class => 'Koha::Cities',
82
        class => 'Koha::Cities',
Lines 130-243 subtest 'objects.search helper' => sub { Link Here
130
    });
86
    });
131
87
132
    # _match=starts_with
88
    # _match=starts_with
133
    $t->get_ok('/cities?city_name=manuel&_per_page=3&_page=1&_match=starts_with')
89
    $t->get_ok('/cities?name=manuel&_per_page=3&_page=1&_match=starts_with')
134
        ->status_is(200)
135
        ->json_has('/0')
136
        ->json_has('/1')
137
        ->json_hasnt('/2')
138
        ->json_is('/0/city_name' => 'Manuel')
139
        ->json_is('/1/city_name' => 'Manuela');
140
141
    # _match=ends_with
142
    $t->get_ok('/cities?city_name=manuel&_per_page=3&_page=1&_match=ends_with')
143
        ->status_is(200)
144
        ->json_has('/0')
145
        ->json_has('/1')
146
        ->json_hasnt('/2')
147
        ->json_is('/0/city_name' => 'Manuel')
148
        ->json_is('/1/city_name' => 'Emanuel');
149
150
    # _match=exact
151
    $t->get_ok('/cities?city_name=manuel&_per_page=3&_page=1&_match=exact')
152
        ->status_is(200)
153
        ->json_has('/0')
154
        ->json_hasnt('/1')
155
        ->json_is('/0/city_name' => 'Manuel');
156
157
    # _match=contains
158
    $t->get_ok('/cities?city_name=manuel&_per_page=3&_page=1&_match=contains')
159
        ->status_is(200)
160
        ->json_has('/0')
161
        ->json_has('/1')
162
        ->json_has('/2')
163
        ->json_hasnt('/3')
164
        ->json_is('/0/city_name' => 'Manuel')
165
        ->json_is('/1/city_name' => 'Manuela')
166
        ->json_is('/2/city_name' => 'Emanuel');
167
168
    ## _to_model tests
169
    # _match=starts_with
170
    $t->get_ok('/cities_to_model?nombre=manuel&_per_page=3&_page=1&_match=starts_with')
171
        ->status_is(200)
172
        ->json_has('/0')
173
        ->json_has('/1')
174
        ->json_hasnt('/2')
175
        ->json_is('/0/city_name' => 'Manuel')
176
        ->json_is('/1/city_name' => 'Manuela');
177
178
    # _match=ends_with
179
    $t->get_ok('/cities_to_model?nombre=manuel&_per_page=3&_page=1&_match=ends_with')
180
        ->status_is(200)
181
        ->json_has('/0')
182
        ->json_has('/1')
183
        ->json_hasnt('/2')
184
        ->json_is('/0/city_name' => 'Manuel')
185
        ->json_is('/1/city_name' => 'Emanuel');
186
187
    # _match=exact
188
    $t->get_ok('/cities_to_model?nombre=manuel&_per_page=3&_page=1&_match=exact')
189
        ->status_is(200)
190
        ->json_has('/0')
191
        ->json_hasnt('/1')
192
        ->json_is('/0/city_name' => 'Manuel');
193
194
    # _match=contains
195
    $t->get_ok('/cities_to_model?nombre=manuel&_per_page=3&_page=1&_match=contains')
196
        ->status_is(200)
197
        ->json_has('/0')
198
        ->json_has('/1')
199
        ->json_has('/2')
200
        ->json_hasnt('/3')
201
        ->json_is('/0/city_name' => 'Manuel')
202
        ->json_is('/1/city_name' => 'Manuela')
203
        ->json_is('/2/city_name' => 'Emanuel');
204
205
    ## _to_model && _to_api tests
206
    # _match=starts_with
207
    $t->get_ok('/cities_to_model_to_api?nombre=manuel&_per_page=3&_page=1&_match=starts_with')
208
        ->status_is(200)
90
        ->status_is(200)
209
        ->json_has('/0')
91
        ->json_has('/0')
210
        ->json_has('/1')
92
        ->json_has('/1')
211
        ->json_hasnt('/2')
93
        ->json_hasnt('/2')
212
        ->json_is('/0/nombre' => 'Manuel')
94
        ->json_is('/0/name' => 'Manuel')
213
        ->json_is('/1/nombre' => 'Manuela');
95
        ->json_is('/1/name' => 'Manuela');
214
96
215
    # _match=ends_with
97
    # _match=ends_with
216
    $t->get_ok('/cities_to_model_to_api?nombre=manuel&_per_page=3&_page=1&_match=ends_with')
98
    $t->get_ok('/cities?name=manuel&_per_page=3&_page=1&_match=ends_with')
217
        ->status_is(200)
99
        ->status_is(200)
218
        ->json_has('/0')
100
        ->json_has('/0')
219
        ->json_has('/1')
101
        ->json_has('/1')
220
        ->json_hasnt('/2')
102
        ->json_hasnt('/2')
221
        ->json_is('/0/nombre' => 'Manuel')
103
        ->json_is('/0/name' => 'Manuel')
222
        ->json_is('/1/nombre' => 'Emanuel');
104
        ->json_is('/1/name' => 'Emanuel');
223
105
224
    # _match=exact
106
    # _match=exact
225
    $t->get_ok('/cities_to_model_to_api?nombre=manuel&_per_page=3&_page=1&_match=exact')
107
    $t->get_ok('/cities?name=manuel&_per_page=3&_page=1&_match=exact')
226
        ->status_is(200)
108
        ->status_is(200)
227
        ->json_has('/0')
109
        ->json_has('/0')
228
        ->json_hasnt('/1')
110
        ->json_hasnt('/1')
229
        ->json_is('/0/nombre' => 'Manuel');
111
        ->json_is('/0/name' => 'Manuel');
230
112
231
    # _match=contains
113
    # _match=contains
232
    $t->get_ok('/cities_to_model_to_api?nombre=manuel&_per_page=3&_page=1&_match=contains')
114
    $t->get_ok('/cities?name=manuel&_per_page=3&_page=1&_match=contains')
233
        ->status_is(200)
115
        ->status_is(200)
234
        ->json_has('/0')
116
        ->json_has('/0')
235
        ->json_has('/1')
117
        ->json_has('/1')
236
        ->json_has('/2')
118
        ->json_has('/2')
237
        ->json_hasnt('/3')
119
        ->json_hasnt('/3')
238
        ->json_is('/0/nombre' => 'Manuel')
120
        ->json_is('/0/name' => 'Manuel')
239
        ->json_is('/1/nombre' => 'Manuela')
121
        ->json_is('/1/name' => 'Manuela')
240
        ->json_is('/2/nombre' => 'Emanuel');
122
        ->json_is('/2/name' => 'Emanuel');
241
123
242
    $schema->storage->txn_rollback;
124
    $schema->storage->txn_rollback;
243
};
125
};
Lines 256-276 subtest 'objects.search helper, sorting on mapped column' => sub { Link Here
256
    $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'A', city_country => 'Argentina' } });
138
    $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'A', city_country => 'Argentina' } });
257
    $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'B', city_country => 'Argentina' } });
139
    $builder->build_object({ class => 'Koha::Cities', value => { city_name => 'B', city_country => 'Argentina' } });
258
140
259
    $t->get_ok('/cities_sorted?_order_by=%2Bnombre&_order_by=+city_country')
141
    $t->get_ok('/cities?_order_by=%2Bname&_order_by=+country')
260
      ->status_is(200)
142
      ->status_is(200)
261
      ->json_has('/0')
143
      ->json_has('/0')
262
      ->json_has('/1')
144
      ->json_has('/1')
263
      ->json_hasnt('/2')
145
      ->json_hasnt('/2')
264
      ->json_is('/0/nombre' => 'A')
146
      ->json_is('/0/name' => 'A')
265
      ->json_is('/1/nombre' => 'B');
147
      ->json_is('/1/name' => 'B');
266
148
267
    $t->get_ok('/cities_sorted?_order_by=-nombre')
149
    $t->get_ok('/cities?_order_by=-name')
268
      ->status_is(200)
150
      ->status_is(200)
269
      ->json_has('/0')
151
      ->json_has('/0')
270
      ->json_has('/1')
152
      ->json_has('/1')
271
      ->json_hasnt('/2')
153
      ->json_hasnt('/2')
272
      ->json_is('/0/nombre' => 'B')
154
      ->json_is('/0/name' => 'B')
273
      ->json_is('/1/nombre' => 'A');
155
      ->json_is('/1/name' => 'A');
274
156
275
    $schema->storage->txn_rollback;
157
    $schema->storage->txn_rollback;
276
}
158
}
277
- 

Return to bug 24321