Bug 19855: Remove $type from the alerts
[koha.git] / t / db_dependent / Letters.t
index e1d67a6..69a9d30 100644 (file)
@@ -18,7 +18,7 @@
 # along with Koha; if not, see <http://www.gnu.org/licenses>.
 
 use Modern::Perl;
-use Test::More tests => 81;
+use Test::More tests => 75;
 use Test::MockModule;
 use Test::Warn;
 
@@ -43,9 +43,9 @@ use t::lib::Mocks;
 use t::lib::TestBuilder;
 use Koha::Database;
 use Koha::DateUtils qw( dt_from_string output_pref );
-use Koha::Acquisition::Order;
 use Koha::Acquisition::Booksellers;
 use Koha::Acquisition::Bookseller::Contacts;
+use Koha::Acquisition::Orders;
 use Koha::Libraries;
 use Koha::Notice::Templates;
 my $schema = Koha::Database->schema;
@@ -70,11 +70,14 @@ my $borrowernumber = AddMember(
     categorycode => $patron_category,
     branchcode   => $library->{branchcode},
     dateofbirth  => $date,
+    smsalertnumber => undef,
 );
 
 my $marc_record = MARC::Record->new;
 my( $biblionumber, $biblioitemnumber ) = AddBiblio( $marc_record, '' );
 
+
+
 # GetMessageTransportTypes
 my $mtts = C4::Letters::GetMessageTransportTypes();
 is( @$mtts, 0, 'GetMessageTransportTypes returns the correct number of message types' );
