|
Lines 17-30
Link Here
|
| 17 |
|
17 |
|
| 18 |
use Modern::Perl; |
18 |
use Modern::Perl; |
| 19 |
|
19 |
|
| 20 |
use Test::More tests => 54; |
20 |
use Test::More tests => 51; |
| 21 |
use Test::MockModule; |
21 |
use Test::MockModule; |
| 22 |
use Test::Mojo; |
22 |
use Test::Mojo; |
| 23 |
use t::lib::Mocks; |
23 |
use t::lib::Mocks; |
| 24 |
use t::lib::TestBuilder; |
24 |
use t::lib::TestBuilder; |
| 25 |
|
25 |
|
| 26 |
use DateTime; |
26 |
use DateTime; |
| 27 |
use MARC::Record; |
|
|
| 28 |
|
27 |
|
| 29 |
use C4::Context; |
28 |
use C4::Context; |
| 30 |
use C4::Circulation; |
29 |
use C4::Circulation; |
|
Lines 35-164
use Koha::DateUtils;
Link Here
|
| 35 |
my $schema = Koha::Database->schema; |
34 |
my $schema = Koha::Database->schema; |
| 36 |
my $builder = t::lib::TestBuilder->new; |
35 |
my $builder = t::lib::TestBuilder->new; |
| 37 |
|
36 |
|
| 38 |
$schema->storage->txn_begin; |
37 |
t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 ); |
| 39 |
|
|
|
| 40 |
t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' ); |
| 41 |
|
| 42 |
$ENV{REMOTE_ADDR} = '127.0.0.1'; |
| 43 |
my $t = Test::Mojo->new('Koha::REST::V1'); |
38 |
my $t = Test::Mojo->new('Koha::REST::V1'); |
| 44 |
my $tx; |
39 |
|
|
|
40 |
$schema->storage->txn_begin; |
| 45 |
|
41 |
|
| 46 |
my $dbh = C4::Context->dbh; |
42 |
my $dbh = C4::Context->dbh; |
| 47 |
|
43 |
|
| 48 |
$dbh->do('DELETE FROM issues'); |
44 |
#FIXME - should be removed |
| 49 |
$dbh->do('DELETE FROM items'); |
|
|
| 50 |
$dbh->do('DELETE FROM issuingrules'); |
45 |
$dbh->do('DELETE FROM issuingrules'); |
| 51 |
my $loggedinuser = $builder->build({ source => 'Borrower' }); |
|
|
| 52 |
|
46 |
|
| 53 |
$dbh->do(q{ |
47 |
my $librarian = $builder->build_object({ |
| 54 |
INSERT INTO user_permissions (borrowernumber, module_bit, code) |
48 |
class => 'Koha::Patrons', |
| 55 |
VALUES (?, 1, 'circulate_remaining_permissions') |
49 |
value => { flags => 2 } |
| 56 |
}, undef, $loggedinuser->{borrowernumber}); |
50 |
}); |
| 57 |
|
51 |
my $password = 'thePassword123'; |
| 58 |
my $session = C4::Auth::get_session(''); |
52 |
$librarian->set_password({ password => $password, skip_validation => 1 }); |
| 59 |
$session->param('number', $loggedinuser->{ borrowernumber }); |
53 |
my $userid = $librarian->userid; |
| 60 |
$session->param('id', $loggedinuser->{ userid }); |
54 |
|
| 61 |
$session->param('ip', '127.0.0.1'); |
55 |
my $patron = $builder->build_object({ |
| 62 |
$session->param('lasttime', time()); |
56 |
class => 'Koha::Patrons', |
| 63 |
$session->flush; |
57 |
value => { flags => 0 } |
| 64 |
|
58 |
}); |
| 65 |
my $patron = $builder->build({ source => 'Borrower', value => { flags => 0 } }); |
59 |
my $unauth_password = 'thePassword000'; |
| 66 |
my $borrowernumber = $patron->{borrowernumber}; |
60 |
$patron->set_password({ password => $unauth_password, skip_validattion => 1 }); |
| 67 |
my $patron_session = C4::Auth::get_session(''); |
61 |
my $unauth_userid = $patron->userid; |
| 68 |
$patron_session->param('number', $borrowernumber); |
62 |
my $patron_id = $patron->borrowernumber; |
| 69 |
$patron_session->param('id', $patron->{ userid }); |
|
|
| 70 |
$patron_session->param('ip', '127.0.0.1'); |
| 71 |
$patron_session->param('lasttime', time()); |
| 72 |
$patron_session->flush; |
| 73 |
|
63 |
|
| 74 |
my $branchcode = $builder->build({ source => 'Branch' })->{ branchcode }; |
64 |
my $branchcode = $builder->build({ source => 'Branch' })->{ branchcode }; |
| 75 |
my $module = new Test::MockModule('C4::Context'); |
65 |
my $module = new Test::MockModule('C4::Context'); |
| 76 |
$module->mock('userenv', sub { { branch => $branchcode } }); |
66 |
$module->mock('userenv', sub { { branch => $branchcode } }); |
| 77 |
|
67 |
|
| 78 |
$tx = $t->ua->build_tx(GET => "/api/v1/checkouts?patron_id=$borrowernumber"); |
68 |
$t->get_ok( "//$userid:$password@/api/v1/checkouts?patron_id=$patron_id" ) |
| 79 |
$tx->req->cookies({name => 'CGISESSID', value => $session->id}); |
|
|
| 80 |
$t->request_ok($tx) |
| 81 |
->status_is(200) |
69 |
->status_is(200) |
| 82 |
->json_is([]); |
70 |
->json_is([]); |
| 83 |
|
71 |
|
| 84 |
my $notexisting_borrowernumber = $borrowernumber + 1; |
72 |
my $notexisting_patron_id = $patron_id + 1; |
| 85 |
$tx = $t->ua->build_tx(GET => "/api/v1/checkouts?patron_id=$notexisting_borrowernumber"); |
73 |
$t->get_ok( "//$userid:$password@/api/v1/checkouts?patron_id=$notexisting_patron_id" ) |
| 86 |
$tx->req->cookies({name => 'CGISESSID', value => $session->id}); |
|
|
| 87 |
$t->request_ok($tx) |
| 88 |
->status_is(200) |
74 |
->status_is(200) |
| 89 |
->json_is([]); |
75 |
->json_is([]); |
| 90 |
|
76 |
|
| 91 |
my $biblionumber = $builder->build_sample_biblio({ title => 'RESTful Web APIs'})->biblionumber; |
77 |
my $item1 = $builder->build_sample_item; |
| 92 |
my $itemnumber1 = $builder->build_sample_item({ biblionumber => $biblionumber, barcode => 'TEST000001'})->itemnumber; |
78 |
my $item2 = $builder->build_sample_item; |
| 93 |
my $itemnumber2 = $builder->build_sample_item({ biblionumber => $biblionumber, barcode => 'TEST000002'})->itemnumber; |
79 |
my $item3 = $builder->build_sample_item; |
| 94 |
my $itemnumber3 = $builder->build_sample_item({ biblionumber => $biblionumber, barcode => 'TEST000003'})->itemnumber; |
|
|
| 95 |
|
80 |
|
| 96 |
my $date_due = DateTime->now->add(weeks => 2); |
81 |
my $date_due = DateTime->now->add(weeks => 2); |
| 97 |
my $issue1 = C4::Circulation::AddIssue($patron, 'TEST000001', $date_due); |
82 |
my $issue1 = C4::Circulation::AddIssue($patron->unblessed, $item1->barcode, $date_due); |
| 98 |
my $date_due1 = Koha::DateUtils::dt_from_string( $issue1->date_due ); |
83 |
my $date_due1 = Koha::DateUtils::dt_from_string( $issue1->date_due ); |
| 99 |
my $issue2 = C4::Circulation::AddIssue($patron, 'TEST000002', $date_due); |
84 |
my $issue2 = C4::Circulation::AddIssue($patron->unblessed, $item2->barcode, $date_due); |
| 100 |
my $date_due2 = Koha::DateUtils::dt_from_string( $issue2->date_due ); |
85 |
my $date_due2 = Koha::DateUtils::dt_from_string( $issue2->date_due ); |
| 101 |
my $issue3 = C4::Circulation::AddIssue($loggedinuser, 'TEST000003', $date_due); |
86 |
my $issue3 = C4::Circulation::AddIssue($librarian->unblessed, $item3->barcode, $date_due); |
| 102 |
my $date_due3 = Koha::DateUtils::dt_from_string( $issue3->date_due ); |
87 |
my $date_due3 = Koha::DateUtils::dt_from_string( $issue3->date_due ); |
| 103 |
|
88 |
|
| 104 |
$tx = $t->ua->build_tx(GET => "/api/v1/checkouts?patron_id=$borrowernumber"); |
89 |
$t->get_ok( "//$userid:$password@/api/v1/checkouts?patron_id=$patron_id" ) |
| 105 |
$tx->req->cookies({name => 'CGISESSID', value => $session->id}); |
|
|
| 106 |
$t->request_ok($tx) |
| 107 |
->status_is(200) |
90 |
->status_is(200) |
| 108 |
->json_is('/0/patron_id' => $borrowernumber) |
91 |
->json_is('/0/patron_id' => $patron_id) |
| 109 |
->json_is('/0/item_id' => $itemnumber1) |
92 |
->json_is('/0/item_id' => $item1->itemnumber) |
| 110 |
->json_is('/0/due_date' => output_pref({ dateformat => "rfc3339", dt => $date_due1 }) ) |
93 |
->json_is('/0/due_date' => output_pref({ dateformat => "rfc3339", dt => $date_due1 }) ) |
| 111 |
->json_is('/1/patron_id' => $borrowernumber) |
94 |
->json_is('/1/patron_id' => $patron_id) |
| 112 |
->json_is('/1/item_id' => $itemnumber2) |
95 |
->json_is('/1/item_id' => $item2->itemnumber) |
| 113 |
->json_is('/1/due_date' => output_pref({ dateformat => "rfc3339", dt => $date_due2 }) ) |
96 |
->json_is('/1/due_date' => output_pref({ dateformat => "rfc3339", dt => $date_due2 }) ) |
| 114 |
->json_hasnt('/2'); |
97 |
->json_hasnt('/2'); |
| 115 |
|
98 |
|
| 116 |
$tx = $t->ua->build_tx(GET => "/api/v1/checkouts/".$issue3->issue_id); |
|
|
| 117 |
$tx->req->cookies({name => 'CGISESSID', value => $patron_session->id}); |
| 118 |
$t->request_ok($tx) |
| 119 |
->status_is(403) |
| 120 |
->json_is({ error => "Authorization failure. Missing required permission(s).", |
| 121 |
required_permissions => { circulate => "circulate_remaining_permissions" } |
| 122 |
}); |
| 123 |
|
99 |
|
| 124 |
$tx = $t->ua->build_tx(GET => "/api/v1/checkouts?patron_id=".$loggedinuser->{borrowernumber}); |
100 |
$t->get_ok( "//$unauth_userid:$unauth_password@/api/v1/checkouts/" . $issue3->issue_id ) |
| 125 |
$tx->req->cookies({name => 'CGISESSID', value => $patron_session->id}); |
|
|
| 126 |
$t->request_ok($tx) |
| 127 |
->status_is(403) |
101 |
->status_is(403) |
| 128 |
->json_is({ error => "Authorization failure. Missing required permission(s).", |
102 |
->json_is({ error => "Authorization failure. Missing required permission(s).", |
| 129 |
required_permissions => { circulate => "circulate_remaining_permissions" } |
103 |
required_permissions => { circulate => "circulate_remaining_permissions" } |
| 130 |
}); |
104 |
}); |
| 131 |
|
105 |
|
| 132 |
$tx = $t->ua->build_tx(GET => "/api/v1/checkouts?patron_id=$borrowernumber"); |
106 |
$t->get_ok( "//$userid:$password@/api/v1/checkouts?patron_id=$patron_id") |
| 133 |
$tx->req->cookies({name => 'CGISESSID', value => $session->id}); |
|
|
| 134 |
$t->request_ok($tx) |
| 135 |
->status_is(200) |
107 |
->status_is(200) |
| 136 |
->json_is('/0/patron_id' => $borrowernumber) |
108 |
->json_is('/0/patron_id' => $patron_id) |
| 137 |
->json_is('/0/item_id' => $itemnumber1) |
109 |
->json_is('/0/item_id' => $item1->itemnumber) |
| 138 |
->json_is('/0/due_date' => output_pref({ dateformat => "rfc3339", dt => $date_due1 }) ) |
110 |
->json_is('/0/due_date' => output_pref({ dateformat => "rfc3339", dt => $date_due1 }) ) |
| 139 |
->json_is('/1/patron_id' => $borrowernumber) |
111 |
->json_is('/1/patron_id' => $patron_id) |
| 140 |
->json_is('/1/item_id' => $itemnumber2) |
112 |
->json_is('/1/item_id' => $item2->itemnumber) |
| 141 |
->json_is('/1/due_date' => output_pref({ dateformat => "rfc3339", dt => $date_due2 }) ) |
113 |
->json_is('/1/due_date' => output_pref({ dateformat => "rfc3339", dt => $date_due2 }) ) |
| 142 |
->json_hasnt('/2'); |
114 |
->json_hasnt('/2'); |
| 143 |
|
115 |
|
| 144 |
$tx = $t->ua->build_tx(GET => "/api/v1/checkouts/" . $issue1->issue_id); |
116 |
$t->get_ok( "//$userid:$password@/api/v1/checkouts/" . $issue1->issue_id) |
| 145 |
$tx->req->cookies({name => 'CGISESSID', value => $session->id}); |
|
|
| 146 |
$t->request_ok($tx) |
| 147 |
->status_is(200) |
117 |
->status_is(200) |
| 148 |
->json_is('/patron_id' => $borrowernumber) |
118 |
->json_is('/patron_id' => $patron_id) |
| 149 |
->json_is('/item_id' => $itemnumber1) |
119 |
->json_is('/item_id' => $item1->itemnumber) |
| 150 |
->json_is('/due_date' => output_pref({ dateformat => "rfc3339", dt => $date_due1 }) ) |
120 |
->json_is('/due_date' => output_pref({ dateformat => "rfc3339", dt => $date_due1 }) ) |
| 151 |
->json_hasnt('/1'); |
121 |
->json_hasnt('/1'); |
| 152 |
|
122 |
|
| 153 |
$tx = $t->ua->build_tx(GET => "/api/v1/checkouts/" . $issue1->issue_id); |
123 |
$t->get_ok( "//$userid:$password@/api/v1/checkouts/" . $issue1->issue_id) |
| 154 |
$tx->req->cookies({name => 'CGISESSID', value => $session->id}); |
|
|
| 155 |
$t->request_ok($tx) |
| 156 |
->status_is(200) |
124 |
->status_is(200) |
| 157 |
->json_is('/due_date' => output_pref({ dateformat => "rfc3339", dt => $date_due1 }) ); |
125 |
->json_is('/due_date' => output_pref({ dateformat => "rfc3339", dt => $date_due1 }) ); |
| 158 |
|
126 |
|
| 159 |
$tx = $t->ua->build_tx(GET => "/api/v1/checkouts/" . $issue2->issue_id); |
127 |
$t->get_ok( "//$userid:$password@/api/v1/checkouts/" . $issue2->issue_id) |
| 160 |
$tx->req->cookies({name => 'CGISESSID', value => $session->id}); |
|
|
| 161 |
$t->request_ok($tx) |
| 162 |
->status_is(200) |
128 |
->status_is(200) |
| 163 |
->json_is('/due_date' => output_pref( { dateformat => "rfc3339", dt => $date_due2 }) ); |
129 |
->json_is('/due_date' => output_pref( { dateformat => "rfc3339", dt => $date_due2 }) ); |
| 164 |
|
130 |
|
|
Lines 170-198
$dbh->do(q{
Link Here
|
| 170 |
}, {}, '*', '*', '*', 7, 1); |
136 |
}, {}, '*', '*', '*', 7, 1); |
| 171 |
|
137 |
|
| 172 |
my $expected_datedue = DateTime->now->add(days => 14)->set(hour => 23, minute => 59, second => 0); |
138 |
my $expected_datedue = DateTime->now->add(days => 14)->set(hour => 23, minute => 59, second => 0); |
| 173 |
$tx = $t->ua->build_tx(PUT => "/api/v1/checkouts/" . $issue1->issue_id); |
139 |
$t->put_ok ( "//$userid:$password@/api/v1/checkouts/" . $issue1->issue_id) |
| 174 |
$tx->req->cookies({name => 'CGISESSID', value => $session->id}); |
|
|
| 175 |
$t->request_ok($tx) |
| 176 |
->status_is(200) |
140 |
->status_is(200) |
| 177 |
->json_is('/due_date' => output_pref( { dateformat => "rfc3339", dt => $expected_datedue }) ); |
141 |
->json_is('/due_date' => output_pref( { dateformat => "rfc3339", dt => $expected_datedue }) ); |
| 178 |
|
142 |
|
| 179 |
$tx = $t->ua->build_tx(PUT => "/api/v1/checkouts/" . $issue3->issue_id); |
143 |
$t->put_ok( "//$unauth_userid:$unauth_password@/api/v1/checkouts/" . $issue3->issue_id) |
| 180 |
$tx->req->cookies({name => 'CGISESSID', value => $patron_session->id}); |
|
|
| 181 |
$t->request_ok($tx) |
| 182 |
->status_is(403) |
144 |
->status_is(403) |
| 183 |
->json_is({ error => "Authorization failure. Missing required permission(s).", |
145 |
->json_is({ error => "Authorization failure. Missing required permission(s).", |
| 184 |
required_permissions => { circulate => "circulate_remaining_permissions" } |
146 |
required_permissions => { circulate => "circulate_remaining_permissions" } |
| 185 |
}); |
147 |
}); |
| 186 |
|
148 |
|
| 187 |
$tx = $t->ua->build_tx(PUT => "/api/v1/checkouts/" . $issue2->issue_id); |
149 |
$t->put_ok( "//$userid:$password@/api/v1/checkouts/" . $issue2->issue_id) |
| 188 |
$tx->req->cookies({name => 'CGISESSID', value => $session->id}); |
|
|
| 189 |
$t->request_ok($tx) |
| 190 |
->status_is(200) |
150 |
->status_is(200) |
| 191 |
->json_is('/due_date' => output_pref({ dateformat => "rfc3339", dt => $expected_datedue}) ); |
151 |
->json_is('/due_date' => output_pref({ dateformat => "rfc3339", dt => $expected_datedue}) ); |
| 192 |
|
152 |
|
| 193 |
$tx = $t->ua->build_tx(PUT => "/api/v1/checkouts/" . $issue1->issue_id); |
153 |
$t->put_ok( "//$userid:$password@/api/v1/checkouts/" . $issue1->issue_id) |
| 194 |
$tx->req->cookies({name => 'CGISESSID', value => $session->id}); |
|
|
| 195 |
$t->request_ok($tx) |
| 196 |
->status_is(403) |
154 |
->status_is(403) |
| 197 |
->json_is({ error => 'Renewal not authorized (too_many)' }); |
155 |
->json_is({ error => 'Renewal not authorized (too_many)' }); |
| 198 |
|
156 |
|
| 199 |
- |
|
|