Bug 18613: Add unit tests for getletter
[koha.git] / t / db_dependent / Letters.t
1 #!/usr/bin/perl
2
3 # This file is part of Koha.
4 #
5 # Copyright (C) 2013 Equinox Software, Inc.
6 #
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.
11 #
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.
16 #
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>.
19
20 use Modern::Perl;
21 use Test::More tests => 75;
22 use Test::MockModule;
23 use Test::Warn;
24
25 use MARC::Record;
26
27 my %mail;
28 my $module = new Test::MockModule('Mail::Sendmail');
29 $module->mock(
30     'sendmail',
31     sub {
32         warn "Fake sendmail";
33         %mail = @_;
34     }
35 );
36
37 use_ok('C4::Context');
38 use_ok('C4::Members');
39 use_ok('C4::Acquisition');
40 use_ok('C4::Biblio');
41 use_ok('C4::Letters');
42 use t::lib::Mocks;
43 use t::lib::TestBuilder;
44 use Koha::Database;
45 use Koha::DateUtils qw( dt_from_string output_pref );
46 use Koha::Acquisition::Order;
47 use Koha::Acquisition::Booksellers;
48 use Koha::Acquisition::Bookseller::Contacts;
49 use Koha::Libraries;
50 use Koha::Notice::Templates;
51 my $schema = Koha::Database->schema;
52 $schema->storage->txn_begin();
53
54 my $builder = t::lib::TestBuilder->new;
55 my $dbh = C4::Context->dbh;
56 $dbh->{RaiseError} = 1;
57
58 $dbh->do(q|DELETE FROM letter|);
59 $dbh->do(q|DELETE FROM message_queue|);
60 $dbh->do(q|DELETE FROM message_transport_types|);
61
62 my $library = $builder->build({
63     source => 'Branch',
64 });
65 my $patron_category = $builder->build({ source => 'Category' })->{categorycode};
66 my $date = dt_from_string;
67 my $borrowernumber = AddMember(
68     firstname    => 'Jane',
69     surname      => 'Smith',
70     categorycode => $patron_category,
71     branchcode   => $library->{branchcode},
72     dateofbirth  => $date,
73     smsalertnumber => undef,
74 );
75
76 my $marc_record = MARC::Record->new;
77 my( $biblionumber, $biblioitemnumber ) = AddBiblio( $marc_record, '' );
78
79
80
81 # GetMessageTransportTypes
82 my $mtts = C4::Letters::GetMessageTransportTypes();
83 is( @$mtts, 0, 'GetMessageTransportTypes returns the correct number of message types' );
84
85 $dbh->do(q|
86     INSERT INTO message_transport_types( message_transport_type ) VALUES ('email'), ('phone'), ('print'), ('sms')
87 |);
88 $mtts = C4::Letters::GetMessageTransportTypes();
89 is_deeply( $mtts, ['email', 'phone', 'print', 'sms'], 'GetMessageTransportTypes returns all values' );
90
91
92 # EnqueueLetter
93 is( C4::Letters::EnqueueLetter(), undef, 'EnqueueLetter without argument returns undef' );
94
95 my $my_message = {
96     borrowernumber         => $borrowernumber,
97     message_transport_type => 'sms',
98     to_address             => undef,
99     from_address           => 'from@example.com',
100 };
101 my $message_id = C4::Letters::EnqueueLetter($my_message);
102 is( $message_id, undef, 'EnqueueLetter without the letter argument returns undef' );
103
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',
111 };
112 $message_id = C4::Letters::EnqueueLetter($my_message);
113 is( $message_id, undef, 'EnqueueLetter without the message type argument argument returns undef' );
114
115 $my_message->{message_transport_type} = 'sms';
116 $message_id = C4::Letters::EnqueueLetter($my_message);
117 ok(defined $message_id && $message_id > 0, 'new message successfully queued');
118
119
120 # GetQueuedMessages
121 my $messages = C4::Letters::GetQueuedMessages();
122 is( @$messages, 1, 'GetQueuedMessages without argument returns all the entries' );
123
124 $messages = C4::Letters::GetQueuedMessages({ borrowernumber => $borrowernumber });
125 is( @$messages, 1, 'one message stored for the borrower' );
126 is( $messages->[0]->{message_id}, $message_id, 'EnqueueLetter returns the message id correctly' );
127 is( $messages->[0]->{borrowernumber}, $borrowernumber, 'EnqueueLetter stores the borrower number correctly' );
128 is( $messages->[0]->{subject}, $my_message->{letter}->{title}, 'EnqueueLetter stores the subject correctly' );
129 is( $messages->[0]->{content}, $my_message->{letter}->{content}, 'EnqueueLetter stores the content correctly' );
130 is( $messages->[0]->{message_transport_type}, $my_message->{message_transport_type}, 'EnqueueLetter stores the message type correctly' );
131 is( $messages->[0]->{status}, 'pending', 'EnqueueLetter stores the status pending correctly' );
132
133
134 # SendQueuedMessages
135 my $messages_processed = C4::Letters::SendQueuedMessages();
136 is($messages_processed, 1, 'all queued messages processed');
137 $messages = C4::Letters::GetQueuedMessages({ borrowernumber => $borrowernumber });
138 is(
139     $messages->[0]->{status},
140     'failed',
141     'message marked failed if tried to send SMS message for borrower with no smsalertnumber set (bug 11208)'
142 );
143
144 # ResendMessage
145 my $resent = C4::Letters::ResendMessage($messages->[0]->{message_id});
146 my $message = C4::Letters::GetMessage( $messages->[0]->{message_id});
147 is( $resent, 1, 'The message should have been resent' );
148 is($message->{status},'pending', 'ResendMessage sets status to pending correctly (bug 12426)');
149 $resent = C4::Letters::ResendMessage($messages->[0]->{message_id});
150 is( $resent, 0, 'The message should not have been resent again' );
151 $resent = C4::Letters::ResendMessage();
152 is( $resent, undef, 'ResendMessage should return undef if not message_id given' );
153
154 # GetLetters
155 my $letters = C4::Letters::GetLetters();
156 is( @$letters, 0, 'GetLetters returns the correct number of letters' );
157
158 my $title = q|<<branches.branchname>> - <<status>>|;
159 my $content = q{Dear <<borrowers.firstname>> <<borrowers.surname>>,
160 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.
161
162 <<branches.branchname>>
163 <<branches.branchaddress1>>
164 URL: <<OPACBaseURL>>
165
166 The following item(s) is/are currently <<status>>:
167
168 <item> <<count>>. <<items.itemcallnumber>>, Barcode: <<items.barcode>> </item>
169
170 Thank-you for your prompt attention to this matter.
171 Don't forget your date of birth: <<borrowers.dateofbirth>>.
172 Look at this wonderful biblio timestamp: <<biblio.timestamp>>.
173 };
174
175 $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 );
176 $letters = C4::Letters::GetLetters();
177 is( @$letters, 1, 'GetLetters returns the correct number of letters' );
178 is( $letters->[0]->{branchcode}, $library->{branchcode}, 'GetLetters gets the branch code correctly' );
179 is( $letters->[0]->{module}, 'my module', 'GetLetters gets the module correctly' );
180 is( $letters->[0]->{code}, 'my code', 'GetLetters gets the code correctly' );
181 is( $letters->[0]->{name}, 'my name', 'GetLetters gets the name correctly' );
182
183
184 # getletter
185 subtest 'getletter' => sub {
186     plan tests => 16;
187     my $letter = C4::Letters::getletter('my module', 'my code', $library->{branchcode}, 'email');
188     is( $letter->{branchcode}, $library->{branchcode}, 'GetLetters gets the branch code correctly' );
189     is( $letter->{module}, 'my module', 'GetLetters gets the module correctly' );
190     is( $letter->{code}, 'my code', 'GetLetters gets the code correctly' );
191     is( $letter->{name}, 'my name', 'GetLetters gets the name correctly' );
192     is( $letter->{is_html}, 1, 'GetLetters gets the boolean is_html correctly' );
193     is( $letter->{title}, $title, 'GetLetters gets the title correctly' );
194     is( $letter->{content}, $content, 'GetLetters gets the content correctly' );
195     is( $letter->{message_transport_type}, 'email', 'GetLetters gets the message type correctly' );
196
197     my $context = Test::MockModule->new('C4::Context');
198     $context->mock( 'userenv', sub {
199         return { branch => "anotherlib" }
200     });
201
202     t::lib::Mocks::mock_preference('IndependentBranches', 1);
203     $letter = C4::Letters::getletter('my module', 'my code', $library->{branchcode}, 'email');
204     is( $letter->{branchcode}, $library->{branchcode}, 'GetLetters gets the branch code correctly' );
205     is( $letter->{module}, 'my module', 'GetLetters gets the module correctly' );
206     is( $letter->{code}, 'my code', 'GetLetters gets the code correctly' );
207     is( $letter->{name}, 'my name', 'GetLetters gets the name correctly' );
208     is( $letter->{is_html}, 1, 'GetLetters gets the boolean is_html correctly' );
209     is( $letter->{title}, $title, 'GetLetters gets the title correctly' );
210     is( $letter->{content}, $content, 'GetLetters gets the content correctly' );
211     is( $letter->{message_transport_type}, 'email', 'GetLetters gets the message type correctly' );
212
213     $context->unmock('userenv');
214 };
215
216
217
218 # Regression test for Bug 14206
219 $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 );
220 my $letter14206_a = C4::Letters::getletter('my module', 'my code', 'FFL' );
221 is( $letter14206_a->{message_transport_type}, 'print', 'Bug 14206 - message_transport_type not passed, correct mtt detected' );
222 my $letter14206_b = C4::Letters::getletter('my module', 'my code', 'FFL', 'print');
223 is( $letter14206_b->{message_transport_type}, 'print', 'Bug 14206 - message_transport_type passed, correct mtt detected'  );
224
225 # test for overdue_notices.pl
226 my $overdue_rules = {
227     letter1         => 'my code',
228 };
229 my $i = 1;
230 my $branchcode = 'FFL';
231 my $letter14206_c = C4::Letters::getletter('my module', $overdue_rules->{"letter$i"}, $branchcode);
232 is( $letter14206_c->{message_transport_type}, 'print', 'Bug 14206 - correct mtt detected for call from overdue_notices.pl' );
233
234 # addalert
235 my $type = 'my type';
236 my $externalid = 'my external id';
237 my $alert_id = C4::Letters::addalert($borrowernumber, $type, $externalid);
238 isnt( $alert_id, undef, 'addalert does not return undef' );
239
240
241 # getalert
242 my $alerts = C4::Letters::getalert();
243 is( @$alerts, 1, 'getalert should not fail without parameter' );
244 $alerts = C4::Letters::getalert($borrowernumber);
245 is( @$alerts, 1, 'addalert adds an alert' );
246 is( $alerts->[0]->{alertid}, $alert_id, 'addalert returns the alert id correctly' );
247 is( $alerts->[0]->{type}, $type, 'addalert stores the type correctly' );
248 is( $alerts->[0]->{externalid}, $externalid, 'addalert stores the externalid correctly' );
249
250 $alerts = C4::Letters::getalert($borrowernumber, $type);
251 is( @$alerts, 1, 'getalert returns the correct number of alerts' );
252 $alerts = C4::Letters::getalert($borrowernumber, $type, $externalid);
253 is( @$alerts, 1, 'getalert returns the correct number of alerts' );
254 $alerts = C4::Letters::getalert($borrowernumber, 'another type');
255 is( @$alerts, 0, 'getalert returns the correct number of alerts' );
256 $alerts = C4::Letters::getalert($borrowernumber, $type, 'another external id');
257 is( @$alerts, 0, 'getalert returns the correct number of alerts' );
258
259
260 # delalert
261 eval {
262     C4::Letters::delalert();
263 };
264 isnt( $@, undef, 'delalert without argument returns an error' );
265 $alerts = C4::Letters::getalert($borrowernumber);
266 is( @$alerts, 1, 'delalert without argument does not remove an alert' );
267
268 C4::Letters::delalert($alert_id);
269 $alerts = C4::Letters::getalert($borrowernumber);
270 is( @$alerts, 0, 'delalert removes an alert' );
271
272
273 # GetPreparedLetter
274 t::lib::Mocks::mock_preference('OPACBaseURL', 'http://thisisatest.com');
275
276 my $sms_content = 'This is a SMS for an <<status>>';
277 $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 );
278
279 my $tables = {
280     borrowers => $borrowernumber,
281     branches => $library->{branchcode},
282     biblio => $biblionumber,
283 };
284 my $substitute = {
285     status => 'overdue',
286 };
287 my $repeat = [
288     {
289         itemcallnumber => 'my callnumber1',
290         barcode        => '1234',
291     },
292     {
293         itemcallnumber => 'my callnumber2',
294         barcode        => '5678',
295     },
296 ];
297 my $prepared_letter = GetPreparedLetter((
298     module      => 'my module',
299     branchcode  => $library->{branchcode},
300     letter_code => 'my code',
301     tables      => $tables,
302     substitute  => $substitute,
303     repeat      => $repeat,
304 ));
305 my $retrieved_library = Koha::Libraries->find($library->{branchcode});
306 my $my_title_letter = $retrieved_library->branchname . qq| - $substitute->{status}|;
307 my $biblio_timestamp = dt_from_string( GetBiblioData($biblionumber)->{timestamp} );
308 my $my_content_letter = qq|Dear Jane Smith,
309 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.
310
311 |.$retrieved_library->branchname.qq|
312 |.$retrieved_library->branchaddress1.qq|
313 URL: http://thisisatest.com
314
315 The following item(s) is/are currently $substitute->{status}:
316
317 <item> 1. $repeat->[0]->{itemcallnumber}, Barcode: $repeat->[0]->{barcode} </item>
318 <item> 2. $repeat->[1]->{itemcallnumber}, Barcode: $repeat->[1]->{barcode} </item>
319
320 Thank-you for your prompt attention to this matter.
321 Don't forget your date of birth: | . output_pref({ dt => $date, dateonly => 1 }) . q|.
322 Look at this wonderful biblio timestamp: | . output_pref({ dt => $biblio_timestamp })  . ".\n";
323
324 is( $prepared_letter->{title}, $my_title_letter, 'GetPreparedLetter returns the title correctly' );
325 is( $prepared_letter->{content}, $my_content_letter, 'GetPreparedLetter returns the content correctly' );
326
327 $prepared_letter = GetPreparedLetter((
328     module                 => 'my module',
329     branchcode             => $library->{branchcode},
330     letter_code            => 'my code',
331     tables                 => $tables,
332     substitute             => $substitute,
333     repeat                 => $repeat,
334     message_transport_type => 'sms',
335 ));
336 $my_content_letter = qq|This is a SMS for an $substitute->{status}|;
337 is( $prepared_letter->{content}, $my_content_letter, 'GetPreparedLetter returns the content correctly' );
338
339 $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>>.');});
340 $prepared_letter = GetPreparedLetter((
341     module                 => 'test_date',
342     branchcode             => '',
343     letter_code            => 'test_date',
344     tables                 => $tables,
345     substitute             => $substitute,
346     repeat                 => $repeat,
347 ));
348 is( $prepared_letter->{content}, q|This one only contains the date: | . output_pref({ dt => $date, dateonly => 1 }) . q|.|, 'dateonly test 1' );
349
350 $dbh->do(q{UPDATE letter SET content = 'And also this one:<<timestamp | dateonly>>.' WHERE code = 'test_date';});
351 $prepared_letter = GetPreparedLetter((
352     module                 => 'test_date',
353     branchcode             => '',
354     letter_code            => 'test_date',
355     tables                 => $tables,
356     substitute             => $substitute,
357     repeat                 => $repeat,
358 ));
359 is( $prepared_letter->{content}, q|And also this one:| . output_pref({ dt => $date, dateonly => 1 }) . q|.|, 'dateonly test 2' );
360
361 $dbh->do(q{UPDATE letter SET content = 'And also this one:<<timestamp|dateonly >>.' WHERE code = 'test_date';});
362 $prepared_letter = GetPreparedLetter((
363     module                 => 'test_date',
364     branchcode             => '',
365     letter_code            => 'test_date',
366     tables                 => $tables,
367     substitute             => $substitute,
368     repeat                 => $repeat,
369 ));
370 is( $prepared_letter->{content}, q|And also this one:| . output_pref({ dt => $date, dateonly => 1 }) . q|.|, 'dateonly test 3' );
371
372 t::lib::Mocks::mock_preference( 'TimeFormat', '12hr' );
373 my $yesterday_night = $date->clone->add( days => -1 )->set_hour(22);
374 $dbh->do(q|UPDATE biblio SET timestamp = ? WHERE biblionumber = ?|, undef, $yesterday_night, $biblionumber );
375 $dbh->do(q{UPDATE letter SET content = 'And also this one:<<timestamp>>.' WHERE code = 'test_date';});
376 $prepared_letter = GetPreparedLetter((
377     module                 => 'test_date',
378     branchcode             => '',
379     letter_code            => 'test_date',
380     tables                 => $tables,
381     substitute             => $substitute,
382     repeat                 => $repeat,
383 ));
384 is( $prepared_letter->{content}, q|And also this one:| . output_pref({ dt => $yesterday_night }) . q|.|, 'dateonly test 3' );
385
386 $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>');});
387 $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>');});
388
389 # Test that _parseletter doesn't modify its parameters bug 15429
390 {
391     my $values = { dateexpiry => '2015-12-13', };
392     C4::Letters::_parseletter($prepared_letter, 'borrowers', $values);
393     is( $values->{dateexpiry}, '2015-12-13', "_parseletter doesn't modify its parameters" );
394 }
395
396 my $bookseller = Koha::Acquisition::Bookseller->new(
397     {
398         name => "my vendor",
399         address1 => "bookseller's address",
400         phone => "0123456",
401         active => 1,
402         deliverytime => 5,
403     }
404 )->store;
405 my $booksellerid = $bookseller->id;
406
407 Koha::Acquisition::Bookseller::Contact->new( { name => 'John Smith',  phone => '0123456x1', claimacquisition => 1, orderacquisition => 1, booksellerid => $booksellerid } )->store;
408 Koha::Acquisition::Bookseller::Contact->new( { name => 'Leo Tolstoy', phone => '0123456x2', claimissues      => 1, booksellerid => $booksellerid } )->store;
409 my $basketno = NewBasket($booksellerid, 1);
410
411 my $budgetid = C4::Budgets::AddBudget({
412     budget_code => "budget_code_test_letters",
413     budget_name => "budget_name_test_letters",
414 });
415
416 my $bib = MARC::Record->new();
417 if (C4::Context->preference('marcflavour') eq 'UNIMARC') {
418     $bib->append_fields(
419         MARC::Field->new('200', ' ', ' ', a => 'Silence in the library'),
420     );
421 } else {
422     $bib->append_fields(
423         MARC::Field->new('245', ' ', ' ', a => 'Silence in the library'),
424     );
425 }
426
427 ($biblionumber, $biblioitemnumber) = AddBiblio($bib, '');
428 my $order = Koha::Acquisition::Order->new(
429     {
430         basketno => $basketno,
431         quantity => 1,
432         biblionumber => $biblionumber,
433         budget_id => $budgetid,
434     }
435 )->insert;
436 my $ordernumber = $order->{ordernumber};
437
438 C4::Acquisition::CloseBasket( $basketno );
439 my $err;
440 warning_like {
441     $err = SendAlerts( 'claimacquisition', [ $ordernumber ], 'TESTACQCLAIM' ) }
442     qr/^Bookseller .* without emails at/,
443     "SendAlerts prints a warning";
444 is($err->{'error'}, 'no_email', "Trying to send an alert when there's no e-mail results in an error");
445
446 $bookseller = Koha::Acquisition::Booksellers->find( $booksellerid );
447 $bookseller->contacts->next->email('testemail@mydomain.com')->store;
448
449 # Ensure that the preference 'LetterLog' is set to logging
450 t::lib::Mocks::mock_preference( 'LetterLog', 'on' );
451
452 # SendAlerts needs branchemail or KohaAdminEmailAddress as sender
453 C4::Context->_new_userenv('DUMMY');
454 C4::Context->set_userenv( 0, 0, 0, 'firstname', 'surname', $library->{branchcode}, 'My Library', 0, '', '');
455 t::lib::Mocks::mock_preference( 'KohaAdminEmailAddress', 'library@domain.com' );
456
457 {
458 warning_is {
459     $err = SendAlerts( 'orderacquisition', $basketno , 'TESTACQORDER' ) }
460     "Fake sendmail",
461     "SendAlerts is using the mocked sendmail routine (orderacquisition)";
462 is($err, 1, "Successfully sent order.");
463 is($mail{'To'}, 'testemail@mydomain.com', "mailto correct in sent order");
464 is($mail{'Message'}, 'my vendor|John Smith|Ordernumber ' . $ordernumber . ' (Silence in the library) (1 ordered)', 'Order notice text constructed successfully');
465
466 $dbh->do(q{DELETE FROM letter WHERE code = 'TESTACQORDER';});
467 warning_like {
468     $err = SendAlerts( 'orderacquisition', $basketno , 'TESTACQORDER' ) }
469     qr/No orderacquisition TESTACQORDER letter transported by email/,
470     "GetPreparedLetter warns about missing notice template";
471 is($err->{'error'}, 'no_letter', "No TESTACQORDER letter was defined.");
472 }
473
474 {
475 warning_is {
476     $err = SendAlerts( 'claimacquisition', [ $ordernumber ], 'TESTACQCLAIM' ) }
477     "Fake sendmail",
478     "SendAlerts is using the mocked sendmail routine";
479
480 is($err, 1, "Successfully sent claim");
481 is($mail{'To'}, 'testemail@mydomain.com', "mailto correct in sent claim");
482 is($mail{'Message'}, 'my vendor|John Smith|Ordernumber ' . $ordernumber . ' (Silence in the library) (1 ordered)', 'Claim notice text constructed successfully');
483 }
484
485 {
486 use C4::Serials;
487
488 my $notes = 'notes';
489 my $internalnotes = 'intnotes';
490 $dbh->do(q|UPDATE subscription_numberpatterns SET numberingmethod='No. {X}' WHERE id=1|);
491 my $subscriptionid = NewSubscription(
492      undef,      "",     undef, undef, undef, $biblionumber,
493     '2013-01-01', 1, undef, undef,  undef,
494     undef,      undef,  undef, undef, undef, undef,
495     1,          $notes,undef, '2013-01-01', undef, 1,
496     undef,       undef,  0,    $internalnotes,  0,
497     undef, undef, 0,          undef,         '2013-12-31', 0
498 );
499 $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>>');});
500 my ($serials_count, @serials) = GetSerials($subscriptionid);
501 my $serial = $serials[0];
502
503 my $borrowernumber = AddMember(
504     firstname    => 'John',
505     surname      => 'Smith',
506     categorycode => $patron_category,
507     branchcode   => $library->{branchcode},
508     dateofbirth  => $date,
509     email        => 'john.smith@test.de',
510 );
511 my $alert_id = C4::Letters::addalert($borrowernumber, 'issue', $subscriptionid);
512
513
514 my $err2;
515 warning_is {
516 $err2 = SendAlerts( 'issue', $serial->{serialid}, 'RLIST' ) }
517     "Fake sendmail",
518     "SendAlerts is using the mocked sendmail routine";
519 is($err2, 1, "Successfully sent serial notification");
520 is($mail{'To'}, 'john.smith@test.de', "mailto correct in sent serial notification");
521 is($mail{'Message'}, 'Silence in the library,'.$subscriptionid.',No. 0', 'Serial notification text constructed successfully');
522 }
523
524 subtest 'GetPreparedLetter' => sub {
525     plan tests => 4;
526
527     Koha::Notice::Template->new(
528         {
529             module                 => 'test',
530             code                   => 'test',
531             branchcode             => '',
532             message_transport_type => 'email'
533         }
534     )->store;
535     my $letter;
536     warning_like {
537         $letter = C4::Letters::GetPreparedLetter(
538             module      => 'test',
539             letter_code => 'test',
540         );
541     }
542     qr{^ERROR: nothing to substitute},
543 'GetPreparedLetter should warn if tables, substiture and repeat are not set';
544     is( $letter, undef,
545 'No letter should be returned by GetPreparedLetter if something went wrong'
546     );
547
548     warning_like {
549         $letter = C4::Letters::GetPreparedLetter(
550             module      => 'test',
551             letter_code => 'test',
552             substitute  => {}
553         );
554     }
555     qr{^ERROR: nothing to substitute},
556 'GetPreparedLetter should warn if tables, substiture and repeat are not set, even if the key is passed';
557     is( $letter, undef,
558 'No letter should be returned by GetPreparedLetter if something went wrong'
559     );
560
561 };
562
563
564
565 subtest 'TranslateNotices' => sub {
566     plan tests => 4;
567
568     t::lib::Mocks::mock_preference( 'TranslateNotices', '1' );
569
570     $dbh->do(
571         q|
572         INSERT INTO letter (module, code, branchcode, name, title, content, message_transport_type, lang) VALUES
573         ('test', 'code', '', 'test', 'a test', 'just a test', 'email', 'default'),
574         ('test', 'code', '', 'test', 'una prueba', 'solo una prueba', 'email', 'es-ES');
575     | );
576     my $substitute = {};
577     my $letter = C4::Letters::GetPreparedLetter(
578             module                 => 'test',
579             tables                 => $tables,
580             letter_code            => 'code',
581             message_transport_type => 'email',
582             substitute             => $substitute,
583     );
584     is(
585         $letter->{title},
586         'a test',
587         'GetPreparedLetter should return the default one if the lang parameter is not provided'
588     );
589
590     $letter = C4::Letters::GetPreparedLetter(
591             module                 => 'test',
592             tables                 => $tables,
593             letter_code            => 'code',
594             message_transport_type => 'email',
595             substitute             => $substitute,
596             lang                   => 'es-ES',
597     );
598     is( $letter->{title}, 'una prueba',
599         'GetPreparedLetter should return the required notice if it exists' );
600
601     $letter = C4::Letters::GetPreparedLetter(
602             module                 => 'test',
603             tables                 => $tables,
604             letter_code            => 'code',
605             message_transport_type => 'email',
606             substitute             => $substitute,
607             lang                   => 'fr-FR',
608     );
609     is(
610         $letter->{title},
611         'a test',
612         'GetPreparedLetter should return the default notice if the one required does not exist'
613     );
614
615     t::lib::Mocks::mock_preference( 'TranslateNotices', '' );
616
617     $letter = C4::Letters::GetPreparedLetter(
618             module                 => 'test',
619             tables                 => $tables,
620             letter_code            => 'code',
621             message_transport_type => 'email',
622             substitute             => $substitute,
623             lang                   => 'es-ES',
624     );
625     is( $letter->{title}, 'a test',
626         'GetPreparedLetter should return the default notice if pref disabled but additional language exists' );
627
628 };
629
630 subtest 'SendQueuedMessages' => sub {
631
632     plan tests => 2;
633     t::lib::Mocks::mock_preference( 'SMSSendDriver', 'Email' );
634     my $patron = Koha::Patrons->find($borrowernumber);
635     $dbh->do(q|
636         INSERT INTO message_queue(borrowernumber, subject, content, message_transport_type, status, letter_code)
637         VALUES (?, 'subject', 'content', 'sms', 'pending', 'just_a_code')
638         |, undef, $borrowernumber
639     );
640     eval { C4::Letters::SendQueuedMessages(); };
641     is( $@, '', 'SendQueuedMessages should not explode if the patron does not have a sms provider set' );
642
643     my $sms_pro = $builder->build_object({ class => 'Koha::SMS::Providers', value => { domain => 'kidclamp.rocks' } });
644     ModMember( borrowernumber => $borrowernumber, smsalertnumber => '5555555555', sms_provider_id => $sms_pro->id() );
645     $message_id = C4::Letters::EnqueueLetter($my_message); #using datas set around line 95 and forward
646     C4::Letters::SendQueuedMessages();
647     my $sms_message_address = $schema->resultset('MessageQueue')->search({
648         borrowernumber => $borrowernumber,
649         status => 'sent'
650     })->next()->to_address();
651     is( $sms_message_address, '5555555555@kidclamp.rocks', 'SendQueuedMessages populates the to address correctly for SMS by email' );
652
653 };