diff --git a/.gitignore b/.gitignore index 7286cc8..1af1148 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ myapp.conf hypnotoad.pid *.db *~ +/images diff --git a/cpanfile b/cpanfile index 5ce2d2e..c0d75f0 100644 --- a/cpanfile +++ b/cpanfile @@ -6,3 +6,4 @@ requires 'Email::Valid'; requires 'ORM::Date'; requires 'Authen::Passphrase::BlowfishCrypt'; requires 'Time::Fake'; +requires 'Scalar::Util'; diff --git a/dropschema.sql b/dropschema.sql index 42c35f3..4be21c4 100644 --- a/dropschema.sql +++ b/dropschema.sql @@ -1,3 +1,5 @@ +DROP TABLE IF EXISTS PendingTransactions; +DROP TABLE IF EXISTS PendingOrganisations; DROP TABLE IF EXISTS SessionTokens; DROP TABLE IF EXISTS AccountTokens; DROP TABLE IF EXISTS Transactions; diff --git a/foodloopserver.pl b/foodloopserver.pl index 28498de..63b018b 100644 --- a/foodloopserver.pl +++ b/foodloopserver.pl @@ -10,6 +10,7 @@ use Data::Dumper; use Email::Valid; use ORM::Date; use Authen::Passphrase::BlowfishCrypt; +use Scalar::Util qw(looks_like_number); # connect to database use DBI; @@ -38,36 +39,243 @@ any '/' => sub { post '/upload' => sub { my $self = shift; -# Fetch parameters to write to DB - my $key = $self->param('key'); -# This will include an if function to see if key matches - unless ($key eq $config->{key}) { - return $self->render( json => { success => Mojo::JSON->false }, status => 403 ); - } - my $username = $self->param('username'); - my $company = $self->param('company'); - my $currency = $self->param('currency'); - my $file = $self->req->upload('file'); -# Get image type and check extension - my $headers = $file->headers->content_type; -# Is content type wrong? - if ($headers ne 'image/jpeg') { + + my $userId = $self->get_active_user_id(); + + my $json = $self->param('json'); + if ( ! defined $json ) { + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); return $self->render( json => { success => Mojo::JSON->false, - message => 'Wrong image extension!', - }); - }; -# Rewrite header data + message => 'JSON is missing.', + }, + status => 400,); #Malformed request + } + + $json = Mojo::JSON::decode_json($json); + $self->app->log->debug( "JSON: " . Dumper $json ); + + my $microCurrencyValue = $json->{microCurrencyValue}; + if ( ! defined $microCurrencyValue ) { + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'microCurrencyValue is missing.', + }, + status => 400,); #Malformed request + } + #Is valid number + elsif (! Scalar::Util::looks_like_number($microCurrencyValue)){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'microCurrencyValue does not look like a number.', + }, + status => 400,); #Malformed request + } + #Is the number range valid. + elsif ($microCurrencyValue <= 0){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'microCurrencyValue cannot be equal to or less than zero.', + }, + status => 400,); #Malformed request + } + + my $transactionAdditionType = $json->{transactionAdditionType}; + if ( ! defined $transactionAdditionType ) { + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'transactionAdditionType is missing.', + }, + status => 400,); #Malformed request + } + + my $file = $self->req->upload('file2'); + $self->app->log->debug( "file: " . Dumper $file ); + + if (! defined $file) { + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'no file uploaded.', + }, + status => 400,); #Malformed request + } + my $ext = '.jpg'; my $uuid = Data::UUID->new->create_str; my $filename = $uuid . $ext; -# send photo to image folder on server - $file->move_to('images/' . $filename); -# send data to foodloop db - my $insert = $self->db->prepare('INSERT INTO foodloop (username, company, currency, filename) VALUES (?,?,?,?)'); - $insert->execute($username, $company, $currency, $filename); - $self->render( json => { success => Mojo::JSON->true } ); - $self->render(text => 'It did not kaboom!'); + + #TODO Check for valid image file. +# my $headers = $file->headers->content_type; +# $self->app->log->debug( "content type: " . Dumper $headers ); + #Is content type wrong? +# if ($headers ne 'image/jpeg') { +# return $self->render( json => { +# success => Mojo::JSON->false, +# message => 'Wrong image extension!', +# }, status => 400); +# }; + + #Add validated organisation. + if ($transactionAdditionType == 1){ + + my $addValidatedId = $json->{addValidatedId}; + if (! defined $addValidatedId){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'addValidatedId is missing.', + }, + status => 400,); #Malformed request + } + + if (! $self->does_organisational_id_exist($addValidatedId)){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'addValidatedId does not exist in the database.', + }, + status => 400,); #Malformed request + } + + my $time = time(); + my $statement = $self->db->prepare("INSERT INTO Transactions (BuyerUserId_FK, SellerOrganisationId_FK, ValueMicroCurrency, ProofImage, TimeDateSubmitted) VALUES (?, ?, ?, ?, ?)"); + my $rowsAdded = $statement->execute($userId, $addValidatedId, $microCurrencyValue, $filename, $time); + + #It was successful. + if ($rowsAdded != 0) { + $file->move_to('images/' . $filename); + $self->app->log->debug('Path Success: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->true, + message => 'Added transaction for validated organisation.', + }, + status => 200,); + } + #TODO Untested, not quite sure how to test it. + else { + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'An unknown error occurred when adding the transaction.', + }, + status => 500,); + } + } + #2 and 3 are similar by the adding of a transaction at the end. + elsif ($transactionAdditionType == 2 || $transactionAdditionType == 3){ + + my $unvalidatedOrganisationId = undef; + + if ($transactionAdditionType == 2){ + $self->app->log->debug('Path: file:' . __FILE__ . ', line: ' . __LINE__); + + $unvalidatedOrganisationId = $json->{addUnvalidatedId}; + if (! defined $unvalidatedOrganisationId){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'addUnvalidatedId is missing.', + }, + status => 400,); #Malformed request + } + elsif (! Scalar::Util::looks_like_number($unvalidatedOrganisationId)){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'addUnvalidatedId does not look like a number.', + }, + status => 400,); #Malformed request + } + + my ($existsRef) = $self->db->selectrow_array("SELECT COUNT(PendingOrganisationId) FROM PendingOrganisations WHERE PendingOrganisationId = ? AND UserSubmitted_FK = ?",undef,($unvalidatedOrganisationId, $userId)); + if ($existsRef == 0) { + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'addUnvalidatedId does not exist in the database for the user.', + }, + status => 400,); #Malformed request + } + + } + #type need to add a organisation for type 3. + else{ # ($transactionAdditionType == 3) + $self->app->log->debug('Path: file:' . __FILE__ . ', line: ' . __LINE__); + + #TODO more validation. + my $organisationName = $json->{organisationName}; + if (! defined $organisationName){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'organisationName is missing.', + }, + status => 400,); #Malformed request + } + + #TODO validation. + #TODO check which ones are present. + my $streetName = $json->{streetName}; + my $town = $json->{town}; + my $postcode = $json->{postcode}; + + ($unvalidatedOrganisationId) = $self->db->selectrow_array("SELECT MAX(PendingOrganisationId) FROM PendingOrganisations",undef,()); + if (defined $unvalidatedOrganisationId){ + $unvalidatedOrganisationId++; + } + else{ + $unvalidatedOrganisationId = 1; + } + + my $statement = $self->db->prepare("INSERT INTO PendingOrganisations (PendingOrganisationId, UserSubmitted_FK, TimeDateSubmitted, Name, StreetName, Town, Postcode) VALUES (?, ?, ?, ?, ?, ?, ?)"); + my $rowsAdded = $statement->execute($unvalidatedOrganisationId,$userId,time(),$organisationName,$streetName,$town,$postcode); + + #TODO, untested. It could not be added for some reason. Most likely race conditions. + if ($rowsAdded == 0) { + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'An unknown error occurred when adding the transaction.', + }, + status => 500,); + } + } + + + my $statement2 = $self->db->prepare("INSERT INTO PendingTransactions (BuyerUserId_FK, PendingSellerOrganisationId_FK, ValueMicroCurrency, ProofImage, TimeDateSubmitted) VALUES (?, ?, ?, ?, ?)"); + my $rowsAdded2 = $statement2->execute($userId, $unvalidatedOrganisationId, $microCurrencyValue, $filename, time()); + + if ($rowsAdded2 != 0) { + $file->move_to('images/' . $filename); + $self->app->log->debug('Path Success: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->true, + message => 'Added transaction for unvalidated organisation.', + }, + status => 200,); + } + else { + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'An unknown error occurred when adding the transaction.', + }, + status => 500,); + } + } + else{ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'transactionAdditionType is not a valid value.', + }, + status => 400,); #Malformed request + } }; @@ -79,7 +287,7 @@ post '/register' => sub { $self->app->log->debug( "JSON: " . Dumper $json ); if ( ! defined $json ){ - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + $self->app->log->debug('Path: file:' . __FILE__ . ', line: ' . __LINE__); return $self->render( json => { success => Mojo::JSON->false, message => 'No json sent.', @@ -515,14 +723,21 @@ helper valid_email => sub { return (Email::Valid->address($email)); }; -helper get_account_by_username => sub { - my ( $self, $username ) = @_; +helper get_active_user_id => sub { + my $self = shift; - return $self->db->selectrow_hashref( - "SELECT keyused, username FROM accounts WHERE username = ?", - {}, - $username, - ); + my $token = $self->get_session_token(); + if (! defined $token){ + return undef; + } + + my @out = $self->db->selectrow_array("SELECT UserIdAssignedTo_FK FROM SessionTokens WHERE SessionTokenName = ?",undef,($token)); + if (! @out){ + return undef; + } + else{ + return $out[0]; + } }; helper get_session_token => sub { @@ -649,24 +864,27 @@ helper is_token_unused => sub { }; +#Return true if and only if the token exists and has not been used. +helper does_organisational_id_exist => sub { + my ( $self, $organisationalId ) = @_; + + my ( $out ) = $self->db->selectrow_array("SELECT COUNT(OrganisationalId) FROM Organisations WHERE OrganisationalId = ?", undef, ($organisationalId)); + return $out != 0; +}; + helper get_age_foreign_key => sub { my ( $self, $ageString ) = @_; - my ($out) = $self->db->selectrow_array( - "SELECT AgeRangeId FROM AgeRanges WHERE AgeRangeString = ?", - {}, - $ageString, - ); - + my ($out) = $self->db->selectrow_array("SELECT AgeRangeId FROM AgeRanges WHERE AgeRangeString = ?", undef, ($ageString)); return $out; }; helper get_userid_foreign_key => sub { my ( $self, $email ) = @_; - my ( $out ) = $self->db->selectrow_array("SELECT UserId FROM Users WHERE Email = ?", undef, ($email)); - + my ($out) = $self->db->selectrow_array("SELECT UserId FROM Users WHERE Email = ?", undef, ($email)); return $out; + }; @@ -674,7 +892,6 @@ helper does_username_exist => sub { my ( $self, $username ) = @_; my ($out) = $self->db->selectrow_array("SELECT COUNT(UserName) FROM Customers WHERE UserName = ?", {}, ($username)); - return $out != 0; }; @@ -682,7 +899,6 @@ helper does_email_exist => sub { my ( $self, $email ) = @_; my ($out) = $self->db->selectrow_array("SELECT COUNT(Email) FROM Users WHERE Email = ?", {}, ($email)); - return $out != 0; }; diff --git a/schema.sql b/schema.sql index 8acd729..64d0d05 100644 --- a/schema.sql +++ b/schema.sql @@ -38,9 +38,9 @@ CREATE TABLE Transactions ( TransactionId INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, BuyerUserId_FK INTEGER NOT NULL, SellerOrganisationId_FK INTEGER NOT NULL, - Date TEXT NOT NULL, ValueMicroCurrency INTEGER NOT NULL, ProofImage TEXT NOT NULL UNIQUE, + TimeDateSubmitted INTEGER NOT NULL, FOREIGN KEY (BuyerUserId_FK) REFERENCES Users (UserId), FOREIGN KEY (SellerOrganisationId_FK) REFERENCES Organisations (OrganisationalId) ); @@ -58,3 +58,25 @@ CREATE TABLE SessionTokens ( ExpireDateTime INTEGER NOT NULL, FOREIGN KEY (UserIdAssignedTo_FK) REFERENCES Users (UserId) ); + +CREATE TABLE PendingOrganisations ( + PendingOrganisationId INTEGER PRIMARY KEY UNIQUE NOT NULL, + UserSubmitted_FK INTEGER NOT NULL, + TimeDateSubmitted INTEGER NOT NULL, + Name TEXT NOT NULL, + StreetName TEXT, + Town TEXT, + Postcode TEXT, + FOREIGN KEY (UserSubmitted_FK) REFERENCES Users (UserId) +); + +CREATE TABLE PendingTransactions ( + PendingTransactionId INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, + BuyerUserId_FK INTEGER NOT NULL, + PendingSellerOrganisationId_FK INTEGER NOT NULL, + ValueMicroCurrency INTEGER NOT NULL, + ProofImage TEXT NOT NULL UNIQUE, + TimeDateSubmitted INTEGER NOT NULL, + FOREIGN KEY (BuyerUserId_FK) REFERENCES Users (UserId), + FOREIGN KEY (PendingSellerOrganisationId_FK) REFERENCES PendingOrganisations (PendingOrganisationId) +); diff --git a/t/test.jpg b/t/test.jpg new file mode 100644 index 0000000..70739f9 Binary files /dev/null and b/t/test.jpg differ diff --git a/t/upload.t b/t/upload.t new file mode 100644 index 0000000..8a1dc75 --- /dev/null +++ b/t/upload.t @@ -0,0 +1,422 @@ +use Test::More; +use Test::Mojo; +use Mojo::JSON; + +use FindBin; + +$ENV{MOJO_MODE} = 'development'; +$ENV{MOJO_LOG_LEVEL} = 'debug'; + +require "$FindBin::Bin/../foodloopserver.pl"; + +my $t = Test::Mojo->new; + +my $dbh = $t->app->db; + +#Dump all pf the test tables and start again. +my $sqlDeployment = Mojo::File->new("$FindBin::Bin/../dropschema.sql")->slurp; +for (split ';', $sqlDeployment){ + $dbh->do($_) or die $dbh->errstr; +} + +my $sqlDeployment = Mojo::File->new("$FindBin::Bin/../schema.sql")->slurp; +for (split ';', $sqlDeployment){ + $dbh->do($_) or die $dbh->errstr; +} + +my @accountTokens = ('a', 'b', 'c'); +my $tokenStatement = $dbh->prepare('INSERT INTO AccountTokens (AccountTokenName) VALUES (?)'); +foreach (@accountTokens){ + my $rowsAdded = $tokenStatement->execute($_); +} + +#Add one company that we've apparently authenticated but does not have an account. +my $companyIdNumShinra = 1; +my $name = "Shinra Electric Power Company"; +my $fullAddress = "Sector 0, Midgar, Eastern Continent, Gaia"; +my $postcode = "E1 M00"; +my $statementOrgIns = $t->app->db->prepare("INSERT INTO Organisations (OrganisationalId, Name, FullAddress, PostCode) VALUES (?, ?, ?, ?)"); + +is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations")}[0],0,"No organisations"; +$statementOrgIns->execute($companyIdNumShinra, $name, $fullAddress, $postcode); +is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations")}[0],1,"1 testing organisation"; + + + +#This depends on "register.t" and "login.t" working. + +#Valid customer, this also tests that redirects are disabled for register. +print "test 1 - Create customer user account (Rufus)\n"; +my $emailRufus = 'rufus@shinra.energy'; +my $passwordRufus = 'MakoGold'; +my $testJson = { + 'usertype' => 'customer', + 'token' => shift(@accountTokens), + 'username' => 'RufusShinra', + 'email' => $emailRufus, + 'postcode' => 'E1 MP01', + 'password' => $passwordRufus, + 'age' => '20-35' +}; +$t->post_ok('/register' => json => $testJson) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true); + +print "test 2 - Create customer user account (Hojo)\n"; +my $emailHojo = 'hojo@shinra.energy'; +my $passwordHojo = 'Mako'; +my $testJson = { + 'usertype' => 'customer', + 'token' => shift(@accountTokens), + 'username' => 'ProfessorHojo', + 'email' => $emailHojo, + 'postcode' => 'E1 MP01', + 'password' => $passwordHojo, + 'age' => '35-50' +}; +$t->post_ok('/register' => json => $testJson) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true); + +print "test 3 - Create organisation user account (Choco Billy)\n"; +my $emailBilly = 'choco.billy@chocofarm.org'; +my $passwordBilly = 'Choco'; +my $testJson = { + 'usertype' => 'organisation', + 'token' => shift(@accountTokens), + 'username' => 'ChocoBillysGreens', + 'email' => $emailBilly, + 'postcode' => 'E4 C12', + 'password' => $passwordBilly, + 'fulladdress' => 'Chocobo Farm, Eastern Continent, Gaia' +}; +$t->post_ok('/register' => json => $testJson) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true); + +###################################################### + +#Login as Hojo (customer) + +#Test login, this also checks that redirects are disabled for login when logged out. +print "test 4 - Login - Rufus (cookies, customer)\n"; +$testJson = { + 'email' => $emailRufus, + 'password' => $passwordRufus, +}; +$t->post_ok('/login' => json => $testJson) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true); + +print "test 5 - JSON missing\n"; +my $upload = {file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/JSON is missing/i); + +#TODO Check for malformed JSON. + +print "test 6 - microCurrencyValue missing\n"; +my $json = { + transactionAdditionType => 1, + addValidatedId => $companyIdNumShinra +}; +my $upload = {json => Mojo::JSON::encode_json($json), file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/microCurrencyValue is missing/i); + +print "test 7 - microCurrencyValue non-numbers\n"; +my $json = { + microCurrencyValue => 'Abc', + transactionAdditionType => 1, + addValidatedId => $companyIdNumShinra +}; +my $upload = {json => Mojo::JSON::encode_json($json), file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/microCurrencyValue does not look like a number/i); + +print "test 8 - microCurrencyValue equal to zero\n"; +my $json = { + microCurrencyValue => 0, + transactionAdditionType => 1, + addValidatedId => $companyIdNumShinra +}; +my $upload = {json => Mojo::JSON::encode_json($json), file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/microCurrencyValue cannot be equal to or less than zero/i); + +print "test 9 - microCurrencyValue less than zero\n"; +my $json = { + microCurrencyValue => -1, + transactionAdditionType => 1, + addValidatedId => $companyIdNumShinra +}; +my $upload = {json => Mojo::JSON::encode_json($json), file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/microCurrencyValue cannot be equal to or less than zero/i); + +print "test 10 - transactionAdditionType missing\n"; +$json = { + microCurrencyValue => 10, +}; +my $upload = {json => Mojo::JSON::encode_json($json), file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/transactionAdditionType is missing/i); + +print "test 11 - transactionAdditionType invalid.\n"; +$json = { + microCurrencyValue => 10, + transactionAdditionType => 4, +# addValidatedId => $companyIdNumShinra +}; +my $upload = {json => Mojo::JSON::encode_json($json), file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/transactionAdditionType is not a valid value/i); + +print "test 12 - file not uploaded.\n"; +$json = { + microCurrencyValue => 10, + transactionAdditionType => 1, + addValidatedId => 1, +}; +my $upload = {json => Mojo::JSON::encode_json($json)}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/no file uploaded/i); + +print "test 13 - addValidatedId missing (type 1: already validated)\n"; +$json = { + microCurrencyValue => 10, + transactionAdditionType => 1, +# addValidatedId => $companyIdNumShinra +}; +my $upload = {json => Mojo::JSON::encode_json($json), file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/addValidatedId is missing/i); + +print "test 14 - addValidatedId for non-existent id. (type 1: already validated)\n"; +$json = { + microCurrencyValue => 10, + transactionAdditionType => 1, + addValidatedId => ($companyIdNumShinra + 100) +}; +my $upload = {json => Mojo::JSON::encode_json($json), file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/addValidatedId does not exist in the database/i); + +print "test 15 - valid addition. (type 1: already validated)\n"; +is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions")}[0],0,"no transactions"; +$json = { + microCurrencyValue => 10, + transactionAdditionType => 1, + addValidatedId => $companyIdNumShinra, +}; +my $upload = {json => Mojo::JSON::encode_json($json), file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true) + ->content_like(qr/Added transaction for validated organisation/i); +is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions")}[0],1,"1 transaction"; + +# Add type 3 (new organisation) checking. + +print "test 16 - organsation missing (type 3: new organisation)\n"; +$json = { + microCurrencyValue => 10, + transactionAdditionType => 3, + streetName => "Slums, Sector 7", + town => "Midgar", + postcode => "E1 MS07" +}; +my $upload = {json => Mojo::JSON::encode_json($json), file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/organisationName is missing/i); + +print "test 17 - add valid transaction (type 3: new organisation)\n"; +is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations")}[0],0,"No pending organisations"; +is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions")}[0],0,"No pending transactions"; + +$json = { + microCurrencyValue => 10, + transactionAdditionType => 3, + organisationName => '7th Heaven', + streetName => "Slums, Sector 7", + town => "Midgar", + postcode => "E1 MS07" +}; +my $upload = {json => Mojo::JSON::encode_json($json), file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true) + ->content_like(qr/Added transaction for unvalidated organisation/i); +is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations")}[0],1,"1 pending organisation"; +is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions")}[0],1,"1 pending transaction"; + + +my ($organisationId) = $t->app->db->selectrow_array("SELECT PendingOrganisationId FROM PendingOrganisations LIMIT 1",undef,()); + +# Add type 2 (unverified organisation) checking. + +print "test 18 - addUnvalidatedId missing (type 2: existing organisation)\n"; +$json = { + microCurrencyValue => 10, + transactionAdditionType => 2, +}; +my $upload = {json => Mojo::JSON::encode_json($json), file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/addUnvalidatedId is missing/i); + +print "test 19 - addUnvalidatedId not a number (type 2: existing organisation)\n"; +$json = { + microCurrencyValue => 10, + transactionAdditionType => 2, + addUnvalidatedId => "Abc", +}; +my $upload = {json => Mojo::JSON::encode_json($json), file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/addUnvalidatedId does not look like a number/i); + +print "test 20 - id does not exist (type 2: existing organisation)\n"; +$json = { + microCurrencyValue => 10, + transactionAdditionType => 2, + addUnvalidatedId => 1000, #Id that does not exist +}; +my $upload = {json => Mojo::JSON::encode_json($json), file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/addUnvalidatedId does not exist in the database for the user/i); + +print "test 21 - Logout Rufus (type 2: existing organisation)\n"; +$t->post_ok('/logout') + ->status_is(200) + ->json_is('/success', Mojo::JSON->true); + +#End of Rufus (customer) + +###################################################### + +#Login as Hojo (customer) + +print "test 22 - Login Hojo (cookies, customer)\n"; +$testJson = { + 'email' => $emailHojo, + 'password' => $passwordHojo, +}; +$t->post_ok('/login' => json => $testJson) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true); + + +print "test 23 - add valid transaction but for with account (type 2: existing organisation)\n"; +is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions")}[0],1,"1 pending transaction"; +$json = { + microCurrencyValue => 10, + transactionAdditionType => 2, + addUnvalidatedId => $organisationId, +}; +my $upload = {json => Mojo::JSON::encode_json($json), file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/addUnvalidatedId does not exist in the database for the user/i); +is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions")}[0],1,"1 pending transaction"; + +print "test 24 - Logout Hojo\n"; +$t->post_ok('/logout') + ->status_is(200) + ->json_is('/success', Mojo::JSON->true); + +#End of Hojo (customer) + +###################################################### + +#Login as Rufus (customer) + +print "test 25 - Login Rufus (cookies, customer)\n"; +$testJson = { + 'email' => $emailRufus, + 'password' => $passwordRufus, +}; +$t->post_ok('/login' => json => $testJson) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true); + + +print "test 26 - add valid transaction (type 2: existing organisation)\n"; +is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions")}[0],1,"1 pending transaction"; +$json = { + microCurrencyValue => 10, + transactionAdditionType => 2, + addUnvalidatedId => $organisationId, +}; +my $upload = {json => Mojo::JSON::encode_json($json), file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true) + ->content_like(qr/Added transaction for unvalidated organisation./i); +is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions")}[0],2,"2 pending transaction"; + + +print "test 27 - Logout Rufus\n"; +$t->post_ok('/logout') + ->status_is(200) + ->json_is('/success', Mojo::JSON->true); + +#End of Rufus (customer) + +###################################################### + +#Login as Choco Billy (organisation) + +print "test 28 - Login Choco Billy (cookies, organisation)\n"; +$testJson = { + 'email' => $emailBilly, + 'password' => $passwordBilly, +}; +$t->post_ok('/login' => json => $testJson) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true); + + +print "test 29 - organisation buy from another organisation\n"; +is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions")}[0],1,"1 transaction"; +$json = { + microCurrencyValue => 100000, + transactionAdditionType => 1, + addValidatedId => $companyIdNumShinra, +}; +my $upload = {json => Mojo::JSON::encode_json($json), file2 => {file => './t/test.jpg'}}; +$t->post_ok('/upload' => form => $upload ) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true) + ->content_like(qr/Added transaction for validated organisation/i); +is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions")}[0],2,"2 transactions"; + +done_testing(); +