From 67d764638a1f75c131964f5d48e39321325be013 Mon Sep 17 00:00:00 2001
From: Paul Dill
Date: Sun, 19 Feb 2017 00:36:41 +0000
Subject: [PATCH] Added upload functionality and tests.
---
.gitignore | 1 +
cpanfile | 1 +
dropschema.sql | 2 +
foodloopserver.pl | 302 ++++++++++++++++++++++++++++-----
schema.sql | 24 ++-
t/test.jpg | Bin 0 -> 539 bytes
t/upload.t | 422 ++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 708 insertions(+), 44 deletions(-)
create mode 100644 t/test.jpg
create mode 100644 t/upload.t
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 0000000000000000000000000000000000000000..70739f9346b9e5a5c9fd85d7432ee0d3ac957fc8
GIT binary patch
literal 539
zcmb7r;Ft(yFdV$vj#hL-SxX%>tqpa+bQQHiJ{eUKFsS8lwz(I>%yR$e5
aPl%9nj$@!1D)Ts!F8*
literal 0
HcmV?d00001
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();
+