#!/usr/bin/perl use DateTime; use Data::Dumper; use Test::Exception; use Test::Builder::Tester; use Test::WWW::Mechanize::CGIApp; use strict; use warnings; use Test::More tests => 164; # use Test::More 'no_plan'; =begin # tests: 0) create new data for tests - outcome not tested 1) update unit_number on single patient entry to unique val - old val replaced by new 2) delete unit_number on single patient entry - old val replaced by default val 3) change unit_number of patient_case with > 1 request attached - single record change 4) select a previous patient_case and set scope to all 5) test effect of resubmitting same patient_case data - should be no change 6) manually change unit_number to match existing patient_case - for scope set to one 7) delete unit number - set scope to all 8) change location to one in same parent_organisation 9) change location to one in different parent_organisation 10) change hospital location to practice 11) change location and unit_number together 12) use back button & re-submit form (should not cause error) 13) emulate consequence of incomplete updates using 2 browser tabs =cut require 't/test-lib.pl'; my $mech = get_mech(); # login/logout tests handled by test-lib.pl do_login(); # print $fh $mech->content; # exit; # 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 = ( parent_organisations => [ # parent_code description referral_type_id [ 'DEF', 'OLDTOWN NHS TRUST', 3 ], ], patient_case => [ # patient_id, referral_source_id, unit_number [ 2, 1, 'ABC123' ], ], referral_sources => [ # display_name org_code parent_org_id referral_type_id [ 'Newtown District Hospital', 'ABC02', 1, 3 ], [ 'Oldtown & Region Trust ', 'DEF01', 5, 3 ], ], requests => [ # yr, request_id, patient_case_id, referrer_dept_id, now [ $year, 3, 2, 1, $now ], # hospital referral - duplicate of request #2 [ $year, 4, 3, 1, $now ], # hospital referral - same as request #2, diff unit_number ], request_specimen => [ # request_id, specimen_id [ 3, 1 ], [ 4, 3 ], ], ); 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); } } # create_view(); } # edit request patient_case: { # update unit_number only: # load request_edit page direct: $mech->get_ok('/request/edit/1'); # print_and_exit(); # no changes, just tests 'reason for edit': $mech->submit_form(); # print_and_exit(); has_dfv_errors(); has_missing(); # change unit number to unqiue - will create new record: $mech->field( unit_number => 'ABC123'); $mech->field( error_code_id =>1 ); $mech->submit_form(); # print_and_exit(); has_edit_success(1); # check fields are as expected: my %params = ( name => 'green', old_unit_number => 1011, new_unit_number => 'ABC123', location => 'The Surgery, Newtown, NT1 1NT', old_val_retained => 0, # old unit_number should not be detected ); check_edit(\%params); # print_and_exit(); # check history: $mech->get_ok('/history/=/1'); # print_and_exit(); $mech->has_tag_like( td => qr(amended unit number \[1011 -> ABC123\]), 'OK: expected history found', ); # print_and_exit(); } { # delete unit_number on single-patient entry: $mech->get_ok('/request/edit/1'); # print_and_exit(); # delete unit number: $mech->field( unit_number => ''); $mech->field( error_code_id =>1 ); $mech->submit_form(); # print_and_exit(); has_edit_success(1); # check fields are as expected: my %params = ( name => 'green', old_unit_number => 'ABC123', new_unit_number => 'UNKNOWN', location => 'The Surgery, Newtown, NT1 1NT', old_val_retained => 0, # old unit_number should not be detected ); check_edit(\%params); # check history: $mech->get_ok('/history/=/1'); # print_and_exit(); $mech->has_tag_like( td => qr(deleted unit number \[ABC123\]), 'OK: expected history found', ); # print_and_exit(); } { # change unit number of patient_case with > 1 request attached: # load request_edit page direct: $mech->get_ok('/request/edit/2'); # print_and_exit(); # check other patient_case data loaded: my %args = ( unit_number => 'ABC123', patient_case_id => 3, record_count => 2, ); check_previous(\%args); # change unit number to unqiue - will create new record: $mech->field( unit_number => '11223344'); $mech->field( error_code_id =>1 ); # just this record - no point testing missing 'scope' as it's not deselectable # should default to 'one' if unit_number not 'unknown' - tests opposite below # $mech->field( scope => 'one'); $mech->submit_form(); # print_and_exit(); has_edit_success(1); # check fields are as expected: my %params = ( name => 'brown', old_unit_number => 1234, new_unit_number => 11223344, location => 'Newtown General Infirmary', old_val_retained => 1, # old unit_number should still be detected ); check_edit(\%params); # print_and_exit(); # check history: $mech->get_ok('/history/=/2'); # print_and_exit(); $mech->has_tag_like( td => qr(amended unit number \[1234 -> 11223344\]), 'OK: expected history found', ); # print_and_exit(); } # select a previous patient_case and change all records to match: { # load page direct: $mech->get_ok('/request/edit/2'); # print_and_exit(); # check other patient_cases data loaded: { my %args = ( unit_number => '1234', patient_case_id => 2, ); check_previous(\%args); } { my %args = ( unit_number => 'ABC123', patient_case_id => 3, ); check_previous(\%args); } # print_and_exit(); $mech->field( use_patient_case_id => 2); $mech->field( scope => 'all'); $mech->field( error_code_id =>1 ); $mech->submit_form(); # print_and_exit(); has_edit_success(1); # check fields are as expected: my %params = ( name => 'brown', new_unit_number => 1234, old_unit_number => 11223344, location => 'Newtown General Infirmary', old_val_retained => 0, # old unit_number should not exist ); check_edit(\%params); # print_and_exit(); # should also be detectable: $params{new_unit_number} = 'ABC123'; check_edit(\%params); # print_and_exit(); # check history: $mech->get_ok('/history/=/2'); # print_and_exit(); $mech->has_tag_like( td => qr(amended unit number \[11223344 -> 1234\]), 'OK: expected history found', ); # print_and_exit(); } # test effect of resubmitting same patient_case data - should be no change: { $mech->get_ok('/request/edit/2'); # print_and_exit(); $mech->field( scope => 'all'); $mech->field( error_code_id =>1 ); $mech->submit_form(); # print_and_exit(); # should have 'no changes' msg instead of 'edit success': $mech->content_lacks( get_messages('action')->{edit_success}, 'OK: edit success message not present', ); $mech->content_contains( get_messages('request_edit')->{edit_failed}, 'OK: no changes detected message present', ); $mech->has_tag( td => 1234, 'OK: original unit number still present', ); # print_and_exit(); } # manually change unit_number to match existing patient_case - for scope set to all: { $mech->get_ok('/request/edit/2'); # print_and_exit(); # check other patient_cases data loaded: { my %args = ( unit_number => 'ABC123', patient_case_id => 3, record_count => 2, ); check_previous(\%args); } # change unit number to one match one previously used: $mech->field( unit_number => 'ABC123' ); $mech->field( scope => 'all'); $mech->field( error_code_id =>1 ); $mech->submit_form(); # print_and_exit(); has_edit_success(2); # check fields are as expected: my %params = ( name => 'brown', new_unit_number => 'ABC123', old_unit_number => 1234, location => 'Newtown General Infirmary', old_val_retained => 0, # old unit_number should not exist ); check_edit(\%params); # print_and_exit(); # check history: $mech->get_ok('/history/=/2'); # print_and_exit(); $mech->has_tag_like( td => qr(amended unit number \[1234 -> ABC123\]), 'OK: expected history found', ); # print_and_exit(); } { # delete unit_number - scope = all: $mech->get_ok('/request/edit/2'); # print_and_exit(); # should have 3 records: $mech->text_contains( 'all 3 records', 'OK: correct number of records', ); # delete unit number: $mech->field( unit_number => ''); $mech->field( error_code_id =>1 ); $mech->field( scope => 'all'); $mech->submit_form(); # print_and_exit(); has_edit_success(3); # check fields are as expected: my %params = ( name => 'brown', old_unit_number => 'ABC123', new_unit_number => 'UNKNOWN', location => 'Newtown General Infirmary', old_val_retained => 0, # old unit_number should not be detected ); check_edit(\%params); # check history: $mech->get_ok('/history/=/2'); # print_and_exit(); $mech->has_tag_like( td => qr(deleted unit number \[ABC123\]), 'OK: expected history found', ); # print_and_exit(); } { # update unit_number from 'unknown' - tests scope defaults to 'all': $mech->get_ok('/request/edit/2'); # print_and_exit(); # should have 3 records: $mech->text_contains( 'all 3 records', 'OK: correct number of records', ); # print_and_exit(); # change unit number to one match one previously used: $mech->field( unit_number => 123456 ); $mech->field( error_code_id =>1 ); # should default to 'all' if unit_number = 'unknown' # $mech->field( scope => 'all'); $mech->submit_form(); # print_and_exit(); has_edit_success(3); # check fields are as expected: my %params = ( name => 'brown', new_unit_number => 123456, old_unit_number => 'UNKNOWN', location => 'Newtown General Infirmary', old_val_retained => 0, # old unit_number should not exist ); check_edit(\%params); # print_and_exit(); # check history: $mech->get_ok('/history/=/2'); # print_and_exit(); $mech->has_tag_like( td => qr(amended unit number \[UNKNOWN -> 123456\]), 'OK: expected history found', ); # print_and_exit(); } # change location to one in same parent_organisation: { $mech->get_ok("/register/patient_search?name=brown"); # print_and_exit(); $mech->follow_link(text => 'Select', n => 1); # print_and_exit(); =begin TODO: # need to test for following before edit: #1. Newtown General Infirmary 123456 =cut $mech->get_ok('/search/=/2'); # print_and_exit(); $mech->has_tag( td => 'Newtown General Infirmary', 'OK: expected location value found' ); $mech->has_tag( td => 123456, 'OK: expected unit_number value found' ); $mech->has_tag_like( span => qr(Brown CC), 'OK: expected referrer value found' ); # print_and_exit(); $mech->follow_link_ok( # {n => 8}, "Logout $_ via eighth link on page", { url_regex => qr(request/edit), }, 'edit request using link', ); # print_and_exit(); # change location to one in same parent_org as current: $mech->field( referral_source_id => 5 ); # this would be done automatically by ajax function: $mech->field( _location_name => 'Newtown District Hospital'); $mech->field( error_code_id =>1 ); $mech->field( scope => 'one'); $mech->submit_form(); # print_and_exit(); has_edit_success(1); # check new details: $mech->has_tag( td => 'Newtown District Hospital', 'OK: expected location value found' ); $mech->has_tag( td => 123456, 'OK: expected unit_number value found' ); $mech->has_tag_like( span => qr(Brown CC), 'OK: expected referrer value found' ); # print_and_exit(); # check old location not found: $mech->content_lacks( 'Newtown General Infirmary', 'OK: old location value not found' ); # print_and_exit(); # check history: $mech->get_ok('/history/=/2'); # print_and_exit(); $mech->has_tag_like( td => qr(amended referral source \[Newtown General Infirmary -> Newtown District Hospital\]), 'OK: expected history found', ); # print_and_exit(); $mech->get_ok("/register/patient_search?name=brown"); # print_and_exit(); $mech->follow_link(text => 'Select', n => 1); # print_and_exit(); =begin # TODO: need to test for following after edit: #1. Newtown General Infirmary 123456 #2. Newtown District Hospital 123456 # <= new patient_case =cut } # change location to one in different parent_organisation: { # check referrer & location 1st: $mech->get_ok('/search/=/2'); # print_and_exit(); $mech->has_tag( td => 'Newtown District Hospital', 'OK: expected location value found' ); $mech->has_tag( td => 123456, 'OK: expected unit_number value found' ); $mech->has_tag_like( span => qr(Brown CC), 'OK: expected referrer value found' ); # print_and_exit(); # going to create new referrer_department, so check correct type: $mech->content_like( qr(span class="acronym"(\s+)title="Haematology"), 'OK: correct hospital_department attribute detected', ); $mech->get_ok('/request/edit/2'); # print_and_exit(); $mech->field( referral_source_id => 6 ); # this would be done automatically by ajax function: $mech->field( _location_name => 'Oldtown & Region Trust'); $mech->field( error_code_id =>1 ); $mech->field( scope => 'one'); $mech->submit_form(); # print_and_exit(); has_edit_success(1); $mech->has_tag( td => 'Oldtown & Region Trust', 'OK: new location detected', ); $mech->has_tag( span => 'Unknown', 'OK: unknown referrer detected', ); # print_and_exit(); # have created new referrer_department, so check correct type: $mech->content_like( qr(span class="acronym"(\s+)title="Unknown/other"), 'OK: changed hospital_department attribute correct', ); # check history: $mech->get_ok('/history/=/2'); # print_and_exit(); $mech->has_tag_like( td => qr(amended referral source \[Newtown District Hospital -> Oldtown & Region Trust\]), 'OK: expected history found', ); # print_and_exit(); $mech->get_ok("/register/patient_search?name=brown"); # print_and_exit(); $mech->follow_link(text => 'Select', n => 1); # print_and_exit(); =begin # TODO: need to test for following after edit: 1. Newtown General Infirmary 123456 2. Newtown District Hospital 123456 3. Oldtown & Region Trust 123456 <= new patient_case =cut } # change hospital to gp: { # check referrer & location 1st: $mech->get_ok('/search/=/3'); # print_and_exit(); $mech->has_tag( td => 'Newtown General Infirmary', 'OK: expected location value found' ); $mech->has_tag_like( span => qr(Brown CC), 'OK: expected referrer value found' ); # print_and_exit(); # going to create new referrer_department, so check correct type: $mech->content_like( qr(span class="acronym"(\s+)title="Haematology"), 'OK: correct hospital_department attribute detected', ); $mech->get_ok('/request/edit/3'); # print_and_exit(); $mech->field( referral_source_id => 2 ); # this would be done automatically by ajax function: $mech->field( _location_name => 'The Surgery, Newtown, NT1 1NT'); $mech->field( error_code_id =>1 ); $mech->field( scope => 'one'); $mech->submit_form(); # print_and_exit(); has_edit_success(1); $mech->has_tag( td => 'The Surgery, Newtown, NT1 1NT', 'OK: new location detected', ); $mech->has_tag( span => 'Unknown', 'OK: unknown referrer detected', ); # print_and_exit(); $mech->content_lacks( 'Newtown General Infirmary', 'OK: old location not detected', ); $mech->content_lacks( 'Brown, CC', 'OK: old referrer not detected', ); # print_and_exit(); # have created new referrer_department, so check correct type: $mech->content_like( qr(span class="acronym"(\s+)title="General Medical Practice"), 'OK: changed hospital_department attribute correct', ); # check history: $mech->get_ok('/history/=/3'); # print_and_exit(); $mech->has_tag_like( td => qr(amended referral source \[Newtown General Infirmary -> The Surgery, Newtown, NT1 1NT\]), 'OK: expected history found', ); # print_and_exit(); } # change location and unit_number together: { $mech->get_ok('/request/edit/1'); # print_and_exit(); is( $mech->value('unit_number', 1), 'UNKNOWN', 'OK: expected unit number detected', ); # print_and_exit(); is( $mech->value('_location_name', 1), 'The Surgery, Newtown, NT1 1NT', 'OK: expected location detected', ); # print_and_exit(); $mech->field( referral_source_id => 6 ); $mech->field( unit_number => 54321 ); # this would be done automatically by ajax function: $mech->field( _location_name => 'Oldtown & Region Trust'); $mech->field( error_code_id =>1 ); $mech->field( scope => 'one'); $mech->submit_form(); # print_and_exit(); has_edit_success(1); # check new details: $mech->has_tag( td => 'Oldtown & Region Trust', 'OK: expected location value found' ); $mech->has_tag( td => 54321, 'OK: expected unit_number value found' ); $mech->has_tag_like( span => qr(Unknown), 'OK: expected referrer value found' ); # print_and_exit(); # check old location not found: $mech->content_lacks( 'The Surgery, Newtown, NT1 1NT', 'OK: old location value not found' ); # print_and_exit(); # check old referrer not found: $mech->content_lacks( 'Brown, CC', 'OK: old referrer not found' ); # print_and_exit(); # have created new referrer_department, so check correct type: $mech->content_like( qr(span class="acronym"(\s+)title="Unknown/other"), 'OK: changed hospital_department attribute correct', ); # check history: $mech->get_ok('/history/=/1'); # print_and_exit(); $mech->has_tag_like( td => qr(amended referral source \[The Surgery, Newtown, NT1 1NT -> Oldtown & Region Trust\]), 'OK: expected history found', ); $mech->has_tag_like( td => qr(amended unit number \[UNKNOWN -> 54321\]), 'OK: expected history found', ); # print_and_exit(); } # use back button & re-submit form (should not cause error): { $mech->get_ok('/request/edit/3'); # print_and_exit(); $mech->field( unit_number => 'ABC123'); $mech->field( error_code_id =>1 ); $mech->field( scope => 'one'); $mech->submit_form(); # print_and_exit(); has_edit_success(1); $mech->back(); # print_and_exit(); $mech->field( error_code_id =>1 ); # still need to add this $mech->submit_form(); # print_and_exit(); $mech->content_contains( get_messages('request_edit')->{edit_failed}, 'OK: no changes detected message present', ); } # emulate what happens when request data loaded in tab1 then update on another # record done in tab2, then tab1 update completed: { # load request/patient_case data into session (1st tab): $mech->get_ok('/request/edit/2'); # print_and_exit(); # submit data for a different request (emulating 2nd tab): $mech->post_ok('/request/update/3', { unit_number => 'ABC1234', error_code_id => 1 }); # print_and_exit(); $mech->content_contains( 'session data belongs to a different request', 'OK: incorrect request data', ); $mech->content_like( qr{expected 3/16, retrieved 2/16}, 'OK: expected vs retrieved request mismatch', ); # print_and_exit(); } # do_logout(); # fails as last test caused 500 error so no logout link sub check_edit { my $params = shift; my $name = $params->{name}; # check new unit_number loaded $mech->has_tag( td => $params->{new_unit_number}, 'OK: new unit_number loaded', ); # check old location still present: $mech->has_tag( td => $params->{location}, 'OK: original refereral_source still present', ); # print_and_exit(); # do reg lookup for same patient to check old record doesn't exist: $mech->get_ok("/register/patient_search?name=$name"); # print_and_exit(); # should only be 1 record: $mech->content_like( qr(Found 1 record matching name=$name), 'OK: only 1 matching record found', ); # print_content(); $mech->follow_link(text => 'Select', n => 1); # if ($name eq 'brown') { print_and_exit(); } # check it's the new record: $mech->has_tag( td => $params->{new_unit_number}, 'OK: new unit_number record found', ); # print_and_exit(); # old unit_number should be retained: if ($params->{old_val_retained}) { $mech->has_tag( td => $params->{old_unit_number}, 'OK: old unit_number record found', ); # print_and_exit(); } # old unit_number should be deleted: else { test_out( 'not ok 1 - foo' ); test_fail( +1 ); $mech->has_tag( td => $params->{old_unit_number}, 'foo' ); test_test( 'OK: old unit_number record not found' ); # print_and_exit(); } # print_content(); } sub check_previous { my $args = shift; # check we have 'previous record' option: $mech->content_like( qr(name="use_patient_case_id"(\s+)value="$args->{patient_case_id}"), 'OK: previous record case_id loaded' ); $mech->content_like( qr(value="$args->{unit_number}"), 'OK: previous record unit_number loaded' ); $mech->has_tag_like( span => qr(select), "OK: 'select' label present", ); # print_and_exit(); if ( my $count = $args->{record_count} ) { # check we have 'Apply change to': $mech->has_tag_like( span => qr(Apply change to), 'OK: scope options loaded', ); $mech->text_contains( "all $count records", 'OK: correct number of records', ); # print_and_exit(); } } sub has_edit_success { my $i = shift; my $msg = sprintf get_messages('request_edit')->{edit_success}, $i; $msg =~ s/([\(\)])/\\$1/g; # need to escape parens in edit_success msg or qr fails $mech->has_tag_like( p => qr(INFO: $msg), 'OK: edit action succeeded', ); } sub create_view { my $sql = <do( qq!CREATE OR REPLACE ALGORITHM=UNDEFINED SQL SECURITY DEFINER VIEW `test`.`_requests` AS $sql! ); }