#!/usr/bin/perl
# just testing for dfv errors using LIMS::Validation profiles:
use Test::WWW::Mechanize::CGIApp;
use Data::Dumper;
use strict;
use warnings;
use Test::More tests => 76; # use Test::More 'no_plan';
=begin: tests:
0) create some new records for this test suite (not tested)
1) new_patient validation profile
2) edit_patient validation profile (nhs_number)
3) edit_patient validation profile (dob)
4) edit_patient validation profile (> 1 record requires confirmation)
6) new_location profile
=cut
BEGIN {
require 't/test-lib.pl';
}
my $mech = get_mech();
do_login();
my $dbh;
eval {
$dbh = get_dbh() or die 'no database handle recieved from get_dbh';
};
warn $@ if $@;
# need to drop & re-create following tables:
foreach ( qw/ / ) { # none - using test-data.pl
drop_and_recreate($_);
}
# create some new patient/request/patient_case records for this test suite:
{
my $dbix = get_dbix();
my $year = DateTime->now->year();
my $now = DateTime->now();
# new data:
my %new = (
patients => [ # last_name, first_name, middle_name, dob, gender, nhs_no, created_at
[ qw( green alan 1940-02-21 M), undef, $now ]
],
patient_case => [ # patient_id, referral_source_id, unit_number
[ 3, 1, 'ABC123' ],
],
requests => [ # yr, request_id, patient_case_id, referrer_dept_id, now
[ $year, 3, 1, 2, $now ], # hospital referral - duplicate of request #1
[ $year, 4, 3, 2, $now ],
],
request_specimen => [ # request_id, specimen_id
[ 3, 1 ],
[ 4, 1 ],
],
);
my $test_data = get_test_data();
while ( my ($tbl, $data) = each %new ) { # warn $tbl, "\n";
my $fields = $test_data->{$tbl}->{fields}; # warn Dumper $fields;
foreach my $data_set (@$data) { # warn $data_set, "\n";
my $i = 0;
# map field_name to its value:
my %data = map { $fields->[$i++] => $_ } @$data_set; # warn Dumper \%data;
$dbix->insert($tbl, \%data);
}
}
}
# new_patient validation profile:
$mech->get_ok('/patient'); # print_and_exit();
{
my %patient = (
last_name => 'WHITE', # uppercase - tests field_filters
first_name => 'Gary',
nhs_number => 2222222222, # duplicate
day => 30,
month => 1,
year => 1950,
gender => 'M',
referral_source_id => 1,
unit_number => 'A123',
);
# test missing fields using local _test_missing_fields():
_test_missing_fields(\%patient);
# test missing unit_number & nhs_number:
{
my %tmp = %patient; # clone %patient
map { $tmp{$_} = undef } qw(unit_number nhs_number);
$mech->submit_form(fields => \%tmp); # print_and_exit();
has_dfv_errors();
has_formvalidator_error( get_messages('require_one') );
}
# require unique nhs_number:
$mech->submit_form(fields => \%patient); # print_and_exit();
has_dfv_errors();
has_duplicate();
# reload page - no need to test:
$mech->get('/patient');
# add 1111111111 to nhs_number to make unique:
$patient{nhs_number} += 1111111111;
# increment month to make invalid (30/Feb):
$patient{month}++;
$mech->submit_form(fields => \%patient); # print_and_exit();
has_dfv_errors();
$mech->content_contains(
dfv_format('invalid_date'),
'OK: invalid date detected',
);
# increment month again to make valid (30/March):
$patient{month}++;
# make year 2-digits:
$patient{year} -= 1900;
$mech->submit_form( fields => \%patient );
$mech->content_contains(
dfv_format('year_digits'),
'OK: year data length incorrect',
);
# year -> future:
$patient{year} = DateTime->now->year() + 1;
$mech->submit_form( fields => \%patient ); # print_and_exit();
$mech->content_contains(
dfv_format('future_date'),
'OK: date in future detected OK',
);
# correct year to valid:
$patient{year} = DateTime->now->year() - 1;
$mech->submit_form(fields => \%patient); # print_and_exit();
lacks_dfv_errors(); # print_and_exit();
}
# edit_patient validation profile (nhs_number):
my $last_patient_id = get_last_insert_id('patients');
$mech->get_ok('/patient/edit_patient/'.$last_patient_id); # print_and_exit();
{
# get patient details from db:
my $dbix = get_dbix();
my $sql = q!select last_name, first_name, year(dob) as 'year', month(dob) as
'month', day(dob) as 'day', gender, nhs_number from patients where id = ?!;
my $patient = $dbix->query($sql, $last_patient_id)->hash; # warn Dumper $patient;
# test field_filters worked (_name's should be lowercase):
{ # fail if tesed againt uppercase values:
isnt($patient->{last_name}, 'WHITE', 'OK: last_name not uppercase');
is($patient->{last_name}, 'white', 'OK: field_filter on last_name working');
isnt($patient->{first_name}, 'Gary', 'OK: first_name not ucfirst');
is($patient->{first_name}, 'gary', 'OK: field_filter on first_name working');
}
# test missing fields using local _test_missing_fields():
_test_missing_fields($patient); # print_and_exit();
# invalid nhs_number:
$patient->{nhs_number} = 1234; # warn Dumper $patient;
$mech->submit_form(fields => $patient); # print_and_exit();
has_dfv_errors();
has_invalid();
# valid & duplicate nhs_number:
$patient->{nhs_number} = 2222222222;
$mech->submit_form(fields => $patient); # print_and_exit();
has_dfv_errors();
has_duplicate(); # print_and_exit();
# valid & unique nhs_number:
$patient->{nhs_number} = 5555555555;
$mech->submit_form(fields => $patient); # print_and_exit();
lacks_duplicate();
lacks_invalid();
has_missing(); # still needs reason for edit
$mech->field(error_code_id => 1);
$mech->submit_form(fields => $patient); # print_and_exit();
lacks_invalid();
lacks_duplicate();
lacks_missing();
}
# edit_patient validation profile (dob):
$mech->get_ok('/patient/edit_patient/2'); # print_and_exit();
{
# change should affect only 1 record:
$mech->has_tag(
span => 'INFO: change affects this record only',
'OK: single record change notice',
); # print_and_exit();
# dob = 04/10/1960 - make it invalid:
$mech->field(day => 44);
$mech->submit_form(); # print_and_exit();
has_dfv_errors();
$mech->content_contains(
dfv_format('invalid_date'),
'OK: invalid date detected',
);
# revert to valid dob:
$mech->field(day => 14);
$mech->submit_form(); # print_and_exit();
lacks_duplicate();
lacks_invalid();
has_missing(); # still needs reason for edit
$mech->field(error_code_id => 1);
$mech->submit_form(); # print_and_exit();
lacks_invalid();
lacks_duplicate();
lacks_missing();
}
# edit_patient validation profile (> 1 record - requires confirmation):
$mech->get_ok('/patient/edit_patient/1/1'); # print_and_exit();
{
# check similar patient data loaded:
$mech->has_tag(
p => 'Usage: select another patient record or edit current record',
'OK: similar entries found'
);
foreach( qw/GREEN Alan 21.Feb.1940 [NULL]/ ) {
$mech->has_tag_like(
td => $_,
'OK: expected field detected'
);
}
$mech->has_tag_like(
li => 'ABC123',
'OK: expected field detected'
);
$mech->has_tag(
span => 'WARNING: change affects 1 other record',
'OK: correct number of records',
); # print_and_exit();
$mech->field(day => 11);
$mech->field(error_code_id => 1);
# confirmation missing:
$mech->submit_form(); # print_and_exit();
has_dfv_errors();
has_formvalidator_error( get_messages('confirm_change') ); # print_and_exit();
$mech->field(all_records => 1); # equivalent to old 'confirmation'
$mech->submit_form(); # print_and_exit();
lacks_dfv_errors();
lacks_missing(); # print_and_exit();
}
SKIP: {
skip('TODO: test consequence of editing nhs_number to null if unit_number also null', 1);
}
# new_location profile:
$mech->get_ok('/patient/select_patient/1'); # print_and_exit();
{
# only required field is referral_source_id:
$mech->submit_form(); # empty
has_dfv_errors();
has_missing(); # print_and_exit();
my %data = (
referral_source_id => 1,
unit_number => 'ABC123',
);
$mech->submit_form(fields => \%data); # print_and_exit();
lacks_dfv_errors();
}
sub _test_missing_fields {
my $patient = shift;
# test missing required on fields which should trigger 'missing':
foreach my $field( qw/last_name first_name gender referral_source_id/ ) {
# create temp hash with one field missing:
my %tmp = %$patient; # clone %patient
$tmp{$field} = undef; # warn Dumper \%tmp_user;
$mech->submit_form(fields => \%tmp);
# check we have dfv error:
has_dfv_errors();
has_missing();
}
# test missing dob:
{
my %tmp = %$patient; # clone %patient
map { $tmp{$_} = undef } qw(day month year);
$mech->submit_form(fields => \%tmp); # print_and_exit();
has_dfv_errors();
has_missing();
}
}