package tests::OutputJobTest;

use strict;

use base qw/ Lire::Test::TestCase /;

use Lire::OutputJob;
use Lire::OutputFormat;
use Time::Local;
use Lire::Test::Mock;
use Lire::PluginManager;
use MIME::Entity;
use MIME::Parser;
use Lire::Utils qw/tempdir create_file /;

sub new {
    my $self = shift()->SUPER::new( @_ );

    $self->{'mock_output'} =
      new_proxy Lire::Test::Mock( 'Lire::OutputFormat' );
    $self->{'mock_output'}->set_result( 'name' => 'mock',
                                        'title' => 'Mock OuputFormat',
                                        'mime_report' => '',
                                        'format_report' => '',
                                      );

    return $self;
}

sub set_up {
    my $self = $_[0];
    $self->SUPER::set_up();

    $self->{'spec'} = $self->lire_default_config_spec();
    $self->{'cfg'}{'_lr_config_spec'} = $self->{'spec'};
    $self->set_up_plugin_mgr();

    Lire::PluginManager->register_plugin( $self->{'mock_output'} );

    return;
}

sub tear_down {
    my $self = $_[0];
    $self->SUPER::tear_down();

    return;
}

sub test_new_invalid {
    my $self = $_[0];

    $self->assert_dies( qr/'type' parameter should be one of 'email' or 'file'/,
                        sub { new Lire::OutputJob( 'type', 'type', '' ) } );
}

sub test_new_file {
    my $self = $_[0];

    my $file = '/var/www/report-%Y-%m-%d';
    my $cfg = {};
    my $job = new Lire::OutputJob( 'file', $self->{'mock_output'}, $cfg,
                                   'file' => $file );
    $self->assert_isa( 'Lire::FileOutputJob', $job );
    $self->assert_str_equals( $self->{'mock_output'}, $job->{'_format'} );
    $self->assert_str_equals( $self->{'mock_output'}, $job->format() );
    $self->assert_str_equals( $cfg, $job->{'_format_cfg'} );
    $self->assert_str_equals( $cfg, $job->format_cfg() );
    $self->assert_str_equals( $file, $job->{'_file'} );
    $self->assert_str_equals( $file, $job->file() );
}

sub test_output_file {
    my $self = $_[0];

    my $jan7_2004 = timelocal( 0, 0, 0, 7, 0, 2004 );
    my $file = '/var/www/report-%Y-%m-%d';
    my $job = new Lire::OutputJob( 'file', $self->{'mock_output'}, '',
                                   'file' => $file );
    $self->assert_str_equals( '/var/www/report-2004-01-07',
                              $job->output_file( $jan7_2004 ) );
}

sub test_new_email {
    my $self = $_[0];

    my $emails = [ 'flacoste@logreport.org', 'wolfgang@logreport.org' ];
    my $job = new Lire::OutputJob( 'email', $self->{'mock_output'}, {},
                                   'emails' => $emails,
                                   'subject' => 'A subject',
                                 );
    $self->assert_isa( 'Lire::EmailOutputJob', $job );
    $self->assert_str_equals( $self->{'mock_output'}, $job->{'_format'} );
    $self->assert_str_equals( $self->{'mock_output'}, $job->format() );
    $self->assert_str_equals( 'A subject', $job->{'_subject'} );
    $self->assert_str_equals( 'A subject', $job->subject() );
    $self->assert_deep_equals( $emails, $job->{'_emails'} );
    $self->assert_deep_equals( $emails, [ $job->emails() ] );
}

