Bug 30650: Add some useful modules and tests
[koha.git] / t / db_dependent / Koha / CurbsidePickups.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 use Test::More tests => 3;
21 use Test::Exception;
22
23 use Koha::City;
24 use Koha::CurbsidePickups;
25 use Koha::CurbsidePickupPolicies;
26 use Koha::Database;
27 use Koha::DateUtils qw( dt_from_string );
28
29 use t::lib::TestBuilder;
30 use t::lib::Dates;
31 use t::lib::Mocks;
32
33 my $schema = Koha::Database->new->schema;
34 $schema->storage->txn_begin;
35
36 my $builder          = t::lib::TestBuilder->new;
37 my $library          = $builder->build_object( { class => 'Koha::Libraries' } );
38 my $library_disabled = $builder->build_object( { class => 'Koha::Libraries' } );
39 my $logged_in_patron = $builder->build_object(
40     {
41         class => 'Koha::Patrons',
42         value => { branchcode => $library->branchcode }
43     }
44 );
45 t::lib::Mocks::mock_userenv( { patron => $logged_in_patron } );
46 my $patron = $builder->build_object(
47     {
48         class => 'Koha::Patrons',
49         value => { branchcode => $library->branchcode }
50     }
51 );
52
53 my $policy = Koha::CurbsidePickupPolicy->new(
54     {
55         branchcode              => $library->branchcode,
56         enabled                 => 1,
57         pickup_interval         => 30,
58         patrons_per_interval    => 2,
59         patron_scheduled_pickup => 1
60     }
61 )->store;
62 my $policy_disabled = Koha::CurbsidePickupPolicy->new(
63     {
64         branchcode              => $library_disabled->branchcode,
65         enabled                 => 0,
66         pickup_interval         => 30,
67         patrons_per_interval    => 2,
68         patron_scheduled_pickup => 1
69     }
70 )->store;
71
72 # Open Mondays from 12 to 18
73 $policy->add_opening_slot('1-12:00-18:00');
74
75 my $today = dt_from_string;
76
77 subtest 'Create a pickup' => sub {
78     plan tests => 5;
79
80     # Day and datetime are ok
81     my $next_monday =
82       $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
83     my $schedule_dt =
84       $next_monday->set_hour(15)->set_minute(00)->set_second(00);
85     my $cp = Koha::CurbsidePickup->new(
86         {
87             branchcode                => $library->branchcode,
88             borrowernumber            => $patron->borrowernumber,
89             scheduled_pickup_datetime => $schedule_dt,
90             notes                     => 'just a note'
91         }
92     )->store;
93     is( $cp->status, 'to-be-staged' );
94
95     throws_ok {
96         Koha::CurbsidePickup->new(
97             {
98                 branchcode                => $library->branchcode,
99                 borrowernumber            => $patron->borrowernumber,
100                 scheduled_pickup_datetime => $schedule_dt,
101                 notes                     => 'just a note'
102             }
103           )->store
104     }
105     'Koha::Exceptions::CurbsidePickup::TooManyPickups',
106       'Cannot create 2 pickups for the same patron';
107
108     $cp->delete;
109
110     # Day is not ok
111     my $next_tuesday =
112       $today->clone->add( days => ( 2 - $today->day_of_week ) % 7 );
113     $schedule_dt = $next_tuesday->set_hour(15)->set_minute(00)->set_second(00);
114     throws_ok {
115         Koha::CurbsidePickup->new(
116             {
117                 branchcode                => $library->branchcode,
118                 borrowernumber            => $patron->borrowernumber,
119                 scheduled_pickup_datetime => $schedule_dt,
120                 notes                     => 'just a note'
121             }
122           )->store
123     }
124     'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
125       'Cannot create a pickup on a day without opening slots defined';
126
127     # Day ok but datetime not ok
128     $schedule_dt = $next_monday->set_hour(19)->set_minute(00)->set_second(00);
129     throws_ok {
130         Koha::CurbsidePickup->new(
131             {
132                 branchcode                => $library->branchcode,
133                 borrowernumber            => $patron->borrowernumber,
134                 scheduled_pickup_datetime => $schedule_dt,
135                 notes                     => 'just a note'
136             }
137           )->store
138     }
139     'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
140       'Cannot create a pickup on a time without opening slots defined';
141
142     # Day ok, datetime inside the opening slot, but wrong (15:15 for instance)
143     $schedule_dt = $next_monday->set_hour(15)->set_minute(15)->set_second(00);
144     throws_ok {
145         Koha::CurbsidePickup->new(
146             {
147                 branchcode                => $library->branchcode,
148                 borrowernumber            => $patron->borrowernumber,
149                 scheduled_pickup_datetime => $schedule_dt,
150                 notes                     => 'just a note'
151             }
152           )->store
153     }
154     'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
155 'Cannot create a pickup on a time that is not matching the start of an interval';
156
157 };
158
159 subtest 'workflow' => sub {
160     plan tests => 9;
161
162     my $pickups =
163       Koha::CurbsidePickups->search( { branchcode => $library->branchcode } );
164
165     my $next_monday =
166       $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
167     my $schedule_dt =
168       $next_monday->set_hour(15)->set_minute(00)->set_second(00);
169     my $cp = Koha::CurbsidePickup->new(
170         {
171             branchcode                => $library->branchcode,
172             borrowernumber            => $patron->borrowernumber,
173             scheduled_pickup_datetime => $schedule_dt,
174             notes                     => 'just a note'
175         }
176     )->store;
177     is( $cp->status, 'to-be-staged' );
178     is( $pickups->filter_by_to_be_staged->count, 1 );
179
180     $cp->mark_as_staged;
181     is( $cp->status, 'staged-and-ready' );
182     is( $pickups->filter_by_staged_and_ready->count, 1 );
183
184     $cp->mark_as_unstaged;
185     is( $cp->status, 'to-be-staged' );
186
187     $cp->mark_as_staged;
188
189     $cp->mark_patron_has_arrived;
190     is( $cp->status, 'patron-is-outside' );
191     is( $pickups->filter_by_patron_outside->count, 1 );
192
193     $cp->mark_as_delivered;
194     is( $cp->status, 'delivered' );
195     is( $pickups->filter_by_delivered->count, 1 );
196 };
197
198 subtest 'mark_as_delivered' => sub {
199     plan tests => 3;
200
201     my $item = $builder->build_sample_item({ library => $library->branchcode });
202     my $reserve_id = C4::Reserves::AddReserve(
203         {
204             branchcode     => $library->branchcode,
205             borrowernumber => $patron->borrowernumber,
206             biblionumber   => $item->biblionumber,
207             priority       => 1,
208             itemnumber     => $item->itemnumber,
209         }
210     );
211     my $hold = Koha::Holds->find($reserve_id);
212     $hold->set_waiting;
213
214     my $next_monday =
215       $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
216     my $schedule_dt =
217       $next_monday->set_hour(15)->set_minute(00)->set_second(00);
218     my $cp = Koha::CurbsidePickup->new(
219         {
220             branchcode                => $library->branchcode,
221             borrowernumber            => $patron->borrowernumber,
222             scheduled_pickup_datetime => $schedule_dt,
223             notes                     => 'just a note'
224         }
225     )->store;
226
227     $cp->mark_as_delivered;
228     $cp->discard_changes;
229     is( t::lib::Dates::compare( $cp->arrival_datetime, dt_from_string), 0, 'Arrival time has been set to now' );
230
231     is( $hold->get_from_storage, undef, 'Hold has been filled' );
232     my $checkout = Koha::Checkouts->find({ itemnumber => $item->itemnumber });
233     is( $checkout->borrowernumber, $patron->borrowernumber, 'Item has correctly been checked out' )
234 };
235
236 $schema->storage->txn_rollback;