Added more tests for the register api.

This commit is contained in:
Paul Dill 2017-02-01 12:07:51 +00:00
parent fc8b74fe13
commit 31fcb1bde8
2 changed files with 296 additions and 46 deletions

View file

@ -70,19 +70,47 @@ post '/register' => sub {
my $self = shift; my $self = shift;
my $json = $self->req->json; my $json = $self->req->json;
$self->app->log->debug( "\n\nStart of register");
$self->app->log->debug( "JSON: " . Dumper $json ); $self->app->log->debug( "JSON: " . Dumper $json );
my $token = $json->{token}; if ( ! defined $json ){
if ( ! $self->is_token_unused($token) ) { $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => { return $self->render( json => {
success => Mojo::JSON->false, success => Mojo::JSON->false,
message => 'Token not valid or has been used.', message => 'No json sent.',
},
status => 400,); #Malformed request
}
my $token = $json->{token};
if ( ! defined $token ){
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => {
success => Mojo::JSON->false,
message => 'No token sent.',
},
status => 400,); #Malformed request
}
elsif ( ! $self->is_token_unused($token) ) {
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => {
success => Mojo::JSON->false,
message => 'Token invalid or has been used.',
}, },
status => 401,); #Unauthorized status => 401,); #Unauthorized
} }
my $username = $json->{username}; my $username = $json->{username};
if ($username eq ''){ if ( ! defined $username ){
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => {
success => Mojo::JSON->false,
message => 'No username sent.',
},
status => 400,); #Malformed request
}
elsif ($username eq ''){
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => { return $self->render( json => {
success => Mojo::JSON->false, success => Mojo::JSON->false,
message => 'Username cannot be blank.', message => 'Username cannot be blank.',
@ -90,6 +118,7 @@ post '/register' => sub {
status => 400,); #Malformed request status => 400,); #Malformed request
} }
elsif ( ! ($username =~ m/^[A-Za-z0-9]+$/)){ elsif ( ! ($username =~ m/^[A-Za-z0-9]+$/)){
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => { return $self->render( json => {
success => Mojo::JSON->false, success => Mojo::JSON->false,
message => 'Username can only be A-Z, a-z and 0-9 characters.', message => 'Username can only be A-Z, a-z and 0-9 characters.',
@ -97,6 +126,7 @@ post '/register' => sub {
status => 400,); #Malformed request status => 400,); #Malformed request
} }
elsif ( $self->does_username_exist($username) ) { elsif ( $self->does_username_exist($username) ) {
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => { return $self->render( json => {
success => Mojo::JSON->false, success => Mojo::JSON->false,
message => 'Username exists.', message => 'Username exists.',
@ -105,7 +135,16 @@ post '/register' => sub {
} }
my $email = $json->{email}; my $email = $json->{email};
if ( ! Email::Valid->address($email)){ if ( ! defined $email ){
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => {
success => Mojo::JSON->false,
message => 'No email sent.',
},
status => 400,); #Malformed request
}
elsif ( ! Email::Valid->address($email)){
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => { return $self->render( json => {
success => Mojo::JSON->false, success => Mojo::JSON->false,
message => 'Email is invalid.', message => 'Email is invalid.',
@ -113,6 +152,7 @@ post '/register' => sub {
status => 400,); #Malformed request status => 400,); #Malformed request
} }
elsif($self->does_email_exist($email)) { elsif($self->does_email_exist($email)) {
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => { return $self->render( json => {
success => Mojo::JSON->false, success => Mojo::JSON->false,
message => 'Email exists.', message => 'Email exists.',
@ -122,9 +162,25 @@ post '/register' => sub {
#TODO test to see if post code is valid. #TODO test to see if post code is valid.
my $postcode = $json->{postcode}; my $postcode = $json->{postcode};
if ( ! defined $postcode ){
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => {
success => Mojo::JSON->false,
message => 'No postcode sent.',
},
status => 400,); #Malformed request
}
#TODO should we enforce password requirements. #TODO should we enforce password requirements.
my $password = $json->{password}; my $password = $json->{password};
if ( ! defined $password ){
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => {
success => Mojo::JSON->false,
message => 'No password sent.',
},
status => 400,); #Malformed request
}
my $hashedPassword = $self->generate_hashed_password($password); my $hashedPassword = $self->generate_hashed_password($password);
my $secondsTime = time(); my $secondsTime = time();
@ -132,11 +188,30 @@ post '/register' => sub {
my $usertype = $json->{usertype}; my $usertype = $json->{usertype};
if ($usertype eq 'customer'){ if ( ! defined $usertype ){
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => {
success => Mojo::JSON->false,
message => 'No usertype sent.',
},
status => 400,); #Malformed request
}
elsif ($usertype eq 'customer'){
$self->app->log->debug('Path: file:' . __FILE__ . ', line: ' . __LINE__);
my $age = $json->{age}; my $age = $json->{age};
if ( ! defined $age ){
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => {
success => Mojo::JSON->false,
message => 'No age sent.',
},
status => 400,); #Malformed request
}
my $ageForeignKey = $self->get_age_foreign_key($age); my $ageForeignKey = $self->get_age_foreign_key($age);
if ( ! defined $ageForeignKey ){ if ( ! defined $ageForeignKey ){
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => { return $self->render( json => {
success => Mojo::JSON->false, success => Mojo::JSON->false,
message => 'Age range is invalid.', message => 'Age range is invalid.',
@ -147,6 +222,7 @@ post '/register' => sub {
#TODO UNTESTED as it's hard to simulate. #TODO UNTESTED as it's hard to simulate.
#Token is no longer valid race condition. #Token is no longer valid race condition.
if ( ! $self->set_token_as_used($token) ){ if ( ! $self->set_token_as_used($token) ){
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => { return $self->render( json => {
success => Mojo::JSON->false, success => Mojo::JSON->false,
message => 'Token no longer is accepted.', message => 'Token no longer is accepted.',
@ -169,15 +245,27 @@ post '/register' => sub {
my $insertUser = $self->db->prepare("INSERT INTO Users (CustomerId_FK, Email, JoinDate, HashedPassword) VALUES (?, ?, ?, ?)"); my $insertUser = $self->db->prepare("INSERT INTO Users (CustomerId_FK, Email, JoinDate, HashedPassword) VALUES (?, ?, ?, ?)");
my $rowsInsertedUser = $insertUser->execute($idToUse, $email, $date, $hashedPassword); my $rowsInsertedUser = $insertUser->execute($idToUse, $email, $date, $hashedPassword);
$self->app->log->debug('Path Success: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => { success => Mojo::JSON->true } ); return $self->render( json => { success => Mojo::JSON->true } );
} }
elsif ($usertype eq 'organisation') { elsif ($usertype eq 'organisation') {
$self->app->log->debug('Path: file:' . __FILE__ . ', line: ' . __LINE__);
#TODO validation on the address. Or perhaps add the organisation to a "to be inspected" list then manually check them. #TODO validation on the address. Or perhaps add the organisation to a "to be inspected" list then manually check them.
my $fullAddress = $json->{fulladdress}; my $fullAddress = $json->{fulladdress};
if ( ! defined $fullAddress ){
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => {
success => Mojo::JSON->false,
message => 'No fulladdress sent.',
},
status => 400,); #Malformed request
}
#TODO UNTESTED as it's hard to simulate. #TODO UNTESTED as it's hard to simulate.
#Token is no longer valid race condition. #Token is no longer valid race condition.
if ( ! $self->set_token_as_used($token) ){ if ( ! $self->set_token_as_used($token) ){
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => { return $self->render( json => {
success => Mojo::JSON->false, success => Mojo::JSON->false,
message => 'Token no longer is accepted.', message => 'Token no longer is accepted.',
@ -200,9 +288,11 @@ post '/register' => sub {
my $insertUser = $self->db->prepare("INSERT INTO Users (OrganisationalId_FK, Email, JoinDate, HashedPassword) VALUES (?, ?, ?, ?)"); my $insertUser = $self->db->prepare("INSERT INTO Users (OrganisationalId_FK, Email, JoinDate, HashedPassword) VALUES (?, ?, ?, ?)");
my $rowsInsertedUser = $insertUser->execute($idToUse, $email, $date, $hashedPassword); my $rowsInsertedUser = $insertUser->execute($idToUse, $email, $date, $hashedPassword);
$self->app->log->debug('Path Success: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => { success => Mojo::JSON->true } ); return $self->render( json => { success => Mojo::JSON->true } );
} }
else{ else{
$self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__);
return $self->render( json => { return $self->render( json => {
success => Mojo::JSON->false, success => Mojo::JSON->false,
message => '"usertype" is invalid.', message => '"usertype" is invalid.',
@ -352,4 +442,5 @@ helper check_password_email => sub{
return $ppr->match($password); return $ppr->match($password);
}; };
app->start; app->start;

View file

@ -25,17 +25,45 @@ for (split ';', $sqlDeployment){
} }
#Variables to be used for uniqueness when testing. #Variables to be used for uniqueness when testing.
my @names = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'); my @names = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
my @emails = ('a@a.com', 'b@a.com', 'c@a.com', 'd@a.com', 'e@a.com', 'f@a.com', 'g@a.com', 'h@a.com', 'i@a.com', 'j@a.com', 'k@a.com', 'l@a.com', 'm@a.com', 'n@a.com'); my @emails = ('a@a.com', 'b@a.com', 'c@a.com', 'd@a.com', 'e@a.com', 'f@a.com', 'g@a.com', 'h@a.com', 'i@a.com', 'j@a.com', 'k@a.com', 'l@a.com', 'm@a.com', 'n@a.com', 'o@a.com', 'p@a.com', 'q@a.com', 'r@a.com', 's@a.com', 't@a.com', 'u@a.com', 'v@a.com', 'w@a.com', 'x@a.com', 'y@a.com', 'z@a.com');
my @tokens = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'); my @tokens = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
my $tokenStatement = $dbh->prepare('INSERT INTO Tokens (TokenName) VALUES (?)'); my $tokenStatement = $dbh->prepare('INSERT INTO Tokens (TokenName) VALUES (?)');
foreach (@tokens){ foreach (@tokens){
my $rowsAdded = $tokenStatement->execute($_); my $rowsAdded = $tokenStatement->execute($_);
} }
#No JSON sent
print "test1\n\n";
$t->post_ok('/register')
->status_is(400)
->json_is('/success', Mojo::JSON->false)
->content_like(qr/no json sent/i);
#Empty JSON
print "test2\n\n";
my $testJson = {};
$t->post_ok('/register' => json => $testJson)
->json_is('/success', Mojo::JSON->false);
#token missing JSON
print "test3\n\n";
my $testJson = {
'usertype' => 'customer',
'username' => shift(@names),
'email' => shift(@emails),
'postcode' => 'LA1 1AA',
'password' => 'Meh',
'age' => '50+'
};
$t->post_ok('/register' => json => $testJson)
->status_is(400)
->json_is('/success', Mojo::JSON->false)
->content_like(qr/no token sent/i);
#Not valid token. #Not valid token.
print "test1\n\n"; print "test4\n\n";
my $testJson = { my $testJson = {
'usertype' => 'customer', 'usertype' => 'customer',
'token' => ' ', 'token' => ' ',
@ -46,12 +74,29 @@ my $testJson = {
'age' => '50+' 'age' => '50+'
}; };
$t->post_ok('/register' => json => $testJson) $t->post_ok('/register' => json => $testJson)
->status_is(401)->or(sub{ diag $t->tx->res->body}) ->status_is(401)
->json_is('/success', Mojo::JSON->false) ->json_is('/success', Mojo::JSON->false)
->content_like(qr/token/i); ->content_like(qr/token/i)
->content_like(qr/invalid/i);
#username missing JSON
print "test5\n\n";
my $testJson = {
'usertype' => 'customer',
'token' => shift(@tokens),
'email' => shift(@emails),
'postcode' => 'LA1 1AA',
'password' => 'Meh',
'age' => '50+'
};
$t->post_ok('/register' => json => $testJson)
->status_is(400)
->json_is('/success', Mojo::JSON->false)
->content_like(qr/no username sent/i);
#Blank username #Blank username
print "test2\n\n"; print "test6\n\n";
my $testJson = { my $testJson = {
'usertype' => 'customer', 'usertype' => 'customer',
'token' => shift(@tokens), 'token' => shift(@tokens),
@ -68,7 +113,7 @@ $t->post_ok('/register' => json => $testJson)
->content_like(qr/username/i); ->content_like(qr/username/i);
#Not alpha numeric chars e.g. ! #Not alpha numeric chars e.g. !
print "test3\n\n"; print "test7\n\n";
my $testJson = { my $testJson = {
'usertype' => 'customer', 'usertype' => 'customer',
'token' => shift(@tokens), 'token' => shift(@tokens),
@ -87,7 +132,7 @@ my $usernameToReuse = shift(@names);
my $emailToReuse = shift(@emails); my $emailToReuse = shift(@emails);
#Valid customer #Valid customer
print "test4\n\n"; print "test8\n\n";
my $testJson = { my $testJson = {
'usertype' => 'customer', 'usertype' => 'customer',
'token' => shift(@tokens), 'token' => shift(@tokens),
@ -102,7 +147,7 @@ $t->post_ok('/register' => json => $testJson)
->json_is('/success', Mojo::JSON->true); ->json_is('/success', Mojo::JSON->true);
#Valid customer2 #Valid customer2
print "test5\n\n"; print "test9\n\n";
my $testJson = { my $testJson = {
'usertype' => 'customer', 'usertype' => 'customer',
'token' => shift(@tokens), 'token' => shift(@tokens),
@ -117,7 +162,7 @@ $t->post_ok('/register' => json => $testJson)
->json_is('/success', Mojo::JSON->true); ->json_is('/success', Mojo::JSON->true);
#Valid customer3 #Valid customer3
print "test6\n\n"; print "test10\n\n";
my $testJson = { my $testJson = {
'usertype' => 'customer', 'usertype' => 'customer',
'token' => shift(@tokens), 'token' => shift(@tokens),
@ -132,7 +177,7 @@ $t->post_ok('/register' => json => $testJson)
->json_is('/success', Mojo::JSON->true); ->json_is('/success', Mojo::JSON->true);
#Username exists #Username exists
print "test7\n\n"; print "test11\n\n";
my $testJson = { my $testJson = {
'usertype' => 'customer', 'usertype' => 'customer',
'token' => shift(@tokens), 'token' => shift(@tokens),
@ -147,8 +192,23 @@ $t->post_ok('/register' => json => $testJson)
->json_is('/success', Mojo::JSON->false) ->json_is('/success', Mojo::JSON->false)
->content_like(qr/exists/i); ->content_like(qr/exists/i);
#email missing JSON
print "test12\n\n";
my $testJson = {
'usertype' => 'customer',
'token' => shift(@tokens),
'username' => shift(@names),
'postcode' => 'LA1 1AA',
'password' => 'Meh',
'age' => '50+'
};
$t->post_ok('/register' => json => $testJson)
->status_is(400)
->json_is('/success', Mojo::JSON->false)
->content_like(qr/no email sent/i);
#invalid email 1 #invalid email 1
print "test8\n\n"; print "test13\n\n";
my $testJson = { my $testJson = {
'usertype' => 'customer', 'usertype' => 'customer',
'token' => shift(@tokens), 'token' => shift(@tokens),
@ -165,7 +225,7 @@ $t->post_ok('/register' => json => $testJson)
->content_like(qr/invalid/i); ->content_like(qr/invalid/i);
#invalid email 2 #invalid email 2
print "test9\n\n"; print "test14\n\n";
my $testJson = { my $testJson = {
'usertype' => 'customer', 'usertype' => 'customer',
'token' => shift(@tokens), 'token' => shift(@tokens),
@ -182,7 +242,7 @@ $t->post_ok('/register' => json => $testJson)
->content_like(qr/invalid/i); ->content_like(qr/invalid/i);
#Email exists #Email exists
print "test10\n\n"; print "test15\n\n";
my $testJson = { my $testJson = {
'usertype' => 'customer', 'usertype' => 'customer',
'token' => shift(@tokens), 'token' => shift(@tokens),
@ -198,41 +258,57 @@ $t->post_ok('/register' => json => $testJson)
->content_like(qr/email/i) ->content_like(qr/email/i)
->content_like(qr/exists/i); ->content_like(qr/exists/i);
#postcode missing JSON
#Age is invalid print "test16\n\n";
print "test11\n\n";
my $testJson = { my $testJson = {
'usertype' => 'customer', 'usertype' => 'customer',
'token' => shift(@tokens), 'token' => shift(@tokens),
'username' => shift(@names), 'username' => shift(@names),
'email' => shift(@emails), 'email' => shift(@emails),
'postcode' => 'LA1 1AA', 'password' => 'Meh',
'password' => 'Meh', 'age' => '50+'
'age' => 'invalid'
}; };
$t->post_ok('/register' => json => $testJson) $t->post_ok('/register' => json => $testJson)
->status_is(400) ->status_is(400)
->json_is('/success', Mojo::JSON->false) ->json_is('/success', Mojo::JSON->false)
->content_like(qr/age/i) ->content_like(qr/no postcode sent/i);
->content_like(qr/invalid/i);
#Organisation valid #TODO validate postcode
print "test12\n\n";
#password missing JSON
print "test17\n\n";
my $testJson = { my $testJson = {
'usertype' => 'organisation', 'usertype' => 'customer',
'token' => shift(@tokens), 'token' => shift(@tokens),
'username' => shift(@names), 'username' => shift(@names),
'email' => shift(@emails), 'email' => shift(@emails),
'postcode' => 'LA1 1AA', 'postcode' => 'LA1 1AA',
'password' => 'Meh', 'age' => '50+'
'fulladdress' => 'mary lane testing....'
}; };
$t->post_ok('/register' => json => $testJson) $t->post_ok('/register' => json => $testJson)
->status_is(200) ->status_is(400)
->json_is('/success', Mojo::JSON->true); ->json_is('/success', Mojo::JSON->false)
->content_like(qr/no password sent/i);
#TODO enforce password complexity requirements.
#usertype missing JSON
print "test18\n\n";
my $testJson = {
'token' => shift(@tokens),
'username' => shift(@names),
'email' => shift(@emails),
'postcode' => 'LA1 1AA',
'password' => 'Meh',
'age' => '50+'
};
$t->post_ok('/register' => json => $testJson)
->status_is(400)
->json_is('/success', Mojo::JSON->false)
->content_like(qr/no usertype sent/i);
#Invalid user type #Invalid user type
print "test13\n\n"; print "test19\n\n";
my $testJson = { my $testJson = {
'usertype' => 'organisation1', 'usertype' => 'organisation1',
'token' => shift(@tokens), 'token' => shift(@tokens),
@ -248,4 +324,87 @@ $t->post_ok('/register' => json => $testJson)
->content_like(qr/usertype/i) ->content_like(qr/usertype/i)
->content_like(qr/invalid/i); ->content_like(qr/invalid/i);
#age missing JSON
print "test20\n\n";
my $testJson = {
'usertype' => 'customer',
'token' => shift(@tokens),
'username' => shift(@names),
'email' => shift(@emails),
'postcode' => 'LA1 1AA',
'password' => 'Meh',
};
$t->post_ok('/register' => json => $testJson)
->status_is(400)
->json_is('/success', Mojo::JSON->false)
->content_like(qr/no age sent/i);
#Age is invalid
print "test21\n\n";
my $testJson = {
'usertype' => 'customer',
'token' => shift(@tokens),
'username' => shift(@names),
'email' => shift(@emails),
'postcode' => 'LA1 1AA',
'password' => 'Meh',
'age' => 'invalid'
};
$t->post_ok('/register' => json => $testJson)
->status_is(400)
->json_is('/success', Mojo::JSON->false)
->content_like(qr/age/i)
->content_like(qr/invalid/i);
#full address missing JSON
print "test22\n\n";
my $testJson = {
'usertype' => 'organisation',
'token' => shift(@tokens),
'username' => shift(@names),
'email' => shift(@emails),
'postcode' => 'LA1 1AA',
'password' => 'Meh',
};
$t->post_ok('/register' => json => $testJson)
->status_is(400)
->json_is('/success', Mojo::JSON->false)
->content_like(qr/no fulladdress sent/i);
#TODO Validation of full address
#Organisation valid
print "test23\n\n";
my $testJson = {
'usertype' => 'organisation',
'token' => shift(@tokens),
'username' => shift(@names),
'email' => shift(@emails),
'postcode' => 'LA1 1AA',
'password' => 'Meh',
'fulladdress' => 'mary lane testing....'
};
$t->post_ok('/register' => json => $testJson)
->status_is(200)
->json_is('/success', Mojo::JSON->true);
#No JSON sent
#print "test14\n\n";
#my $testJson = {
# 'usertype' => 'customer',
# 'token' => shift(@tokens),
# 'username' => shift(@names),
# 'email' => shift(@emails),
# 'postcode' => 'LA1 1AA',
# 'password' => 'Meh',
# 'age' => '50+'
#};
#$t->post_ok('/register' => json => $testJson)
# ->status_is(401)->or(sub{ diag $t->tx->res->body})
# ->json_is('/success', Mojo::JSON->false)
# ->content_like(qr/token/i);
done_testing(); done_testing();