package tests::XMLSpecContainerTest;

use strict;

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

use Lire::Param;
use Lire::XMLSpecContainer;
use Lire::DlfSchema;
use Lire::Test::Mock;
use Lire::Utils qw/create_file tempdir /;

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

    $self->init();
    $self->init_i18n();

    return $self;
}

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

    $self->{'tmpdir'} = tempdir( __PACKAGE__ . "XXXXXX", CLEANUP => 1 );

    $self->set_up_locale();
    $self->set_up_test_schema();

    my $spec = new Lire::XMLSpecContainer();
    $spec->superservice( 'test' );
    $spec->param( 'bidon', new Lire::Param( 'name' => 'bidon',
                                            'type' => 'int',
                                            'default' => 5 ) );

    $self->{'xmlspec'} = $spec;

    $Lire::DlfSchema::SCHEMA_CACHE{'test2'} =
      new Lire::DlfSchema( 'superservice' => 'test2',
                           'timestamp' => 'time' );

    return $self;
}

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

    $self->tear_down_locale();

    delete $Lire::DlfSChema::SCHEMA_CACHE{'test2'};

    return $self;
}

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

    my $spec = $self->{'xmlspec'};
    $self->assert_deep_equals( [ 'test' ], $spec->schemas() );
    $spec->joined_schemas( [ 'test-extended' ] );
    $self->assert_deep_equals( [ 'test', 'test-extended' ], $spec->schemas() );
}

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

    my $spec = $self->{'xmlspec'};
    $self->assert_deep_equals( [], $spec->joined_schemas() );

    $self->assert_dies( qr/no schema 'test-extended2'/,
                        sub { $spec->joined_schemas( [ 'test-extended2'] ) } );

    $self->assert_dies( qr/cannot join 'test2' schema with 'test'/,
                        sub { $spec->joined_schemas( [ 'test2' ] ) } );

    my $joined = [ 'test-extended' ];
    $spec->joined_schemas( $joined );
    $self->assert_deep_equals( $joined, $spec->{'_joined_schemas'} );
    $self->assert_str_not_equals( $joined, $spec->{'_joined_schemas'} );
}

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

    my $spec = $self->{'xmlspec'};

    $self->assert( $spec->has_field( 'connection_id' ) );
    $self->assert( ! $spec->has_field( 'dirname' ) );
    $spec->{'_joined_schemas'} = [ 'test-extended' ];

    $self->assert( $spec->has_field( 'connection_id' ) );
    $self->assert( $spec->has_field( 'dirname' ) );
}

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

    my $test = Lire::DlfSchema::load_schema( 'test' );
    my $ext = Lire::DlfSchema::load_schema( 'test-extended' );

    my $spec = $self->{'xmlspec'};
    $self->assert_dies( qr/no field 'dirname' in this specification's schemas: test/,
                        sub { $spec->field( 'dirname' ) } );

    $self->assert_str_equals( $test->field( 'connection_id' ),
                              $spec->field( 'connection_id' ) );

    $spec->{'_joined_schemas'} = [ 'test-extended' ];
    $self->assert_dies( qr/no field 'session_length' in this specification's schemas: test, test-extended/,
                        sub { $spec->field( 'session_length' ) } );
    $self->assert_str_equals( $test->field( 'connection_id' ),
                              $spec->field( 'connection_id' ) );
    $self->assert_str_equals( $ext->field( 'dirname' ),
                              $spec->field( 'dirname' ) );
}

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

    $self->assert_null( $self->{'xmlspec'}->resolve_param_ref(),
                        'expected undef' );
    $self->assert_num_equals( 4, $self->{'xmlspec'}->resolve_param_ref( 4 ));
    $self->assert_num_equals( 5, $self->{'xmlspec'}->resolve_param_ref('$bidon' ));
    $self->assert_dies(  qr/no such parameter: 'wawa'/,
                         sub {$self->{'xmlspec'}->resolve_param_ref('$wawa')});

}

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

    my $spec = $self->{'xmlspec'};
    $spec->{'title'} = 'JPEG Files';
    $self->assert_str_equals( 'JPEG Files', $spec->title() );
    $self->set_locale( 'fr_CA.iso8859-1' );
    $self->assert_str_equals( 'Fichiers JPEG', $spec->title() );
}

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

    my $spec = $self->{'xmlspec'};
    $spec->{'description'} = '<para>JPEG Files</para>';
    $self->assert_str_equals( '<para>JPEG Files</para>',
                              $spec->description() );
    $self->set_locale( 'fr_CA.iso8859-1' );
    $self->assert_str_equals( '<para>Fichiers JPEG</para>',
                              $spec->description() );
}

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

    my $spec = $self->{'xmlspec'};
    $spec->{'display_title'} = 'Downloads by File, Top $files_to_show';
    $self->assert_str_equals( 'Downloads by File, Top $files_to_show',
                              $spec->display_title() );
    $self->set_locale( 'fr_CA.iso8859-1' );
    $self->assert_str_equals( 'Transferts par fichiers, les $files_to_show les plus transférés',
                              $spec->display_title() );
}

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

    my $spec = $self->{'xmlspec'};
    $spec->{'display_description'} = 'Downloads by File, Top $files_to_show';
    $self->assert_str_equals( 'Downloads by File, Top $files_to_show',
                              $spec->display_description() );
    $self->set_locale( 'fr_CA.iso8859-1' );
    $self->assert_str_equals( 'Transferts par fichiers, les $files_to_show les plus transférés',
                              $spec->display_description() );
}

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

    my $mock = new_proxy Lire::Test::Mock( 'Lire::XMLSpecContainer' );
    $mock->set_result( 'spec_path', [ "$self->{'testdir'}/reports",
                                      $self->{'tmpdir'} ] );

    $self->assert_str_equals( "$self->{'testdir'}/reports/test/downloads-by-period.xml",, $mock->file_from_id( 'test', 'downloads-by-period' ) );
    $self->assert_dies( qr/can't find 'test' Class.* XML specification 'unknown' in "$self->{'testdir'}\/reports:$self->{'tmpdir'}/,
                        sub { $mock->file_from_id( 'test', 'unknown' ) } );
}

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

    my $mock = new_proxy Lire::Test::Mock( 'Lire::XMLSpecContainer' );
    $mock->set_result( 'spec_path', [ "$self->{'testdir'}/reports" ] );

    $self->assert( $mock->has_spec( 'test', 'downloads-by-period' ) ? 1 : 0,
                   'has_spec()' );
    $self->assert( ! $mock->has_spec( 'test', 'no-such-file' ) ? 1 : 0,
                 '!has_error' );
}

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

    my $mock = new_proxy Lire::Test::Mock( 'Lire::XMLSpecContainer' );
    $mock->set_result( 'spec_path', [ "$self->{'testdir'}/reports",
                                     "$self->{'tmpdir'}" ] );
    mkdir "$self->{'tmpdir'}/test/", 0777
      or $self->error( "mkdir failed: $!" );
    create_file( "$self->{'tmpdir'}/test/a-test.xml", "" );
    $self->assert_deep_equals( [ sort qw/ avg-file_size-by-timeslot
downloads-by-period sessions-by-length sessions-by-user_class top-dirs
top-dirs2 top-files user-downloads-utf8 user_downloads-report a-test / ],
                               [ sort @{$mock->list_specs( 'test' ) } ] );
}

1;


syntax highlighted by Code2HTML, v. 0.9.1