adf3001c4ffc850475607b620fe55c88ed490cde
[koha.git] / t / Koha / REST / Plugin / Pagination.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 # Dummy app for testing the plugin
21 use Mojolicious::Lite;
22
23 app->log->level('error');
24
25 plugin 'Koha::REST::Plugin::Pagination';
26
27 # For add_pagination_headers()
28
29 get '/empty' => sub {
30     my $c = shift;
31     $c->render( json => { ok => 1 }, status => 200 );
32 };
33
34 get '/pagination_headers' => sub {
35     my $c = shift;
36     $c->add_pagination_headers({ total => 10, params => { _page => 2, _per_page => 3, firstname => 'Jonathan' } });
37     $c->render( json => { ok => 1 }, status => 200 );
38 };
39
40 get '/pagination_headers_first_page' => sub {
41     my $c = shift;
42     $c->add_pagination_headers({ total => 10, params => { _page => 1, _per_page => 3, firstname => 'Jonathan' } });
43     $c->render( json => { ok => 1 }, status => 200 );
44 };
45
46 get '/pagination_headers_last_page' => sub {
47     my $c = shift;
48     $c->add_pagination_headers({ total => 10, params => { _page => 4, _per_page => 3, firstname => 'Jonathan' } });
49     $c->render( json => { ok => 1 }, status => 200 );
50 };
51
52 # For dbic_merge_pagination
53
54 get '/dbic_merge_pagination' => sub {
55     my $c = shift;
56     my $filter = { firstname => 'Kyle', surname => 'Hall' };
57     $filter = $c->dbic_merge_pagination({ filter => $filter, params => { _page => 1, _per_page => 3 } });
58     $c->render( json => $filter, status => 200 );
59 };
60
61 get '/pagination_headers_without_page_size' => sub {
62     my $c = shift;
63     $c->add_pagination_headers({ total => 10, params => { _page => 2, firstname => 'Jonathan' } });
64     $c->render( json => { ok => 1 }, status => 200 );
65 };
66
67 get '/pagination_headers_without_page' => sub {
68     my $c = shift;
69     $c->add_pagination_headers({ total => 10, params => { _per_page => 3, firstname => 'Jonathan' } });
70     $c->render( json => { ok => 1 }, status => 200 );
71 };
72
73 # The tests
74
75 use Test::More tests => 2;
76 use Test::Mojo;
77
78 use t::lib::Mocks;
79
80 subtest 'add_pagination_headers() tests' => sub {
81
82     plan tests => 75;
83
84     my $t = Test::Mojo->new;
85
86     $t->get_ok('/empty')
87       ->status_is( 200 )
88       ->header_is( 'X-Total-Count' => undef, 'X-Total-Count is undefined' )
89       ->header_is( 'Link'          => undef, 'Link is undefined' );
90
91     $t->get_ok('/pagination_headers')
92       ->status_is( 200 )
93       ->header_is( 'X-Total-Count' => 10, 'X-Total-Count contains the passed value' )
94       ->header_like( 'Link' => qr/<http:\/\/.*\?.*_per_page=3.*>; rel="prev",/ )
95       ->header_like( 'Link' => qr/<http:\/\/.*\?.*_page=1.*>; rel="prev",/ )
96       ->header_like( 'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="prev",/ )
97       ->header_like( 'Link' => qr/<http:\/\/.*\?.*_per_page=3.*>; rel="next",/ )
98       ->header_like( 'Link' => qr/<http:\/\/.*\?.*_page=3.*>; rel="next",/ )
99       ->header_like( 'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="next",/ )
100       ->header_like( 'Link' => qr/<http:\/\/.*\?.*_per_page=3.*>; rel="first",/ )
101       ->header_like( 'Link' => qr/<http:\/\/.*\?.*_page=1.*>; rel="first",/ )
102       ->header_like( 'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="first",/ )
103       ->header_like( 'Link' => qr/<http:\/\/.*\?.*_per_page=3.*>; rel="last"/ )
104       ->header_like( 'Link' => qr/<http:\/\/.*\?.*_page=4.*>; rel="last"/ )
105       ->header_like( 'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="last"/ );
106
107     $t->get_ok('/pagination_headers_first_page')
108       ->status_is( 200 )
109       ->header_is( 'X-Total-Count' => 10, 'X-Total-Count contains the passed value' )
110       ->header_unlike( 'Link' => qr/<http:\/\/.*\?.*>; rel="prev",/ )
111       ->header_like(   'Link' => qr/<http:\/\/.*\?.*_per_page=3.*>; rel="next",/ )
112       ->header_like(   'Link' => qr/<http:\/\/.*\?.*_page=2.*>; rel="next",/ )
113       ->header_like(   'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="next",/ )
114       ->header_like(   'Link' => qr/<http:\/\/.*\?.*_per_page=3.*>; rel="first",/ )
115       ->header_like(   'Link' => qr/<http:\/\/.*\?.*_page=1.*>; rel="first",/ )
116       ->header_like(   'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="first",/ )
117       ->header_like(   'Link' => qr/<http:\/\/.*\?.*_per_page=3.*>; rel="last"/ )
118       ->header_like(   'Link' => qr/<http:\/\/.*\?.*_page=4.*>; rel="last"/ )
119       ->header_like(   'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="last"/ );
120
121     $t->get_ok('/pagination_headers_last_page')
122       ->status_is( 200 )
123       ->header_is( 'X-Total-Count' => 10, 'X-Total-Count contains the passed value' )
124       ->header_like(   'Link' => qr/<http:\/\/.*\?.*_per_page=3.*>; rel="prev",/ )
125       ->header_like(   'Link' => qr/<http:\/\/.*\?.*_page=3.*>; rel="prev",/ )
126       ->header_like(   'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="prev",/ )
127       ->header_unlike( 'Link' => qr/<http:\/\/.*\?.*>; rel="next",/ )
128       ->header_like(   'Link' => qr/<http:\/\/.*\?.*_per_page=3.*>; rel="first",/ )
129       ->header_like(   'Link' => qr/<http:\/\/.*\?.*_page=1.*>; rel="first",/ )
130       ->header_like(   'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="first",/ )
131       ->header_like(   'Link' => qr/<http:\/\/.*\?.*_per_page=3.*>; rel="last"/ )
132       ->header_like(   'Link' => qr/<http:\/\/.*\?.*_page=4.*>; rel="last"/ )
133       ->header_like(   'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="last"/ );
134
135     t::lib::Mocks::mock_preference('RESTdefaultPageSize', 3);
136     $t->get_ok('/pagination_headers_without_page_size')
137       ->status_is( 200 )
138       ->header_is( 'X-Total-Count' => 10, 'X-Total-Count contains the passed value' )
139       ->header_like( 'Link' => qr/<http:\/\/.*\?.*per_page=3.*>; rel="prev",/ )
140       ->header_like( 'Link' => qr/<http:\/\/.*\?.*page=1.*>; rel="prev",/ )
141       ->header_like( 'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="prev",/ )
142       ->header_like( 'Link' => qr/<http:\/\/.*\?.*per_page=3.*>; rel="next",/ )
143       ->header_like( 'Link' => qr/<http:\/\/.*\?.*page=3.*>; rel="next",/ )
144       ->header_like( 'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="next",/ )
145       ->header_like( 'Link' => qr/<http:\/\/.*\?.*per_page=3.*>; rel="first",/ )
146       ->header_like( 'Link' => qr/<http:\/\/.*\?.*page=1.*>; rel="first",/ )
147       ->header_like( 'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="first",/ )
148       ->header_like( 'Link' => qr/<http:\/\/.*\?.*per_page=3.*>; rel="last"/ )
149       ->header_like( 'Link' => qr/<http:\/\/.*\?.*page=4.*>; rel="last"/ )
150       ->header_like( 'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="last"/ );
151
152     $t->get_ok('/pagination_headers_without_page')
153       ->status_is( 200 )
154       ->header_is( 'X-Total-Count' => 10, 'X-Total-Count header present, even without page param' )
155       ->header_unlike( 'Link' => qr/<http:\/\/.*\?.*per_page=3.*>; rel="prev",/, 'First page, no previous' )
156       ->header_unlike( 'Link' => qr/<http:\/\/.*\?.*page=1.*>; rel="prev",/, 'First page, no previous' )
157       ->header_unlike( 'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="prev",/, 'First page, no previous' )
158       ->header_like( 'Link' => qr/<http:\/\/.*\?.*per_page=3.*>; rel="next",/ )
159       ->header_like( 'Link' => qr/<http:\/\/.*\?.*page=3.*>; rel="next",/ )
160       ->header_like( 'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="next",/ )
161       ->header_like( 'Link' => qr/<http:\/\/.*\?.*per_page=3.*>; rel="first",/ )
162       ->header_like( 'Link' => qr/<http:\/\/.*\?.*page=1.*>; rel="first",/ )
163       ->header_like( 'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="first",/ )
164       ->header_like( 'Link' => qr/<http:\/\/.*\?.*per_page=3.*>; rel="last"/ )
165       ->header_like( 'Link' => qr/<http:\/\/.*\?.*page=4.*>; rel="last"/ )
166       ->header_like( 'Link' => qr/<http:\/\/.*\?.*firstname=Jonathan.*>; rel="last"/ );
167 };
168
169 subtest 'dbic_merge_pagination() tests' => sub {
170
171     plan tests => 3;
172
173     my $t = Test::Mojo->new;
174
175     $t->get_ok('/dbic_merge_pagination')
176       ->status_is(200)
177       ->json_is({ firstname => 'Kyle', surname => 'Hall', page => 1, rows => 3 });
178 };