RSS Git Download  Clone
Raw Blame History
use strict;
use warnings;

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 IO::All;
use Plack::Test;
use HTTP::Cookies;
use Plack::Builder;
use Data::Printer alias => 'ddp'; # ddp \%ENV;
use HTTP::Request::Common; # GET

use Test::More;
use Test::Most; # bail_on_fail

require_ok('Reporter::Test');  # also loads Reporter::Class - imports Data::Printer, Moo, etc
require_ok('Reporter::Routes');
require_ok('Reporter::Routes::AJAX');

# create a testing object for app:
my $app = builder {
  mount '/'     => Reporter::Routes->to_app;
  mount '/ajax' => Reporter::Routes::AJAX->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};

# check test scripts using sqlite in-memory db:
bail_on_fail;
like  ($dbix->dbh->{Name}, qr/:memory:/, 'sqlite db in use');

use lib 't';
use schema;
run_schema($dbix); # create tables & add some data (users, requests, request_specimen, etc)

my $user_id = 1;
{ # 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');
    }
}
{ # ajax call:
    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/ajax/get_diagnoses?diagnosis=cll';
    $cookie_jar->add_cookie_header( $request ); # p $request->dump;
    # returns json:
    my $content = $test->request( $request ); # p $content->as_string;
    like( $content->as_string, qr{9823/3}, 'expected icdo3 code' );
    like( $content->as_string, qr{CLL}, 'expected diagnosis' );
}

done_testing();