#!/usr/bin/perl

use Test::WWW::Mechanize::CGIApp;
use Test::Builder::Tester;

use Data::Dumper;

use strict;
use warnings;

use Test::More; #  use Test::More 'no_plan';
use constant TESTS => 30;

=begin: tests:
tests results data entry using date, datetime, integer & decimal data types
also tests specific formats from result_data_validation.yml
=cut

BEGIN {
    require 't/test-lib.pl';
}

ok( get_yaml('results_data_validation') , "require a results_data_validation.yml file" ); # check for required yaml file

my $mech = get_mech();

do_login();

my $dbh;

eval {
    $dbh = get_dbh() or die 'no database handle recieved from get_dbh';
};

warn $@ if $@;

my $dbix = get_dbix();

# register new data-types
$dbix->insert('lab_test_result_data_types', { description => $_ })
    for qw(integer decimal date datetime);
my $data_type_map = $dbix->select('lab_test_result_data_types',
    [ qw(description id) ])->map;

# register new lab tests with data-types & validators:
{ # CD1 = integer
    $dbix->insert('lab_tests', { test_name => 'cd1', field_label => 'CD1',
        lab_section_id => 1, test_type => 'test', has_results => 'yes' });
    my $tid = get_last_insert_id('lab_tests');
    $dbix->insert('lab_test_data_type',
        { lab_test_id => $tid, data_type_id => $data_type_map->{integer} });
}
{ # CD2 = decimal
    $dbix->insert('lab_tests', { test_name => 'cd2', field_label => 'CD2',
        lab_section_id => 1, test_type => 'test', has_results => 'yes' });
    my $tid = get_last_insert_id('lab_tests');
    $dbix->insert('lab_test_data_type',
        { lab_test_id => $tid, data_type_id => $data_type_map->{decimal} });
}
{ # CD3 = integer
    $dbix->insert('lab_tests', { test_name => 'cd3', field_label => 'CD3',
        lab_section_id => 1, test_type => 'test', has_results => 'yes' });
    my $tid = get_last_insert_id('lab_tests');
    $dbix->insert('lab_test_data_type',
        { lab_test_id => $tid, data_type_id => $data_type_map->{integer} });
}
{ # date = date
    $dbix->insert('lab_tests', { test_name => 'date', field_label => 'Date',
        lab_section_id => 1, test_type => 'test', has_results => 'yes' });
    my $tid = get_last_insert_id('lab_tests');
    $dbix->insert('lab_test_data_type',
        { lab_test_id => $tid, data_type_id => $data_type_map->{date} });
}
{ # datetime = datetime
    $dbix->insert('lab_tests', { test_name => 'datetime', field_label => 'DateTime',
        lab_section_id => 1, test_type => 'test', has_results => 'yes' });
    my $tid = get_last_insert_id('lab_tests');
    $dbix->insert('lab_test_data_type',
        { lab_test_id => $tid, data_type_id => $data_type_map->{datetime} });
}
{ # yaml-file defined valdaition (use name unlikely ever to be used in app):
    $dbix->insert('lab_tests', {
        test_name => '__xx_test_result_1', field_label => 'T1',
        lab_section_id => 1, test_type => 'test', has_results => 'yes' });
    my $tid = get_last_insert_id('lab_tests');
    $dbix->insert('lab_test_data_type',
        { lab_test_id => $tid, data_type_id => $data_type_map->{decimal} });
}
{ # yaml-file defined valdaition (use name unlikely ever to be used in app):
    $dbix->insert('lab_tests', {
        test_name => '__xx_test_result_2', field_label => 'T2',
        lab_section_id => 1, test_type => 'test', has_results => 'yes' });
    my $tid = get_last_insert_id('lab_tests');
    $dbix->insert('lab_test_data_type',
        { lab_test_id => $tid, data_type_id =>$data_type_map->{integer} });
}
#===============================================================================
{ # request lab-tests:
    $mech->get_ok('/result/=/2');
    $mech->form_name('flow_requests');
    $mech->tick('test_id', $_, 1) for (10 .. 16);
    $mech->submit();                                          # print_and_exit();
}
{ # invalid integer:
    my $test_id = 'lab_test_id_10'; # cd1

    $mech->get_ok('/result/=/2');
    $mech->form_name('flow_results');
    # enter invalid result:
    $mech->field($test_id, '1.2');
    $mech->submit();                                          # print_and_exit();
    my $err_msg = get_messages('dfv_msgs')->{need_integer}; # warn $err_msg;
    $mech->text_contains(
        $err_msg,
        "OK: failed validation [$err_msg]",
    );                                                        # print_and_exit();
    # correct format:
    $mech->form_name('flow_results');
    $mech->field($test_id, 2);
    $mech->submit();                                         # print_and_exit();
    $mech->has_tag(
        p => 'INFO: results data update successful',
        'OK: results update success',
    );
}
{ # invalid decimal:
    my $test_id = 'lab_test_id_11'; # cd2

    $mech->get_ok('/result/=/2');
    $mech->form_name('flow_results');
    # enter invalid result:
    $mech->field($test_id, 2);
    $mech->submit();                                          # print_and_exit();
    my $err_msg = get_messages('dfv_msgs')->{need_decimal};
    $mech->text_contains(
        $err_msg,
        "OK: failed validation [$err_msg]",
    );
    # correct format:
    $mech->form_name('flow_results');
    $mech->field($test_id, '1.2');
    $mech->submit();                                          # print_and_exit();
    $mech->has_tag(
        p => 'INFO: results data update successful',
        'OK: results update success',
    );
}
{ # invalid date:
    my $test_id = 'lab_test_id_13'; # date

    $mech->get_ok('/result/=/2');
    $mech->form_name('flow_results');
    # enter invalid result:
    $mech->field($test_id, '2015-18-12');
    $mech->submit();                                          # print_and_exit();
    my $err_msg = get_messages('dfv_msgs')->{invalid_date};
    $mech->text_contains(
        $err_msg,
        "OK: failed validation [$err_msg]",
    );
    # correct format:
    $mech->form_name('flow_results');
    $mech->field($test_id, '2015-08-12');
    $mech->submit();                                          # print_and_exit();
    $mech->has_tag(
        p => 'INFO: results data update successful',
        'OK: results update success',
    );
}
{ # invalid datetime:
    my $test_id = 'lab_test_id_14'; # datetime

    $mech->get_ok('/result/=/2');
    $mech->form_name('flow_results');
    # enter invalid result:
    $mech->field($test_id, '2015-18-12 12:18:22');
    $mech->submit();                                          # print_and_exit();
    my $err_msg = get_messages('dfv_msgs')->{invalid_datetime};
    $mech->text_contains(
        $err_msg,
        "OK: failed validation [$err_msg]",
    );
    # correct format:
    $mech->form_name('flow_results');
    $mech->field($test_id, '2015-08-12 12:18:22');
    $mech->submit();                                          # print_and_exit();
    $mech->has_tag(
        p => 'INFO: results data update successful',
        'OK: results update success',
    );
}
{ # invalid format using yaml file:
    my $test_id = 'lab_test_id_15'; # __xx_test_result_1

    $mech->get_ok('/result/=/2');
    $mech->form_name('flow_results');
    # enter invalid result:
    $mech->field($test_id, 2);
    $mech->submit();                                          # print_and_exit();
    my $err_msg = get_messages('dfv_msgs')->{need_decimal};
    $mech->text_contains(
        $err_msg,
        "OK: failed validation [$err_msg]",
    );
    # decimal but still invalid format:
    $mech->form_name('flow_results');
    $mech->field($test_id, '123456.2');
    $mech->submit();                                          # print_and_exit();
    $err_msg = get_messages('dfv_msgs')->{invalid_format};
    $mech->text_contains(
        $err_msg,
        "OK: failed validation [$err_msg]",
    );
    # correct format:
    $mech->form_name('flow_results');
    $mech->field($test_id, '1234567.2');
    $mech->submit();                                          # print_and_exit();
    $mech->has_tag(
        p => 'INFO: results data update successful',
        'OK: results update success',
    );
}
{ # invalid format using yaml file:
    my $test_id = 'lab_test_id_16'; # __xx_test_result_2

    $mech->get_ok('/result/=/2');
    $mech->form_name('flow_results');
    # enter invalid result:
    $mech->field($test_id, 2.2);
    $mech->submit();                                          # print_and_exit();
    my $err_msg = get_messages('dfv_msgs')->{need_integer};
    $mech->text_contains(
        $err_msg,
        "OK: failed validation [$err_msg]",
    );
    # integer but still invalid format:
    $mech->form_name('flow_results');
    $mech->field($test_id, '1234567');
    $mech->submit();                                          # print_and_exit();
    $err_msg = get_messages('dfv_msgs')->{invalid_format};
    $mech->text_contains(
        $err_msg,
        "OK: failed validation [$err_msg]",
    );
    # correct format:
    $mech->form_name('flow_results');
    $mech->field($test_id, '12345678');
    $mech->submit();                                          # print_and_exit();
    $mech->has_tag(
        p => 'INFO: results data update successful',
        'OK: results update success',
    );
}
{ # change existing result to invalid format, resubmit form with new valid param:
    $dbix->update('request_lab_test_results', { result => '1234567_2' },
        { result => '1234567.2' }); # lab_test_id_14

    my $test_id = 'lab_test_id_12';
    $mech->get_ok('/result/=/2');
    $mech->form_name('flow_results');
    # enter valid integer result:
    $mech->field($test_id, 22);
    $mech->submit();                                          # print_and_exit();
    # still get validation failure from lab_test_id_14:
    my $err_msg = get_messages('dfv_msgs')->{need_decimal};
    $mech->text_contains(
        $err_msg,
        "OK: failed validation [$err_msg]",
    );
}
do_logout();
done_testing(TESTS);
