Bug 33360: Add Koha::Notice::Util for mail domain limits
[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 => 4;
21 use Test::Exception;
22
23 use C4::Calendar;
24 use Koha::CurbsidePickups;
25 use Koha::CurbsidePickupPolicies;
26 use Koha::Calendar;
27 use Koha::Database;
28 use Koha::DateUtils qw( dt_from_string );
29
30 use t::lib::TestBuilder;
31 use t::lib::Dates;
32 use t::lib::Mocks;
33
34 my $schema = Koha::Database->new->schema;
35 $schema->storage->txn_begin;
36
37 my $builder          = t::lib::TestBuilder->new;
38 my $library          = $builder->build_object( { class => 'Koha::Libraries' } );
39 my $library_disabled = $builder->build_object( { class => 'Koha::Libraries' } );
40 my $logged_in_patron = $builder->build_object(
41     {
42         class => 'Koha::Patrons',
43         value => { branchcode => $library->branchcode }
44     }
45 );
46 t::lib::Mocks::mock_userenv( { patron => $logged_in_patron } );
47 my $patron = $builder->build_object(
48     {
49         class => 'Koha::Patrons',
50         value => { branchcode => $library->branchcode }
51     }
52 );
53
54 my $policy = Koha::CurbsidePickupPolicy->new(
55     {
56         branchcode              => $library->branchcode,
57         enabled                 => 1,
58         enable_waiting_holds_only => 0,
59         pickup_interval         => 15,
60         patrons_per_interval    => 2,
61         patron_scheduled_pickup => 1
62     }
63 )->store;
64 my $policy_disabled = Koha::CurbsidePickupPolicy->new(
65     {
66         branchcode              => $library_disabled->branchcode,
67         enabled                 => 0,
68         enable_waiting_holds_only => 0,
69         pickup_interval         => 30,
70         patrons_per_interval    => 2,
71         patron_scheduled_pickup => 1
72     }
73 )->store;
74
75 # Open Mondays from 12 to 18
76 $policy->add_opening_slot('1-12:00-18:45');
77
78 my $today = dt_from_string;
79
80 subtest 'Create a pickup' => sub {
81     plan tests => 10;
82
83     # Day and datetime are ok
84     my $next_monday =
85       $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
86     my $schedule_dt =
87       $next_monday->set_hour(15)->set_minute(00)->set_second(00);
88     my $params =
89         {
90             branchcode                => $library->branchcode,
91             borrowernumber            => $patron->borrowernumber,
92             scheduled_pickup_datetime => $schedule_dt,
93             notes                     => 'just a note'
94         };
95
96     throws_ok {
97         Koha::CurbsidePickup->new({%$params, branchcode => $library_disabled->branchcode})->store;
98     }
99     'Koha::Exceptions::CurbsidePickup::NotEnabled',
100       'Cannot create pickup if the policy does not allow it';
101
102    $policy->enabled(1)->store;
103
104    $policy->enable_waiting_holds_only(1)->store;
105     throws_ok {
106         Koha::CurbsidePickup->new($params)->store;
107     }
108     'Koha::Exceptions::CurbsidePickup::NoWaitingHolds',
109       'Cannot create pickup for a patron without waiting hold if flag is set';
110
111     $policy->enable_waiting_holds_only(0)->store;
112     my $cp = Koha::CurbsidePickup->new($params)->store;
113     is( $cp->status, 'to-be-staged' );
114     is( $patron->curbside_pickups->count, 1, 'Koha::Patron->curbside_pickups' );
115
116     throws_ok {
117         Koha::CurbsidePickup->new($params)->store
118     }
119     'Koha::Exceptions::CurbsidePickup::TooManyPickups',
120       'Cannot create 2 pickups for the same patron';
121
122     $cp->delete;
123
124     $schedule_dt = $next_monday->set_hour(18)->set_minute(15)->set_second(00);
125     $cp          = Koha::CurbsidePickup->new( { %$params, scheduled_pickup_datetime => $schedule_dt } )->store;
126     ok($cp);
127     $cp->delete;
128
129     # Day is not ok
130     my $next_tuesday =
131       $today->clone->add( days => ( 2 - $today->day_of_week ) % 7 );
132     $schedule_dt = $next_tuesday->set_hour(15)->set_minute(00)->set_second(00);
133     throws_ok {
134         Koha::CurbsidePickup->new({%$params, scheduled_pickup_datetime => $schedule_dt})->store;
135     }
136     'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
137       'Cannot create a pickup on a day without opening slots defined';
138
139     # Day ok but datetime not ok
140     $schedule_dt = $next_monday->set_hour(19)->set_minute(00)->set_second(00);
141     throws_ok {
142         Koha::CurbsidePickup->new({%$params, scheduled_pickup_datetime => $schedule_dt})->store;
143     }
144     'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
145       'Cannot create a pickup on a time without opening slots defined';
146
147     # Day ok, datetime inside the opening slot, but wrong (15:07 for instance)
148     $schedule_dt = $next_monday->set_hour(15)->set_minute(7)->set_second(0);
149     throws_ok {
150         Koha::CurbsidePickup->new({%$params, scheduled_pickup_datetime => $schedule_dt})->store;
151     }
152     'Koha::Exceptions::CurbsidePickup::NoMatchingSlots',
153 'Cannot create a pickup on a time that is not matching the start of an interval';
154
155     # Day is a holiday
156     Koha::Caches->get_instance->flush_all;
157     C4::Calendar->new( branchcode => $library->branchcode )->insert_week_day_holiday(
158         weekday     => 1,
159         title       => '',
160         description => 'Mondays',
161     );
162     my $calendar = Koha::Calendar->new( branchcode => $library->branchcode );
163     throws_ok {
164         Koha::CurbsidePickup->new({%$params, scheduled_pickup_datetime => $schedule_dt})->store;
165     }
166     'Koha::Exceptions::CurbsidePickup::LibraryIsClosed',
167       'Cannot create a pickup on a holiday';
168
169     C4::Context->dbh->do(q{DELETE FROM repeatable_holidays});
170     Koha::Caches->get_instance->flush_all;
171 };
172
173 subtest 'workflow' => sub {
174     plan tests => 11;
175
176     my $pickups =
177       Koha::CurbsidePickups->search( { branchcode => $library->branchcode } );
178
179     my $next_monday =
180       $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
181     my $schedule_dt =
182       $next_monday->set_hour(15)->set_minute(00)->set_second(00);
183     my $cp = Koha::CurbsidePickup->new(
184         {
185             branchcode                => $library->branchcode,
186             borrowernumber            => $patron->borrowernumber,
187             scheduled_pickup_datetime => $schedule_dt,
188             notes                     => 'just a note'
189         }
190     )->store;
191     is( $cp->status, 'to-be-staged' );
192     is( $pickups->filter_by_to_be_staged->count, 1 );
193
194     $cp->mark_as_staged;
195     is( $cp->status, 'staged-and-ready' );
196     is( $pickups->filter_by_staged_and_ready->count, 1 );
197
198     $cp->mark_as_unstaged;
199     is( $cp->status, 'to-be-staged' );
200
201     $cp->mark_as_staged;
202
203     $cp->mark_patron_has_arrived;
204     is( $cp->status, 'patron-is-outside' );
205     is( $pickups->filter_by_patron_outside->count, 1 );
206
207     $cp->mark_as_delivered;
208     is( $cp->status, 'delivered' );
209     is( $pickups->filter_by_delivered->count, 1 );
210
211     is( $pickups->filter_by_scheduled_today->count, 1 );
212     $cp->scheduled_pickup_datetime($today->clone->subtract(days => 1))->store;
213     is( $pickups->filter_by_scheduled_today->count, 0 );
214
215     $cp->delete;
216 };
217
218 subtest 'mark_as_delivered' => sub {
219     plan tests => 3;
220
221     my $item = $builder->build_sample_item({ library => $library->branchcode });
222     my $reserve_id = C4::Reserves::AddReserve(
223         {
224             branchcode     => $library->branchcode,
225             borrowernumber => $patron->borrowernumber,
226             biblionumber   => $item->biblionumber,
227             priority       => 1,
228             itemnumber     => $item->itemnumber,
229         }
230     );
231     my $hold = Koha::Holds->find($reserve_id);
232     $hold->set_waiting;
233
234     my $next_monday =
235       $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
236     my $schedule_dt =
237       $next_monday->set_hour(15)->set_minute(00)->set_second(00);
238     my $cp = Koha::CurbsidePickup->new(
239         {
240             branchcode                => $library->branchcode,
241             borrowernumber            => $patron->borrowernumber,
242             scheduled_pickup_datetime => $schedule_dt,
243             notes                     => 'just a note'
244         }
245     )->store;
246
247     $cp->mark_as_delivered;
248     $cp->discard_changes;
249     is( t::lib::Dates::compare( $cp->arrival_datetime, dt_from_string), 0, 'Arrival time has been set to now' );
250
251     is( $hold->get_from_storage, undef, 'Hold has been filled' );
252     my $checkout = Koha::Checkouts->find({ itemnumber => $item->itemnumber });
253     is( $checkout->borrowernumber, $patron->borrowernumber, 'Item has correctly been checked out' );
254
255     $cp->delete;
256 };
257
258 subtest 'notify_new_pickup' => sub {
259     plan tests => 2;
260
261     my $item =
262       $builder->build_sample_item( { library => $library->branchcode } );
263     my $reserve_id = C4::Reserves::AddReserve(
264         {
265             branchcode     => $library->branchcode,
266             borrowernumber => $patron->borrowernumber,
267             biblionumber   => $item->biblionumber,
268             priority       => 1,
269             itemnumber     => $item->itemnumber,
270         }
271     );
272     my $hold = Koha::Holds->find($reserve_id);
273     $hold->set_waiting;
274
275     my $next_monday =
276       $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
277     my $schedule_dt =
278       $next_monday->set_hour(15)->set_minute(00)->set_second(00);
279     my $cp = Koha::CurbsidePickup->new(
280         {
281             branchcode                => $library->branchcode,
282             borrowernumber            => $patron->borrowernumber,
283             scheduled_pickup_datetime => $schedule_dt,
284             notes                     => 'just a note'
285         }
286     )->store;
287
288     $patron->set( { email => 'test@example.org' } )->store;
289     my $dbh = C4::Context->dbh;
290     $dbh->do( q|INSERT INTO borrower_message_preferences( borrowernumber, message_attribute_id ) VALUES ( ?, ?)|,
291         undef, $patron->borrowernumber, 4
292     );
293     my $borrower_message_preference_id =
294       $dbh->last_insert_id( undef, undef, "borrower_message_preferences", undef );
295     $dbh->do(
296         q|INSERT INTO borrower_message_transport_preferences( borrower_message_preference_id, message_transport_type) VALUES ( ?, ? )|,
297         undef, $borrower_message_preference_id, 'email'
298     );
299
300     $cp->notify_new_pickup;
301
302     my $messages = C4::Letters::GetQueuedMessages(
303         { borrowernumber => $patron->borrowernumber } );
304     is(
305         $messages->[0]->{subject},
306         sprintf ("You have scheduled a curbside pickup for %s", $library->branchname),
307         "Notice correctly generated"
308     );
309     my $biblio_title = $item->biblio->title;
310     like( $messages->[0]->{content},
311         qr{$biblio_title}, "Content contains the list of waiting holds" );
312 };
313
314 $schema->storage->txn_rollback;