package tests::ReportJobTest;

use strict;

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

use Lire::ReportJob;
use Lire::ReportConfig;
use Lire::ReportSchedule;
use Lire::Test::Mock;
use Lire::Config::Index;

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

    $self->init();

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

    return $self;
}

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

    $self->set_up_test_schema();
    $self->set_up_test_store();
    $self->{'cfg'}{'_lr_config_spec'} = $self->{'spec'};
    $self->{'test_cfg'} = new Lire::ReportConfig();

    $self->{'_old_index_ref'} = \%Lire::Config::Index::REGISTRY;
    my $index = new Lire::Test::Mock( 'Lire::Config::Index',
                                      'has_entry' => 1,
                                      'get_ref' => $self->{'test_cfg'} );
    Lire::Config::Index->set_index( 'store_report_configurations', $index );


    return;
}

sub tear_down {
    my $self = $_[0];
    *Lire::Config::Index::REGISTRY = $self->{'_old_index_ref'};

    $self->SUPER::tear_down();
    $self->tear_down_test_store();

    return;
}

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

    my $job = new Lire::ReportJob( "aTest" );
    $self->assert_isa( 'Lire::ReportJob', $job );

    $self->assert_str_equals( 'aTest', $job->{'_name'} );
    $self->assert_str_equals( 'aTest', $job->name() );
    $self->assert_deep_equals( [], $job->{'_schedules'} );
    $self->assert_deep_equals( [], [ $job->schedules() ] );
}

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

    my $job = new Lire::ReportJob( "aTest" );
    my $schedule = bless {}, 'Lire::ReportSchedule';

    $self->assert_dies( qr/missing one or more 'schedule' parameters/,
                        sub { $job->add_schedule() } );
    $job->add_schedule( $schedule, $schedule );
    $self->assert_deep_equals( [ $schedule, $schedule ],
                               $job->{'_schedules'} );
}

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

    my $job = $self->{'spec'}->get( 'report_jobs' )->get( 'report_job' )->instance();
    $job->get( 'name' )->set( 'myReport' );

    my $jobObject = $job->as_value();
    $self->assert_isa( 'Lire::ReportJob', $jobObject );
    $self->assert_str_equals( 'myReport', $jobObject->{'_name'} );
    $self->assert_deep_equals( [], $jobObject->{'_schedules'} );

    my $sched = $job->spec()->get( 'schedules' )->get( 'schedule' )->instance();
    $sched->get( 'period' )->set( 'daily' );
    $sched->get( 'report_config' )->set( 'test_cfg' );
    $job->get( 'schedules' )->append( $sched );

    $sched = $sched->spec()->instance();
    $sched->get( 'period' )->set( 'hourly' );
    $sched->get( 'report_config' )->set( $self->{'test_cfg'} );
    $job->get( 'schedules' )->append( $sched );

    $jobObject = $job->as_value();
    my @sched = $jobObject->schedules();
    $self->assert_num_equals( 2, scalar @sched );
    $self->assert_isa( 'Lire::ReportSchedule', $sched[0] );
    $self->assert_isa( 'Lire::ReportSchedule', $sched[1] );
}

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

    my $job = new Lire::ReportJob( 'myReport', 'test' );
    my $daily = new Lire::Test::Mock( 'Lire::ReportSchedule',
                                      'period' => 'daily' );
    my $weekly = new Lire::Test::Mock( 'Lire::ReportSchedule',
                                       'period' => 'weekly' );

    $job->add_schedule( $daily, $weekly );

    my $one_hour_ago = time - 3600;
    $job->run( $self->{'store'}, 'daily', $one_hour_ago );
    $self->assert_deep_equals( [ $daily, $self->{'store'}, $job,$one_hour_ago],
                               $daily->get_invocation( 'run' ) );
    $self->assert_num_equals( 0, $weekly->invocation_count( 'run' ) );


    my $now = time;
    $job->run( $self->{'store'}, 'weekly' );
    $self->assert_num_equals( 1, $daily->invocation_count( 'run' ) );
    $self->assert_deep_equals( [ $weekly, $self->{'store'}, $job,$now ],
                               $weekly->get_invocation( 'run' ) );
}

1;


syntax highlighted by Code2HTML, v. 0.9.1