sub test_email_run {
    my $self = $_[0];

    $self->{'cfg'}{'lr_mail_from'} = 'responder@logreport.org';
    $self->{'cfg'}{'lr_mail_reply_to'} = 'admin@logreport.org';
    my $cfg = {};
    my $tmpdir = tempdir( $self->name() . "_XXXXXX", 'CLEANUP' => 1 );
    create_file( "$tmpdir/signature.txt", "My signature\n" );
    my $job = new Lire::OutputJob( 'email', $self->{'mock_output'}, $cfg,
                                   'emails' => [ 'flacoste@logreport.org' ],
                                   'subject' => "LogReport's \\ \"subject\"",
                                   'extra_file' => "$tmpdir/signature.txt" );
    $self->{'mock_output'}->set_result( 'mime_report' =>
                                        MIME::Entity->build( 'Type' => 'text/plain',
                                                             'Data' => "A test\n" ) );

    create_file( "$tmpdir/sendmail", "#! /bin/sh\nexec cat >$tmpdir/email" );
    chmod 0755, "$tmpdir/sendmail";
    $self->{'cfg'}{'sendmail_path'} = "$tmpdir/sendmail";

    $job->run( 'report.xml' );
    $self->assert_deep_equals( [ $self->{'mock_output'}, 'report.xml', $cfg, ],
                               $self->{'mock_output'}->get_invocation( 'mime_report' ) );
    my $parser = new MIME::Parser();
    $parser->output_under( $tmpdir );
    my $msg = $parser->parse_open( "$tmpdir/email" );
    $self->assert_str_equals( 'text/plain', $msg->mime_type() );
    $self->assert_str_equals( 'LogReport\'s \\ "subject"' . "\n",
                              $msg->head()->get( 'subject' ) );
    $self->assert_str_equals( 'flacoste@logreport.org' . "\n",
                              $msg->head()->get( 'to' ) );
    $self->assert_str_equals( 'responder@logreport.org' ."\n",
                              $msg->head()->get( 'from' ) );
    $self->assert_str_equals( 'admin@logreport.org' . "\n",
                              $msg->head()->get( 'reply-to' ) );
    $self->assert_str_equals( "A test\n\nMy signature\n", $msg->bodyhandle()->as_string() );

    $self->{'mock_output'}->set_result( 'mime_report' => MIME::Entity->build( 'Type' => 'multipart/related' ) );

    $job->run( 'report.xml' );
    $msg = $parser->parse_open( "$tmpdir/email" );
    $self->assert_str_equals( 'multipart/mixed', $msg->mime_type() );
    $self->assert_num_equals( 2, scalar $msg->parts() );
    $self->assert_str_equals( "multipart/related",
                              $msg->parts(0)->mime_type() );
    $self->assert_str_equals( 'text/plain', $msg->parts(1)->mime_type() );
    $self->assert_str_equals( "My signature\n",
                              $msg->parts(1)->bodyhandle()->as_string() );
}

sub test_file_run {
    my $self = $_[0];

    my $jan7_2004 = timelocal( 0, 0, 0, 7, 0, 2004 );
    my $file = '/var/www/report-%Y-%m-%d';
    my $cfg = {};
    my $job = new Lire::OutputJob( 'file', $self->{'mock_output'}, $cfg,
                                   'file' => $file );
    $job->run( 'report.xml', $jan7_2004 );
    $self->assert_deep_equals( [ $self->{'mock_output'},
                                 'report.xml',
                                 '/var/www/report-2004-01-07',
                                 $cfg,
                               ],
                               $self->{'mock_output'}->get_invocation( 'format_report' ) );
}

sub test_new_from_config {
    my $self = $_[0];

    my $job = $self->{'spec'}->get( 'report_jobs' )->get( 'report_job' )->get( 'schedules' )->get( 'schedule' )->get( 'output_jobs' )->get( 'output_job' )->instance();
    $job->get( 'name' )->set( 'myJob' );
    $job->get( 'format' )->set_plugin( 'mock' );

    $job->get( 'destination' )->set_plugin( 'file' );
    $job->get( 'destination' )->get( 'file' )->set( 'report.txt' );

    my $jobObject = $job->as_value();
    $self->assert_isa( 'Lire::FileOutputJob', $jobObject );
    $self->assert_isa( 'Lire::OutputFormat', $jobObject->{'_format'} );
}

1;


syntax highlighted by Code2HTML, v. 0.9.1