Bug 23634: (QA follow-up) Catch all email cases in API
[koha.git] / t / db_dependent / api / v1 / illrequests.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 => 1;
21 use Test::MockModule;
22 use Test::MockObject;
23 use Test::Mojo;
24 use Test::Warn;
25
26 use t::lib::TestBuilder;
27 use t::lib::Mocks;
28
29 use C4::Auth;
30 use Koha::Illrequests;
31 use Koha::DateUtils qw( format_sqldatetime );
32
33 my $schema  = Koha::Database->new->schema;
34 my $builder = t::lib::TestBuilder->new;
35
36 t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' );
37
38 my $remote_address = '127.0.0.1';
39 my $t              = Test::Mojo->new('Koha::REST::V1');
40
41 subtest 'list() tests' => sub {
42
43     plan tests => 30;
44
45     # Mock ILLBackend (as object)
46     my $backend = Test::MockObject->new;
47     $backend->set_isa('Koha::Illbackends::Mock');
48     $backend->set_always('name', 'Mock');
49     $backend->set_always('capabilities', sub { return 'bar'; } );
50     $backend->mock(
51         'metadata',
52         sub {
53             my ( $self, $rq ) = @_;
54             return {
55                 ID => $rq->illrequest_id,
56                 Title => $rq->patron->borrowernumber
57             }
58         }
59     );
60     $backend->mock(
61         'status_graph', sub {},
62     );
63
64     # Mock Koha::Illrequest::load_backend (to load Mocked Backend)
65     my $illreqmodule = Test::MockModule->new('Koha::Illrequest');
66     $illreqmodule->mock( 'load_backend',
67         sub { my $self = shift; $self->{_my_backend} = $backend; return $self }
68     );
69
70     $schema->storage->txn_begin;
71
72     Koha::Illrequests->search->delete;
73     # ill => 22 (userflags.sql)
74     my ( $borrowernumber, $session_id ) = create_user_and_session({ authorized => 22 });
75
76     ## Authorized user tests
77     # No requests, so empty array should be returned
78     my $tx = $t->ua->build_tx( GET => '/api/v1/illrequests' );
79     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
80     $tx->req->env( { REMOTE_ADDR => $remote_address } );
81     $t->request_ok($tx)->status_is(200)->json_is( [] );
82
83     my $library = $builder->build_object( { class => 'Koha::Libraries' } );
84     my $patron_1  = $builder->build_object( { class => 'Koha::Patrons' } );
85     my $patron_2  = $builder->build_object( { class => 'Koha::Patrons' } );
86
87     # Create an ILL request
88     my $illrequest = $builder->build_object(
89         {
90             class => 'Koha::Illrequests',
91             value => {
92                 backend        => 'Mock',
93                 branchcode     => $library->branchcode,
94                 borrowernumber => $patron_1->borrowernumber,
95                 status         => 'STATUS1',
96             }
97         }
98     );
99
100     # The api response is always augmented with the id_prefix
101     my $response = $illrequest->unblessed;
102     $response->{id_prefix} = $illrequest->id_prefix;
103
104     my $req_formatted = add_formatted($response);
105
106     # One illrequest created, should get returned
107     $tx = $t->ua->build_tx( GET => '/api/v1/illrequests' );
108     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
109     $tx->req->env( { REMOTE_ADDR => $remote_address } );
110     $t->request_ok($tx)->status_is(200)->json_is( [ $req_formatted ] );
111
112     # One illrequest created, returned with augmented data
113     $tx = $t->ua->build_tx( GET =>
114           '/api/v1/illrequests?embed=patron,library,capabilities,metadata,requested_partners' );
115     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
116     $tx->req->env( { REMOTE_ADDR => $remote_address } );
117     $t->request_ok($tx)->status_is(200)
118         ->json_has( '/0/patron', 'patron embedded' )
119         ->json_is( '/0/patron/patron_id', $patron_1->borrowernumber, 'The right patron is embeded')
120         ->json_has( '/0/requested_partners', 'requested_partners embedded' )
121         ->json_has( '/0/capabilities', 'capabilities embedded' )
122         ->json_has( '/0/library', 'library embedded'  )
123         ->json_has( '/0/metadata', 'metadata embedded'  )
124         ->json_hasnt( '/1', 'Only one request was created' );
125
126     # Create another ILL request
127     my $illrequest2 = $builder->build_object(
128         {
129             class => 'Koha::Illrequests',
130             value => {
131                 backend        => 'Mock',
132                 branchcode     => $library->branchcode,
133                 borrowernumber => $patron_2->borrowernumber,
134                 status         => 'STATUS2',
135             }
136         }
137     );
138
139     # The api response is always augmented with the id_prefix
140     my $response2 = $illrequest2->unblessed;
141     $response2->{id_prefix} = $illrequest2->id_prefix;
142
143     my $req2_formatted = add_formatted($response2);
144
145     # Two illrequest created, should get returned
146     $tx = $t->ua->build_tx( GET => '/api/v1/illrequests' );
147     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
148     $tx->req->env( { REMOTE_ADDR => $remote_address } );
149     $t->request_ok($tx)->status_is(200)
150       ->json_is( [ $req_formatted, $req2_formatted ] );
151
152     # Warn on unsupported query parameter
153     $tx = $t->ua->build_tx( GET => '/api/v1/illrequests?request_blah=blah' );
154     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
155     $tx->req->env( { REMOTE_ADDR => $remote_address } );
156     $t->request_ok($tx)->status_is(400)->json_is(
157         [{ path => '/query/request_blah', message => 'Malformed query string'}]
158     );
159
160     # Test the borrowernumber parameter
161     $tx = $t->ua->build_tx( GET => '/api/v1/illrequests?borrowernumber=' .
162         $patron_2->borrowernumber );
163     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
164     $tx->req->env( { REMOTE_ADDR => $remote_address } );
165     $t->request_ok($tx)->status_is(200)->json_is( [ $response2 ] );
166
167     # Test the ILLHiddenRequestStatuses syspref
168     t::lib::Mocks::mock_preference( 'ILLHiddenRequestStatuses', 'STATUS1' );
169     $tx = $t->ua->build_tx( GET => '/api/v1/illrequests' );
170     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
171     $tx->req->env( { REMOTE_ADDR => $remote_address } );
172     $t->request_ok($tx)->status_is(200)
173       ->json_is( [ $req2_formatted ] );
174
175     t::lib::Mocks::mock_preference( 'ILLHiddenRequestStatuses', 'STATUS2' );
176     $tx = $t->ua->build_tx( GET => '/api/v1/illrequests' );
177     $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
178     $tx->req->env( { REMOTE_ADDR => $remote_address } );
179     $t->request_ok($tx)->status_is(200)
180       ->json_is( [ $req_formatted ] );
181
182     $schema->storage->txn_rollback;
183 };
184
185 sub add_formatted {
186     my $req = shift;
187     my @format_dates = ( 'placed', 'updated', 'completed' );
188     # We need to embellish the request with properties that the API
189     # controller calculates on the fly
190     # Create new "formatted" columns for each date column
191     # that needs formatting
192     foreach my $field(@format_dates) {
193         if (defined $req->{$field}) {
194             $req->{$field . "_formatted"} = format_sqldatetime(
195                 $req->{$field},
196                 undef,
197                 undef,
198                 1
199             );
200         }
201     }
202     return $req;
203 }
204
205 sub create_user_and_session {
206
207     my $args = shift;
208     my $dbh  = C4::Context->dbh;
209
210     my $flags = ( $args->{authorized} ) ? 2**$args->{authorized} : 0;
211
212     my $user = $builder->build(
213         {
214             source => 'Borrower',
215             value  => {
216                 flags => $flags
217             }
218         }
219     );
220
221     # Create a session for the authorized user
222     my $session = C4::Auth::get_session('');
223     $session->param( 'number',   $user->{borrowernumber} );
224     $session->param( 'id',       $user->{userid} );
225     $session->param( 'ip',       '127.0.0.1' );
226     $session->param( 'lasttime', time() );
227     $session->flush;
228
229     return ( $user->{borrowernumber}, $session->id );
230 }
231
232 1;