BEGIN { # set test env otherwise get development config settings - unless explicitly
# set at command-line: "DANCER_ENVIRONMENT=development prove -lv t/"
$ENV{DANCER_ENVIRONMENT} ||= $ENV{PLACK_ENV} ||= 'test';
# set EMAIL_SENDER_TRANSPORT=TestFail at command line to force email failure:
$ENV{EMAIL_SENDER_TRANSPORT} ||= 'Test'; # default to Test if not set at command-line
}
use Test::More;
use Test::Most; # bail_on_fail
use Reporter::Class;
use Reporter::Routes;
require_ok('Reporter::Test'); # Data::Printer, Moo, etc
require_ok('Reporter::Routes');
use IO::All;
use Plack::Test;
use HTTP::Cookies;
use Reporter::Test;
use Data::Printer; # ddp \%ENV;
use HTTP::Request::Common; # GET
# create a testing object for app:
my $app = Reporter::Routes->to_app;
isa_ok( $app, 'CODE' );
my $test = Plack::Test->create($app);
# create a testing object for model:
my $model = Reporter::Test->new->app->model;
# get model dbix (using sqlite db):
my $dbix = $model->db->dbix; # ddp $dbix->dbh->{Name};
my $now = DateTime->now;
# check test scripts using sqlite in-memory db:
bail_on_fail;
like ($dbix->dbh->{Name}, qr/:memory:/, 'sqlite db in use');
run_schema(); # create tables & add some data (users, requests, request_specimen, etc)
my $user_id = 1;
{ # userid = username, incorrect password:
my %params = ( userid => 'queenie', password => 'queenie' );
my $res = $model->authenticate_user(\%params); # ddp $res;
is($res, 0, 'incorrect password');
}
{ # userid = username, correct password:
my %params = ( userid => 'queenie', password => 'Queenie' );
my $res = $model->authenticate_user(\%params); # ddp $res;
is( ref $res, 'HASH', 'authenticate returned hashref' );
is( $res->{username}, 'queenie', 'username matches for userid = username' );
is( $res->{id}, $user_id, 'user id matches' );
}
{ # userid = email, correct password:
my %params = ( userid => 'queenie@mail.com', password => 'Queenie' );
my $res = $model->authenticate_user(\%params); # ddp $res;
is( ref $res, 'HASH', 'authenticate returned hashref' );
is( $res->{username}, 'queenie', 'username matches for userid = email' );
}
{ # get reports for user #1:
my $n = get_reports_for_user($user_id);
is( $n, 0, "no reports for user id $user_id" );
}
{ # add some draft_reports:
my %h = (
user_id => $user_id,
request_id => 1, # will auto-increment in loop
diagnosis_id => 1,
);
$dbix->insert('request_draft_report', \%h) && $h{request_id}++ for (1..5);
# my $ref = $dbix->select('request_draft_report', '*')->hashes; p $ref;
# my $n = $dbix->count('request_draft_report'); p $n;
}
{ # get reports for user #1:
my $n = get_reports_for_user($user_id);
is( $n, 5, "5 reports for user id $user_id" );
}
{ # user reports:
my $res = $model->user_reports_list($user_id); # p $res;
is ( ref $res, 'HASH', 'user reports returned hashref' );
is ( ref $res->{reports}, 'ARRAY', 'reports is in list format' );
is ( @{ $res->{reports} }, 5, '5 reports returned' );
is( ref $res->{specimen}, 'ARRAY', 'specimen is in list format' );
# contains 5 PB's:
is ( $res->{specimen}->[0]->{id}, 'PB', 'expected sample type' );
is ( $res->{specimen}->[0]->{n}, 5, 'expected sample number' );
}
{ # new report:
my %h = (
biopsy_site => 'biopsy site',
clinical_details => 'clinical details',
comment => 'comment',
created_at => $now,
diagnosis_id => 1,
gross_description => 'gross description',
morphology => 'morphology',
request_id => 6,
request_notes => 'request notes',
secondary_diagnosis_id => undef,
specimen_quality => 'specimen quality',
status => 'new',
user_id => $user_id,
);
my $res = $model->save_report(\%h); # p $res;
is ( ref $res, 'HASH', 'save report returned hashref' );
is ( $res->{success}, 1, 'new record created successfully');
my $ref = $dbix->select('request_draft_report','*', { request_id => 6 })->hash; # p $ref;
is_deeply( $ref, \%h, 'data structures identical' );
}
{ # user roles:
my $response = $test->request( POST '/login',
[ userid => 'queenie', password => 'Queenie' ] ); # p $response;
# handle cookies for next request:
my $cookie_jar = HTTP::Cookies->new;
$cookie_jar->extract_cookies($response);
# my @cookies;
# $cookie_jar->scan( sub { @cookies = @_ }); p \@cookies;
# create HTTP::Request object and add cookies to it:
my $request = GET 'http://localhost/'; # full url to match cookie expectation
$cookie_jar->add_cookie_header( $request ); # p $request->dump;
# resubmit, should get search page:
my $content = $test->request( $request ); # p $content;
like( $content->as_string, qr/Miranda(\s+)RICHARDSON/, 'logged in user displayed' );
unlike( $content->as_string, qr/register/, 'register link not present' );
# error if requested directly:
$request = GET 'http://localhost/register'; # full url to match cookie expectation
$cookie_jar->add_cookie_header( $request ); # p $request->dump;
# resubmit, should get search page:
$content = $test->request( $request ); # p $content;
is( $content->code, 403, 'forbidden request' );
{ # register admin user role:
my %h = (
user_id => $user_id,
function_id => 1,
function_name => 'admin',
);
$dbix->insert('user_permission_view', \%h);
# login again:
$response = $test->request( POST 'http://localhost/login',
[ userid => 'queenie', password => 'Queenie' ] ); # p $response;
my $cookie_jar = HTTP::Cookies->new;
$cookie_jar->extract_cookies($response);
# request register link:
$request = GET 'http://localhost/register'; # full url to match cookie expectation
$cookie_jar->add_cookie_header( $request ); # p $request->dump;
$content = $test->request( $request ); # p $content;
is( $content->code, 200, 'allowed request' );
like( $content->as_string, qr/register/, 'register link now present' );
}
}
{ # register new user:
# check email transport set to test or die:
like( $ENV{EMAIL_SENDER_TRANSPORT}, qr/Test/, 'safe email transport set' )
or BAIL_OUT('unsafe email transport set');
# login:
my $response = $test->request( POST '/login',
[ userid => 'queenie', password => 'Queenie' ] ); # p $response;
# handle cookies for next request:
my $cookie_jar = HTTP::Cookies->new;
$cookie_jar->extract_cookies($response);
# create HTTP::Request object and add cookies to it:
my $request = GET 'http://localhost/register'; # full url to match cookie expectation
$cookie_jar->add_cookie_header( $request ); # p $request->dump;
# resubmit, should get registration page:
my $content = $test->request( $request ); # p $content->as_string;
my %user = (
first_name => 'tony',
last_name => 'robinson',
email => 'baldrick@email.com',
username => 'baldrick',
password => 'Imbecile',
);
$request = POST 'http://localhost/register', \%user; # full url to match cookie expectation
$cookie_jar->add_cookie_header( $request ); # p $request->dump;
$content = $test->request( $request ); # p $content->as_string; exit;
# my @deliveries = Email::Sender::Simple->default_transport->deliveries; p \@deliveries; exit;
is( $content->code, 200, 'request OK' );
my $content_string = $content->as_string; # p $content_string;
# uncomment to dump html to file:
# io('/tmp/draft_reporter_email_message.html')->print($content_string);
# success or failure depends on $ENV{EMAIL_SENDER_TRANSPORT} setting:
my $status_msg = $ENV{EMAIL_SENDER_TRANSPORT} eq 'TestFail'
? 'email failed: test delivery failure' : 'Message sent OK';
like( $content_string, qr/$status_msg/, 'expected test email response' );
like( $content_string, qr/to: $user{email}/, 'expected user email' );
like( $content_string, qr/from: no-reply\@hmds.info/, 'expected from address' );
like( $content_string, qr/reply-to: hmds.lth\@nhs.net/, 'expected reply-to address' );
like( $content_string, qr/cc: hmds.lth\@nhs.net/, 'expected copy-to address' );
like( $content_string, qr/subject: HMDS draft reporter registration/,
'expected subject line' );
like( $content_string, qr/Your HMDS draft reporter registration details/,
'expected text body' );
like( $content_string, qr/username: $user{email}/, 'expected username' ); # email NOT username
like( $content_string, qr/password: $user{password}/, 'expected password' );
# test Email::Sender::Simple->default_transport->deliveries:
SKIP: { # only tests headers, doesn't test any more than above $message:
$ENV{EMAIL_SENDER_TRANSPORT} eq 'Test'
or skip 'unsuitable EMAIL_SENDER_TRANSPORT setting', 4;
my @deliveries = Email::Sender::Simple->default_transport->deliveries; # p \@deliveries;
my $ref = $deliveries[0]; # only 1 msg
is( $ref->{envelope}->{from}, 'no-reply@hmds.info',
'expected from address' );
for my $recipient ($user{email}, 'hmds.lth@nhs.net') {
my $n = grep { $recipient eq $_ } @{ $ref->{envelope}->{to} }; # p $n;
is( $n, 1, 'expected recipient' );
}
is( scalar @{ $ref->{successes} }, 2,
'expected number of recipient successes');
}
}
done_testing(41);
sub get_reports_for_user {
my $user_id = shift;
my %h = (
user_id => $user_id,
page => 1,
uri => '/',
);
my $res = $model->get_reports_for_user(\%h); # ddp $res;
my $n = @{ $res->{reports} };
return $n;
}
sub run_schema {
my @schema = _schema();
do { $dbix->dbh->do($_) || die $dbix->error } foreach @schema; # $dbix->error doesn't work here
{ # draft_report_users & users table:
my %h = (
username => 'queenie',
first_name => 'miranda',
last_name => 'richardson',
password => 'WdQRFOH9t2KmvPpjgHCjTunkDpM', # sha1 Queenie
email => 'queenie@mail.com',
);
$dbix->insert($_, \%h) for qw(draft_report_users users);
}
{ # requests (5):
my %h = (
request_number => 1, # will auto-increment in loop
year => $now->year,
patient_case_id => 1,
status_option_id => 1,
referrer_department_id => 1,
);
$dbix->insert('requests', \%h) && $h{request_number}++ for (1..5);
}
{ # request_specimen (5) & specimen:
my $i = 1;
$dbix->insert('specimens',
{ sample_code => 'PB', description => 'blood' });
$dbix->insert('request_specimen',
{ request_id => $i++, specimen_id => 1}) for (1..5);
}
{ # diagnoses:
my %h = (
name => 'CLL',
icdo3 => '9823/3'
);
$dbix->insert('diagnoses', \%h);
}
}
sub _schema {
return (
q{
CREATE TABLE draft_report_users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username VARCHAR,
first_name VARCHAR,
last_name VARCHAR,
password VARCHAR,
email VARCHAR
)
},
q{
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username VARCHAR,
first_name VARCHAR,
last_name VARCHAR,
password VARCHAR,
email VARCHAR,
active VARCHAR NOT NULL DEFAULT 'yes'
)
},
q{
CREATE TABLE request_draft_report (
user_id INTEGER,
request_id INTEGER,
request_notes VARCHAR,
clinical_details VARCHAR,
biopsy_site VARCHAR,
gross_description VARCHAR,
morphology VARCHAR,
comment VARCHAR,
status VARCHAR,
diagnosis_id INTEGER,
secondary_diagnosis_id INTEGER,
specimen_quality INTEGER,
created_at DATETIME,
updated_at DATETIME
)
},
q{
CREATE TABLE requests (
id INTEGER PRIMARY KEY AUTOINCREMENT,
request_number INTEGER,
year INTEGER,
patient_case_id INTEGER,
referrer_department_id INTEGER,
status_option_id INTEGER,
created_at DATETIME,
updated_at DATETIME
)
},
q{
CREATE TABLE request_specimen (
request_id INTEGER,
specimen_id INTEGER
)
},
q{
CREATE TABLE specimens (
id INTEGER PRIMARY KEY AUTOINCREMENT,
sample_code TEXT,
description TEXT,
active TEXT
)
},
q{
CREATE TABLE diagnoses (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
icdo3 TEXT,
diagnostic_category_id INTEGER,
active TEXT
)
},
q{
CREATE TABLE user_permission_view (
user_id INTEGER,
function_id INTEGER,
function_name VARCHAR
)
}
);
}