3 # This file is part of Koha.
5 # Copyright (C) 2013 Equinox Software, Inc.
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
21 use Test::More tests => 77;
28 my $module = new Test::MockModule('Mail::Sendmail');
37 use_ok('C4::Context');
38 use_ok('C4::Members');
39 use_ok('C4::Acquisition');
41 use_ok('C4::Letters');
43 use t::lib::TestBuilder;
45 use Koha::DateUtils qw( dt_from_string output_pref );
46 use Koha::Acquisition::Booksellers;
47 use Koha::Acquisition::Bookseller::Contacts;
48 use Koha::Acquisition::Orders;
50 use Koha::Notice::Templates;
51 my $schema = Koha::Database->schema;
52 $schema->storage->txn_begin();
54 my $builder = t::lib::TestBuilder->new;
55 my $dbh = C4::Context->dbh;
56 $dbh->{RaiseError} = 1;
58 $dbh->do(q|DELETE FROM letter|);
59 $dbh->do(q|DELETE FROM message_queue|);
60 $dbh->do(q|DELETE FROM message_transport_types|);
62 my $library = $builder->build({
65 my $patron_category = $builder->build({ source => 'Category' })->{categorycode};
66 my $date = dt_from_string;
67 my $borrowernumber = AddMember(
70 categorycode => $patron_category,
71 branchcode => $library->{branchcode},
73 smsalertnumber => undef,
76 my $marc_record = MARC::Record->new;
77 my( $biblionumber, $biblioitemnumber ) = AddBiblio( $marc_record, '' );
81 # GetMessageTransportTypes
82 my $mtts = C4::Letters::GetMessageTransportTypes();
83 is( @$mtts, 0, 'GetMessageTransportTypes returns the correct number of message types' );
86 INSERT INTO message_transport_types( message_transport_type ) VALUES ('email'), ('phone'), ('print'), ('sms')
88 $mtts = C4::Letters::GetMessageTransportTypes();
89 is_deeply( $mtts, ['email', 'phone', 'print', 'sms'], 'GetMessageTransportTypes returns all values' );
93 is( C4::Letters::EnqueueLetter(), undef, 'EnqueueLetter without argument returns undef' );
96 borrowernumber => $borrowernumber,
97 message_transport_type => 'sms',
99 from_address => 'from@example.com',
101 my $message_id = C4::Letters::EnqueueLetter($my_message);
102 is( $message_id, undef, 'EnqueueLetter without the letter argument returns undef' );
104 delete $my_message->{message_transport_type};
105 $my_message->{letter} = {
106 content => 'a message',
107 title => 'message title',
108 metadata => 'metadata',
109 code => 'TEST_MESSAGE',
110 content_type => 'text/plain',
113 $message_id = C4::Letters::EnqueueLetter($my_message);
114 is( $message_id, undef, 'EnqueueLetter without the message type argument argument returns undef' );
116 $my_message->{message_transport_type} = 'sms';
117 $message_id = C4::Letters::EnqueueLetter($my_message);
118 ok(defined $message_id && $message_id > 0, 'new message successfully queued');
122 my $messages = C4::Letters::GetQueuedMessages();
123 is( @$messages, 1, 'GetQueuedMessages without argument returns all the entries' );
125 $messages = C4::Letters::GetQueuedMessages({ borrowernumber => $borrowernumber });
126 is( @$messages, 1, 'one message stored for the borrower' );
127 is( $messages->[0]->{message_id}, $message_id, 'EnqueueLetter returns the message id correctly' );
128 is( $messages->[0]->{borrowernumber}, $borrowernumber, 'EnqueueLetter stores the borrower number correctly' );
129 is( $messages->[0]->{subject}, $my_message->{letter}->{title}, 'EnqueueLetter stores the subject correctly' );
130 is( $messages->[0]->{content}, $my_message->{letter}->{content}, 'EnqueueLetter stores the content correctly' );
131 is( $messages->[0]->{message_transport_type}, $my_message->{message_transport_type}, 'EnqueueLetter stores the message type correctly' );
132 is( $messages->[0]->{status}, 'pending', 'EnqueueLetter stores the status pending correctly' );
136 my $messages_processed = C4::Letters::SendQueuedMessages();
137 is($messages_processed, 1, 'all queued messages processed');
138 $messages = C4::Letters::GetQueuedMessages({ borrowernumber => $borrowernumber });
140 $messages->[0]->{status},
142 'message marked failed if tried to send SMS message for borrower with no smsalertnumber set (bug 11208)'
146 my $resent = C4::Letters::ResendMessage($messages->[0]->{message_id});
147 my $message = C4::Letters::GetMessage( $messages->[0]->{message_id});
148 is( $resent, 1, 'The message should have been resent' );
149 is($message->{status},'pending', 'ResendMessage sets status to pending correctly (bug 12426)');
150 $resent = C4::Letters::ResendMessage($messages->[0]->{message_id});
151 is( $resent, 0, 'The message should not have been resent again' );
152 $resent = C4::Letters::ResendMessage();
153 is( $resent, undef, 'ResendMessage should return undef if not message_id given' );
156 my $letters = C4::Letters::GetLetters();
157 is( @$letters, 0, 'GetLetters returns the correct number of letters' );
159 my $title = q|<<branches.branchname>> - <<status>>|;
160 my $content = q{Dear <<borrowers.firstname>> <<borrowers.surname>>,
161 According to our current records, you have items that are overdue.Your library does not charge late fines, but please return or renew them at the branch below as soon as possible.
163 <<branches.branchname>>
164 <<branches.branchaddress1>>
167 The following item(s) is/are currently <<status>>:
169 <item> <<count>>. <<items.itemcallnumber>>, Barcode: <<items.barcode>> </item>
171 Thank-you for your prompt attention to this matter.
172 Don't forget your date of birth: <<borrowers.dateofbirth>>.
173 Look at this wonderful biblio timestamp: <<biblio.timestamp>>.
176 $dbh->do( q|INSERT INTO letter(branchcode,module,code,name,is_html,title,content,message_transport_type) VALUES (?,'my module','my code','my name',1,?,?,'email')|, undef, $library->{branchcode}, $title, $content );
177 $letters = C4::Letters::GetLetters();
178 is( @$letters, 1, 'GetLetters returns the correct number of letters' );
179 is( $letters->[0]->{branchcode}, $library->{branchcode}, 'GetLetters gets the branch code correctly' );
180 is( $letters->[0]->{module}, 'my module', 'GetLetters gets the module correctly' );
181 is( $letters->[0]->{code}, 'my code', 'GetLetters gets the code correctly' );
182 is( $letters->[0]->{name}, 'my name', 'GetLetters gets the name correctly' );
186 subtest 'getletter' => sub {
188 t::lib::Mocks::mock_preference('IndependentBranches', 0);
189 my $letter = C4::Letters::getletter('my module', 'my code', $library->{branchcode}, 'email');
190 is( $letter->{branchcode}, $library->{branchcode}, 'GetLetters gets the branch code correctly' );
191 is( $letter->{module}, 'my module', 'GetLetters gets the module correctly' );
192 is( $letter->{code}, 'my code', 'GetLetters gets the code correctly' );
193 is( $letter->{name}, 'my name', 'GetLetters gets the name correctly' );
194 is( $letter->{is_html}, 1, 'GetLetters gets the boolean is_html correctly' );
195 is( $letter->{title}, $title, 'GetLetters gets the title correctly' );
196 is( $letter->{content}, $content, 'GetLetters gets the content correctly' );
197 is( $letter->{message_transport_type}, 'email', 'GetLetters gets the message type correctly' );
199 my $context = Test::MockModule->new('C4::Context');
200 $context->mock( 'userenv', sub {
203 branch => "anotherlib" }
206 t::lib::Mocks::mock_preference('IndependentBranches', 1);
207 $letter = C4::Letters::getletter('my module', 'my code', $library->{branchcode}, 'email');
208 is( $letter->{branchcode}, $library->{branchcode}, 'GetLetters gets the branch code correctly' );
209 is( $letter->{module}, 'my module', 'GetLetters gets the module correctly' );
210 is( $letter->{code}, 'my code', 'GetLetters gets the code correctly' );
211 is( $letter->{name}, 'my name', 'GetLetters gets the name correctly' );
212 is( $letter->{is_html}, 1, 'GetLetters gets the boolean is_html correctly' );
213 is( $letter->{title}, $title, 'GetLetters gets the title correctly' );
214 is( $letter->{content}, $content, 'GetLetters gets the content correctly' );
215 is( $letter->{message_transport_type}, 'email', 'GetLetters gets the message type correctly' );
217 $context->unmock('userenv');
222 # Regression test for Bug 14206
223 $dbh->do( q|INSERT INTO letter(branchcode,module,code,name,is_html,title,content,message_transport_type) VALUES ('FFL','my module','my code','my name',1,?,?,'print')|, undef, $title, $content );
224 my $letter14206_a = C4::Letters::getletter('my module', 'my code', 'FFL' );
225 is( $letter14206_a->{message_transport_type}, 'print', 'Bug 14206 - message_transport_type not passed, correct mtt detected' );
226 my $letter14206_b = C4::Letters::getletter('my module', 'my code', 'FFL', 'print');
227 is( $letter14206_b->{message_transport_type}, 'print', 'Bug 14206 - message_transport_type passed, correct mtt detected' );
229 # test for overdue_notices.pl
230 my $overdue_rules = {
231 letter1 => 'my code',
234 my $branchcode = 'FFL';
235 my $letter14206_c = C4::Letters::getletter('my module', $overdue_rules->{"letter$i"}, $branchcode);
236 is( $letter14206_c->{message_transport_type}, 'print', 'Bug 14206 - correct mtt detected for call from overdue_notices.pl' );
239 my $type = 'my type';
240 my $externalid = 'my external id';
241 my $alert_id = C4::Letters::addalert($borrowernumber, $type, $externalid);
242 isnt( $alert_id, undef, 'addalert does not return undef' );
246 my $alerts = C4::Letters::getalert();
247 is( @$alerts, 1, 'getalert should not fail without parameter' );
248 $alerts = C4::Letters::getalert($borrowernumber);
249 is( @$alerts, 1, 'addalert adds an alert' );
250 is( $alerts->[0]->{alertid}, $alert_id, 'addalert returns the alert id correctly' );
251 is( $alerts->[0]->{type}, $type, 'addalert stores the type correctly' );
252 is( $alerts->[0]->{externalid}, $externalid, 'addalert stores the externalid correctly' );
254 $alerts = C4::Letters::getalert($borrowernumber, $type);
255 is( @$alerts, 1, 'getalert returns the correct number of alerts' );
256 $alerts = C4::Letters::getalert($borrowernumber, $type, $externalid);
257 is( @$alerts, 1, 'getalert returns the correct number of alerts' );
258 $alerts = C4::Letters::getalert($borrowernumber, 'another type');
259 is( @$alerts, 0, 'getalert returns the correct number of alerts' );
260 $alerts = C4::Letters::getalert($borrowernumber, $type, 'another external id');
261 is( @$alerts, 0, 'getalert returns the correct number of alerts' );
266 C4::Letters::delalert();
268 isnt( $@, undef, 'delalert without argument returns an error' );
269 $alerts = C4::Letters::getalert($borrowernumber);
270 is( @$alerts, 1, 'delalert without argument does not remove an alert' );
272 C4::Letters::delalert($alert_id);
273 $alerts = C4::Letters::getalert($borrowernumber);
274 is( @$alerts, 0, 'delalert removes an alert' );
278 t::lib::Mocks::mock_preference('OPACBaseURL', 'http://thisisatest.com');
280 my $sms_content = 'This is a SMS for an <<status>>';
281 $dbh->do( q|INSERT INTO letter(branchcode,module,code,name,is_html,title,content,message_transport_type) VALUES (?,'my module','my code','my name',1,'my title',?,'sms')|, undef, $library->{branchcode}, $sms_content );
284 borrowers => $borrowernumber,
285 branches => $library->{branchcode},
286 biblio => $biblionumber,
293 itemcallnumber => 'my callnumber1',
297 itemcallnumber => 'my callnumber2',
301 my $prepared_letter = GetPreparedLetter((
302 module => 'my module',
303 branchcode => $library->{branchcode},
304 letter_code => 'my code',
306 substitute => $substitute,
309 my $retrieved_library = Koha::Libraries->find($library->{branchcode});
310 my $my_title_letter = $retrieved_library->branchname . qq| - $substitute->{status}|;
311 my $biblio_timestamp = dt_from_string( GetBiblioData($biblionumber)->{timestamp} );
312 my $my_content_letter = qq|Dear Jane Smith,
313 According to our current records, you have items that are overdue.Your library does not charge late fines, but please return or renew them at the branch below as soon as possible.
315 |.$retrieved_library->branchname.qq|
316 |.$retrieved_library->branchaddress1.qq|
317 URL: http://thisisatest.com
319 The following item(s) is/are currently $substitute->{status}:
321 <item> 1. $repeat->[0]->{itemcallnumber}, Barcode: $repeat->[0]->{barcode} </item>
322 <item> 2. $repeat->[1]->{itemcallnumber}, Barcode: $repeat->[1]->{barcode} </item>
324 Thank-you for your prompt attention to this matter.
325 Don't forget your date of birth: | . output_pref({ dt => $date, dateonly => 1 }) . q|.
326 Look at this wonderful biblio timestamp: | . output_pref({ dt => $biblio_timestamp }) . ".\n";
328 is( $prepared_letter->{title}, $my_title_letter, 'GetPreparedLetter returns the title correctly' );
329 is( $prepared_letter->{content}, $my_content_letter, 'GetPreparedLetter returns the content correctly' );
331 $prepared_letter = GetPreparedLetter((
332 module => 'my module',
333 branchcode => $library->{branchcode},
334 letter_code => 'my code',
336 substitute => $substitute,
338 message_transport_type => 'sms',
340 $my_content_letter = qq|This is a SMS for an $substitute->{status}|;
341 is( $prepared_letter->{content}, $my_content_letter, 'GetPreparedLetter returns the content correctly' );
343 $dbh->do(q{INSERT INTO letter (module, code, name, title, content) VALUES ('test_date','TEST_DATE','Test dates','A title with a timestamp: <<biblio.timestamp>>','This one only contains the date: <<biblio.timestamp | dateonly>>.');});
344 $prepared_letter = GetPreparedLetter((
345 module => 'test_date',
347 letter_code => 'test_date',
349 substitute => $substitute,
352 is( $prepared_letter->{content}, q|This one only contains the date: | . output_pref({ dt => $date, dateonly => 1 }) . q|.|, 'dateonly test 1' );
354 $dbh->do(q{UPDATE letter SET content = 'And also this one:<<timestamp | dateonly>>.' WHERE code = 'test_date';});
355 $prepared_letter = GetPreparedLetter((
356 module => 'test_date',
358 letter_code => 'test_date',
360 substitute => $substitute,
363 is( $prepared_letter->{content}, q|And also this one:| . output_pref({ dt => $date, dateonly => 1 }) . q|.|, 'dateonly test 2' );
365 $dbh->do(q{UPDATE letter SET content = 'And also this one:<<timestamp|dateonly >>.' WHERE code = 'test_date';});
366 $prepared_letter = GetPreparedLetter((
367 module => 'test_date',
369 letter_code => 'test_date',
371 substitute => $substitute,
374 is( $prepared_letter->{content}, q|And also this one:| . output_pref({ dt => $date, dateonly => 1 }) . q|.|, 'dateonly test 3' );
376 t::lib::Mocks::mock_preference( 'TimeFormat', '12hr' );
377 my $yesterday_night = $date->clone->add( days => -1 )->set_hour(22);
378 $dbh->do(q|UPDATE biblio SET timestamp = ? WHERE biblionumber = ?|, undef, $yesterday_night, $biblionumber );
379 $dbh->do(q{UPDATE letter SET content = 'And also this one:<<timestamp>>.' WHERE code = 'test_date';});
380 $prepared_letter = GetPreparedLetter((
381 module => 'test_date',
383 letter_code => 'test_date',
385 substitute => $substitute,
388 is( $prepared_letter->{content}, q|And also this one:| . output_pref({ dt => $yesterday_night }) . q|.|, 'dateonly test 3' );
390 $dbh->do(q{INSERT INTO letter (module, code, name, title, content) VALUES ('claimacquisition','TESTACQCLAIM','Acquisition Claim','Item Not Received','<<aqbooksellers.name>>|<<aqcontacts.name>>|<order>Ordernumber <<aqorders.ordernumber>> (<<biblio.title>>) (<<aqorders.quantity>> ordered)</order>');});
391 $dbh->do(q{INSERT INTO letter (module, code, name, title, content) VALUES ('orderacquisition','TESTACQORDER','Acquisition Order','Order','<<aqbooksellers.name>>|<<aqcontacts.name>>|<order>Ordernumber <<aqorders.ordernumber>> (<<biblio.title>>) (<<aqorders.quantity>> ordered)</order>');});
393 # Test that _parseletter doesn't modify its parameters bug 15429
395 my $values = { dateexpiry => '2015-12-13', };
396 C4::Letters::_parseletter($prepared_letter, 'borrowers', $values);
397 is( $values->{dateexpiry}, '2015-12-13', "_parseletter doesn't modify its parameters" );
400 my $bookseller = Koha::Acquisition::Bookseller->new(
403 address1 => "bookseller's address",
409 my $booksellerid = $bookseller->id;
411 Koha::Acquisition::Bookseller::Contact->new( { name => 'John Smith', phone => '0123456x1', claimacquisition => 1, orderacquisition => 1, booksellerid => $booksellerid } )->store;
412 Koha::Acquisition::Bookseller::Contact->new( { name => 'Leo Tolstoy', phone => '0123456x2', claimissues => 1, booksellerid => $booksellerid } )->store;
413 my $basketno = NewBasket($booksellerid, 1);
415 my $budgetid = C4::Budgets::AddBudget({
416 budget_code => "budget_code_test_letters",
417 budget_name => "budget_name_test_letters",
420 my $bib = MARC::Record->new();
421 if (C4::Context->preference('marcflavour') eq 'UNIMARC') {
423 MARC::Field->new('200', ' ', ' ', a => 'Silence in the library'),
427 MARC::Field->new('245', ' ', ' ', a => 'Silence in the library'),
431 ($biblionumber, $biblioitemnumber) = AddBiblio($bib, '');
432 my $order = Koha::Acquisition::Order->new(
434 basketno => $basketno,
436 biblionumber => $biblionumber,
437 budget_id => $budgetid,
440 my $ordernumber = $order->ordernumber;
442 C4::Acquisition::CloseBasket( $basketno );
445 $err = SendAlerts( 'claimacquisition', [ $ordernumber ], 'TESTACQCLAIM' ) }
446 qr/^Bookseller .* without emails at/,
447 "SendAlerts prints a warning";
448 is($err->{'error'}, 'no_email', "Trying to send an alert when there's no e-mail results in an error");
450 $bookseller = Koha::Acquisition::Booksellers->find( $booksellerid );
451 $bookseller->contacts->next->email('testemail@mydomain.com')->store;
453 # Ensure that the preference 'LetterLog' is set to logging
454 t::lib::Mocks::mock_preference( 'LetterLog', 'on' );
456 # SendAlerts needs branchemail or KohaAdminEmailAddress as sender
457 C4::Context->_new_userenv('DUMMY');
458 C4::Context->set_userenv( 0, 0, 0, 'firstname', 'surname', $library->{branchcode}, 'My Library', 0, '', '');
459 t::lib::Mocks::mock_preference( 'KohaAdminEmailAddress', 'library@domain.com' );
463 $err = SendAlerts( 'orderacquisition', $basketno , 'TESTACQORDER' ) }
465 "SendAlerts is using the mocked sendmail routine (orderacquisition)";
466 is($err, 1, "Successfully sent order.");
467 is($mail{'To'}, 'testemail@mydomain.com', "mailto correct in sent order");
468 is($mail{'Message'}, 'my vendor|John Smith|Ordernumber ' . $ordernumber . ' (Silence in the library) (1 ordered)', 'Order notice text constructed successfully');
470 $dbh->do(q{DELETE FROM letter WHERE code = 'TESTACQORDER';});
472 $err = SendAlerts( 'orderacquisition', $basketno , 'TESTACQORDER' ) }
473 qr/No orderacquisition TESTACQORDER letter transported by email/,
474 "GetPreparedLetter warns about missing notice template";
475 is($err->{'error'}, 'no_letter', "No TESTACQORDER letter was defined.");
480 $err = SendAlerts( 'claimacquisition', [ $ordernumber ], 'TESTACQCLAIM' ) }
482 "SendAlerts is using the mocked sendmail routine";
484 is($err, 1, "Successfully sent claim");
485 is($mail{'To'}, 'testemail@mydomain.com', "mailto correct in sent claim");
486 is($mail{'Message'}, 'my vendor|John Smith|Ordernumber ' . $ordernumber . ' (Silence in the library) (1 ordered)', 'Claim notice text constructed successfully');
493 my $internalnotes = 'intnotes';
494 $dbh->do(q|UPDATE subscription_numberpatterns SET numberingmethod='No. {X}' WHERE id=1|);
495 my $subscriptionid = NewSubscription(
496 undef, "", undef, undef, undef, $biblionumber,
497 '2013-01-01', 1, undef, undef, undef,
498 undef, undef, undef, undef, undef, undef,
499 1, $notes,undef, '2013-01-01', undef, 1,
500 undef, undef, 0, $internalnotes, 0,
501 undef, undef, 0, undef, '2013-12-31', 0
503 $dbh->do(q{INSERT INTO letter (module, code, name, title, content) VALUES ('serial','RLIST','Serial issue notification','Serial issue notification','<<biblio.title>>,<<subscription.subscriptionid>>,<<serial.serialseq>>');});
504 my ($serials_count, @serials) = GetSerials($subscriptionid);
505 my $serial = $serials[0];
507 my $borrowernumber = AddMember(
510 categorycode => $patron_category,
511 branchcode => $library->{branchcode},
512 dateofbirth => $date,
513 email => 'john.smith@test.de',
515 my $alert_id = C4::Letters::addalert($borrowernumber, 'issue', $subscriptionid);
520 $err2 = SendAlerts( 'issue', $serial->{serialid}, 'RLIST' ) }
522 "SendAlerts is using the mocked sendmail routine";
523 is($err2, 1, "Successfully sent serial notification");
524 is($mail{'To'}, 'john.smith@test.de', "mailto correct in sent serial notification");
525 is($mail{'Message'}, 'Silence in the library,'.$subscriptionid.',No. 0', 'Serial notification text constructed successfully');
528 subtest 'GetPreparedLetter' => sub {
531 Koha::Notice::Template->new(
536 message_transport_type => 'email'
541 $letter = C4::Letters::GetPreparedLetter(
543 letter_code => 'test',
546 qr{^ERROR: nothing to substitute},
547 'GetPreparedLetter should warn if tables, substiture and repeat are not set';
549 'No letter should be returned by GetPreparedLetter if something went wrong'
553 $letter = C4::Letters::GetPreparedLetter(
555 letter_code => 'test',
559 qr{^ERROR: nothing to substitute},
560 'GetPreparedLetter should warn if tables, substiture and repeat are not set, even if the key is passed';
562 'No letter should be returned by GetPreparedLetter if something went wrong'
569 subtest 'TranslateNotices' => sub {
572 t::lib::Mocks::mock_preference( 'TranslateNotices', '1' );
576 INSERT INTO letter (module, code, branchcode, name, title, content, message_transport_type, lang) VALUES
577 ('test', 'code', '', 'test', 'a test', 'just a test', 'email', 'default'),
578 ('test', 'code', '', 'test', 'una prueba', 'solo una prueba', 'email', 'es-ES');
581 my $letter = C4::Letters::GetPreparedLetter(
584 letter_code => 'code',
585 message_transport_type => 'email',
586 substitute => $substitute,
591 'GetPreparedLetter should return the default one if the lang parameter is not provided'
594 $letter = C4::Letters::GetPreparedLetter(
597 letter_code => 'code',
598 message_transport_type => 'email',
599 substitute => $substitute,
602 is( $letter->{title}, 'una prueba',
603 'GetPreparedLetter should return the required notice if it exists' );
605 $letter = C4::Letters::GetPreparedLetter(
608 letter_code => 'code',
609 message_transport_type => 'email',
610 substitute => $substitute,
616 'GetPreparedLetter should return the default notice if the one required does not exist'
619 t::lib::Mocks::mock_preference( 'TranslateNotices', '' );
621 $letter = C4::Letters::GetPreparedLetter(
624 letter_code => 'code',
625 message_transport_type => 'email',
626 substitute => $substitute,
629 is( $letter->{title}, 'a test',
630 'GetPreparedLetter should return the default notice if pref disabled but additional language exists' );
634 subtest 'SendQueuedMessages' => sub {
637 t::lib::Mocks::mock_preference( 'SMSSendDriver', 'Email' );
638 my $patron = Koha::Patrons->find($borrowernumber);
640 INSERT INTO message_queue(borrowernumber, subject, content, message_transport_type, status, letter_code)
641 VALUES (?, 'subject', 'content', 'sms', 'pending', 'just_a_code')
642 |, undef, $borrowernumber
644 eval { C4::Letters::SendQueuedMessages(); };
645 is( $@, '', 'SendQueuedMessages should not explode if the patron does not have a sms provider set' );
647 my $sms_pro = $builder->build_object({ class => 'Koha::SMS::Providers', value => { domain => 'kidclamp.rocks' } });
648 ModMember( borrowernumber => $borrowernumber, smsalertnumber => '5555555555', sms_provider_id => $sms_pro->id() );
649 $message_id = C4::Letters::EnqueueLetter($my_message); #using datas set around line 95 and forward
650 C4::Letters::SendQueuedMessages();
651 my $sms_message_address = $schema->resultset('MessageQueue')->search({
652 borrowernumber => $borrowernumber,
654 })->next()->to_address();
655 is( $sms_message_address, '5555555555@kidclamp.rocks', 'SendQueuedMessages populates the to address correctly for SMS by email' );
658 subtest 'get_item_content' => sub {
661 t::lib::Mocks::mock_preference('dateformat', 'metric');
662 t::lib::Mocks::mock_preference('timeformat', '24hr');
664 {date_due => '2041-01-01 12:34', title => 'a first title', barcode => 'a_first_barcode', author => 'a_first_author', itemnumber => 1 },
665 {date_due => '2042-01-02 23:45', title => 'a second title', barcode => 'a_second_barcode', author => 'a_second_author', itemnumber => 2 },
667 my @item_content_fields = qw( date_due title barcode author itemnumber );
670 for my $item ( @items ) {
671 $items_content .= C4::Letters::get_item_content( { item => $item, item_content_fields => \@item_content_fields } );
674 my $expected_items_content = <<EOF;
675 01/01/2041 12:34\ta first title\ta_first_barcode\ta_first_author\t1
676 02/01/2042 23:45\ta second title\ta_second_barcode\ta_second_author\t2
678 is( $items_content, $expected_items_content, 'get_item_content should return correct items info with time (default)' );
681 $items_content = q||;
682 for my $item ( @items ) {
683 $items_content .= C4::Letters::get_item_content( { item => $item, item_content_fields => \@item_content_fields, dateonly => 1, } );
686 $expected_items_content = <<EOF;
687 01/01/2041\ta first title\ta_first_barcode\ta_first_author\t1
688 02/01/2042\ta second title\ta_second_barcode\ta_second_author\t2
690 is( $items_content, $expected_items_content, 'get_item_content should return correct items info without time (if dateonly => 1)' );
693 subtest 'Test limit parameter for SendQueuedMessages' => sub {
696 my $dbh = C4::Context->dbh;
698 my $borrowernumber = AddMember(
701 categorycode => $patron_category,
702 branchcode => $library->{branchcode},
703 dateofbirth => $date,
704 smsalertnumber => undef,
707 $dbh->do(q|DELETE FROM message_queue|);
710 'content' => 'a message',
711 'metadata' => 'metadata',
712 'code' => 'TEST_MESSAGE',
713 'content_type' => 'text/plain',
714 'title' => 'message title'
716 'borrowernumber' => $borrowernumber,
717 'to_address' => undef,
718 'message_transport_type' => 'sms',
719 'from_address' => 'from@example.com'
721 C4::Letters::EnqueueLetter($my_message);
722 C4::Letters::EnqueueLetter($my_message);
723 C4::Letters::EnqueueLetter($my_message);
724 C4::Letters::EnqueueLetter($my_message);
725 C4::Letters::EnqueueLetter($my_message);
726 my $messages_processed = C4::Letters::SendQueuedMessages( { limit => 1 } );
727 is( $messages_processed, 1,
728 'Processed 1 message with limit of 1 and 5 unprocessed messages' );
729 $messages_processed = C4::Letters::SendQueuedMessages( { limit => 2 } );
730 is( $messages_processed, 2,
731 'Processed 2 message with limit of 2 and 4 unprocessed messages' );
732 $messages_processed = C4::Letters::SendQueuedMessages( { limit => 3 } );
733 is( $messages_processed, 2,
734 'Processed 2 message with limit of 3 and 2 unprocessed messages' );