Bug 18292: Remove return 1 statements in tests
[koha.git] / t / db_dependent / Circulation / TooMany.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 under the
6 # terms of the GNU General Public License as published by the Free Software
7 # Foundation; either version 3 of the License, or (at your option) any later
8 # version.
9 #
10 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License along
15 # with Koha; if not, see <http://www.gnu.org/licenses>.
16
17 use Modern::Perl;
18 use Test::More tests => 6;
19 use C4::Context;
20
21 use C4::Biblio;
22 use C4::Members;
23 use C4::Circulation;
24 use C4::Items;
25 use C4::Context;
26
27 use Koha::DateUtils qw( dt_from_string );
28 use Koha::Database;
29
30 use t::lib::TestBuilder;
31 use t::lib::Mocks;
32
33 my $schema = Koha::Database->new->schema;
34 $schema->storage->txn_begin;
35
36 our $dbh = C4::Context->dbh;
37
38 $dbh->do(q|DELETE FROM issues|);
39 $dbh->do(q|DELETE FROM items|);
40 $dbh->do(q|DELETE FROM borrowers|);
41 $dbh->do(q|DELETE FROM branches|);
42 $dbh->do(q|DELETE FROM categories|);
43 $dbh->do(q|DELETE FROM accountlines|);
44 $dbh->do(q|DELETE FROM itemtypes|);
45 $dbh->do(q|DELETE FROM branch_item_rules|);
46 $dbh->do(q|DELETE FROM branch_borrower_circ_rules|);
47 $dbh->do(q|DELETE FROM default_branch_circ_rules|);
48 $dbh->do(q|DELETE FROM default_circ_rules|);
49 $dbh->do(q|DELETE FROM default_branch_item_rules|);
50 $dbh->do(q|DELETE FROM issuingrules|);
51
52 my $builder = t::lib::TestBuilder->new();
53 t::lib::Mocks::mock_preference('item-level_itypes', 1); # Assuming the item type is defined at item level
54
55 my $branch = $builder->build({
56     source => 'Branch',
57 });
58
59 my $category = $builder->build({
60     source => 'Category',
61 });
62
63 my $patron = $builder->build({
64     source => 'Borrower',
65     value => {
66         categorycode => $category->{categorycode},
67         branchcode => $branch->{branchcode},
68     },
69 });
70
71 my $biblio = $builder->build({
72     source => 'Biblio',
73     value => {
74         branchcode => $branch->{branchcode},
75     },
76 });
77 my $item = $builder->build({
78     source => 'Item',
79     value => {
80         biblionumber => $biblio->{biblionumber},
81         homebranch => $branch->{branchcode},
82         holdingbranch => $branch->{branchcode},
83     },
84 });
85
86 C4::Context->_new_userenv ('DUMMY_SESSION_ID');
87 C4::Context->set_userenv($patron->{borrowernumber}, $patron->{userid}, 'usercnum', 'First name', 'Surname', $branch->{branchcode}, 'My Library', 0);
88
89 # TooMany return ($current_loan_count, $max_loans_allowed) or undef
90 # CO = Checkout
91 # OSCO: On-site checkout
92
93 subtest 'no rules exist' => sub {
94     plan tests => 2;
95     is_deeply(
96         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
97         { reason => 'NO_RULE_DEFINED', max_allowed => 0 },
98         'CO should not be allowed, in any cases'
99     );
100     is_deeply(
101         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
102         { reason => 'NO_RULE_DEFINED', max_allowed => 0 },
103         'OSCO should not be allowed, in any cases'
104     );
105 };
106
107 subtest '1 Issuingrule exist 0 0: no issue allowed' => sub {
108     plan tests => 4;
109     my $issuingrule = $builder->build({
110         source => 'Issuingrule',
111         value => {
112             branchcode         => $branch->{branchcode},
113             categorycode       => $category->{categorycode},
114             itemtype           => '*',
115             maxissueqty        => 0,
116             maxonsiteissueqty  => 0,
117         },
118     });
119     t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 0);
120     is_deeply(
121         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
122         {
123             reason => 'TOO_MANY_CHECKOUTS',
124             count => 0,
125             max_allowed => 0,
126         },
127         'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
128     );
129     is_deeply(
130         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
131         {
132             reason => 'TOO_MANY_ONSITE_CHECKOUTS',
133             count => 0,
134             max_allowed => 0,
135         },
136         'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
137     );
138
139     t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 1);
140     is_deeply(
141         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
142         {
143             reason => 'TOO_MANY_CHECKOUTS',
144             count => 0,
145             max_allowed => 0,
146         },
147         'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
148     );
149     is_deeply(
150         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
151         {
152             reason => 'TOO_MANY_ONSITE_CHECKOUTS',
153             count => 0,
154             max_allowed => 0,
155         },
156         'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
157     );
158
159     teardown();
160 };
161
162 subtest '1 Issuingrule exist 1 1: issue is allowed' => sub {
163     plan tests => 4;
164     my $issuingrule = $builder->build({
165         source => 'Issuingrule',
166         value => {
167             branchcode         => $branch->{branchcode},
168             categorycode       => $category->{categorycode},
169             itemtype           => '*',
170             maxissueqty        => 1,
171             maxonsiteissueqty  => 1,
172         },
173     });
174     t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 0);
175     is(
176         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
177         undef,
178         'CO should be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
179     );
180     is(
181         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
182         undef,
183         'OSCO should be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
184     );
185
186     t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 1);
187     is(
188         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
189         undef,
190         'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
191     );
192     is(
193         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
194         undef,
195         'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
196     );
197
198     teardown();
199 };
200
201 subtest '1 Issuingrule exist: 1 CO allowed, 1 OSCO allowed. Do a CO' => sub {
202     plan tests => 5;
203     my $issuingrule = $builder->build({
204         source => 'Issuingrule',
205         value => {
206             branchcode         => $branch->{branchcode},
207             categorycode       => $category->{categorycode},
208             itemtype           => '*',
209             maxissueqty        => 1,
210             maxonsiteissueqty  => 1,
211         },
212     });
213
214     my $issue = C4::Circulation::AddIssue( $patron, $item->{barcode}, dt_from_string() );
215     like( $issue->issue_id, qr|^\d+$|, 'The issue should have been inserted' );
216
217     t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 0);
218     is_deeply(
219         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
220         {
221             reason => 'TOO_MANY_CHECKOUTS',
222             count => 1,
223             max_allowed => 1,
224         },
225         'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
226     );
227     is(
228         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
229         undef,
230         'OSCO should be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
231     );
232
233     t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 1);
234     is_deeply(
235         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
236         {
237             reason => 'TOO_MANY_CHECKOUTS',
238             count => 1,
239             max_allowed => 1,
240         },
241         'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
242     );
243     is_deeply(
244         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
245         {
246             reason => 'TOO_MANY_CHECKOUTS',
247             count => 1,
248             max_allowed => 1,
249         },
250         'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
251     );
252
253     teardown();
254 };
255
256 subtest '1 Issuingrule exist: 1 CO allowed, 1 OSCO allowed, Do a OSCO' => sub {
257     plan tests => 5;
258     my $issuingrule = $builder->build({
259         source => 'Issuingrule',
260         value => {
261             branchcode         => $branch->{branchcode},
262             categorycode       => $category->{categorycode},
263             itemtype           => '*',
264             maxissueqty        => 1,
265             maxonsiteissueqty  => 1,
266         },
267     });
268
269     my $issue = C4::Circulation::AddIssue( $patron, $item->{barcode}, dt_from_string(), undef, undef, undef, { onsite_checkout => 1 } );
270     like( $issue->issue_id, qr|^\d+$|, 'The issue should have been inserted' );
271
272     t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 0);
273     is(
274         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
275         undef,
276         'CO should be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
277     );
278     is_deeply(
279         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
280         {
281             reason => 'TOO_MANY_ONSITE_CHECKOUTS',
282             count => 1,
283             max_allowed => 1,
284         },
285         'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
286     );
287
288     t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 1);
289     is_deeply(
290         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
291         {
292             reason => 'TOO_MANY_CHECKOUTS',
293             count => 1,
294             max_allowed => 1,
295         },
296         'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
297     );
298     is_deeply(
299         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
300         {
301             reason => 'TOO_MANY_ONSITE_CHECKOUTS',
302             count => 1,
303             max_allowed => 1,
304         },
305         'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
306     );
307
308     teardown();
309 };
310
311 subtest '1 BranchBorrowerCircRule exist: 1 CO allowed, 1 OSCO allowed' => sub {
312     # Note: the same test coul be done for
313     # DefaultBorrowerCircRule, DefaultBranchCircRule, DefaultBranchItemRule ans DefaultCircRule.pm
314
315     plan tests => 10;
316     my $issuingrule = $builder->build({
317         source => 'BranchBorrowerCircRule',
318         value => {
319             branchcode         => $branch->{branchcode},
320             categorycode       => $category->{categorycode},
321             maxissueqty        => 1,
322             maxonsiteissueqty  => 1,
323         },
324     });
325
326     my $issue = C4::Circulation::AddIssue( $patron, $item->{barcode}, dt_from_string(), undef, undef, undef );
327     like( $issue->issue_id, qr|^\d+$|, 'The issue should have been inserted' );
328
329     t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 0);
330     is_deeply(
331         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
332         {
333             reason => 'TOO_MANY_CHECKOUTS',
334             count => 1,
335             max_allowed => 1,
336         },
337         'CO should be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
338     );
339     is(
340         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
341         undef,
342         'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
343     );
344
345     t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 1);
346     is_deeply(
347         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
348         {
349             reason => 'TOO_MANY_CHECKOUTS',
350             count => 1,
351             max_allowed => 1,
352         },
353         'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
354     );
355     is_deeply(
356         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
357         {
358             reason => 'TOO_MANY_CHECKOUTS',
359             count => 1,
360             max_allowed => 1,
361         },
362         'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
363     );
364
365     teardown();
366
367     $issue = C4::Circulation::AddIssue( $patron, $item->{barcode}, dt_from_string(), undef, undef, undef, { onsite_checkout => 1 } );
368     like( $issue->issue_id, qr|^\d+$|, 'The issue should have been inserted' );
369
370     t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 0);
371     is(
372         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
373         undef,
374         'CO should be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
375     );
376     is_deeply(
377         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
378         {
379             reason => 'TOO_MANY_ONSITE_CHECKOUTS',
380             count => 1,
381             max_allowed => 1,
382         },
383         'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
384     );
385
386     t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 1);
387     is_deeply(
388         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
389         {
390             reason => 'TOO_MANY_CHECKOUTS',
391             count => 1,
392             max_allowed => 1,
393         },
394         'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
395     );
396     is_deeply(
397         C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
398         {
399             reason => 'TOO_MANY_ONSITE_CHECKOUTS',
400             count => 1,
401             max_allowed => 1,
402         },
403         'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
404     );
405
406     teardown();
407 };
408
409 $schema->storage->txn_rollback;
410
411 sub teardown {
412     $dbh->do(q|DELETE FROM issues|);
413     $dbh->do(q|DELETE FROM issuingrules|);
414 }
415