@@ -92,7 +95,7 @@ is( C4::Letters::EnqueueLetter(), undef, 'EnqueueLetter without argument returns
 my $my_message = {
     borrowernumber         => $borrowernumber,
     message_transport_type => 'sms',
-    to_address             => 'to@example.com',
+    to_address             => undef,
     from_address           => 'from@example.com',
 };
 my $message_id = C4::Letters::EnqueueLetter($my_message);
@@ -106,6 +109,7 @@ $my_message->{letter} = {
     code         => 'TEST_MESSAGE',
     content_type => 'text/plain',
 };
+
 $message_id = C4::Letters::EnqueueLetter($my_message);
 is( $message_id, undef, 'EnqueueLetter without the message type argument argument returns undef' );
 
@@ -129,9 +133,10 @@ is( $messages->[0]->{status}, 'pending', 'EnqueueLetter stores the status pendin
 
 
 # SendQueuedMessages
-my $messages_processed = C4::Letters::SendQueuedMessages();
-is($messages_processed, 1, 'all queued messages processed');
-
+my $messages_processed = C4::Letters::SendQueuedMessages( { type => 'email' });
+is($messages_processed, 0, 'No queued messages processed if type limit passed with unused type');
+$messages_processed = C4::Letters::SendQueuedMessages( { type => 'sms' });
+is($messages_processed, 1, 'All queued messages processed, found correct number of messages with type limit');
 $messages = C4::Letters::GetQueuedMessages({ borrowernumber => $borrowernumber });
 is(
     $messages->[0]->{status},
@@ -173,22 +178,47 @@ Look at this wonderful biblio timestamp: <<biblio.timestamp>>.
 $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 );
 $letters = C4::Letters::GetLetters();
 is( @$letters, 1, 'GetLetters returns the correct number of letters' );
-is( $letters->[0]->{branchcode}, $library->{branchcode}, 'GetLetters gets the branch code correctly' );
 is( $letters->[0]->{module}, 'my module', 'GetLetters gets the module correctly' );
 is( $letters->[0]->{code}, 'my code', 'GetLetters gets the code correctly' );
 is( $letters->[0]->{name}, 'my name', 'GetLetters gets the name correctly' );
 
 
 # getletter
-my $letter = C4::Letters::getletter('my module', 'my code', $library->{branchcode}, 'email');
-is( $letter->{branchcode}, $library->{branchcode}, 'GetLetters gets the branch code correctly' );
-is( $letter->{module}, 'my module', 'GetLetters gets the module correctly' );
-is( $letter->{code}, 'my code', 'GetLetters gets the code correctly' );
-is( $letter->{name}, 'my name', 'GetLetters gets the name correctly' );
-is( $letter->{is_html}, 1, 'GetLetters gets the boolean is_html correctly' );
-is( $letter->{title}, $title, 'GetLetters gets the title correctly' );
-is( $letter->{content}, $content, 'GetLetters gets the content correctly' );
-is( $letter->{message_transport_type}, 'email', 'GetLetters gets the message type correctly' );
+subtest 'getletter' => sub {
+    plan tests => 16;
+    t::lib::Mocks::mock_preference('IndependentBranches', 0);
+    my $letter = C4::Letters::getletter('my module', 'my code', $library->{branchcode}, 'email');
+    is( $letter->{branchcode}, $library->{branchcode}, 'GetLetters gets the branch code correctly' );
+    is( $letter->{module}, 'my module', 'GetLetters gets the module correctly' );
+    is( $letter->{code}, 'my code', 'GetLetters gets the code correctly' );
+    is( $letter->{name}, 'my name', 'GetLetters gets the name correctly' );
+    is( $letter->{is_html}, 1, 'GetLetters gets the boolean is_html correctly' );
+    is( $letter->{title}, $title, 'GetLetters gets the title correctly' );
+    is( $letter->{content}, $content, 'GetLetters gets the content correctly' );
+    is( $letter->{message_transport_type}, 'email', 'GetLetters gets the message type correctly' );
+
+    my $context = Test::MockModule->new('C4::Context');
+    $context->mock( 'userenv', sub {
+        return {
+            flags  => 1,
+            branch => "anotherlib" }
+    });
+
+    t::lib::Mocks::mock_preference('IndependentBranches', 1);
+    $letter = C4::Letters::getletter('my module', 'my code', $library->{branchcode}, 'email');
+    is( $letter->{branchcode}, $library->{branchcode}, 'GetLetters gets the branch code correctly' );
+    is( $letter->{module}, 'my module', 'GetLetters gets the module correctly' );
+    is( $letter->{code}, 'my code', 'GetLetters gets the code correctly' );
+    is( $letter->{name}, 'my name', 'GetLetters gets the name correctly' );
+    is( $letter->{is_html}, 1, 'GetLetters gets the boolean is_html correctly' );
+    is( $letter->{title}, $title, 'GetLetters gets the title correctly' );
+    is( $letter->{content}, $content, 'GetLetters gets the content correctly' );
+    is( $letter->{message_transport_type}, 'email', 'GetLetters gets the message type correctly' );
+
+    $context->unmock('userenv');
+};
+
+
 
 # Regression test for Bug 14206
 $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 );
@@ -207,9 +237,8 @@ my $letter14206_c = C4::Letters::getletter('my module', $overdue_rules->{"letter
 is( $letter14206_c->{message_transport_type}, 'print', 'Bug 14206 - correct mtt detected for call from overdue_notices.pl' );
 
 # addalert
-my $type = 'my type';
 my $externalid = 'my external id';
-my $alert_id = C4::Letters::addalert($borrowernumber, $type, $externalid);
+my $alert_id = C4::Letters::addalert($borrowernumber, $externalid);
 isnt( $alert_id, undef, 'addalert does not return undef' );
 
 
@@ -219,16 +248,13 @@ is( @$alerts, 1, 'getalert should not fail without parameter' );
 $alerts = C4::Letters::getalert($borrowernumber);
 is( @$alerts, 1, 'addalert adds an alert' );
 is( $alerts->[0]->{alertid}, $alert_id, 'addalert returns the alert id correctly' );
-is( $alerts->[0]->{type}, $type, 'addalert stores the type correctly' );
 is( $alerts->[0]->{externalid}, $externalid, 'addalert stores the externalid correctly' );
 
-$alerts = C4::Letters::getalert($borrowernumber, $type);
+$alerts = C4::Letters::getalert($borrowernumber);
 is( @$alerts, 1, 'getalert returns the correct number of alerts' );
-$alerts = C4::Letters::getalert($borrowernumber, $type, $externalid);
+$alerts = C4::Letters::getalert($borrowernumber, $externalid);
 is( @$alerts, 1, 'getalert returns the correct number of alerts' );
-$alerts = C4::Letters::getalert($borrowernumber, 'another type');
-is( @$alerts, 0, 'getalert returns the correct number of alerts' );
-$alerts = C4::Letters::getalert($borrowernumber, $type, 'another external id');
+$alerts = C4::Letters::getalert($borrowernumber, 'another external id');
 is( @$alerts, 0, 'getalert returns the correct number of alerts' );
 
 
@@ -279,6 +305,7 @@ my $prepared_letter = GetPreparedLetter((
 ));
 my $retrieved_library = Koha::Libraries->find($library->{branchcode});
 my $my_title_letter = $retrieved_library->branchname . qq| - $substitute->{status}|;
+my $biblio_timestamp = dt_from_string( GetBiblioData($biblionumber)->{timestamp} );
 my $my_content_letter = qq|Dear Jane Smith,
 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.
 
@@ -293,7 +320,7 @@ The following item(s) is/are currently $substitute->{status}:
 
 Thank-you for your prompt attention to this matter.
 Don't forget your date of birth: | . output_pref({ dt => $date, dateonly => 1 }) . q|.
-Look at this wonderful biblio timestamp: | . output_pref({ dt => $date }) . ".\n";
+Look at this wonderful biblio timestamp: | . output_pref({ dt => $biblio_timestamp })  . ".\n";
 
 is( $prepared_letter->{title}, $my_title_letter, 'GetPreparedLetter returns the title correctly' );
 is( $prepared_letter->{content}, $my_content_letter, 'GetPreparedLetter returns the content correctly' );
@@ -406,8 +433,8 @@ my $order = Koha::Acquisition::Order->new(
         biblionumber => $biblionumber,
         budget_id => $budgetid,
     }
-)->insert;
-my $ordernumber = $order->{ordernumber};
+)->store;
+my $ordernumber = $order->ordernumber;
 
 C4::Acquisition::CloseBasket( $basketno );
 my $err;
@@ -445,45 +472,6 @@ warning_like {
 is($err->{'error'}, 'no_letter', "No TESTACQORDER letter was defined.");
 }
 
-subtest 'GetPreparedLetter' => sub {
-    plan tests => 4;
-
-    Koha::Notice::Template->new(
-        {
-            module                 => 'test',
-            code                   => 'test',
-            branchcode             => '',
-            message_transport_type => 'email'
-        }
-    )->store;
-    my $letter;
-    warning_like {
-        $letter = C4::Letters::GetPreparedLetter(
-            module      => 'test',
-            letter_code => 'test',
-        );
-    }
-    qr{^ERROR: nothing to substitute},
-'GetPreparedLetter should warn if tables, substiture and repeat are not set';
-    is( $letter, undef,
-'No letter should be returned by GetPreparedLetter if something went wrong'
-    );
-
-    warning_like {
-        $letter = C4::Letters::GetPreparedLetter(
-            module      => 'test',
-            letter_code => 'test',
-            substitute  => {}
-        );
-    }
-    qr{^ERROR: nothing to substitute},
-'GetPreparedLetter should warn if tables, substiture and repeat are not set, even if the key is passed';
-    is( $letter, undef,
-'No letter should be returned by GetPreparedLetter if something went wrong'
-    );
-
-};
-
 {
 warning_is {
     $err = SendAlerts( 'claimacquisition', [ $ordernumber ], 'TESTACQCLAIM' ) }
@@ -521,7 +509,7 @@ my $borrowernumber = AddMember(
     dateofbirth  => $date,
     email        => 'john.smith@test.de',
 );
-my $alert_id = C4::Letters::addalert($borrowernumber, 'issue', $subscriptionid);
+my $alert_id = C4::Letters::addalert($borrowernumber, $subscriptionid);
 
 
 my $err2;
@@ -534,8 +522,115 @@ is($mail{'To'}, 'john.smith@test.de', "mailto correct in sent serial notificatio
 is($mail{'Message'}, 'Silence in the library,'.$subscriptionid.',No. 0', 'Serial notification text constructed successfully');
 }
 
+subtest 'GetPreparedLetter' => sub {
+    plan tests => 4;
+
+    Koha::Notice::Template->new(
+        {
+            module                 => 'test',
+            code                   => 'test',
+            branchcode             => '',
+            message_transport_type => 'email'
+        }
+    )->store;
+    my $letter;
+    warning_like {
+        $letter = C4::Letters::GetPreparedLetter(
+            module      => 'test',
+            letter_code => 'test',
+        );
+    }
+    qr{^ERROR: nothing to substitute},
+'GetPreparedLetter should warn if tables, substiture and repeat are not set';
+    is( $letter, undef,
+'No letter should be returned by GetPreparedLetter if something went wrong'
+    );
+
+    warning_like {
+        $letter = C4::Letters::GetPreparedLetter(
+            module      => 'test',
+            letter_code => 'test',
+            substitute  => {}
+        );
+    }
+    qr{^ERROR: nothing to substitute},
+'GetPreparedLetter should warn if tables, substiture and repeat are not set, even if the key is passed';
+    is( $letter, undef,
+'No letter should be returned by GetPreparedLetter if something went wrong'
+    );
+
+};
+
+
+
+subtest 'TranslateNotices' => sub {
+    plan tests => 4;
+
+    t::lib::Mocks::mock_preference( 'TranslateNotices', '1' );
+
+    $dbh->do(
+        q|
+        INSERT INTO letter (module, code, branchcode, name, title, content, message_transport_type, lang) VALUES
+        ('test', 'code', '', 'test', 'a test', 'just a test', 'email', 'default'),
+        ('test', 'code', '', 'test', 'una prueba', 'solo una prueba', 'email', 'es-ES');
+    | );
+    my $substitute = {};
+    my $letter = C4::Letters::GetPreparedLetter(
+            module                 => 'test',
+            tables                 => $tables,
+            letter_code            => 'code',
+            message_transport_type => 'email',
+            substitute             => $substitute,
+    );
+    is(
+        $letter->{title},
+        'a test',
+        'GetPreparedLetter should return the default one if the lang parameter is not provided'
+    );
+
+    $letter = C4::Letters::GetPreparedLetter(
+            module                 => 'test',
+            tables                 => $tables,
+            letter_code            => 'code',
+            message_transport_type => 'email',
+            substitute             => $substitute,
+            lang                   => 'es-ES',
+    );
+    is( $letter->{title}, 'una prueba',
+        'GetPreparedLetter should return the required notice if it exists' );
+
+    $letter = C4::Letters::GetPreparedLetter(
+            module                 => 'test',
+            tables                 => $tables,
+            letter_code            => 'code',
+            message_transport_type => 'email',
+            substitute             => $substitute,
+            lang                   => 'fr-FR',
+    );
+    is(
+        $letter->{title},
+        'a test',
+        'GetPreparedLetter should return the default notice if the one required does not exist'
+    );
+
+    t::lib::Mocks::mock_preference( 'TranslateNotices', '' );
+
+    $letter = C4::Letters::GetPreparedLetter(
+            module                 => 'test',
+            tables                 => $tables,
+            letter_code            => 'code',
+            message_transport_type => 'email',
+            substitute             => $substitute,
+            lang                   => 'es-ES',
+    );
+    is( $letter->{title}, 'a test',
+        'GetPreparedLetter should return the default notice if pref disabled but additional language exists' );
+
+};
+
 subtest 'SendQueuedMessages' => sub {
-    plan tests => 1;
+
+    plan tests => 4;
     t::lib::Mocks::mock_preference( 'SMSSendDriver', 'Email' );
     my $patron = Koha::Patrons->find($borrowernumber);
     $dbh->do(q|
@@ -545,4 +640,110 @@ subtest 'SendQueuedMessages' => sub {
     );
     eval { C4::Letters::SendQueuedMessages(); };
     is( $@, '', 'SendQueuedMessages should not explode if the patron does not have a sms provider set' );
+
+    my $sms_pro = $builder->build_object({ class => 'Koha::SMS::Providers', value => { domain => 'kidclamp.rocks' } });
+    ModMember( borrowernumber => $borrowernumber, smsalertnumber => '5555555555', sms_provider_id => $sms_pro->id() );
+    $message_id = C4::Letters::EnqueueLetter($my_message); #using datas set around line 95 and forward
+    C4::Letters::SendQueuedMessages();
+    my $sms_message_address = $schema->resultset('MessageQueue')->search({
+        borrowernumber => $borrowernumber,
+        status => 'sent'
+    })->next()->to_address();
+    is( $sms_message_address, '5555555555@kidclamp.rocks', 'SendQueuedMessages populates the to address correctly for SMS by email when to_address not set' );
+    $schema->resultset('MessageQueue')->search({borrowernumber => $borrowernumber,status => 'sent'})->delete(); #clear borrower queue
+    $my_message->{to_address} = 'fixme@kidclamp.iswrong';
+    $message_id = C4::Letters::EnqueueLetter($my_message);
+
+    my $number_attempted = C4::Letters::SendQueuedMessages({
+        borrowernumber => -1, # -1 still triggers the borrowernumber condition
+        letter_code    => 'PASSWORD_RESET',
+    });
+    is ( $number_attempted, 0, 'There were no password reset messages for SendQueuedMessages to attempt.' );
+
+    C4::Letters::SendQueuedMessages();
+    $sms_message_address = $schema->resultset('MessageQueue')->search({
+        borrowernumber => $borrowernumber,
+        status => 'sent'
+    })->next()->to_address();
+    is( $sms_message_address, '5555555555@kidclamp.rocks', 'SendQueuedMessages populates the to address correctly for SMS by email when to_address is set incorrectly' );
+
+};
+
+subtest 'get_item_content' => sub {
+    plan tests => 2;
+
+    t::lib::Mocks::mock_preference('dateformat', 'metric');
+    t::lib::Mocks::mock_preference('timeformat', '24hr');
+    my @items = (
+        {date_due => '2041-01-01 12:34', title => 'a first title', barcode => 'a_first_barcode', author => 'a_first_author', itemnumber => 1 },
+        {date_due => '2042-01-02 23:45', title => 'a second title', barcode => 'a_second_barcode', author => 'a_second_author', itemnumber => 2 },
+    );
+    my @item_content_fields = qw( date_due title barcode author itemnumber );
+
+    my $items_content;
+    for my $item ( @items ) {
+        $items_content .= C4::Letters::get_item_content( { item => $item, item_content_fields => \@item_content_fields } );
+    }
+
+    my $expected_items_content = <<EOF;
+01/01/2041 12:34\ta first title\ta_first_barcode\ta_first_author\t1
+02/01/2042 23:45\ta second title\ta_second_barcode\ta_second_author\t2
+EOF
+    is( $items_content, $expected_items_content, 'get_item_content should return correct items info with time (default)' );
+
+
+    $items_content = q||;
+    for my $item ( @items ) {
+        $items_content .= C4::Letters::get_item_content( { item => $item, item_content_fields => \@item_content_fields, dateonly => 1, } );
+    }
+
+    $expected_items_content = <<EOF;
+01/01/2041\ta first title\ta_first_barcode\ta_first_author\t1
+02/01/2042\ta second title\ta_second_barcode\ta_second_author\t2
+EOF
+    is( $items_content, $expected_items_content, 'get_item_content should return correct items info without time (if dateonly => 1)' );
+};
+
+subtest 'Test limit parameter for SendQueuedMessages' => sub {
+    plan tests => 3;
+
+    my $dbh = C4::Context->dbh;
+
+    my $borrowernumber = AddMember(
+        firstname    => 'Jane',
+        surname      => 'Smith',
+        categorycode => $patron_category,
+        branchcode   => $library->{branchcode},
+        dateofbirth  => $date,
+        smsalertnumber => undef,
+    );
+
+    $dbh->do(q|DELETE FROM message_queue|);
+    $my_message = {
+        'letter' => {
+            'content'      => 'a message',
+            'metadata'     => 'metadata',
+            'code'         => 'TEST_MESSAGE',
+            'content_type' => 'text/plain',
+            'title'        => 'message title'
+        },
+        'borrowernumber'         => $borrowernumber,
+        'to_address'             => undef,
+        'message_transport_type' => 'sms',
+        'from_address'           => 'from@example.com'
+    };
+    C4::Letters::EnqueueLetter($my_message);
+    C4::Letters::EnqueueLetter($my_message);
+    C4::Letters::EnqueueLetter($my_message);
+    C4::Letters::EnqueueLetter($my_message);
+    C4::Letters::EnqueueLetter($my_message);
+    my $messages_processed = C4::Letters::SendQueuedMessages( { limit => 1 } );
+    is( $messages_processed, 1,
+        'Processed 1 message with limit of 1 and 5 unprocessed messages' );
+    $messages_processed = C4::Letters::SendQueuedMessages( { limit => 2 } );
+    is( $messages_processed, 2,
+        'Processed 2 message with limit of 2 and 4 unprocessed messages' );
+    $messages_processed = C4::Letters::SendQueuedMessages( { limit => 3 } );
+    is( $messages_processed, 2,
+        'Processed 2 message with limit of 3 and 2 unprocessed messages' );
 };