Bug 19042: Add mock IndependentBranches=0 for the other test
[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     t::lib::Mocks::mock_preference('IndependentBranches', 0);
188     my $letter = C4::Letters::getletter('my module', 'my code', $library->{branchcode}, 'email');
189     is( $letter->{branchcode}, $library->{branchcode}, 'GetLetters gets the branch code correctly' );
190     is( $letter->{module}, 'my module', 'GetLetters gets the module correctly' );
191     is( $letter->{code}, 'my code', 'GetLetters gets the code correctly' );
192     is( $letter->{name}, 'my name', 'GetLetters gets the name correctly' );
193     is( $letter->{is_html}, 1, 'GetLetters gets the boolean is_html correctly' );
194     is( $letter->{title}, $title, 'GetLetters gets the title correctly' );
195     is( $letter->{content}, $content, 'GetLetters gets the content correctly' );
196     is( $letter->{message_transport_type}, 'email', 'GetLetters gets the message type correctly' );
197
198     my $context = Test::MockModule->new('C4::Context');
199     $context->mock( 'userenv', sub {
200         return {
201             flags  => 1,
202             branch => "anotherlib" }
203     });
204
205     t::lib::Mocks::mock_preference('IndependentBranches', 1);
206     $letter = C4::Letters::getletter('my module', 'my code', $library->{branchcode}, 'email');
207     is( $letter->{branchcode}, $library->{branchcode}, 'GetLetters gets the branch code correctly' );
208     is( $letter->{module}, 'my module', 'GetLetters gets the module correctly' );
209     is( $letter->{code}, 'my code', 'GetLetters gets the code correctly' );
210     is( $letter->{name}, 'my name', 'GetLetters gets the name correctly' );
211     is( $letter->{is_html}, 1, 'GetLetters gets the boolean is_html correctly' );
212     is( $letter->{title}, $title, 'GetLetters gets the title correctly' );
213     is( $letter->{content}, $content, 'GetLetters gets the content correctly' );
214     is( $letter->{message_transport_type}, 'email', 'GetLetters gets the message type correctly' );
215
216     $context->unmock('userenv');
217 };
218
219
220
221 # Regression test for Bug 14206
222 $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 );
223 my $letter14206_a = C4::Letters::getletter('my module', 'my code', 'FFL' );
224 is( $letter14206_a->{message_transport_type}, 'print', 'Bug 14206 - message_transport_type not passed, correct mtt detected' );
225 my $letter14206_b = C4::Letters::getletter('my module', 'my code', 'FFL', 'print');
226 is( $letter14206_b->{message_transport_type}, 'print', 'Bug 14206 - message_transport_type passed, correct mtt detected'  );
227
228 # test for overdue_notices.pl
229 my $overdue_rules = {
230     letter1         => 'my code',
231 };
232 my $i = 1;
233 my $branchcode = 'FFL';
234 my $letter14206_c = C4::Letters::getletter('my module', $overdue_rules->{"letter$i"}, $branchcode);
235 is( $letter14206_c->{message_transport_type}, 'print', 'Bug 14206 - correct mtt detected for call from overdue_notices.pl' );
236
237 # addalert
238 my $type = 'my type';
239 my $externalid = 'my external id';
240 my $alert_id = C4::Letters::addalert($borrowernumber, $type, $externalid);
241 isnt( $alert_id, undef, 'addalert does not return undef' );
242
243
244 # getalert
245 my $alerts = C4::Letters::getalert();
246 is( @$alerts, 1, 'getalert should not fail without parameter' );
247 $alerts = C4::Letters::getalert($borrowernumber);
248 is( @$alerts, 1, 'addalert adds an alert' );
249 is( $alerts->[0]->{alertid}, $alert_id, 'addalert returns the alert id correctly' );
250 is( $alerts->[0]->{type}, $type, 'addalert stores the type correctly' );
251 is( $alerts->[0]->{externalid}, $externalid, 'addalert stores the externalid correctly' );
252
253 $alerts = C4::Letters::getalert($borrowernumber, $type);
254 is( @$alerts, 1, 'getalert returns the correct number of alerts' );
255 $alerts = C4::Letters::getalert($borrowernumber, $type, $externalid);
256 is( @$alerts, 1, 'getalert returns the correct number of alerts' );
257 $alerts = C4::Letters::getalert($borrowernumber, 'another type');
258 is( @$alerts, 0, 'getalert returns the correct number of alerts' );
259 $alerts = C4::Letters::getalert($borrowernumber, $type, 'another external id');
260 is( @$alerts, 0, 'getalert returns the correct number of alerts' );
261
262
263 # delalert
264 eval {
265     C4::Letters::delalert();
266 };
267 isnt( $@, undef, 'delalert without argument returns an error' );
268 $alerts = C4::Letters::getalert($borrowernumber);
269 is( @$alerts, 1, 'delalert without argument does not remove an alert' );
270
271 C4::Letters::delalert($alert_id);
272 $alerts = C4::Letters::getalert($borrowernumber);
273 is( @$alerts, 0, 'delalert removes an alert' );
274
275
276 # GetPreparedLetter
277 t::lib::Mocks::mock_preference('OPACBaseURL', 'http://thisisatest.com');
278
279 my $sms_content = 'This is a SMS for an <<status>>';
280 $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 );
281
282 my $tables = {
283     borrowers => $borrowernumber,
284     branches => $library->{branchcode},
285     biblio => $biblionumber,
286 };
287 my $substitute = {
288     status => 'overdue',
289 };
290 my $repeat = [
291     {
292         itemcallnumber => 'my callnumber1',
293         barcode        => '1234',
294     },
295     {
296         itemcallnumber => 'my callnumber2',
297         barcode        => '5678',
298     },
299 ];
300 my $prepared_letter = GetPreparedLetter((
301     module      => 'my module',
302     branchcode  => $library->{branchcode},
303     letter_code => 'my code',
304     tables      => $tables,
305     substitute  => $substitute,
306     repeat      => $repeat,
307 ));
308 my $retrieved_library = Koha::Libraries->find($library->{branchcode});
309 my $my_title_letter = $retrieved_library->branchname . qq| - $substitute->{status}|;
310 my $biblio_timestamp = dt_from_string( GetBiblioData($biblionumber)->{timestamp} );
311 my $my_content_letter = qq|Dear Jane Smith,
312 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.
313
314 |.$retrieved_library->branchname.qq|
315 |.$retrieved_library->branchaddress1.qq|
316 URL: http://thisisatest.com
317
318 The following item(s) is/are currently $substitute->{status}:
319
320 <item> 1. $repeat->[0]->{itemcallnumber}, Barcode: $repeat->[0]->{barcode} </item>
321 <item> 2. $repeat->[1]->{itemcallnumber}, Barcode: $repeat->[1]->{barcode} </item>
322
323 Thank-you for your prompt attention to this matter.
324 Don't forget your date of birth: | . output_pref({ dt => $date, dateonly => 1 }) . q|.
325 Look at this wonderful biblio timestamp: | . output_pref({ dt => $biblio_timestamp })  . ".\n";
326
327 is( $prepared_letter->{title}, $my_title_letter, 'GetPreparedLetter returns the title correctly' );
328 is( $prepared_letter->{content}, $my_content_letter, 'GetPreparedLetter returns the content correctly' );
329
330 $prepared_letter = GetPreparedLetter((
331     module                 => 'my module',
332     branchcode             => $library->{branchcode},
333     letter_code            => 'my code',
334     tables                 => $tables,
335     substitute             => $substitute,
336     repeat                 => $repeat,
337     message_transport_type => 'sms',
338 ));
339 $my_content_letter = qq|This is a SMS for an $substitute->{status}|;
340 is( $prepared_letter->{content}, $my_content_letter, 'GetPreparedLetter returns the content correctly' );
341
342 $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>>.');});
343 $prepared_letter = GetPreparedLetter((
344     module                 => 'test_date',
345     branchcode             => '',
346     letter_code            => 'test_date',
347     tables                 => $tables,
348     substitute             => $substitute,
349     repeat                 => $repeat,
350 ));
351 is( $prepared_letter->{content}, q|This one only contains the date: | . output_pref({ dt => $date, dateonly => 1 }) . q|.|, 'dateonly test 1' );
352
353 $dbh->do(q{UPDATE letter SET content = 'And also this one:<<timestamp | dateonly>>.' WHERE code = 'test_date';});
354 $prepared_letter = GetPreparedLetter((
355     module                 => 'test_date',
356     branchcode             => '',
357     letter_code            => 'test_date',
358     tables                 => $tables,
359     substitute             => $substitute,
360     repeat                 => $repeat,
361 ));
362 is( $prepared_letter->{content}, q|And also this one:| . output_pref({ dt => $date, dateonly => 1 }) . q|.|, 'dateonly test 2' );
363
364 $dbh->do(q{UPDATE letter SET content = 'And also this one:<<timestamp|dateonly >>.' WHERE code = 'test_date';});
365 $prepared_letter = GetPreparedLetter((
366     module                 => 'test_date',
367     branchcode             => '',
368     letter_code            => 'test_date',
369     tables                 => $tables,
370     substitute             => $substitute,
371     repeat                 => $repeat,
372 ));
373 is( $prepared_letter->{content}, q|And also this one:| . output_pref({ dt => $date, dateonly => 1 }) . q|.|, 'dateonly test 3' );
374
375 t::lib::Mocks::mock_preference( 'TimeFormat', '12hr' );
376 my $yesterday_night = $date->clone->add( days => -1 )->set_hour(22);
377 $dbh->do(q|UPDATE biblio SET timestamp = ? WHERE biblionumber = ?|, undef, $yesterday_night, $biblionumber );
378 $dbh->do(q{UPDATE letter SET content = 'And also this one:<<timestamp>>.' WHERE code = 'test_date';});
379 $prepared_letter = GetPreparedLetter((
380     module                 => 'test_date',
381     branchcode             => '',
382     letter_code            => 'test_date',
383     tables                 => $tables,
384     substitute             => $substitute,
385     repeat                 => $repeat,
386 ));
387 is( $prepared_letter->{content}, q|And also this one:| . output_pref({ dt => $yesterday_night }) . q|.|, 'dateonly test 3' );
388
389 $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>');});
390 $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>');});
391
392 # Test that _parseletter doesn't modify its parameters bug 15429
393 {
394     my $values = { dateexpiry => '2015-12-13', };
395     C4::Letters::_parseletter($prepared_letter, 'borrowers', $values);
396     is( $values->{dateexpiry}, '2015-12-13', "_parseletter doesn't modify its parameters" );
397 }
398
399 my $bookseller = Koha::Acquisition::Bookseller->new(
400     {
401         name => "my vendor",
402         address1 => "bookseller's address",
403         phone => "0123456",
404         active => 1,
405         deliverytime => 5,
406     }
407 )->store;
408 my $booksellerid = $bookseller->id;
409
410 Koha::Acquisition::Bookseller::Contact->new( { name => 'John Smith',  phone => '0123456x1', claimacquisition => 1, orderacquisition => 1, booksellerid => $booksellerid } )->store;
411 Koha::Acquisition::Bookseller::Contact->new( { name => 'Leo Tolstoy', phone => '0123456x2', claimissues      => 1, booksellerid => $booksellerid } )->store;
412 my $basketno = NewBasket($booksellerid, 1);
413
414 my $budgetid = C4::Budgets::AddBudget({
415     budget_code => "budget_code_test_letters",
416     budget_name => "budget_name_test_letters",
417 });
418
419 my $bib = MARC::Record->new();
420 if (C4::Context->preference('marcflavour') eq 'UNIMARC') {
421     $bib->append_fields(
422         MARC::Field->new('200', ' ', ' ', a => 'Silence in the library'),
423     );
424 } else {
425     $bib->append_fields(
426         MARC::Field->new('245', ' ', ' ', a => 'Silence in the library'),
427     );
428 }
429
430 ($biblionumber, $biblioitemnumber) = AddBiblio($bib, '');
431 my $order = Koha::Acquisition::Order->new(
432     {
433         basketno => $basketno,
434         quantity => 1,
435         biblionumber => $biblionumber,
436         budget_id => $budgetid,
437     }
438 )->insert;
439 my $ordernumber = $order->{ordernumber};
440
441 C4::Acquisition::CloseBasket( $basketno );
442 my $err;
443 warning_like {
444     $err = SendAlerts( 'claimacquisition', [ $ordernumber ], 'TESTACQCLAIM' ) }
445     qr/^Bookseller .* without emails at/,
446     "SendAlerts prints a warning";
447 is($err->{'error'}, 'no_email', "Trying to send an alert when there's no e-mail results in an error");
448
449 $bookseller = Koha::Acquisition::Booksellers->find( $booksellerid );
450 $bookseller->contacts->next->email('testemail@mydomain.com')->store;
451
452 # Ensure that the preference 'LetterLog' is set to logging
453 t::lib::Mocks::mock_preference( 'LetterLog', 'on' );
454
455 # SendAlerts needs branchemail or KohaAdminEmailAddress as sender
456 C4::Context->_new_userenv('DUMMY');
457 C4::Context->set_userenv( 0, 0, 0, 'firstname', 'surname', $library->{branchcode}, 'My Library', 0, '', '');
458 t::lib::Mocks::mock_preference( 'KohaAdminEmailAddress', 'library@domain.com' );
459
460 {
461 warning_is {
462     $err = SendAlerts( 'orderacquisition', $basketno , 'TESTACQORDER' ) }
463     "Fake sendmail",
464     "SendAlerts is using the mocked sendmail routine (orderacquisition)";
465 is($err, 1, "Successfully sent order.");
466 is($mail{'To'}, 'testemail@mydomain.com', "mailto correct in sent order");
467 is($mail{'Message'}, 'my vendor|John Smith|Ordernumber ' . $ordernumber . ' (Silence in the library) (1 ordered)', 'Order notice text constructed successfully');
468
469 $dbh->do(q{DELETE FROM letter WHERE code = 'TESTACQORDER';});
470 warning_like {
471     $err = SendAlerts( 'orderacquisition', $basketno , 'TESTACQORDER' ) }
472     qr/No orderacquisition TESTACQORDER letter transported by email/,
473     "GetPreparedLetter warns about missing notice template";
474 is($err->{'error'}, 'no_letter', "No TESTACQORDER letter was defined.");
475 }
476
477 {
478 warning_is {
479     $err = SendAlerts( 'claimacquisition', [ $ordernumber ], 'TESTACQCLAIM' ) }
480     "Fake sendmail",
481     "SendAlerts is using the mocked sendmail routine";
482
483 is($err, 1, "Successfully sent claim");
484 is($mail{'To'}, 'testemail@mydomain.com', "mailto correct in sent claim");
485 is($mail{'Message'}, 'my vendor|John Smith|Ordernumber ' . $ordernumber . ' (Silence in the library) (1 ordered)', 'Claim notice text constructed successfully');
486 }
487
488 {
489 use C4::Serials;
490
491 my $notes = 'notes';
492 my $internalnotes = 'intnotes';
493 $dbh->do(q|UPDATE subscription_numberpatterns SET numberingmethod='No. {X}' WHERE id=1|);
494 my $subscriptionid = NewSubscription(
495      undef,      "",     undef, undef, undef, $biblionumber,
496     '2013-01-01', 1, undef, undef,  undef,
497     undef,      undef,  undef, undef, undef, undef,
498     1,          $notes,undef, '2013-01-01', undef, 1,
499     undef,       undef,  0,    $internalnotes,  0,
500     undef, undef, 0,          undef,         '2013-12-31', 0
501 );
502 $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>>');});
503 my ($serials_count, @serials) = GetSerials($subscriptionid);
504 my $serial = $serials[0];
505
506 my $borrowernumber = AddMember(
507     firstname    => 'John',
508     surname      => 'Smith',
509     categorycode => $patron_category,
510     branchcode   => $library->{branchcode},
511     dateofbirth  => $date,
512     email        => 'john.smith@test.de',
513 );
514 my $alert_id = C4::Letters::addalert($borrowernumber, 'issue', $subscriptionid);
515
516
517 my $err2;
518 warning_is {
519 $err2 = SendAlerts( 'issue', $serial->{serialid}, 'RLIST' ) }
520     "Fake sendmail",
521     "SendAlerts is using the mocked sendmail routine";
522 is($err2, 1, "Successfully sent serial notification");
523 is($mail{'To'}, 'john.smith@test.de', "mailto correct in sent serial notification");
524 is($mail{'Message'}, 'Silence in the library,'.$subscriptionid.',No. 0', 'Serial notification text constructed successfully');
525 }
526
527 subtest 'GetPreparedLetter' => sub {
528     plan tests => 4;
529
530     Koha::Notice::Template->new(
531         {
532             module                 => 'test',
533             code                   => 'test',
534             branchcode             => '',
535             message_transport_type => 'email'
536         }
537     )->store;
538     my $letter;
539     warning_like {
540         $letter = C4::Letters::GetPreparedLetter(
541             module      => 'test',
542             letter_code => 'test',
543         );
544     }
545     qr{^ERROR: nothing to substitute},
546 'GetPreparedLetter should warn if tables, substiture and repeat are not set';
547     is( $letter, undef,
548 'No letter should be returned by GetPreparedLetter if something went wrong'
549     );
550
551     warning_like {
552         $letter = C4::Letters::GetPreparedLetter(
553             module      => 'test',
554             letter_code => 'test',
555             substitute  => {}
556         );
557     }
558     qr{^ERROR: nothing to substitute},
559 'GetPreparedLetter should warn if tables, substiture and repeat are not set, even if the key is passed';
560     is( $letter, undef,
561 'No letter should be returned by GetPreparedLetter if something went wrong'
562     );
563
564 };
565
566
567
568 subtest 'TranslateNotices' => sub {
569     plan tests => 4;
570
571     t::lib::Mocks::mock_preference( 'TranslateNotices', '1' );
572
573     $dbh->do(
574         q|
575         INSERT INTO letter (module, code, branchcode, name, title, content, message_transport_type, lang) VALUES
576         ('test', 'code', '', 'test', 'a test', 'just a test', 'email', 'default'),
577         ('test', 'code', '', 'test', 'una prueba', 'solo una prueba', 'email', 'es-ES');
578     | );
579     my $substitute = {};
580     my $letter = C4::Letters::GetPreparedLetter(
581             module                 => 'test',
582             tables                 => $tables,
583             letter_code            => 'code',
584             message_transport_type => 'email',
585             substitute             => $substitute,
586     );
587     is(
588         $letter->{title},
589         'a test',
590         'GetPreparedLetter should return the default one if the lang parameter is not provided'
591     );
592
593     $letter = C4::Letters::GetPreparedLetter(
594             module                 => 'test',
595             tables                 => $tables,
596             letter_code            => 'code',
597             message_transport_type => 'email',
598             substitute             => $substitute,
599             lang                   => 'es-ES',
600     );
601     is( $letter->{title}, 'una prueba',
602         'GetPreparedLetter should return the required notice if it exists' );
603
604     $letter = C4::Letters::GetPreparedLetter(
605             module                 => 'test',
606             tables                 => $tables,
607             letter_code            => 'code',
608             message_transport_type => 'email',
609             substitute             => $substitute,
610             lang                   => 'fr-FR',
611     );
612     is(
613         $letter->{title},
614         'a test',
615         'GetPreparedLetter should return the default notice if the one required does not exist'
616     );
617
618     t::lib::Mocks::mock_preference( 'TranslateNotices', '' );
619
620     $letter = C4::Letters::GetPreparedLetter(
621             module                 => 'test',
622             tables                 => $tables,
623             letter_code            => 'code',
624             message_transport_type => 'email',
625             substitute             => $substitute,
626             lang                   => 'es-ES',
627     );
628     is( $letter->{title}, 'a test',
629         'GetPreparedLetter should return the default notice if pref disabled but additional language exists' );
630
631 };
632
633 subtest 'SendQueuedMessages' => sub {
634
635     plan tests => 2;
636     t::lib::Mocks::mock_preference( 'SMSSendDriver', 'Email' );
637     my $patron = Koha::Patrons->find($borrowernumber);
638     $dbh->do(q|
639         INSERT INTO message_queue(borrowernumber, subject, content, message_transport_type, status, letter_code)
640         VALUES (?, 'subject', 'content', 'sms', 'pending', 'just_a_code')
641         |, undef, $borrowernumber
642     );
643     eval { C4::Letters::SendQueuedMessages(); };
644     is( $@, '', 'SendQueuedMessages should not explode if the patron does not have a sms provider set' );
645
646     my $sms_pro = $builder->build_object({ class => 'Koha::SMS::Providers', value => { domain => 'kidclamp.rocks' } });
647     ModMember( borrowernumber => $borrowernumber, smsalertnumber => '5555555555', sms_provider_id => $sms_pro->id() );
648     $message_id = C4::Letters::EnqueueLetter($my_message); #using datas set around line 95 and forward
649     C4::Letters::SendQueuedMessages();
650     my $sms_message_address = $schema->resultset('MessageQueue')->search({
651         borrowernumber => $borrowernumber,
652         status => 'sent'
653     })->next()->to_address();
654     is( $sms_message_address, '5555555555@kidclamp.rocks', 'SendQueuedMessages populates the to address correctly for SMS by email' );
655
656 };