Bug 30719: Tests
[koha.git] / t / db_dependent / api / v1 / ill_requests.t
1 #!/usr/bin/env 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 Test::More tests => 2;
21
22 use Test::MockModule;
23 use Test::MockObject;
24 use Test::Mojo;
25
26 use JSON qw(encode_json);
27
28 use t::lib::TestBuilder;
29 use t::lib::Mocks;
30
31 use Koha::AuthorisedValueCategories;
32 use Koha::Illrequests;
33 use Koha::DateUtils qw( format_sqldatetime );
34
35 my $schema  = Koha::Database->new->schema;
36 my $builder = t::lib::TestBuilder->new;
37
38 t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
39
40 my $t = Test::Mojo->new('Koha::REST::V1');
41
42 subtest 'list() tests' => sub {
43
44     plan tests => 34;
45
46     # Mock ILLBackend (as object)
47     my $backend = Test::MockObject->new;
48     $backend->set_isa('Koha::Illbackends::Mock');
49     $backend->set_always('name', 'Mock');
50     $backend->set_always('capabilities', sub { return 'bar'; } );
51     $backend->mock(
52         'metadata',
53         sub {
54             my ( $self, $rq ) = @_;
55             return {
56                 ID => $rq->illrequest_id,
57                 Title => $rq->patron->borrowernumber
58             }
59         }
60     );
61     $backend->mock(
62         'status_graph', sub {},
63     );
64
65     # Mock Koha::Illrequest::load_backend (to load Mocked Backend)
66     my $illreqmodule = Test::MockModule->new('Koha::Illrequest');
67     $illreqmodule->mock( 'load_backend',
68         sub { my $self = shift; $self->{_my_backend} = $backend; return $self }
69     );
70
71     $schema->storage->txn_begin;
72
73     Koha::Illrequests->search->delete;
74
75     # create an authorized user
76     my $librarian = $builder->build_object(
77         {
78             class => 'Koha::Patrons',
79             value => { flags => 2 ** 22 } # 22 => ill
80         }
81     );
82     my $password = 'thePassword123';
83     $librarian->set_password( { password => $password, skip_validation => 1 } );
84     my $userid = $librarian->userid;
85
86     # create an unauthorized user
87     my $patron = $builder->build_object(
88         {
89             class => 'Koha::Patrons',
90             value => { flags => 0 }
91         }
92     );
93
94     $patron->set_password( { password => $password, skip_validation => 1 } );
95     my $unauth_userid = $patron->userid;
96
97     # Make sure the ILL_STATUS_ALIAS authorised value category is defined
98     unless ( Koha::AuthorisedValueCategories->search( { category_name => 'ILL_STATUS_ALIAS' } )->count > 0 ) {
99         $builder->build_object(
100             { class => 'Koha::AuthorisedValueCategories', value => { category_name => 'ILL_STATUS_ALIAS' } } );
101     }
102
103     my $tag = "Print copy";
104     my $av_code = "print_copy";
105     my $av  = $builder->build_object(
106         {   class => 'Koha::AuthorisedValues',
107             value => {
108                 category => 'ILL_STATUS_ALIAS',
109                 authorised_value => $av_code,
110                 lib      => $tag,
111             }
112         }
113     );
114
115     # No requests, expect empty
116     $t->get_ok("//$userid:$password@/api/v1/ill/requests")
117       ->status_is(200)
118       ->json_is( [] );
119
120
121     # Prepare some expected response structure
122     my $request_status = {
123         code =>"REQ",
124         str =>"Requested"
125     };
126
127     my $response_status = {
128         backend => $backend->name,
129         code =>$request_status->{code},
130         str =>$request_status->{str},
131         type =>"ill_status"
132     };
133
134     my $response_status_av = {
135         category => "ILL_STATUS_ALIAS",
136         code => $av_code,
137         str => $tag,
138         type => "av"
139     };
140
141     # Create some ILL requests
142     my $req_1 = $builder->build_object(
143         {
144             class => 'Koha::Illrequests',
145             value => {
146                 borrowernumber => $patron->borrowernumber,
147                 status         => $request_status->{code},
148                 backend        => $backend->name,
149                 notesstaff     => '1'
150             }
151         }
152     );
153     my $req_2 = $builder->build_object(
154         {
155             class => 'Koha::Illrequests',
156             value => {
157                 status       => $request_status->{code},
158                 backend      => $backend->name,
159                 status_alias => $av->authorised_value,
160                 notesstaff   => '2'
161             }
162
163         }
164     );
165     my $ret = $builder->build_object({ class => 'Koha::Illrequests', value => { status => 'RET' } });
166
167     # Three requests exist, expect all three to be returned
168     $t->get_ok("//$userid:$password@/api/v1/ill/requests")
169       ->status_is(200)
170       ->json_is( [ $req_1->to_api, $req_2->to_api, $ret->to_api ]);
171
172     my $status_query = encode_json({ status => 'REQ' });
173     my $status_alias_query = encode_json({ status_av => $av_code });
174
175     # x-koha-embed: +strings
176     # Two requests exist with status 'REQ', expect them to be returned
177     # One of which also has a status_alias, expect that to be in that request's body
178     $t->get_ok("//$userid:$password@/api/v1/ill/requests?q=$status_query" => {"x-koha-embed" => "+strings"} )
179       ->status_is(200)
180       ->json_is( [
181                 { _strings => { status => $response_status }, %{$req_1->to_api} },
182                 { _strings => { status => $response_status, status_av => $response_status_av }, %{$req_2->to_api} }
183             ]
184         );
185
186     # One request with status_alias 'print_copy' exists, expect that to be returned
187     $t->get_ok("//$userid:$password@/api/v1/ill/requests?q=$status_alias_query" => {"x-koha-embed" => "+strings"} )
188       ->status_is(200)
189       ->json_is( [
190                 { _strings => { status => $response_status, status_av => $response_status_av }, %{$req_2->to_api} }
191             ]
192         );
193
194     # x-koha-embed: patron
195     my $patron_query = encode_json({ borrowernumber => $patron->borrowernumber });
196
197     # One request related to $patron, make sure it comes back
198     $t->get_ok("//$userid:$password@/api/v1/ill/requests" => {"x-koha-embed" => "patron"} )
199       ->status_is(200)
200       ->json_has('/0/patron', $patron->to_api);
201
202     # x-koha-embed: comments
203     # Create comment
204     my $comment_text = "This is the comment";
205     my $comment = $builder->build_object({ class => 'Koha::Illcomments', value => { illrequest_id => $req_1->illrequest_id, comment => $comment_text , borrowernumber => $patron->borrowernumber } } );
206
207     # Make sure comments come back
208     $t->get_ok("//$userid:$password@/api/v1/ill/requests" => {"x-koha-embed" => "comments"} )
209       ->status_is(200)
210       ->json_has('/0/comments', $comment_text);
211
212     # x-koha-embed: id_prefix
213     # Mock Illrequest::Config to return a static prefix
214     my $id_prefix = 'ILL';
215     my $config = Test::MockObject->new;
216     $config->set_isa('Koha::Illrequest::Config::Mock');
217     $config->set_always('getPrefixes', $id_prefix);
218
219     # Make sure id_prefix comes back
220     $t->get_ok("//$userid:$password@/api/v1/ill/requests" => {"x-koha-embed" => "id_prefix"} )
221       ->status_is(200)
222       ->json_has('/0/id_prefix', $id_prefix);
223
224     # ILLHiddenRequestStatuses syspref
225     # Hide 'REQ', expect to return just 1 'RET'
226     t::lib::Mocks::mock_preference( 'ILLHiddenRequestStatuses', 'REQ' );
227     $t->get_ok( "//$userid:$password@/api/v1/ill/requests" )
228       ->status_is(200)
229       ->json_is( [ $ret->to_api ] );
230
231     # Hide 'RET', expect to return 2 'REQ'
232     t::lib::Mocks::mock_preference( 'ILLHiddenRequestStatuses', 'RET' );
233     $t->get_ok( "//$userid:$password@/api/v1/ill/requests?_order_by=staff_notes" )
234       ->status_is(200)
235       ->json_is( [ $req_1->to_api, $req_2->to_api ]);
236
237     # Status code
238     # Warn on unsupported query parameter
239     $t->get_ok( "//$userid:$password@/api/v1/ill/requests?request_blah=blah" )
240       ->status_is(400)
241       ->json_is(
242         [{ path => '/query/request_blah', message => 'Malformed query string'}]
243     );
244
245     # Unauthorized attempt to list
246     $t->get_ok(
247         "//$unauth_userid:$password@/api/v1/ill/requests")
248       ->status_is(403);
249
250     # DELETE method not supported
251     $t->delete_ok(
252         "//$unauth_userid:$password@/api/v1/ill/requests/1")
253       ->status_is(404);
254
255     #TODO; test complex query on extended_attributes
256
257     $schema->storage->txn_rollback;
258 };
259
260 subtest 'add() tests' => sub {
261
262     plan tests => 2;
263
264     $schema->storage->txn_begin;
265
266     # create an authorized user
267     my $patron = $builder->build_object({
268         class => 'Koha::Patrons',
269         value => { flags => 2 ** 22 } # 22 => ill
270     });
271     my $password = 'thePassword123';
272     $patron->set_password({ password => $password, skip_validation => 1 });
273     my $userid = $patron->userid;
274
275     my $library  = $builder->build_object( { class => 'Koha::Libraries' } );
276
277     # Create an ILL request
278     my $illrequest = $builder->build_object(
279         {
280             class => 'Koha::Illrequests',
281             value => {
282                 backend        => 'Mock',
283                 branchcode     => $library->branchcode,
284                 borrowernumber => $patron->borrowernumber,
285                 status         => 'STATUS1',
286             }
287         }
288     );
289
290     # Mock ILLBackend (as object)
291     my $backend = Test::MockObject->new;
292     $backend->set_isa('Koha::Illbackends::Mock');
293     $backend->set_always('name', 'Mock');
294     $backend->set_always('capabilities', sub {
295         return $illrequest;
296     } );
297     $backend->mock(
298         'metadata',
299         sub {
300             my ( $self, $rq ) = @_;
301             return {
302                 ID => $rq->illrequest_id,
303                 Title => $rq->patron->borrowernumber
304             }
305         }
306     );
307     $backend->mock(
308         'status_graph', sub {},
309     );
310
311     # Mock Koha::Illrequest::load_backend (to load Mocked Backend)
312     my $illreqmodule = Test::MockModule->new('Koha::Illrequest');
313     $illreqmodule->mock( 'load_backend',
314         sub { my $self = shift; $self->{_my_backend} = $backend; return $self }
315     );
316
317     $schema->storage->txn_begin;
318
319     Koha::Illrequests->search->delete;
320
321     my $body = {
322         backend => 'Mock',
323         borrowernumber => $patron->borrowernumber,
324         branchcode => $library->branchcode,
325         metadata => {
326             article_author => "Jessop, E. G.",
327             article_title => "Sleep",
328             issn => "0957-4832",
329             issue => "2",
330             pages => "89-90",
331             publisher => "OXFORD UNIVERSITY PRESS",
332             title => "Journal of public health medicine.",
333             year => "2001"
334         }
335     };
336
337     ## Authorized user test
338     $t->post_ok( "//$userid:$password@/api/v1/illrequests" => json => $body)
339       ->status_is(201);
340
341     $schema->storage->txn_rollback;
342 };