diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..fb4ae32 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,13 @@ +sudo: false + +language: perl +perl: + - "5.20" +env: + - HARNESS_PERL_SWITCHES="-MDevel::Cover" +install: + - cpanm --quiet --notest --installdeps . + - cpanm Devel::Cover +script: + - prove -lr + - cover diff --git a/README.md b/README.md new file mode 100644 index 0000000..3f4fa37 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Pear LocalLoop Server + +[![Build Status](https://travis-ci.org/Pear-Trading/Foodloop-Server.svg?branch=master)](https://travis-ci.org/Pear-Trading/Foodloop-Server) diff --git a/cpanfile b/cpanfile index f84010f..01c7fc2 100644 --- a/cpanfile +++ b/cpanfile @@ -10,8 +10,9 @@ requires 'Time::Fake'; requires 'Scalar::Util'; requires 'DBIx::Class'; requires 'DBIx::Class::PassphraseColumn'; +requires 'DBIx::Class::TimeStamp'; requires 'DBIx::Class::Schema::Loader'; requires 'SQL::Translator'; requires 'DateTime'; +requires 'DateTime::Format::Strptime'; requires 'DateTime::Format::SQLite'; -requires 'TryCatch'; diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index dae393a..bfd43ce 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -3,9 +3,10 @@ package Pear::LocalLoop; use Mojo::Base 'Mojolicious'; use Data::UUID; use Mojo::JSON; -use Scalar::Util qw(looks_like_number); use Pear::LocalLoop::Schema; use DateTime; +use Mojo::Asset::File; +use Mojo::File qw/ path tempdir /; has schema => sub { my $c = shift; @@ -21,6 +22,7 @@ sub startup { $self->plugin('Config', { default => { + storage_path => tempdir, sessionTimeSeconds => 60 * 60 * 24 * 7, sessionTokenJsonName => 'session_key', sessionExpiresJsonName => 'sessionExpires', @@ -40,7 +42,7 @@ sub startup { my $user = $c->schema->resultset('User')->find({email => $email}); if ( defined $user ) { if ( $user->check_password( $password ) ) { - return $user->userid; + return $user->id; } } return undef; @@ -48,7 +50,7 @@ sub startup { }); # shortcut for use in template - $self->helper( db => sub { $self->app->schema->storage->dbh }); + $self->helper( db => sub { warn "DEPRECATED db helper"; return $self->app->schema->storage->dbh }); $self->helper( schema => sub { $self->app->schema }); $self->helper( api_validation_error => sub { @@ -60,12 +62,46 @@ sub startup { json => { success => Mojo::JSON->false, message => $c->error_messages->{$val}->{$check}->{message}, + error => $check, }, status => $c->error_messages->{$val}->{$check}->{status}, ); } }); + $self->helper( datetime_formatter => sub { + my $c = shift; + + return DateTime::Format::Strptime->new( + pattern => '%FT%T%z', + strict => 1, + on_error => 'undef', + ); + }); + + $self->helper( get_path_from_uuid => sub { + my $c = shift; + my $uuid = shift; + my ( $folder ) = $uuid =~ /(..)/; + return path($c->app->config->{storage_path}, $folder, $uuid); + }); + + $self->helper( store_file_from_upload => sub { + my $c = shift; + my $upload = shift; + my $uuid = Data::UUID->new->create_str; + my $path = $c->get_path_from_uuid( $uuid ); + $path->dirname->make_path; + $upload->move_to( $path ); + return $uuid; + }); + + $self->helper( get_file_from_uuid => sub { + my $c = shift; + my $uuid = shift; + return Mojo::Asset::File->new( path => $c->get_path_from_uuid( $uuid ) ); + }); + my $r = $self->routes; $r->get('/')->to('root#index'); $r->post('/')->to('root#auth_login'); @@ -73,6 +109,9 @@ sub startup { $r->post('/register')->to('register#register'); $r->any('/logout')->to('root#auth_logout'); + my $api_public_get = $r->under('/api'); + $api_public_get->get('/info/ages')->to('api-info#get_ages'); + # Always available api routes my $api_public = $r->under('/api')->to('api-auth#check_json'); @@ -91,117 +130,68 @@ sub startup { }); $api->post('/upload')->to('api-upload#post_upload'); $api->post('/search')->to('api-upload#post_search'); - $api->post('/admin-approve')->to('api-admin#post_admin_approve'); - $api->post('/admin-merge')->to('api-admin#post_admin_merge'); + $api->post('/user/day')->to('api-user#post_day'); $api->post('/edit')->to('api-api#post_edit'); $api->post('/fetchuser')->to('api-api#post_fetchuser'); $api->post('/user-history')->to('api-user#post_user_history'); + my $api_admin = $api->under('/')->to('api-admin#auth'); + + $api_admin->post('/admin-approve')->to('api-admin#post_admin_approve'); + $api_admin->post('/admin-merge')->to('api-admin#post_admin_merge'); + my $admin_routes = $r->under('/admin')->to('admin#under'); $admin_routes->get('/')->to('admin#home'); + $admin_routes->get('/tokens')->to('admin-tokens#index'); $admin_routes->post('/tokens')->to('admin-tokens#create'); $admin_routes->get('/tokens/:id')->to('admin-tokens#read'); $admin_routes->post('/tokens/:id')->to('admin-tokens#update'); $admin_routes->post('/tokens/:id/delete')->to('admin-tokens#delete'); + $admin_routes->get('/users')->to('admin-users#index'); $admin_routes->get('/users/:id')->to('admin-users#read'); $admin_routes->post('/users/:id')->to('admin-users#update'); $admin_routes->post('/users/:id/delete')->to('admin-users#delete'); + $admin_routes->get('/organisations')->to('admin-organisations#list'); + $admin_routes->get('/organisations/valid/:id')->to('admin-organisations#valid_read'); + $admin_routes->get('/organisations/pending/:id')->to('admin-organisations#pending_read'); + $admin_routes->get('/organisations/pending/:id/approve')->to('admin-organisations#pending_approve'); + my $user_routes = $r->under('/')->to('root#under'); $user_routes->get('/home')->to('root#home'); + my $portal_api = $r->under('/portal')->to('api-auth#check_json')->under('/')->to('portal#under'); + + $portal_api->post('/upload')->to('api-upload#post_upload'); + $portal_api->post('/search')->to('api-upload#post_search'); + $self->hook( before_dispatch => sub { my $self = shift; $self->res->headers->header('Access-Control-Allow-Origin' => '*') if $self->app->mode eq 'development'; }); - $self->helper( is_admin => sub { - my ($c, $user_id) = @_; - my $admin = $c->schema->resultset('Administrator')->find($user_id); - return defined $admin; - }); + $self->helper( copy_transactions_and_delete => sub { + my ( $c, $from_org, $to_org ) = @_; - $self->helper( create_hash => sub{ - my ($self, $id, $name, $fullAddress, $postcode) = @_; + my $from_org_transaction_rs = $from_org->transactions; - return { - id => $id, - name => $name, - fullAddress => $fullAddress . ", " . $postcode, - } - }); - - $self->helper(get_active_user_id => sub { - my $self = shift; - - my $token = $self->get_session_token(); - if (! defined $token){ - return undef; + while ( my $from_org_transaction = $from_org_transaction_rs->next ) { + $to_org->create_related( + 'transactions', { + buyer_id => $from_org_transaction->buyer_id, + value => $from_org_transaction->value, + proof_image => $from_org_transaction->proof_image, + submitted_at => $from_org_transaction->submitted_at, + } + ); } - my @out = $self->db->selectrow_array("SELECT UserIdAssignedTo_FK FROM SessionTokens WHERE SessionTokenName = ?",undef,($token)); - if (! @out){ - return undef; - } - else{ - return $out[0]; - } - }); - - $self->helper(get_session_token => sub { - my $self = shift; - - #See if logged in. - my $sessionToken = undef; - - my $json = $self->req->json; - if (defined $json) { - $sessionToken = $json->{$self->app->config->{sessionTokenJsonName}}; - } - - if ( ! defined $sessionToken || $sessionToken eq "" ) { - $sessionToken = $self->session->{$self->app->config->{sessionTokenJsonName}}; - } - - if (defined $sessionToken && $sessionToken eq "" ) { - $sessionToken = undef; - } - - return $sessionToken; - }); - - - #This assumes the user has no current session on that device. - $self->helper(generate_session => sub { - my ($self, $userId) = @_; - - my $sessionToken = $self->generate_session_token(); - - my $insertStatement = $self->db->prepare('INSERT INTO SessionTokens (SessionTokenName, UserIdAssignedTo_FK, ExpireDateTime) VALUES (?, ?, ?)'); - my $rowsAdded = $insertStatement->execute($sessionToken, $userId, DateTime->now()->add( years => 1 )); - - return $sessionToken; - }); - - $self->helper(generate_session_token => sub { - my $self = shift; - return Data::UUID->new->create_str(); - }); - - $self->helper(does_organisational_id_exist => sub { - my ( $c, $org_id ) = @_; - return defined $c->schema->resultset('Organisation')->find({ organisationalid => $org_id }); - }); - - $self->helper(get_age_foreign_key => sub { - my ( $c, $age_string ) = @_; - my $age_range = $c->schema->resultset('AgeRange')->find({ agerangestring => $age_string }); - return defined $age_range ? $age_range->agerangeid : undef; + $from_org->delete; }); } diff --git a/lib/Pear/LocalLoop/Controller/Admin.pm b/lib/Pear/LocalLoop/Controller/Admin.pm index dbae956..b7bb204 100644 --- a/lib/Pear/LocalLoop/Controller/Admin.pm +++ b/lib/Pear/LocalLoop/Controller/Admin.pm @@ -18,12 +18,16 @@ sub home { my $user_rs = $c->schema->resultset('User'); my $token_rs = $c->schema->resultset('AccountToken'); + my $pending_orgs_rs = $c->schema->resultset('PendingOrganisation'); + my $pending_transaction_rs = $c->schema->resultset('PendingTransaction'); $c->stash( user_count => $user_rs->count, tokens => { total => $token_rs->count, - unused => $token_rs->search({used => 0 })->count, + unused => $token_rs->search({ used => 0 })->count, }, + pending_orgs => $pending_orgs_rs->count, + pending_trans => $pending_transaction_rs->count, ); } diff --git a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm new file mode 100644 index 0000000..d1b39b3 --- /dev/null +++ b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm @@ -0,0 +1,42 @@ +package Pear::LocalLoop::Controller::Admin::Organisations; +use Mojo::Base 'Mojolicious::Controller'; + +sub list { + my $c = shift; + + my $valid_orgs_rs = $c->schema->resultset('Organisation'); + my $pending_orgs_rs = $c->schema->resultset('PendingOrganisation'); + + $c->stash( + valid_orgs_rs => $valid_orgs_rs, + pending_orgs_rs => $pending_orgs_rs, + ); +} + +sub valid_read { + my $c = shift; + my $valid_org = $c->schema->resultset('Organisation')->find( $c->param('id') ); + $c->stash( valid_org => $valid_org ); +} + +sub pending_read { + my $c = shift; + my $pending_org = $c->schema->resultset('PendingOrganisation')->find( $c->param('id') ); + $c->stash( pending_org => $pending_org ); +} + +sub pending_approve { + my $c = shift; + my $pending_org = $c->schema->resultset('PendingOrganisation')->find( $c->param('id') ); + my $valid_org = $c->schema->resultset('Organisation')->create({ + name => $pending_org->name, + street_name => $pending_org->street_name, + town => $pending_org->town, + postcode => $pending_org->postcode, + }); + $c->copy_transactions_and_delete( $pending_org, $valid_org ); + $c->flash( success => 'Validated Organisation' ); + $c->redirect_to( '/admin/organisations/valid/' . $valid_org->id ); +} + +1; diff --git a/lib/Pear/LocalLoop/Controller/Admin/Tokens.pm b/lib/Pear/LocalLoop/Controller/Admin/Tokens.pm index 982aca8..5fec0cb 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Tokens.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Tokens.pm @@ -17,21 +17,24 @@ sub index { # POST sub create { my $c = shift; + my $validation = $c->validation; - $validation->required('token-name', 'trim')->like(qr/^[\w]*$/); + $validation->required('token', 'trim')->like(qr/^[\w]*$/)->not_in_resultset('name', $c->result_set); - my $token_name = $validation->param('token-name'); + my $token_name = $validation->param('token'); - my $token_rs = $c->result_set; - if ( $validation->has_error ) { - # Only one validator, fairly obvious whats broke - $c->flash( error => 'Token name not valid - Alphanumeric characters and Underscore only' ); - } elsif ( $token_rs->find({ accounttokenname => $token_name }) ) { - $c->flash( error => 'Token Already Exists' ); + my $check = shift @{ $c->validation->error('token') }; + if ( $check eq 'required' ) { + $c->flash( error => 'Token name is required' ); + } elsif ( $check eq 'like' ) { + $c->flash( error => 'Token name not valid - Alphanumeric characters and Underscore only' ); + } elsif ( $check eq 'not_in_resultset' ) { + $c->flash( error => 'Token Already Exists' ); + } } else { $c->flash( success => 'Token Created' ); - $token_rs->create({ accounttokenname => $token_name }); + $c->result_set->create({ name => $token_name }); } $c->redirect_to( '/admin/tokens' ); } @@ -54,8 +57,8 @@ sub read { sub update { my $c = shift; my $validation = $c->validation; - $validation->required('token-name', 'trim')->like(qr/^[\w]*$/); - $validation->required('token-used')->in( qw/ 0 1 / ); + $validation->required('token', 'trim')->like(qr/^[\w]*$/); + $validation->required('used')->in( qw/ 0 1 / ); my $id = $c->param('id'); @@ -65,8 +68,8 @@ sub update { $c->redirect_to( '/admin/tokens/' . $id ); } elsif ( my $token = $c->result_set->find($id) ) { $token->update({ - accounttokenname => $validation->param('token-name'), - used => $validation->param('token-used'), + name => $validation->param('token'), + used => $validation->param('used'), }); $c->flash( success => 'Token Updated' ); $c->redirect_to( '/admin/tokens/' . $id ); diff --git a/lib/Pear/LocalLoop/Controller/Api/Admin.pm b/lib/Pear/LocalLoop/Controller/Api/Admin.pm index f9e0d54..e5d629a 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Admin.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Admin.pm @@ -1,6 +1,23 @@ package Pear::LocalLoop::Controller::Api::Admin; use Mojo::Base 'Mojolicious::Controller'; -use Data::Dumper; + +has error_messages => sub { + return { + target_organisation_id => { + required => { message => 'target_organisation_id is missing', status => 400 }, + number => { message => 'target_organisation_id is not a number', status => 400 }, + in_resultset => { message => 'target_organisation_id does not exist in the database', status => 400 }, + }, + pending_organisation_id => { + required => { message => 'pending_organisation_id is missing', status => 400 }, + number => { message => 'pending_organisation_id is not a number', status => 400 }, + in_resultset => { message => 'pending_organisation_id does not exist in the database', status => 400 }, + }, + postcode => { + postcode => { message => 'postcode is not a valid uk postcode', status => 400 }, + }, + }; +}; sub auth { my $c = shift; @@ -21,214 +38,69 @@ sub auth { sub post_admin_approve { my $c = shift; - my $self = $c; - my $user = $c->stash->{ api_user }; + my $validation = $c->validation; - my $userId = $self->get_active_user_id(); - if ( ! $self->is_admin($userId) ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'You are not an admin.', + $validation->input( $c->stash->{api_json} ); + + my $pending_org_rs = $c->schema->resultset('PendingOrganisation'); + $validation->required('pending_organisation_id')->number->in_resultset('id', $pending_org_rs); + $validation->optional('name'); + $validation->optional('street_name'); + $validation->optional('town'); + $validation->optional('postcode')->postcode; + + return $c->api_validation_error if $validation->has_error; + + my $pending_org = $pending_org_rs->find( $validation->param('pending_organisation_id') ); + + my $valid_org = $c->schema->resultset('Organisation')->create({ + name => $validation->param('name') || $pending_org->name, + street_name => $validation->param('street_name') || $pending_org->street_name, + town => $validation->param('town') || $pending_org->town, + postcode => $validation->param('postcode') || $pending_org->postcode, + }); + + $c->copy_transactions_and_delete( $pending_org, $valid_org ); + + return $c->render( + json => { + success => Mojo::JSON->true, + message => 'Successfully Approved Organisation', }, - status => 403,); #Forbidden request - } - - my $json = $self->req->json; - if ( ! defined $json ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'JSON is missing.', - }, - status => 400,); #Malformed request - } - - my $unvalidatedOrganisationId = $json->{unvalidatedOrganisationId}; - if ( ! defined $unvalidatedOrganisationId ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'unvalidatedOrganisationId 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 => 'unvalidatedOrganisationId does not look like a number.', - }, - status => 400,); #Malformed request - } - - - my ($id, $name, $fullAddress, $postcode) = $self->db->selectrow_array("SELECT PendingOrganisationId, Name, FullAddress, Postcode FROM PendingOrganisations WHERE PendingOrganisationId = ?", undef, ($unvalidatedOrganisationId)); - - #It does not exist. - if (! defined $id) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'the specified unvalidatedOrganisationId does not exist.', - }, - status => 400,); #Malformed request - } - - - my $nameJson = $json->{name}; - if (defined $nameJson) { - $name = $nameJson; - } - - my $fullAddressJson = $json->{fullAddress}; - if (defined $fullAddressJson) { - $fullAddress = $fullAddressJson; - } - - my $postCodeJson = $json->{postCode}; - if (defined $postCodeJson) { - $postcode = $postCodeJson; - } - - - #FIXME there may be race conditions here, so may get the wrong number, mutux is needed. - my $statementInsOrg = $self->db->prepare("INSERT INTO Organisations (Name, FullAddress, PostCode) VALUES (?, ?, ?)"); - $statementInsOrg->execute($name, $fullAddress, $postcode); - my $organisationalId = $self->db->last_insert_id(undef,undef, "Organisations", "OrganisationalId"); - #print "OrgId: " . $organisationalId . "\n"; - - my $statementSelectPendingTrans = $self->db->prepare("SELECT BuyerUserId_FK, ValueMicroCurrency, ProofImage, TimeDateSubmitted FROM PendingTransactions WHERE PendingSellerOrganisationId_FK = ?"); - $statementSelectPendingTrans->execute($unvalidatedOrganisationId); - - my $statementInsTrans = $self->db->prepare("INSERT INTO Transactions (BuyerUserId_FK, SellerOrganisationId_FK, ValueMicroCurrency, ProofImage, TimeDateSubmitted) VALUES (?, ?, ?, ?, ?)"); - - #Move all transactions from pending onto verified. - while (my ($buyerUserId, $value, $imgName, $timeDate) = $statementSelectPendingTrans->fetchrow_array()) { - $statementInsTrans->execute($buyerUserId, $organisationalId, $value, $imgName, $timeDate); - } - - #Delete transactions first, so there is no dependancy when deleting the row from PendingOrganisations. - $self->db->prepare("DELETE FROM PendingTransactions WHERE PendingSellerOrganisationId_FK = ?")->execute($unvalidatedOrganisationId); - $self->db->prepare("DELETE FROM PendingOrganisations WHERE PendingOrganisationId = ?")->execute($unvalidatedOrganisationId); - - $self->app->log->debug('Path Success: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->true, - validatedOrganisationId => $organisationalId, - }, - status => 200,); - + status => 200, + ); } sub post_admin_merge { - my $self = shift; + my $c = shift; - my $userId = $self->get_active_user_id(); - if ( ! $self->is_admin($userId) ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'You are not an admin.', + my $validation = $c->validation; + + $validation->input( $c->stash->{api_json} ); + + my $pending_org_rs = $c->schema->resultset('PendingOrganisation'); + $validation->required('pending_organisation_id')->number->in_resultset('id', $pending_org_rs); + + my $valid_org_rs = $c->schema->resultset('Organisation'); + $validation->required('target_organisation_id')->number->in_resultset('id', $valid_org_rs); + + return $c->api_validation_error if $validation->has_error; + + my $pending_org = $pending_org_rs->find( $validation->param('pending_organisation_id') ); + my $target_org = $valid_org_rs->find( $validation->param('target_organisation_id') ); + + $c->copy_transactions_and_delete( $pending_org, $target_org ); + + return $c->render( + json => { + success => Mojo::JSON->true, + message => 'Successfully Merged Organisations', }, - status => 403,); #Forbidden request - } - - my $json = $self->req->json; - if ( ! defined $json ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'JSON is missing.', - }, - status => 400,); #Malformed request - } - - my $unvalidatedOrganisationId = $json->{unvalidatedOrganisationId}; - if ( ! defined $unvalidatedOrganisationId ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'unvalidatedOrganisationId 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 => 'unvalidatedOrganisationId does not look like a number.', - }, - status => 400,); #Malformed request - } - - my $validatedOrganisationId = $json->{validatedOrganisationId}; - if ( ! defined $validatedOrganisationId ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'validatedOrganisationId is missing.', - }, - status => 400,); #Malformed request - } - elsif (! Scalar::Util::looks_like_number($validatedOrganisationId)){ - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'validatedOrganisationId does not look like a number.', - }, - status => 400,); #Malformed request - } - - #FIXME This requires mutual exclusion. - - my $doesUnvalidatedIdNotExist = ($self->db->selectrow_array("SELECT COUNT(*) FROM PendingOrganisations WHERE PendingOrganisationId = ?", undef, ($unvalidatedOrganisationId)) == 0); - if ($doesUnvalidatedIdNotExist) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'unvalidatedOrganisationId does not exist in the database.', - }, - status => 400,); #Malformed request - } - - my $doesValidatedIdNotExist = ($self->db->selectrow_array("SELECT COUNT(*) FROM Organisations WHERE OrganisationalId = ?", undef, ($validatedOrganisationId)) == 0); - if ($doesValidatedIdNotExist) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'validatedOrganisationId does not exist in the database.', - }, - status => 400,); #Malformed request - } - - - #FIXME there may be race conditions here, so may get the wrong number, mutux is needed. - my $statementSelectPendingTrans = $self->db->prepare("SELECT BuyerUserId_FK, ValueMicroCurrency, ProofImage, TimeDateSubmitted FROM PendingTransactions WHERE PendingSellerOrganisationId_FK = ?"); - $statementSelectPendingTrans->execute($unvalidatedOrganisationId); - - my $statementInsTrans = $self->db->prepare("INSERT INTO Transactions (BuyerUserId_FK, SellerOrganisationId_FK, ValueMicroCurrency, ProofImage, TimeDateSubmitted) VALUES (?, ?, ?, ?, ?)"); - - #Move all transactions from pending onto verified. - while (my ($buyerUserId, $value, $imgName, $timeDate) = $statementSelectPendingTrans->fetchrow_array()) { - $statementInsTrans->execute($buyerUserId, $validatedOrganisationId, $value, $imgName, $timeDate); - } - - #Delete transactions first, so there is no dependancy when deleting the row from PendingOrganisations. - $self->db->prepare("DELETE FROM PendingTransactions WHERE PendingSellerOrganisationId_FK = ?")->execute($unvalidatedOrganisationId); - $self->db->prepare("DELETE FROM PendingOrganisations WHERE PendingOrganisationId = ?")->execute($unvalidatedOrganisationId); - - $self->app->log->debug('Path Success: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->true, - }, - status => 200,); - + status => 200, + ); } - - 1; diff --git a/lib/Pear/LocalLoop/Controller/Api/Auth.pm b/lib/Pear/LocalLoop/Controller/Api/Auth.pm index 43ecfae..4642bba 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Auth.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Auth.pm @@ -42,7 +42,7 @@ sub auth { my $session_key = $c->stash->{api_json}->{session_key}; if ( defined $session_key ) { - my $session_result = $c->schema->resultset('SessionToken')->find({ sessiontokenname => $session_key }); + my $session_result = $c->schema->resultset('SessionToken')->find({ token => $session_key }); if ( defined $session_result ) { $c->stash( api_user => $session_result->user ); @@ -78,7 +78,7 @@ sub post_login { if ( defined $user_result ) { if ( $user_result->check_password($password) ) { - my $session_key = $c->generate_session( $user_result->userid ); + my $session_key = $user_result->generate_session; return $c->render( json => { success => Mojo::JSON->true, @@ -101,7 +101,7 @@ sub post_logout { my $session_key = $c->req->json( '/session_key' ); - my $session_result = $c->schema->resultset('SessionToken')->find({ sessiontokenname => $session_key }); + my $session_result = $c->schema->resultset('SessionToken')->find({ token => $session_key }); if ( defined $session_result ) { $session_result->delete; diff --git a/lib/Pear/LocalLoop/Controller/Api/Info.pm b/lib/Pear/LocalLoop/Controller/Api/Info.pm new file mode 100644 index 0000000..949847b --- /dev/null +++ b/lib/Pear/LocalLoop/Controller/Api/Info.pm @@ -0,0 +1,12 @@ +package Pear::LocalLoop::Controller::Api::Info; +use Mojo::Base 'Mojolicious::Controller'; + +sub get_ages { + my $c = shift; + + my $ages = $c->schema->resultset('AgeRange'); + + $c->render( json => { ages => [ $ages->all ] } ); +} + +1; diff --git a/lib/Pear/LocalLoop/Controller/Api/Register.pm b/lib/Pear/LocalLoop/Controller/Api/Register.pm index 4bbe97a..db12e9d 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Register.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Register.pm @@ -8,10 +8,8 @@ has error_messages => sub { required => { message => 'No token sent.', status => 400 }, in_resultset => { message => 'Token invalid or has been used.', status => 401 }, }, - username => { - required => { message => 'No username sent or was blank.', status => 400 }, - like => { message => 'Username can only be A-Z, a-z and 0-9 characters.', status => 400 }, - not_in_resultset => { message => 'Username exists.', status => 403 }, + name => { + required => { message => 'No name sent or was blank.', status => 400 }, }, email => { required => { message => 'No email sent.', status => 400 }, @@ -20,6 +18,7 @@ has error_messages => sub { }, postcode => { required => { message => 'No postcode sent.', status => 400 }, + postcode => { message => 'Postcode is invalid', status => 400 }, }, password => { required => { message => 'No password sent.', status => 400 }, @@ -28,12 +27,16 @@ has error_messages => sub { required => { message => 'No usertype sent.', status => 400 }, in => { message => '"usertype" is invalid.', status => 400 }, }, - age => { - required => { message => 'No age sent.', status => 400 }, - in_resultset => { message => 'Age range is invalid.', status => 400 }, + age_range => { + required => { message => 'No age_range sent.', status => 400 }, + number => { message => 'age_range is invalid', status => 400 }, + in_resultset => { message => 'age_range is invalid.', status => 400 }, }, - fulladdress => { - required => { message => 'No fulladdress sent.', status => 400 }, + street_name => { + required => { message => 'No street_name sent.', status => 400 }, + }, + town => { + required => { message => 'No town sent.', status => 400 }, }, }; }; @@ -42,87 +45,46 @@ sub post_register{ my $c = shift; my $validation = $c->validation; - - my $json = $c->req->json; - - if ( ! defined $json ){ - return $c->render( json => { - success => Mojo::JSON->false, - message => 'No json sent.', - }, - status => 400,); #Malformed request - } - $validation->input( $json ); + $validation->input( $c->stash->{api_json} ); my $token_rs = $c->schema->resultset('AccountToken')->search_rs({used => 0}); - $validation->required('token')->in_resultset('accounttokenname', $token_rs); - - my $customer_rs = $c->schema->resultset('Customer'); - $validation->required('username')->like(qr/^[A-Za-z0-9]+$/)->not_in_resultset('username', $customer_rs); + $validation->required('token')->in_resultset('name', $token_rs); my $user_rs = $c->schema->resultset('User'); $validation->required('email')->email->not_in_resultset('email', $user_rs); - - #TODO test to see if post code is valid. - $validation->required('postcode'); - - #TODO should we enforce password requirements. $validation->required('password'); + $validation->required('name'); + $validation->required('postcode')->postcode; $validation->required('usertype')->in('customer', 'organisation'); my $usertype = $validation->param('usertype') || ''; if ( $usertype eq 'customer' ) { - my $age_rs = $c->schema->resultset('AgeRange'); - $validation->required('age')->in_resultset('agerangestring', $age_rs); - + $validation->required('age_range')->number->in_resultset('id', $age_rs); } elsif ( $usertype eq 'organisation' ) { - - #TODO validation on the address. Or perhaps add the organisation to a "to be inspected" list then manually check them. - $validation->required('fulladdress'); - + $validation->required('street_name'); + $validation->required('town'); } - if ( $validation->has_error ) { - my $failed_vals = $validation->failed; - for my $val ( @$failed_vals ) { - my $check = shift @{ $validation->error($val) }; - return $c->render( - json => { - success => Mojo::JSON->false, - message => $c->error_messages->{$val}->{$check}->{message}, - }, - status => $c->error_messages->{$val}->{$check}->{status}, - ); - } - } - - my $token = $validation->param('token'); - my $username = $validation->param('username'); - my $email = $validation->param('email'); - my $postcode = $validation->param('postcode'); - my $password = $validation->param('password'); + return $c->api_validation_error if $validation->has_error; if ($usertype eq 'customer'){ - # TODO replace with actually using the value on the post request - my $ageForeignKey = $c->get_age_foreign_key( $validation->param('age') ); $c->schema->txn_do( sub { $c->schema->resultset('AccountToken')->find({ - accounttokenname => $token, + name => $validation->param('token'), used => 0, })->update({ used => 1 }); $c->schema->resultset('User')->create({ customer => { - username => $username, - agerange_fk => $ageForeignKey, - postcode => $postcode, + name => $validation->param('name'), + age_range_id => $validation->param('age_range'), + postcode => $validation->param('postcode'), }, - email => $email, - hashedpassword => $password, - joindate => DateTime->now, + email => $validation->param('email'), + password => $validation->param('password'), }); }); @@ -132,23 +94,26 @@ sub post_register{ $c->schema->txn_do( sub { $c->schema->resultset('AccountToken')->find({ - accounttokenname => $token, + name => $validation->param('token'), used => 0, })->update({ used => 1 }); $c->schema->resultset('User')->create({ organisation => { - name => $username, - fulladdress => $fullAddress, - postcode => $postcode, + name => $validation->param('name'), + street_name => $validation->param('street_name'), + town => $validation->param('town'), + postcode => $validation->param('postcode'), }, - email => $email, - hashedpassword => $password, - joindate => DateTime->now, + email => $validation->param('email'), + password => $validation->param('password'), }); }); } - return $c->render( json => { success => Mojo::JSON->true } ); + return $c->render( json => { + success => Mojo::JSON->true, + message => 'Registered Successfully', + }); } 1; diff --git a/lib/Pear/LocalLoop/Controller/Api/Upload.pm b/lib/Pear/LocalLoop/Controller/Api/Upload.pm index abe28f9..c376129 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Upload.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Upload.pm @@ -67,12 +67,14 @@ has error_messages => sub { organisation_name => { required => { message => 'organisation_name is missing', status => 400 }, }, + search_name => { + required => { message => 'search_name is missing', status => 400 }, + }, }; }; sub post_upload { my $c = shift; - my $self = $c; my $user = $c->stash->{api_user}; @@ -91,171 +93,114 @@ sub post_upload { my $type = $validation->param('transaction_type'); + my $organisation; + if ( $type == 1 ) { # Validated Organisation my $valid_org_rs = $c->schema->resultset('Organisation'); - $validation->required('organisation_id')->number->in_resultset( 'organisationalid', $valid_org_rs ); + $validation->required('organisation_id')->number->in_resultset( 'id', $valid_org_rs ); + + return $c->api_validation_error if $validation->has_error; + + $organisation = $valid_org_rs->find( $validation->param('organisation_id') ); + } elsif ( $type == 2 ) { # Unvalidated Organisation - my $valid_org_rs = $c->schema->resultset('PendingOrganisation')->search({ usersubmitted_fk => $user->id }); - $validation->required('organisation_id')->number->in_resultset( 'pendingorganisationid', $valid_org_rs ); + my $valid_org_rs = $c->schema->resultset('PendingOrganisation')->search({ submitted_by_id => $user->id }); + $validation->required('organisation_id')->number->in_resultset( 'id', $valid_org_rs ); + + return $c->api_validation_error if $validation->has_error; + + $organisation = $valid_org_rs->find( $validation->param('organisation_id') ); + } elsif ( $type == 3 ) { # Unknown Organisation $validation->required('organisation_name'); $validation->optional('street_name'); $validation->optional('town'); $validation->optional('postcode')->postcode; - } + + return $c->api_validation_error if $validation->has_error; - return $c->api_validation_error if $validation->has_error; + $organisation = $c->schema->resultset('PendingOrganisation')->create({ + submitted_by => $user, + submitted_at => DateTime->now, + name => $validation->param('organisation_name'), + street_name => $validation->param('street_name'), + town => $validation->param('town'), + postcode => $validation->param('postcode'), + }); + } my $transaction_value = $validation->param('transaction_value'); + my $upload = $validation->param('file'); + my $file = $c->store_file_from_upload( $upload ); - my $file = $validation->param('file'); - - my $ext = '.jpg'; - my $uuid = Data::UUID->new->create_str; - my $filename = $uuid . $ext; - - if ( $type == 1 ) { - # Validated organisation - $c->schema->resultset('Transaction')->create({ - buyeruserid_fk => $user->id, - sellerorganisationid_fk => $validation->param('organisation_id'), - valuemicrocurrency => $transaction_value, - proofimage => $filename, - timedatesubmitted => DateTime->now, - }); - - $file->move_to('images/' . $filename); - } elsif ( $type == 2 ) { - # Unvalidated Organisation - $c->schema->resultset('PendingTransaction')->create({ - buyeruserid_fk => $user->id, - pendingsellerorganisationid_fk => $validation->param('organisation_id'), - valuemicrocurrency => $transaction_value, - proofimage => $filename, - timedatesubmitted => DateTime->now, - }); - - $file->move_to('images/' . $filename); - } elsif ( $type == 3 ) { - my $organisation_name = $validation->param('organisation_name'); - my $street_name = $validation->param('street_name'); - my $town = $validation->param('town'); - my $postcode = $validation->param('postcode'); - - my $fullAddress = ""; - - if ( defined $street_name && ! ($street_name =~ m/^\s*$/) ){ - $fullAddress = $street_name; + $organisation->create_related( + 'transactions', + { + buyer => $user, + value => $transaction_value, + proof_image => $file, } + ); - if ( defined $town && ! ($town =~ m/^\s*$/) ){ - if ($fullAddress eq ""){ - $fullAddress = $town; - } - else{ - $fullAddress = $fullAddress . ", " . $town; - } - - } - - my $pending_org = $c->schema->resultset('PendingOrganisation')->create({ - usersubmitted_fk => $user->id, - timedatesubmitted => DateTime->now, - name => $organisation_name, - fulladdress => $fullAddress, - postcode => $postcode, - }); - - $c->schema->resultset('PendingTransaction')->create({ - buyeruserid_fk => $user->id, - pendingsellerorganisationid_fk => $pending_org->pendingorganisationid, - valuemicrocurrency => $transaction_value, - proofimage => $filename, - timedatesubmitted => DateTime->now, - }); - - $file->move_to('images/' . $filename); - } - return $self->render( json => { + return $c->render( json => { success => Mojo::JSON->true, message => 'Upload Successful', }); - } -#TODO this should limit the number of responses returned, when location is implemented that would be the main way of filtering. +# TODO Limit search results, possibly paginate them? +# TODO Search by location as well sub post_search { - my $self = shift; - my $userId = $self->get_active_user_id(); + my $c = shift; + my $self = $c; - my $json = $self->req->json; - if ( ! defined $json ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'JSON is missing.', - }, - status => 400,); #Malformed request - } + my $validation = $c->validation; - my $searchName = $json->{searchName}; - if ( ! defined $searchName ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'searchName is missing.', - }, - status => 400,); #Malformed request - } - #Is blank - elsif ( $searchName =~ m/^\s*$/) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'searchName is blank.', - }, - status => 400,); #Malformed request - } + $validation->input( $c->stash->{api_json} ); - #Currently ignored - #TODO implement further. - my $searchLocation = $json->{searchLocation}; + $validation->required('search_name'); - my @validatedOrgs = (); - { - my $statementValidated = $self->db->prepare("SELECT OrganisationalId, Name, FullAddress, PostCode FROM Organisations WHERE UPPER( Name ) LIKE ?"); - $statementValidated->execute('%'. uc $searchName.'%'); + return $c->api_validation_error if $validation->has_error; - while (my ($id, $name, $address, $postcode) = $statementValidated->fetchrow_array()) { - push(@validatedOrgs, $self->create_hash($id,$name,$address,$postcode)); - } - } + my $search_name = $validation->param('search_name'); - $self->app->log->debug( "Orgs: " . Dumper @validatedOrgs ); + my $valid_orgs_rs = $c->schema->resultset('Organisation')->search( + { 'LOWER(name)' => { -like => '%' . lc $search_name . '%' } }, + ); - my @unvalidatedOrgs = (); - { - my $statementUnvalidated = $self->db->prepare("SELECT PendingOrganisationId, Name, FullAddress, Postcode FROM PendingOrganisations WHERE UPPER( Name ) LIKE ? AND UserSubmitted_FK = ?"); - $statementUnvalidated->execute('%'. uc $searchName.'%', $userId); + my $pending_orgs_rs = $c->stash->{api_user}->pending_organisations->search( + { 'LOWER(name)' => { -like => '%' . lc $search_name . '%' } }, + ); + + my @valid_orgs = ( + map {{ + id => $_->id, + name => $_->name, + street_name => $_->street_name, + town => $_->town, + postcode => $_->postcode, + }} $valid_orgs_rs->all + ); + + my @pending_orgs = ( + map {{ + id => $_->id, + name => $_->name, + street_name => $_->street_name, + town => $_->town, + postcode => $_->postcode, + }} $pending_orgs_rs->all + ); - while (my ($id, $name, $fullAddress, $postcode) = $statementUnvalidated->fetchrow_array()) { - push(@unvalidatedOrgs, $self->create_hash($id, $name, $fullAddress, $postcode)); - } - } - - $self->app->log->debug( "Non Validated Orgs: " . Dumper @unvalidatedOrgs ); - $self->app->log->debug('Path Success: file:' . __FILE__ . ', line: ' . __LINE__); return $self->render( json => { success => Mojo::JSON->true, - unvalidated => \@unvalidatedOrgs, - validated => \@validatedOrgs, - }, - status => 200,); - + validated => \@valid_orgs, + unvalidated => \@pending_orgs, + }); } 1; diff --git a/lib/Pear/LocalLoop/Controller/Api/User.pm b/lib/Pear/LocalLoop/Controller/Api/User.pm index 3f7b673..f1532a6 100644 --- a/lib/Pear/LocalLoop/Controller/Api/User.pm +++ b/lib/Pear/LocalLoop/Controller/Api/User.pm @@ -1,341 +1,29 @@ package Pear::LocalLoop::Controller::Api::User; use Mojo::Base 'Mojolicious::Controller'; -use Data::Dumper; use Mojo::JSON; -use DateTime; -use DateTime::Duration; -use TryCatch; -sub post_user_history { - my $self = shift; - - my $userId = $self->get_active_user_id(); - my $json = $self->req->json; - if ( ! defined $json ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'JSON is missing.', +has error_messages => sub { + return { + day => { + is_iso_datetime => { message => 'Invalid ISO8601 Datetime', status => 400 }, }, - status => 400,); #Malformed request - } + }; +}; - my $retrieveType = $json->{retrieveType}; - if ( ! defined $retrieveType ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'retrieveType is missing.', - }, - status => 400,); #Malformed request - } - elsif (! Scalar::Util::looks_like_number($retrieveType)){ - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'retrieveType does not look like a number.', - }, - status => 400,); #Malformed request - } +sub post_day { + my $c = shift; - #Date time. - my $startDateTime; - my $endDateTime; + my $validation = $c->validation; - #One day - if ($retrieveType == 1){ - my $startDayNumber = $json->{dayNumber}; - if ( ! defined $startDayNumber ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'dayNumber is missing.', - }, - status => 400,); #Malformed request - } - elsif (! Scalar::Util::looks_like_number($startDayNumber)){ - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'dayNumber does not look like a number.', - }, - status => 400,); #Malformed request - } + $validation->input( $c->stash->{api_json} ); - my $startMonthNumber = $json->{monthNumber}; - if ( ! defined $startMonthNumber ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'monthNumber is missing.', - }, - status => 400,); #Malformed request - } - elsif (! Scalar::Util::looks_like_number($startMonthNumber)){ - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'monthNumber does not look like a number.', - }, - status => 400,); #Malformed request - } + $validation->optional('day')->is_iso_datetime; - my $startYear = $json->{year}; - if ( ! defined $startYear ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'year is missing.', - }, - status => 400,); #Malformed request - } - elsif (! Scalar::Util::looks_like_number($startYear)){ - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'year does not look like a number.', - }, - status => 400,); #Malformed request - } + return $c->api_validation_error if $validation->has_error; - try - { - $startDateTime = DateTime->new( - year => $startYear, - month => $startMonthNumber, - day => $startDayNumber, - ); - } - catch - { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'date is invalid.', - }, - status => 400,); #Malformed request - }; - - $endDateTime = $startDateTime->clone(); - - } - elsif ($retrieveType == 2){ - my $startDayNumber = $json->{startDayNumber}; - if ( ! defined $startDayNumber ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'startDayNumber is missing.', - }, - status => 400,); #Malformed request - } - elsif (! Scalar::Util::looks_like_number($startDayNumber)){ - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'startDayNumber does not look like a number.', - }, - status => 400,); #Malformed request - } - - my $startMonthNumber = $json->{startMonthNumber}; - if ( ! defined $startMonthNumber ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'startMonthNumber is missing.', - }, - status => 400,); #Malformed request - } - elsif (! Scalar::Util::looks_like_number($startMonthNumber)){ - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'startMonthNumber does not look like a number.', - }, - status => 400,); #Malformed request - } - - my $startYear = $json->{startYear}; - if ( ! defined $startYear ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'startYear is missing.', - }, - status => 400,); #Malformed request - } - elsif (! Scalar::Util::looks_like_number($startYear)){ - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'startYear does not look like a number.', - }, - status => 400,); #Malformed request - } - - try - { - $startDateTime = DateTime->new( - year => $startYear, - month => $startMonthNumber, - day => $startDayNumber, - ); - } - catch - { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'start date is invalid.', - }, - status => 400,); #Malformed request - }; - - - my $endDayNumber = $json->{endDayNumber}; - if ( ! defined $endDayNumber ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'endDayNumber is missing.', - }, - status => 400,); #Malformed request - } - elsif (! Scalar::Util::looks_like_number($endDayNumber)){ - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'endDayNumber does not look like a number.', - }, - status => 400,); #Malformed request - } - - my $endMonthNumber = $json->{endMonthNumber}; - if ( ! defined $endMonthNumber ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'endMonthNumber is missing.', - }, - status => 400,); #Malformed request - } - elsif (! Scalar::Util::looks_like_number($endMonthNumber)){ - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'endMonthNumber does not look like a number.', - }, - status => 400,); #Malformed request - } - - my $endYear = $json->{endYear}; - if ( ! defined $endYear ) { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'endYear is missing.', - }, - status => 400,); #Malformed request - } - elsif (! Scalar::Util::looks_like_number($endYear)){ - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'endYear does not look like a number.', - }, - status => 400,); #Malformed request - } - - try - { - $endDateTime = DateTime->new( - year => $endYear, - month => $endMonthNumber, - day => $endDayNumber, - ); - } - catch - { - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'end date is invalid.', - }, - status => 400,); #Malformed request - }; - - } - else{ - $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - success => Mojo::JSON->false, - message => 'retrieveType can only be 1 or 2.', - }, - status => 400,); #Malformed request - } - - $endDateTime->add(days => 1); - - my $startEpoch = $startDateTime->epoch(); - my $endEpoch = $endDateTime->epoch(); - - $self->app->log->debug( "startEpoch: " . Dumper($startEpoch)); - $self->app->log->debug( "endEpoch: " . Dumper($endEpoch)); - - my $dataSpend = {}; - - my $statementSelectPendingTrans = $self->db->prepare("SELECT TimeDateSubmitted, ValueMicroCurrency FROM Transactions WHERE BuyerUserId_FK = ? AND ? <= TimeDateSubmitted AND TimeDateSubmitted < ? ORDER BY TimeDateSubmitted ASC"); - $statementSelectPendingTrans->execute($userId, $startEpoch, $endEpoch); - - #We assume "microCurrencySum" is always more than 0 due to database and input constraints in "/upload". - sub add_value_to_hash { - my ($self, $microCurrencySum, $dateTimePreviousState, $dataSpend) = @_; - - #if ($microCurrencySum != 0) { - my $year = $dateTimePreviousState->year(); - my $month = $dateTimePreviousState->month(); - my $day = $dateTimePreviousState->day(); - - $dataSpend->{$year}{$month}{$day} = $microCurrencySum; - #} - } - - if (my ($timeDateSubmitted, $valueMicroCurrency) = $statementSelectPendingTrans->fetchrow_array()) { - my $dateTimeTruncator = DateTime->from_epoch(epoch => $timeDateSubmitted); - $dateTimeTruncator->truncate( to => 'day'); - - #Set to 0 then add the current value like the else block. - my $microCurrencySum = $valueMicroCurrency; - #Set to the first row time - my $dateTimePreviousState = $dateTimeTruncator; - - while (my ($timeDateSubmitted, $valueMicroCurrency) = $statementSelectPendingTrans->fetchrow_array()) { - $dateTimeTruncator = DateTime->from_epoch(epoch => $timeDateSubmitted); - $dateTimeTruncator->truncate( to => 'day'); - - if (DateTime->compare($dateTimePreviousState, $dateTimeTruncator) != 0 ){ - add_value_to_hash($self, $microCurrencySum, $dateTimePreviousState, $dataSpend); - $microCurrencySum = $valueMicroCurrency; #Reset to 0 then add the current value like the else block. - $dateTimePreviousState = $dateTimeTruncator; - } - else{ - $microCurrencySum += $valueMicroCurrency; #Same day to keep adding the values. - } - } - - add_value_to_hash($self, $microCurrencySum, $dateTimePreviousState, $dataSpend); - } - - - $self->app->log->debug('Path Success: file:' . __FILE__ . ', line: ' . __LINE__); - return $self->render( json => { - microCurencySpent => $dataSpend, + $c->render( json => { success => Mojo::JSON->true, - }, - status => 200,); - + }); } 1; - diff --git a/lib/Pear/LocalLoop/Controller/Portal.pm b/lib/Pear/LocalLoop/Controller/Portal.pm new file mode 100644 index 0000000..5e4b4ef --- /dev/null +++ b/lib/Pear/LocalLoop/Controller/Portal.pm @@ -0,0 +1,11 @@ +package Pear::LocalLoop::Controller::Portal; +use Mojo::Base 'Mojolicious::Controller'; + +sub under { + my $c = shift; + + $c->stash( api_user => $c->current_user ); + return 1; +} + +1; diff --git a/lib/Pear/LocalLoop/Controller/Register.pm b/lib/Pear/LocalLoop/Controller/Register.pm index 0a34896..65b00fe 100644 --- a/lib/Pear/LocalLoop/Controller/Register.pm +++ b/lib/Pear/LocalLoop/Controller/Register.pm @@ -35,10 +35,10 @@ sub register { $validation->required('email')->email->not_in_resultset('email', $user_rs); my $token_rs = $c->schema->resultset('AccountToken')->search_rs({used => 0}); - $validation->required('token')->in_resultset('accounttokenname', $token_rs); + $validation->required('token')->in_resultset('name', $token_rs); my $age_rs = $c->schema->resultset('AgeRange'); - $validation->required('agerange')->in_resultset('agerangeid', $age_rs); + $validation->required('agerange')->in_resultset('id', $age_rs); my @error_messages; if ( $validation->has_error ) { @@ -47,12 +47,11 @@ sub register { } else { my $new_user = $c->schema->resultset('User')->find_or_new({ email => $validation->param('email'), - hashedpassword => $validation->param('password'), - joindate => DateTime->now(), + password => $validation->param('password'), customer => { username => $validation->param('name'), postcode => $validation->param('postcode'), - agerange_fk => $validation->param('agerange'), + age_range_id => $validation->param('agerange'), }, }); if ( $new_user->in_storage ) { diff --git a/lib/Pear/LocalLoop/Plugin/Validators.pm b/lib/Pear/LocalLoop/Plugin/Validators.pm index b938a2c..8dfaf4e 100644 --- a/lib/Pear/LocalLoop/Plugin/Validators.pm +++ b/lib/Pear/LocalLoop/Plugin/Validators.pm @@ -4,7 +4,8 @@ use Mojo::Base 'Mojolicious::Plugin'; use Email::Valid; use Geo::UK::Postcode; use Scalar::Util qw/ looks_like_number /; -use File::Basename; +use File::Basename qw/ fileparse /; +use DateTime::Format::Strptime; sub register { my ( $plugin, $app, $conf ) = @_; @@ -45,6 +46,12 @@ sub register { $extension =~ s/^\.//; return $app->types->type($extension) eq $filetype ? undef : 1; }); + + $app->validator->add_check( is_iso_datetime => sub { + my ( $validation, $name, $value ) = @_; + $value = $app->datetime_formatter->parse_datetime( $value ); + return defined $value ? undef : 1; + }); } 1; diff --git a/lib/Pear/LocalLoop/Schema.pm b/lib/Pear/LocalLoop/Schema.pm index cea012b..7814cd6 100644 --- a/lib/Pear/LocalLoop/Schema.pm +++ b/lib/Pear/LocalLoop/Schema.pm @@ -1,9 +1,6 @@ use utf8; package Pear::LocalLoop::Schema; -# Created by DBIx::Class::Schema::Loader -# DO NOT MODIFY THE FIRST PART OF THIS FILE - use strict; use warnings; @@ -11,10 +8,4 @@ use base 'DBIx::Class::Schema'; __PACKAGE__->load_namespaces; - -# Created by DBIx::Class::Schema::Loader v0.07046 @ 2017-02-24 17:32:21 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:JNwB+HEKyNyE5ZP1Br1pog - - -# You can replace this text with custom code or comments, and it will be preserved on regeneration 1; diff --git a/lib/Pear/LocalLoop/Schema/Result/AccountToken.pm b/lib/Pear/LocalLoop/Schema/Result/AccountToken.pm index 7bace3b..51e2f1f 100644 --- a/lib/Pear/LocalLoop/Schema/Result/AccountToken.pm +++ b/lib/Pear/LocalLoop/Schema/Result/AccountToken.pm @@ -1,98 +1,23 @@ -use utf8; package Pear::LocalLoop::Schema::Result::AccountToken; -# Created by DBIx::Class::Schema::Loader -# DO NOT MODIFY THE FIRST PART OF THIS FILE - -=head1 NAME - -Pear::LocalLoop::Schema::Result::AccountToken - -=cut - use strict; use warnings; use base 'DBIx::Class::Core'; -=head1 COMPONENTS LOADED - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->load_components("InflateColumn::DateTime"); - -=head1 TABLE: C - -=cut - -__PACKAGE__->table("AccountTokens"); - -=head1 ACCESSORS - -=head2 accounttokenid - - data_type: 'integer' - is_auto_increment: 1 - is_nullable: 0 - -=head2 accounttokenname - - data_type: 'text' - is_nullable: 0 - -=head2 used - - data_type: 'integer' - default_value: 0 - is_nullable: 0 - -=cut +__PACKAGE__->table("account_tokens"); __PACKAGE__->add_columns( - "accounttokenid", + "id", { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, - "accounttokenname", + "name", { data_type => "text", is_nullable => 0 }, "used", { data_type => "integer", default_value => 0, is_nullable => 0 }, ); -=head1 PRIMARY KEY +__PACKAGE__->set_primary_key("id"); -=over 4 +__PACKAGE__->add_unique_constraint(["name"]); -=item * L - -=back - -=cut - -__PACKAGE__->set_primary_key("accounttokenid"); - -=head1 UNIQUE CONSTRAINTS - -=head2 C - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->add_unique_constraint("accounttokenname_unique", ["accounttokenname"]); - - -# Created by DBIx::Class::Schema::Loader v0.07046 @ 2017-02-24 17:32:21 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:MeN6dMZY0drrWk+En7E5Ag - - -# You can replace this text with custom code or comments, and it will be preserved on regeneration 1; diff --git a/lib/Pear/LocalLoop/Schema/Result/Administrator.pm b/lib/Pear/LocalLoop/Schema/Result/Administrator.pm index fcc190c..1fd2bfc 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Administrator.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Administrator.pm @@ -1,92 +1,28 @@ -use utf8; package Pear::LocalLoop::Schema::Result::Administrator; -# Created by DBIx::Class::Schema::Loader -# DO NOT MODIFY THE FIRST PART OF THIS FILE - -=head1 NAME - -Pear::LocalLoop::Schema::Result::Administrator - -=cut - use strict; use warnings; use base 'DBIx::Class::Core'; -=head1 COMPONENTS LOADED - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->load_components("InflateColumn::DateTime"); - -=head1 TABLE: C - -=cut - -__PACKAGE__->table("Administrators"); - -=head1 ACCESSORS - -=head2 userid - - data_type: 'integer' - is_auto_increment: 1 - is_foreign_key: 1 - is_nullable: 0 - -=cut +__PACKAGE__->table("administrators"); __PACKAGE__->add_columns( - "userid", + "user_id", { - data_type => "integer", - is_auto_increment => 1, - is_foreign_key => 1, - is_nullable => 0, + data_type => "integer", + is_foreign_key => 1, + is_nullable => 0, }, ); -=head1 PRIMARY KEY - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->set_primary_key("userid"); - -=head1 RELATIONS - -=head2 userid - -Type: belongs_to - -Related object: L - -=cut +__PACKAGE__->set_primary_key("user_id"); __PACKAGE__->belongs_to( - "userid", + "user", "Pear::LocalLoop::Schema::Result::User", - { userid => "userid" }, + { id => "user_id" }, { is_deferrable => 0, on_delete => "NO ACTION", on_update => "NO ACTION" }, ); - -# Created by DBIx::Class::Schema::Loader v0.07046 @ 2017-02-24 17:32:21 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:YLzlp1ru+1id/O4bTJGqbw - - -# You can replace this text with custom code or comments, and it will be preserved on regeneration 1; diff --git a/lib/Pear/LocalLoop/Schema/Result/AgeRange.pm b/lib/Pear/LocalLoop/Schema/Result/AgeRange.pm index 1adf168..73c4ffd 100644 --- a/lib/Pear/LocalLoop/Schema/Result/AgeRange.pm +++ b/lib/Pear/LocalLoop/Schema/Result/AgeRange.pm @@ -1,107 +1,37 @@ -use utf8; package Pear::LocalLoop::Schema::Result::AgeRange; -# Created by DBIx::Class::Schema::Loader -# DO NOT MODIFY THE FIRST PART OF THIS FILE - -=head1 NAME - -Pear::LocalLoop::Schema::Result::AgeRange - -=cut - use strict; use warnings; use base 'DBIx::Class::Core'; -=head1 COMPONENTS LOADED - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->load_components("InflateColumn::DateTime"); - -=head1 TABLE: C - -=cut - -__PACKAGE__->table("AgeRanges"); - -=head1 ACCESSORS - -=head2 agerangeid - - data_type: 'integer' - is_auto_increment: 1 - is_nullable: 0 - -=head2 agerangestring - - data_type: 'text' - is_nullable: 0 - -=cut +__PACKAGE__->table("age_ranges"); __PACKAGE__->add_columns( - "agerangeid", + "id", { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, - "agerangestring", + "string", { data_type => "text", is_nullable => 0 }, ); -=head1 PRIMARY KEY +__PACKAGE__->set_primary_key("id"); -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->set_primary_key("agerangeid"); - -=head1 UNIQUE CONSTRAINTS - -=head2 C - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->add_unique_constraint("agerangestring_unique", ["agerangestring"]); - -=head1 RELATIONS - -=head2 customers - -Type: has_many - -Related object: L - -=cut +__PACKAGE__->add_unique_constraint(["string"]); __PACKAGE__->has_many( "customers", "Pear::LocalLoop::Schema::Result::Customer", - { "foreign.agerange_fk" => "self.agerangeid" }, + { "foreign.age_range_id" => "self.id" }, { cascade_copy => 0, cascade_delete => 0 }, ); +sub TO_JSON { + my $self = shift; -# Created by DBIx::Class::Schema::Loader v0.07046 @ 2017-02-24 17:32:21 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:4zGNm0RlwptF9hlj9oErVA + return { + id => $self->id, + string => $self->string, + }; +} - -# You can replace this text with custom code or comments, and it will be preserved on regeneration 1; diff --git a/lib/Pear/LocalLoop/Schema/Result/Customer.pm b/lib/Pear/LocalLoop/Schema/Result/Customer.pm index c59f178..100be3a 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Customer.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Customer.pm @@ -1,137 +1,49 @@ -use utf8; package Pear::LocalLoop::Schema::Result::Customer; -# Created by DBIx::Class::Schema::Loader -# DO NOT MODIFY THE FIRST PART OF THIS FILE - -=head1 NAME - -Pear::LocalLoop::Schema::Result::Customer - -=cut - use strict; use warnings; use base 'DBIx::Class::Core'; -=head1 COMPONENTS LOADED - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->load_components("InflateColumn::DateTime"); - -=head1 TABLE: C - -=cut - -__PACKAGE__->table("Customers"); - -=head1 ACCESSORS - -=head2 customerid - - data_type: 'integer' - is_auto_increment: 1 - is_nullable: 0 - -=head2 username - - data_type: 'text' - is_nullable: 0 - -=head2 agerange_fk - - data_type: 'integer' - is_foreign_key: 1 - is_nullable: 0 - -=head2 postcode - - data_type: 'text' - is_nullable: 0 - -=cut +__PACKAGE__->table("customers"); __PACKAGE__->add_columns( - "customerid", - { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, - "username", - { data_type => "text", is_nullable => 0 }, - "agerange_fk", - { data_type => "integer", is_foreign_key => 1, is_nullable => 0 }, - "postcode", - { data_type => "text", is_nullable => 0 }, + "id" => { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + }, + "name" => { + data_type => "varchar", + size => 255, + is_nullable => 0, + }, + "age_range_id" => { + data_type => "integer", + is_foreign_key => 1, + is_nullable => 0, + }, + "postcode" => { + data_type => "varchar", + size => 16, + is_nullable => 0, + }, ); -=head1 PRIMARY KEY - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->set_primary_key("customerid"); - -=head1 UNIQUE CONSTRAINTS - -=head2 C - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->add_unique_constraint("username_unique", ["username"]); - -=head1 RELATIONS - -=head2 agerange_fk - -Type: belongs_to - -Related object: L - -=cut +__PACKAGE__->set_primary_key("id"); __PACKAGE__->belongs_to( - "agerange_fk", + "age_range", "Pear::LocalLoop::Schema::Result::AgeRange", - { agerangeid => "agerange_fk" }, + { id => "age_range_id" }, { is_deferrable => 0, on_delete => "NO ACTION", on_update => "NO ACTION" }, ); -=head2 user - -Type: might_have - -Related object: L - -=cut - __PACKAGE__->might_have( "user", "Pear::LocalLoop::Schema::Result::User", - { "foreign.customerid_fk" => "self.customerid" }, + { "foreign.customer_id" => "self.id" }, { cascade_copy => 0, cascade_delete => 0 }, ); - -# Created by DBIx::Class::Schema::Loader v0.07046 @ 2017-02-24 17:32:21 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ocoCGZYvw9O9wxzr14okiQ - - -# You can replace this text with custom code or comments, and it will be preserved on regeneration 1; diff --git a/lib/Pear/LocalLoop/Schema/Result/Organisation.pm b/lib/Pear/LocalLoop/Schema/Result/Organisation.pm index 2014575..e5a30a3 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Organisation.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Organisation.pm @@ -1,122 +1,55 @@ -use utf8; package Pear::LocalLoop::Schema::Result::Organisation; -# Created by DBIx::Class::Schema::Loader -# DO NOT MODIFY THE FIRST PART OF THIS FILE - -=head1 NAME - -Pear::LocalLoop::Schema::Result::Organisation - -=cut - use strict; use warnings; use base 'DBIx::Class::Core'; -=head1 COMPONENTS LOADED - -=over 4 - -=item * L - -=back - -=cut - __PACKAGE__->load_components("InflateColumn::DateTime"); -=head1 TABLE: C - -=cut - -__PACKAGE__->table("Organisations"); - -=head1 ACCESSORS - -=head2 organisationalid - - data_type: 'integer' - is_auto_increment: 1 - is_nullable: 0 - -=head2 name - - data_type: 'text' - is_nullable: 0 - -=head2 fulladdress - - data_type: 'text' - is_nullable: 0 - -=head2 postcode - - data_type: 'text' - is_nullable: 0 - -=cut +__PACKAGE__->table("organisations"); __PACKAGE__->add_columns( - "organisationalid", - { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, - "name", - { data_type => "text", is_nullable => 0 }, - "fulladdress", - { data_type => "text", is_nullable => 0 }, - "postcode", - { data_type => "text", is_nullable => 0 }, + id => { + data_type => 'integer', + is_auto_increment => 1, + is_nullable => 0, + }, + name => { + data_type => 'varchar', + size => 255, + is_nullable => 0, + }, + street_name => { + data_type => 'text', + is_nullable => 1, + }, + town => { + data_type => 'varchar', + size => 255, + is_nullable => 0, + }, + postcode => { + data_type => 'varchar', + size => 16, + is_nullable => 1, + }, ); -=head1 PRIMARY KEY - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->set_primary_key("organisationalid"); - -=head1 RELATIONS - -=head2 transactions - -Type: has_many - -Related object: L - -=cut +__PACKAGE__->set_primary_key('id'); __PACKAGE__->has_many( "transactions", "Pear::LocalLoop::Schema::Result::Transaction", - { "foreign.sellerorganisationid_fk" => "self.organisationalid" }, + { "foreign.seller_id" => 'self.id' }, { cascade_copy => 0, cascade_delete => 0 }, ); -=head2 user - -Type: might_have - -Related object: L - -=cut - __PACKAGE__->might_have( "user", "Pear::LocalLoop::Schema::Result::User", - { "foreign.organisationalid_fk" => "self.organisationalid" }, + { "foreign.organisation_id" => 'self.id' }, { cascade_copy => 0, cascade_delete => 0 }, ); - -# Created by DBIx::Class::Schema::Loader v0.07046 @ 2017-02-24 17:32:21 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:p9FzM/H5YQbo2d0lN/DfCg - - -# You can replace this text with custom code or comments, and it will be preserved on regeneration 1; diff --git a/lib/Pear/LocalLoop/Schema/Result/PendingOrganisation.pm b/lib/Pear/LocalLoop/Schema/Result/PendingOrganisation.pm index e9790fc..5cf1f51 100644 --- a/lib/Pear/LocalLoop/Schema/Result/PendingOrganisation.pm +++ b/lib/Pear/LocalLoop/Schema/Result/PendingOrganisation.pm @@ -1,139 +1,70 @@ -use utf8; package Pear::LocalLoop::Schema::Result::PendingOrganisation; -# Created by DBIx::Class::Schema::Loader -# DO NOT MODIFY THE FIRST PART OF THIS FILE - -=head1 NAME - -Pear::LocalLoop::Schema::Result::PendingOrganisation - -=cut - use strict; use warnings; use base 'DBIx::Class::Core'; -=head1 COMPONENTS LOADED +__PACKAGE__->load_components( qw/ + InflateColumn::DateTime + TimeStamp +/); -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->load_components("InflateColumn::DateTime"); - -=head1 TABLE: C - -=cut - -__PACKAGE__->table("PendingOrganisations"); - -=head1 ACCESSORS - -=head2 pendingorganisationid - - data_type: 'integer' - is_auto_increment: 1 - is_nullable: 0 - -=head2 usersubmitted_fk - - data_type: 'integer' - is_foreign_key: 1 - is_nullable: 0 - -=head2 timedatesubmitted - - data_type: 'integer' - is_nullable: 0 - -=head2 name - - data_type: 'text' - is_nullable: 0 - -=head2 fulladdress - - data_type: 'text' - is_nullable: 1 - -=head2 postcode - - data_type: 'text' - is_nullable: 1 - -=cut +__PACKAGE__->table("pending_organisations"); __PACKAGE__->add_columns( - "pendingorganisationid", - { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, - "usersubmitted_fk", - { data_type => "integer", is_foreign_key => 1, is_nullable => 0 }, - "timedatesubmitted", - { data_type => "datetime", is_nullable => 0 }, - "name", - { data_type => "text", is_nullable => 0 }, - "fulladdress", - { data_type => "text", is_nullable => 1 }, - "postcode", - { data_type => "text", is_nullable => 1 }, + id => { + data_type => 'integer', + is_auto_increment => 1, + is_nullable => 0, + }, + name => { + data_type => 'varchar', + size => 255, + is_nullable => 0, + }, + street_name => { + data_type => 'text', + is_nullable => 1, + }, + town => { + data_type => 'varchar', + size => 255, + is_nullable => 0, + }, + postcode => { + data_type => 'varchar', + size => 16, + is_nullable => 1, + }, + submitted_by_id => { + data_type => "integer", + is_foreign_key => 1, + is_nullable => 0, + }, + submitted_at => { + data_type => "datetime", + is_nullable => 0, + set_on_create => 1, + }, ); -=head1 PRIMARY KEY - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->set_primary_key("pendingorganisationid"); - -=head1 RELATIONS - -=head2 pending_transactions - -Type: has_many - -Related object: L - -=cut +__PACKAGE__->set_primary_key('id'); __PACKAGE__->has_many( - "pending_transactions", + "transactions", "Pear::LocalLoop::Schema::Result::PendingTransaction", { - "foreign.pendingsellerorganisationid_fk" => "self.pendingorganisationid", + "foreign.seller_id" => "self.id", }, - { cascade_copy => 0, cascade_delete => 0 }, + { cascade_copy => 0, cascade_delete => 1 }, ); -=head2 usersubmitted_fk - -Type: belongs_to - -Related object: L - -=cut - __PACKAGE__->belongs_to( - "usersubmitted_fk", + "submitted_by", "Pear::LocalLoop::Schema::Result::User", - { userid => "usersubmitted_fk" }, + { id => "submitted_by_id" }, { is_deferrable => 0, on_delete => "NO ACTION", on_update => "NO ACTION" }, ); - -# Created by DBIx::Class::Schema::Loader v0.07046 @ 2017-02-24 17:32:21 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ekEOt+ESCwQxrqqlMurehA - - -# You can replace this text with custom code or comments, and it will be preserved on regeneration 1; diff --git a/lib/Pear/LocalLoop/Schema/Result/PendingTransaction.pm b/lib/Pear/LocalLoop/Schema/Result/PendingTransaction.pm index 07ea25c..f737725 100644 --- a/lib/Pear/LocalLoop/Schema/Result/PendingTransaction.pm +++ b/lib/Pear/LocalLoop/Schema/Result/PendingTransaction.pm @@ -1,152 +1,63 @@ -use utf8; package Pear::LocalLoop::Schema::Result::PendingTransaction; -# Created by DBIx::Class::Schema::Loader -# DO NOT MODIFY THE FIRST PART OF THIS FILE - -=head1 NAME - -Pear::LocalLoop::Schema::Result::PendingTransaction - -=cut - use strict; use warnings; use base 'DBIx::Class::Core'; -=head1 COMPONENTS LOADED +__PACKAGE__->load_components( qw/ + InflateColumn::DateTime + TimeStamp +/); -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->load_components("InflateColumn::DateTime"); - -=head1 TABLE: C - -=cut - -__PACKAGE__->table("PendingTransactions"); - -=head1 ACCESSORS - -=head2 pendingtransactionid - - data_type: 'integer' - is_auto_increment: 1 - is_nullable: 0 - -=head2 buyeruserid_fk - - data_type: 'integer' - is_foreign_key: 1 - is_nullable: 0 - -=head2 pendingsellerorganisationid_fk - - data_type: 'integer' - is_foreign_key: 1 - is_nullable: 0 - -=head2 valuemicrocurrency - - data_type: 'integer' - is_nullable: 0 - -=head2 proofimage - - data_type: 'text' - is_nullable: 0 - -=head2 timedatesubmitted - - data_type: 'integer' - is_nullable: 0 - -=cut +__PACKAGE__->table("pending_transactions"); __PACKAGE__->add_columns( - "pendingtransactionid", - { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, - "buyeruserid_fk", - { data_type => "integer", is_foreign_key => 1, is_nullable => 0 }, - "pendingsellerorganisationid_fk", - { data_type => "integer", is_foreign_key => 1, is_nullable => 0 }, - "valuemicrocurrency", - { data_type => "integer", is_nullable => 0 }, - "proofimage", - { data_type => "text", is_nullable => 0 }, - "timedatesubmitted", - { data_type => "datetime", is_nullable => 0 }, + "id" => { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + }, + "buyer_id" => { + data_type => "integer", + is_foreign_key => 1, + is_nullable => 0, + }, + "seller_id" => { + data_type => "integer", + is_foreign_key => 1, + is_nullable => 0, + }, + "value" => { + data_type => "decimal", + size => [ 16, 2 ], + is_nullable => 0, + }, + "proof_image" => { + data_type => "text", + is_nullable => 0, + }, + "submitted_at" => { + data_type => "datetime", + is_nullable => 0, + set_on_create => 1, + }, ); -=head1 PRIMARY KEY - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->set_primary_key("pendingtransactionid"); - -=head1 UNIQUE CONSTRAINTS - -=head2 C - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->add_unique_constraint("proofimage_unique", ["proofimage"]); - -=head1 RELATIONS - -=head2 buyeruserid_fk - -Type: belongs_to - -Related object: L - -=cut +__PACKAGE__->set_primary_key("id"); __PACKAGE__->belongs_to( - "buyeruserid_fk", + "buyer", "Pear::LocalLoop::Schema::Result::User", - { userid => "buyeruserid_fk" }, + { id => "buyer_id" }, { is_deferrable => 0, on_delete => "NO ACTION", on_update => "NO ACTION" }, ); -=head2 pendingsellerorganisationid_fk - -Type: belongs_to - -Related object: L - -=cut - __PACKAGE__->belongs_to( - "pendingsellerorganisationid_fk", + "seller", "Pear::LocalLoop::Schema::Result::PendingOrganisation", - { pendingorganisationid => "pendingsellerorganisationid_fk" }, + { id => "seller_id" }, { is_deferrable => 0, on_delete => "NO ACTION", on_update => "NO ACTION" }, ); - -# Created by DBIx::Class::Schema::Loader v0.07046 @ 2017-02-24 17:32:21 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:zwtxzfW5uB4FNA6mKdFOvg - - -# You can replace this text with custom code or comments, and it will be preserved on regeneration 1; diff --git a/lib/Pear/LocalLoop/Schema/Result/SessionToken.pm b/lib/Pear/LocalLoop/Schema/Result/SessionToken.pm index fddf569..17eb162 100644 --- a/lib/Pear/LocalLoop/Schema/Result/SessionToken.pm +++ b/lib/Pear/LocalLoop/Schema/Result/SessionToken.pm @@ -1,122 +1,39 @@ -use utf8; package Pear::LocalLoop::Schema::Result::SessionToken; -# Created by DBIx::Class::Schema::Loader -# DO NOT MODIFY THE FIRST PART OF THIS FILE - -=head1 NAME - -Pear::LocalLoop::Schema::Result::SessionToken - -=cut - use strict; use warnings; use base 'DBIx::Class::Core'; -=head1 COMPONENTS LOADED - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->load_components("InflateColumn::DateTime"); - -=head1 TABLE: C - -=cut - -__PACKAGE__->table("SessionTokens"); - -=head1 ACCESSORS - -=head2 sessiontokenid - - data_type: 'integer' - is_auto_increment: 1 - is_nullable: 0 - -=head2 sessiontokenname - - data_type: 'text' - is_nullable: 0 - -=head2 useridassignedto_fk - - data_type: 'integer' - is_foreign_key: 1 - is_nullable: 0 - -=head2 expiredatetime - - data_type: 'integer' - is_nullable: 0 - -=cut +__PACKAGE__->table("session_tokens"); __PACKAGE__->add_columns( - "sessiontokenid", - { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, - "sessiontokenname", - { data_type => "text", is_nullable => 0 }, - "useridassignedto_fk", - { data_type => "integer", is_foreign_key => 1, is_nullable => 0 }, - "expiredatetime", - { data_type => "datetime", is_nullable => 0 }, + "id" => { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + }, + "token" => { + data_type => "varchar", + size => 255, + is_nullable => 0, + }, + "user_id" => { + data_type => "integer", + is_foreign_key => 1, + is_nullable => 0, + }, ); -=head1 PRIMARY KEY +__PACKAGE__->set_primary_key("id"); -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->set_primary_key("sessiontokenid"); - -=head1 UNIQUE CONSTRAINTS - -=head2 C - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->add_unique_constraint("sessiontokenname_unique", ["sessiontokenname"]); - -=head1 RELATIONS - -=head2 useridassignedto_fk - -Type: belongs_to - -Related object: L - -=cut +__PACKAGE__->add_unique_constraint(["token"]); __PACKAGE__->belongs_to( "user", "Pear::LocalLoop::Schema::Result::User", - { userid => "useridassignedto_fk" }, + { id => "user_id" }, { is_deferrable => 0, on_delete => "NO ACTION", on_update => "NO ACTION" }, ); - -# Created by DBIx::Class::Schema::Loader v0.07046 @ 2017-02-24 17:32:21 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:/mNAPeSmfsDSIpey+eUucg - - -# You can replace this text with custom code or comments, and it will be preserved on regeneration 1; diff --git a/lib/Pear/LocalLoop/Schema/Result/Transaction.pm b/lib/Pear/LocalLoop/Schema/Result/Transaction.pm index 9f22a25..198c9ee 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Transaction.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Transaction.pm @@ -1,152 +1,63 @@ -use utf8; package Pear::LocalLoop::Schema::Result::Transaction; -# Created by DBIx::Class::Schema::Loader -# DO NOT MODIFY THE FIRST PART OF THIS FILE - -=head1 NAME - -Pear::LocalLoop::Schema::Result::Transaction - -=cut - use strict; use warnings; use base 'DBIx::Class::Core'; -=head1 COMPONENTS LOADED +__PACKAGE__->load_components(qw/ + InflateColumn::DateTime + TimeStamp +/); -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->load_components("InflateColumn::DateTime"); - -=head1 TABLE: C - -=cut - -__PACKAGE__->table("Transactions"); - -=head1 ACCESSORS - -=head2 transactionid - - data_type: 'integer' - is_auto_increment: 1 - is_nullable: 0 - -=head2 buyeruserid_fk - - data_type: 'integer' - is_foreign_key: 1 - is_nullable: 0 - -=head2 sellerorganisationid_fk - - data_type: 'integer' - is_foreign_key: 1 - is_nullable: 0 - -=head2 valuemicrocurrency - - data_type: 'integer' - is_nullable: 0 - -=head2 proofimage - - data_type: 'text' - is_nullable: 0 - -=head2 timedatesubmitted - - data_type: 'integer' - is_nullable: 0 - -=cut +__PACKAGE__->table("transactions"); __PACKAGE__->add_columns( - "transactionid", - { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, - "buyeruserid_fk", - { data_type => "integer", is_foreign_key => 1, is_nullable => 0 }, - "sellerorganisationid_fk", - { data_type => "integer", is_foreign_key => 1, is_nullable => 0 }, - "valuemicrocurrency", - { data_type => "integer", is_nullable => 0 }, - "proofimage", - { data_type => "text", is_nullable => 0 }, - "timedatesubmitted", - { data_type => "datetime", is_nullable => 0 }, + "id" => { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + }, + "buyer_id" => { + data_type => "integer", + is_foreign_key => 1, + is_nullable => 0, + }, + "seller_id" => { + data_type => "integer", + is_foreign_key => 1, + is_nullable => 0, + }, + "value" => { + data_type => "decimal", + size => [ 16, 2 ], + is_nullable => 0, + }, + "proof_image" => { + data_type => "text", + is_nullable => 0, + }, + "submitted_at" => { + data_type => "datetime", + is_nullable => 0, + set_on_create => 1, + }, ); -=head1 PRIMARY KEY - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->set_primary_key("transactionid"); - -=head1 UNIQUE CONSTRAINTS - -=head2 C - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->add_unique_constraint("proofimage_unique", ["proofimage"]); - -=head1 RELATIONS - -=head2 buyeruserid_fk - -Type: belongs_to - -Related object: L - -=cut +__PACKAGE__->set_primary_key("id"); __PACKAGE__->belongs_to( - "buyeruserid_fk", + "buyer", "Pear::LocalLoop::Schema::Result::User", - { userid => "buyeruserid_fk" }, + { id => "buyer_id" }, { is_deferrable => 0, on_delete => "NO ACTION", on_update => "NO ACTION" }, ); -=head2 sellerorganisationid_fk - -Type: belongs_to - -Related object: L - -=cut - __PACKAGE__->belongs_to( - "sellerorganisationid_fk", + "seller", "Pear::LocalLoop::Schema::Result::Organisation", - { organisationalid => "sellerorganisationid_fk" }, + { id => "seller_id" }, { is_deferrable => 0, on_delete => "NO ACTION", on_update => "NO ACTION" }, ); - -# Created by DBIx::Class::Schema::Loader v0.07046 @ 2017-02-24 17:32:21 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:CfPoE2egoSD1tKo7fYjZdg - - -# You can replace this text with custom code or comments, and it will be preserved on regeneration 1; diff --git a/lib/Pear/LocalLoop/Schema/Result/User.pm b/lib/Pear/LocalLoop/Schema/Result/User.pm index c814194..6974cb4 100644 --- a/lib/Pear/LocalLoop/Schema/Result/User.pm +++ b/lib/Pear/LocalLoop/Schema/Result/User.pm @@ -1,88 +1,45 @@ -use utf8; package Pear::LocalLoop::Schema::Result::User; -# Created by DBIx::Class::Schema::Loader -# DO NOT MODIFY THE FIRST PART OF THIS FILE - -=head1 NAME - -Pear::LocalLoop::Schema::Result::User - -=cut - use strict; use warnings; use base 'DBIx::Class::Core'; -=head1 COMPONENTS LOADED +use Data::UUID; -=over 4 +__PACKAGE__->load_components( qw/ + InflateColumn::DateTime + PassphraseColumn + TimeStamp +/); -=item * L - -=back - -=cut - -__PACKAGE__->load_components("InflateColumn::DateTime", "PassphraseColumn"); - -=head1 TABLE: C - -=cut - -__PACKAGE__->table("Users"); - -=head1 ACCESSORS - -=head2 userid - - data_type: 'integer' - is_auto_increment: 1 - is_nullable: 0 - -=head2 customerid_fk - - data_type: 'integer' - is_foreign_key: 1 - is_nullable: 1 - -=head2 organisationalid_fk - - data_type: 'integer' - is_foreign_key: 1 - is_nullable: 1 - -=head2 email - - data_type: 'text' - is_nullable: 0 - -=head2 joindate - - data_type: 'integer' - is_nullable: 0 - -=head2 hashedpassword - - data_type: 'text' - is_nullable: 0 - -=cut +__PACKAGE__->table("users"); __PACKAGE__->add_columns( - "userid", - { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, - "customerid_fk", - { data_type => "integer", is_foreign_key => 1, is_nullable => 1 }, - "organisationalid_fk", - { data_type => "integer", is_foreign_key => 1, is_nullable => 1 }, - "email", - { data_type => "text", is_nullable => 0 }, - "joindate", - { data_type => "datetime", is_nullable => 0 }, - "hashedpassword", - { + "id" => { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + }, + "customer_id" => { + data_type => "integer", + is_foreign_key => 1, + is_nullable => 1, + }, + "organisation_id" => { + data_type => "integer", + is_foreign_key => 1, + is_nullable => 1, + }, + "email" => { + data_type => "text", + is_nullable => 0, + }, + "join_date" => { + data_type => "datetime", + set_on_create => 1, + }, + "password" => { data_type => "varchar", is_nullable => 0, size => 100, @@ -96,85 +53,25 @@ __PACKAGE__->add_columns( }, ); -=head1 PRIMARY KEY +__PACKAGE__->set_primary_key("id"); -=over 4 +__PACKAGE__->add_unique_constraint(["customer_id"]); -=item * L +__PACKAGE__->add_unique_constraint(["email"]); -=back - -=cut - -__PACKAGE__->set_primary_key("userid"); - -=head1 UNIQUE CONSTRAINTS - -=head2 C - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->add_unique_constraint("customerid_fk_unique", ["customerid_fk"]); - -=head2 C - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->add_unique_constraint("email_unique", ["email"]); - -=head2 C - -=over 4 - -=item * L - -=back - -=cut - -__PACKAGE__->add_unique_constraint("organisationalid_fk_unique", ["organisationalid_fk"]); - -=head1 RELATIONS - -=head2 administrator - -Type: might_have - -Related object: L - -=cut +__PACKAGE__->add_unique_constraint(["organisation_id"]); __PACKAGE__->might_have( "administrator", "Pear::LocalLoop::Schema::Result::Administrator", - { "foreign.userid" => "self.userid" }, + { "foreign.user_id" => "self.id" }, { cascade_copy => 0, cascade_delete => 0 }, ); -=head2 customerid_fk - -Type: belongs_to - -Related object: L - -=cut - __PACKAGE__->belongs_to( "customer", "Pear::LocalLoop::Schema::Result::Customer", - { customerid => "customerid_fk" }, + { "foreign.id" => "self.customer_id" }, { is_deferrable => 0, join_type => "LEFT", @@ -183,18 +80,10 @@ __PACKAGE__->belongs_to( }, ); -=head2 organisationalid_fk - -Type: belongs_to - -Related object: L - -=cut - __PACKAGE__->belongs_to( "organisation", "Pear::LocalLoop::Schema::Result::Organisation", - { organisationalid => "organisationalid_fk" }, + { "foreign.id" => "self.organisation_id" }, { is_deferrable => 0, join_type => "LEFT", @@ -203,70 +92,58 @@ __PACKAGE__->belongs_to( }, ); -=head2 pending_organisations - -Type: has_many - -Related object: L - -=cut - __PACKAGE__->has_many( "pending_organisations", "Pear::LocalLoop::Schema::Result::PendingOrganisation", - { "foreign.usersubmitted_fk" => "self.userid" }, + { "foreign.submitted_by_id" => "self.id" }, { cascade_copy => 0, cascade_delete => 0 }, ); -=head2 pending_transactions - -Type: has_many - -Related object: L - -=cut - __PACKAGE__->has_many( "pending_transactions", "Pear::LocalLoop::Schema::Result::PendingTransaction", - { "foreign.buyeruserid_fk" => "self.userid" }, + { "foreign.buyer_id" => "self.id" }, { cascade_copy => 0, cascade_delete => 0 }, ); -=head2 session_tokens - -Type: has_many - -Related object: L - -=cut - __PACKAGE__->has_many( "session_tokens", "Pear::LocalLoop::Schema::Result::SessionToken", - { "foreign.useridassignedto_fk" => "self.userid" }, + { "foreign.user_id" => "self.id" }, { cascade_copy => 0, cascade_delete => 0 }, ); -=head2 transactions - -Type: has_many - -Related object: L - -=cut - __PACKAGE__->has_many( "transactions", "Pear::LocalLoop::Schema::Result::Transaction", - { "foreign.buyeruserid_fk" => "self.userid" }, + { "foreign.buyer_id" => "self.id" }, { cascade_copy => 0, cascade_delete => 0 }, ); +sub generate_session { + my $self = shift; -# Created by DBIx::Class::Schema::Loader v0.07046 @ 2017-02-24 17:32:21 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:qjAgtJR1zaUr00HsiR1aPw + my $token = Data::UUID->new->create_str(); + $self->create_related( + 'session_tokens', + { + token => $token, + }, + ); + return $token; +} + +sub name { + my $self = shift; + + if ( defined $self->customer_id ) { + return $self->customer->name; + } elsif ( defined $self->organisation_id ) { + return $self->organisation->name; + } else { + return undef; + } +} -# You can replace this text with custom code or comments, and it will be preserved on regeneration 1; diff --git a/lib/Test/Pear/LocalLoop.pm b/lib/Test/Pear/LocalLoop.pm index f18e24e..606f109 100644 --- a/lib/Test/Pear/LocalLoop.pm +++ b/lib/Test/Pear/LocalLoop.pm @@ -1,8 +1,10 @@ package Test::Pear::LocalLoop; use Mojo::Base -base; +use Test::More; use File::Temp; use Test::Mojo; +use DateTime::Format::Strptime; has config => sub { my $file = File::Temp->new; @@ -29,7 +31,7 @@ has framework => sub { $schema->deploy; $schema->resultset('AgeRange')->populate([ - [ qw/ agerangestring / ], + [ qw/ string / ], [ '20-35' ], [ '35-50' ], [ '50+' ], @@ -38,4 +40,40 @@ has framework => sub { return $t; }; +sub dump_error { + return sub { + my $self = shift; + if ( my $error = $self->tx->res->dom->at('pre[id="error"]') ) { + diag $error->text; + } else { + diag $self->tx->res->to_string; + } + }; +} + +sub register_customer { + my $self = shift; + my $args = shift; + + my $json = { + usertype => 'customer', + %$args, + }; + + $self->framework->post_ok('/api/register' => json => $json) + ->status_is(200)->or($self->dump_error) + ->json_is('/success', Mojo::JSON->true)->or($self->dump_error); +} + +sub login { + my $self = shift; + my $args = shift; + + $self->framework->post_ok('/api/login' => json => $args) + ->status_is(200)->or($self->dump_error) + ->json_is('/success', Mojo::JSON->true)->or($self->dump_error); + + return $self->framework->tx->res->json->{session_key}; +} + 1; diff --git a/pear-local_loop.development.conf b/pear-local_loop.development.conf index 6810316..cfb1416 100644 --- a/pear-local_loop.development.conf +++ b/pear-local_loop.development.conf @@ -1,4 +1,5 @@ { + storage_path => 'images', dsn => "dbi:SQLite:dbname=foodloop.db", user => undef, pass => undef, diff --git a/public/static/user/css/main.css b/public/static/user/css/main.css new file mode 100644 index 0000000..91558d6 --- /dev/null +++ b/public/static/user/css/main.css @@ -0,0 +1,4 @@ +body { + background: whitesmoke; + padding-top: 70px; +} diff --git a/public/static/user/js/home.js b/public/static/user/js/home.js new file mode 100644 index 0000000..5f618da --- /dev/null +++ b/public/static/user/js/home.js @@ -0,0 +1,39 @@ +$(function() { + $('form#receipt-form').submit(function( event ) { + event.preventDefault(); + event.stopPropagation(); + + // Create new form data object with the contents of this form + var formData = new FormData(); + formData.append('file', $('#tran-file')[0].files[0]); + formData.append('json', JSON.stringify({ + transaction_type: $('#tran-type').val(), + organisation_name: $('#org-name').val(), + street_name: $('#org-street').val(), + town: $('#org-town').val(), + postcode: $('#org-postcode').val(), + transaction_value: $('#tran-value').val() + })); + + $.ajax({ + url: $(this).attr("action"), + type: 'POST', + data: formData, + success: function(data) { + console.log(data); + alert(data.message); + $('form#receipt-form')[0].reset(); + }, + error: function(data) { + console.log(data); + alert(data.responseJSON.message); + }, + cache: false, + contentType: false, + processData: false + }); + + // Stop propogation of event + return false; + }); +}); diff --git a/script/deploy_db b/script/deploy_db old mode 100644 new mode 100755 index 350d0e2..bce12d8 --- a/script/deploy_db +++ b/script/deploy_db @@ -3,6 +3,9 @@ use strict; use warnings; +use FindBin qw/ $Bin /; +use lib "$Bin/../lib"; + use Pear::LocalLoop::Schema; my @con = @ARGV; @@ -10,3 +13,25 @@ my @con = @ARGV; my $schema = Pear::LocalLoop::Schema->connect(@con); $schema->deploy; + +$schema->resultset('AgeRange')->populate([ + [ qw/ string / ], + [ '20-35' ], + [ '35-50' ], + [ '50+' ], +]); + +if ( $ENV{MOJO_MODE} eq 'development' ) { + + $schema->resultset('User')->create({ + email => 'test@example.com', + password => 'abc123', + customer => { + name => 'Test User', + age_range_id => 1, + postcode => 'LA1 1AA', + }, + administrator => {}, + }); + +} diff --git a/script/pear-local_loop b/script/pear-local_loop old mode 100644 new mode 100755 index 4b05581..c48df8e --- a/script/pear-local_loop +++ b/script/pear-local_loop @@ -4,7 +4,7 @@ use strict; use warnings; use FindBin qw/ $Bin /; -use lib '$Bin/../lib'; +use lib "$Bin/../lib"; use Mojolicious::Commands; Mojolicious::Commands->start_app("Pear::LocalLoop"); diff --git a/t/admin-approve.t b/t/admin-approve.t index db3edd2..0f108f0 100644 --- a/t/admin-approve.t +++ b/t/admin-approve.t @@ -1,36 +1,20 @@ use Mojo::Base -strict; + use Test::More; -use Test::Mojo; use Mojo::JSON; +use Test::Pear::LocalLoop; -use FindBin; +my $framework = Test::Pear::LocalLoop->new; +my $t = $framework->framework; +my $schema = $t->app->schema; +my $dump_error = sub { diag $t->tx->res->dom->at('pre[id="error"]')->text }; -BEGIN { - $ENV{MOJO_MODE} = 'testing'; - $ENV{MOJO_LOG_LEVEL} = 'debug'; -} - -my $t = Test::Mojo->new("Pear::LocalLoop"); - -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; -} - -$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($_); -} +my @account_tokens = ('a', 'b', 'c'); +$schema->resultset('AccountToken')->populate([ + [ 'name' ], + map { [ $_ ] } @account_tokens, +]); #This depends on "register.t", "login.t" and "upload.t" working. @@ -40,15 +24,15 @@ my $emailReno = 'reno@shinra.energy'; my $passwordReno = 'turks'; my $testJson = { 'usertype' => 'customer', - 'token' => shift(@accountTokens), - 'username' => 'Reno', + 'token' => shift(@account_tokens), + 'name' => 'Reno', 'email' => $emailReno, - 'postcode' => 'E1 MP01', + 'postcode' => 'SA4 3FA', 'password' => $passwordReno, - 'age' => '20-35' + 'age_range' => 1 }; $t->post_ok('/api/register' => json => $testJson) - ->status_is(200) + ->status_is(200)->or($dump_error) ->json_is('/success', Mojo::JSON->true); print "test 2 - Create organisation user account (Choco Billy)\n"; @@ -56,40 +40,39 @@ my $emailBilly = 'choco.billy@chocofarm.org'; my $passwordBilly = 'Choco'; $testJson = { 'usertype' => 'organisation', - 'token' => shift(@accountTokens), - 'username' => 'ChocoBillysGreens', + 'token' => shift(@account_tokens), + 'name' => 'ChocoBillysGreens', 'email' => $emailBilly, - 'postcode' => 'E4 C12', + 'postcode' => 'ST20 0LG', 'password' => $passwordBilly, - 'fulladdress' => 'Chocobo Farm, Eastern Continent, Gaia' + 'street_name' => 'Chocobo Farm, Eastern Continent', + 'town' => 'Gaia', }; $t->post_ok('/api/register' => json => $testJson) ->status_is(200) ->json_is('/success', Mojo::JSON->true); - print "test 3 - Create admin account\n"; my $emailAdmin = 'admin@foodloop.net'; my $passwordAdmin = 'ethics'; $testJson = { 'usertype' => 'customer', - 'token' => shift(@accountTokens), - 'username' => 'admin', + 'token' => shift(@account_tokens), + 'name' => 'admin', 'email' => $emailAdmin, - 'postcode' => 'NW1 W01', + 'postcode' => 'HD5 9XU', 'password' => $passwordAdmin, - 'age' => '35-50' + 'age_range' => 2 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(200) ->json_is('/success', Mojo::JSON->true); print "test 4 - Making 'admin' an Admin\n"; -my $rufusUserId = $t->app->db->selectrow_array("SELECT UserId FROM Users WHERE Email = ?", undef, ($emailAdmin)); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Administrators")}[0],0,"No admins"; -$t->app->db->prepare("INSERT INTO Administrators (UserId) VALUES (?)")->execute($rufusUserId); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Administrators")}[0],1,"1 admin"; - +my $rufus_user = $schema->resultset('User')->find({ email => $emailAdmin }); +is $schema->resultset('Administrator')->count, 0, "No admins"; +$rufus_user->find_or_create_related('administrator', {}); +is $schema->resultset('Administrator')->count, 1, "1 admin"; ###################################################### @@ -101,17 +84,16 @@ $testJson = { 'password' => $passwordReno, }; $t->post_ok('/api/login' => json => $testJson) - ->status_is(200) + ->status_is(200)->or($dump_error) ->json_is('/success', Mojo::JSON->true); my $session_key = $t->tx->res->json('/session_key'); print "test 6 - add valid transaction (type 3: new organisation)\n"; -my ($test1) = $t->app->db->selectrow_array("SELECT COUNT(*) FROM PendingOrganisations", undef, ()); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],0,"No unverified organisations."; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],0,"No unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisation (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified transactions." ; +is $schema->resultset('PendingOrganisation')->count, 0, "No unverified organisations"; +is $schema->resultset('PendingTransaction')->count, 0, "No unverified transactions" ; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation (choco billy)" ; +is $schema->resultset('Transaction')->count, 0, "No verified transactions" ; my $nameToTestTurtle = 'Turtle\'s Paradise'; my $json = { transaction_value => 20, @@ -124,30 +106,30 @@ my $json = { }; my $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; $t->post_ok('/api/upload' => form => $upload ) - ->status_is(200) + ->status_is(200)->or($dump_error) ->json_is('/success', Mojo::JSON->true); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],1,"1 unverified organisation." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],1,"1 unverified transaction." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisations (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified transactions." ; +is $schema->resultset('PendingOrganisation')->count, 1, "1 unverified organisation"; +is $schema->resultset('PendingTransaction')->count, 1, "1 unverified transaction" ; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation (choco billy)" ; +is $schema->resultset('Transaction')->count, 0, "No verified transactions" ; -my $newPendingTurtleOrgId = $t->app->schema->resultset('PendingOrganisation')->find({ name => $nameToTestTurtle })->pendingorganisationid; +my $newPendingTurtleOrgId = $t->app->schema->resultset('PendingOrganisation')->find({ name => $nameToTestTurtle })->id; #print "Turtle Id: " . $newPendingTurtleOrgId . "\n"; print "test 7 - Non-admin (customer) tries to approve their organisation and fails.\n"; $json = { - unvalidatedOrganisationId => $newPendingTurtleOrgId, + pending_organisation_id => $newPendingTurtleOrgId, session_key => $session_key, }; $t->post_ok('/api/admin-approve' => json => $json) ->status_is(403) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/You are not an admin/i); + ->json_like('/message', qr/Not Authorised/i); print "test 8 - Logout Reno\n"; $t->post_ok('/api/logout', json => { session_key => $session_key } ) - ->status_is(200) + ->status_is(200)->or($dump_error) ->json_is('/success', Mojo::JSON->true); #End of non-admin Reno @@ -167,10 +149,11 @@ $t->post_ok('/api/login' => json => $testJson) $session_key = $t->tx->res->json('/session_key'); print "test 10 - add valid transaction (type 3: new organisation)\n"; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],1,"1 unverified organisations." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],1,"1 unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisations (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified transactions." ; +is $schema->resultset('PendingOrganisation')->count, 1, "1 unverified organisation"; +is $schema->resultset('PendingTransaction')->count, 1, "1 unverified transaction" ; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation (choco billy)" ; +is $schema->resultset('Transaction')->count, 0, "No verified transactions" ; + my $nameToTestKalm = 'Kalm Inn'; $json = { transaction_value => 10, @@ -185,14 +168,13 @@ $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jp $t->post_ok('/api/upload' => form => $upload ) ->status_is(200) ->json_is('/success', Mojo::JSON->true); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],2,"2 unverified organisations." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],2,"2 unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisations (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified transactions." ; -my $newPendingKalmOrgId = $t->app->schema->resultset('PendingOrganisation')->find({ name => $nameToTestKalm })->pendingorganisationid; -#print "Kalm Id: " . $newPendingKalmOrgId . "\n"; +is $schema->resultset('PendingOrganisation')->count, 2, "2 unverified organisation"; +is $schema->resultset('PendingTransaction')->count, 2, "2 unverified transaction" ; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation (choco billy)" ; +is $schema->resultset('Transaction')->count, 0, "No verified transactions" ; +my $newPendingKalmOrgId = $t->app->schema->resultset('PendingOrganisation')->find({ name => $nameToTestKalm })->id; print "test 11 - add valid transaction (type 2: unvalidated organisation)\n"; $json = { @@ -203,12 +185,13 @@ $json = { }; $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; $t->post_ok('/api/upload' => form => $upload ) - ->status_is(200) + ->status_is(200)->or($dump_error) ->json_is('/success', Mojo::JSON->true); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],2,"2 unverified organisations." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],3,"3 unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisations (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified transactions." ; + +is $schema->resultset('PendingOrganisation')->count, 2, "2 unverified organisation"; +is $schema->resultset('PendingTransaction')->count, 3, "3 unverified transaction" ; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation (choco billy)" ; +is $schema->resultset('Transaction')->count, 0, "No verified transactions" ; print "test 12 - add valid transaction (type 3: new organisation)\n"; my $nameToTestJunon = 'Store'; @@ -226,14 +209,12 @@ $t->post_ok('/api/upload' => form => $upload) ->status_is(200) ->json_is('/success', Mojo::JSON->true); -my $newPendingJunonOrgId = $t->app->schema->resultset('PendingOrganisation')->find({ name => $nameToTestJunon })->pendingorganisationid; +my $newPendingJunonOrgId = $t->app->schema->resultset('PendingOrganisation')->find({ name => $nameToTestJunon })->id; #print "Junon Id: " . $newPendingJunonOrgId . "\n"; - -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],3,"3 unverified organisations." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],4,"4 unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisations (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified transactions." ; - +is $schema->resultset('PendingOrganisation')->count, 3, "3 unverified organisation"; +is $schema->resultset('PendingTransaction')->count, 4, "4 unverified transaction" ; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation (choco billy)" ; +is $schema->resultset('Transaction')->count, 0, "No verified transactions" ; print "test 13 - add valid transaction (type 2: unvalidated organisation)\n"; $json = { @@ -245,13 +226,11 @@ $json = { $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; $t->post_ok('/api/upload' => form => $upload ) ->status_is(200) - ->json_is('/success', Mojo::JSON->true) - ->json_hasnt('/unvalidatedOrganisationId'); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],3,"3 unverified organisations." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],5,"5 unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisations (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified transactions." ; - + ->json_is('/success', Mojo::JSON->true); +is $schema->resultset('PendingOrganisation')->count, 3, "3 unverified organisation"; +is $schema->resultset('PendingTransaction')->count, 5, "5 unverified transaction" ; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation (choco billy)" ; +is $schema->resultset('Transaction')->count, 0, "No verified transactions" ; print "test 14 - add valid transaction (type 2: unvalidated organisation)\n"; $json = { @@ -263,22 +242,21 @@ $json = { $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; $t->post_ok('/api/upload' => form => $upload ) ->status_is(200) - ->json_is('/success', Mojo::JSON->true) - ->json_hasnt('/unvalidatedOrganisationId'); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],3,"3 unverified organisations." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],6,"6 unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisations (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified transactions." ; + ->json_is('/success', Mojo::JSON->true); +is $schema->resultset('PendingOrganisation')->count, 3, "3 unverified organisation"; +is $schema->resultset('PendingTransaction')->count, 6, "6 unverified transaction" ; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation (choco billy)" ; +is $schema->resultset('Transaction')->count, 0, "No verified transactions" ; print "test 15 - Non-admin (organisation) tries to approve their organisation and fails.\n"; $json = { - unvalidatedOrganisationId => $newPendingKalmOrgId, + pending_organisation_id => $newPendingKalmOrgId, session_key => $session_key, }; $t->post_ok('/api/admin-approve' => json => $json) ->status_is(403) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/You are not an admin/i); + ->json_like('/message', qr/Not Authorised/i); print "test 16 - Logout Choco Billy\n"; $t->post_ok('/api/logout', json => { session_key => $session_key } ) @@ -307,99 +285,107 @@ $t->post_ok('/api/admin-approve' => json => {}) ->json_is('/success', Mojo::JSON->false) ->json_like('/message', qr/JSON is missing/i); -print "test 19 - unvalidatedOrganisationId missing (non-modify).\n"; +print "test 19 - pending_organisation_id missing (non-modify).\n"; $json = { session_key => $session_key, }; $t->post_ok('/api/admin-approve' => json => $json) ->status_is(400) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/unvalidatedOrganisationId is missing/i); + ->content_like(qr/pending_organisation_id is missing/i); -print "test 20 - unvalidatedOrganisationId not number (non-modify).\n"; +print "test 20 - pending_organisation_id not number (non-modify).\n"; $json = { - unvalidatedOrganisationId => 'Abc', + pending_organisation_id => 'Abc', session_key => $session_key, }; $t->post_ok('/api/admin-approve' => json => $json) ->status_is(400) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/unvalidatedOrganisationId does not look like a number/i); + ->json_like('/message', qr/pending_organisation_id is not a number/i); +print "test 21 - pending_organisation_id does not exist (non-modify).\n"; -print "test 21 - unvalidatedOrganisationId does not exist (non-modify).\n"; -my ($maxPendingId) = $t->app->db->selectrow_array("SELECT MAX(PendingOrganisationId) FROM PendingOrganisations", undef,()); +my $maxPendingId = $schema->resultset('PendingOrganisation')->get_column('id')->max; $json = { - unvalidatedOrganisationId => ($maxPendingId + 1), + pending_organisation_id => $maxPendingId + 1, session_key => $session_key, }; $t->post_ok('/api/admin-approve' => json => $json) ->status_is(400) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/the specified unvalidatedOrganisationId does not exist/i); + ->json_like('/message', qr/pending_organisation_id does not exist in the database/i); #TODO add text to see the specific one has moved. print "test 22 - valid approval (non-modify).\n"; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],3,"3 unverified organisations."; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],6,"6 unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisations (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified organisations."; +is $schema->resultset('PendingOrganisation')->count, 3, "3 unverified organisation"; +is $schema->resultset('PendingTransaction')->count, 6, "6 unverified transaction"; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation"; +is $schema->resultset('Transaction')->count, 0, "No verified transactions"; $json = { - unvalidatedOrganisationId => $newPendingKalmOrgId, + pending_organisation_id => $newPendingKalmOrgId, session_key => $session_key, }; $t->post_ok('/api/admin-approve' => json => $json) - ->status_is(200) + ->status_is(200)->or($dump_error) ->json_is('/success', Mojo::JSON->true); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],2,"2 unverified organisation." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],4,"4 unverified transaction." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],2,"2 verified organisations (choco billy and kalm inn)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],2,"2 verified transaction." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations WHERE Name = ?", undef, ($nameToTestKalm))}[0],0,"Kalm does not exist in pending orgs."; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations WHERE Name = ?", undef, ($nameToTestKalm))}[0],1,"Kalm exists in verified orgs."; + +is $schema->resultset('PendingOrganisation')->count, 2, "2 unverified organisation"; +is $schema->resultset('PendingTransaction')->count, 4, "4 unverified transaction"; +is $schema->resultset('Organisation')->count, 2, "2 verified organisations"; +is $schema->resultset('Transaction')->count, 2, "2 verified transactions"; +is $schema->resultset('PendingOrganisation')->find({ name => $nameToTestKalm }), undef, "Kalm does not exist in pending orgs."; +ok $schema->resultset('Organisation')->find({ name => $nameToTestKalm }), "Kalm exists in verified orgs."; print "test 23 - valid approval (modify all).\n"; #TODO if we implement constraints on the input data this will fail -my $testName = "Change testing turtle name"; -my $testFullAddress = "Change testing turtle address"; -my $testPostCode = "Change testing turtle postcode"; +my $test_name = "Change testing turtle name"; +my $test_street_name = "Change testing turtle address"; +my $test_town = "TestinTown"; +my $test_postcode = "BN21 2RB"; $json = { - unvalidatedOrganisationId => $newPendingTurtleOrgId, - name => $testName, - fullAddress => $testFullAddress, - postCode => $testPostCode, + pending_organisation_id => $newPendingTurtleOrgId, + name => $test_name, + street_name => $test_street_name, + town => $test_town, + postcode => $test_postcode, session_key => $session_key, }; $t->post_ok('/api/admin-approve' => json => $json) ->status_is(200) ->json_is('/success', Mojo::JSON->true); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],1,"1 unverified organisation." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],3,"3 unverified transaction." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],3,"3 verified organisations (choco billy, kalm inn and turtle)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],3,"3 verified transaction." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations WHERE Name = ?", undef, ($nameToTestTurtle))}[0],0,"Turtle does not exist in pending orgs."; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations WHERE Name = ?", undef, ($nameToTestTurtle))}[0],0,"Turtle does not exist in verified orgs, its been renamed."; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations WHERE Name = ? AND FullAddress = ? AND PostCode = ?", undef, ($testName, $testFullAddress, $testPostCode))}[0],1,"Turtle exists and has been renamed in verified orgs."; +is $schema->resultset('PendingOrganisation')->count, 1, "1 unverified organisation"; +is $schema->resultset('PendingTransaction')->count, 3, "3 unverified transaction" ; +is $schema->resultset('Organisation')->count, 3, "3 verified organisation (choco billy)" ; +is $schema->resultset('Transaction')->count, 3, "3 verified transactions" ; +is $schema->resultset('PendingOrganisation')->find({ name => $nameToTestTurtle }), undef, "Turtle does not exist in pending orgs."; +is $schema->resultset('Organisation')->find({ name => $nameToTestTurtle }), undef, "original Turtle does not exists in verified orgs."; +my $turtle_result = $schema->resultset('Organisation')->find({ name => $test_name }); +ok $turtle_result, "new Turtle exists in verified orgs."; +is $turtle_result->street_name, $test_street_name, 'street_name correct'; +is $turtle_result->town, $test_town, 'town correct'; +is $turtle_result->postcode, $test_postcode, 'postcode correct'; print "test 24 - valid approval (modify some).\n"; #TODO if we implement constraints on the input data this will fail -$testName = "Change testing junon name"; +$test_name = "Change testing junon name"; $json = { - unvalidatedOrganisationId => $newPendingJunonOrgId, - name => $testName, + pending_organisation_id => $newPendingJunonOrgId, + name => $test_name, session_key => $session_key, }; $t->post_ok('/api/admin-approve' => json => $json) ->status_is(200) ->json_is('/success', Mojo::JSON->true); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],0,"0 unverified organisation." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],0,"0 unverified transaction." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],4,"4 verified organisations (choco billy, kalm inn, turtle and junon)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],6,"6 verified transaction." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations WHERE Name = ?", undef, ($nameToTestJunon))}[0],0,"Junon does not exist in pending orgs."; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations WHERE Name = ?", undef, ($nameToTestJunon))}[0],0,"Junon does not exist in verified orgs, its been renamed."; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations WHERE Name = ?", undef, ($testName))}[0],1,"Junon exists and has been renamed in verified orgs."; +is $schema->resultset('PendingOrganisation')->count, 0, "0 unverified organisation"; +is $schema->resultset('PendingTransaction')->count, 0, "0 unverified transaction"; +is $schema->resultset('Organisation')->count, 4, "4 verified organisations"; +is $schema->resultset('Transaction')->count, 6, "6 verified transactions"; +is $schema->resultset('PendingOrganisation')->find({ name => $nameToTestJunon }), undef, "Junon does not exist in pending orgs."; +is $schema->resultset('Organisation')->find({ name => $nameToTestJunon }), undef, "original Junon does not exists in verified orgs."; +my $junon_result = $schema->resultset('Organisation')->find({ name => $test_name }); +ok $junon_result, "new Junon exists in verified orgs."; ############################################## diff --git a/t/admin-merge.t b/t/admin-merge.t index bc3308f..83f86f4 100644 --- a/t/admin-merge.t +++ b/t/admin-merge.t @@ -1,36 +1,20 @@ use Mojo::Base -strict; + use Test::More; -use Test::Mojo; use Mojo::JSON; +use Test::Pear::LocalLoop; -use FindBin; +my $framework = Test::Pear::LocalLoop->new; +my $t = $framework->framework; +my $schema = $t->app->schema; +my $dump_error = sub { diag $t->tx->res->dom->at('pre[id="error"]')->text }; -BEGIN { - $ENV{MOJO_MODE} = 'testing'; - $ENV{MOJO_LOG_LEVEL} = 'debug'; -} - -my $t = Test::Mojo->new("Pear::LocalLoop"); - -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; -} - -$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($_); -} +my @account_tokens = ('a', 'b', 'c'); +$schema->resultset('AccountToken')->populate([ + [ 'name' ], + map { [ $_ ] } @account_tokens, +]); #This depends on "register.t", "login.t", "upload.t" and "admin-approve.t" working. @@ -40,12 +24,12 @@ my $emailReno = 'reno@shinra.energy'; my $passwordReno = 'turks'; my $testJson = { 'usertype' => 'customer', - 'token' => shift(@accountTokens), - 'username' => 'Reno', + 'token' => shift(@account_tokens), + 'name' => 'Reno', 'email' => $emailReno, - 'postcode' => 'E1 MP01', + 'postcode' => 'SA4 3FA', 'password' => $passwordReno, - 'age' => '20-35' + 'age_range' => 1 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(200) @@ -56,12 +40,13 @@ my $emailBilly = 'choco.billy@chocofarm.org'; my $passwordBilly = 'Choco'; $testJson = { 'usertype' => 'organisation', - 'token' => shift(@accountTokens), - 'username' => 'ChocoBillysGreens', + 'token' => shift(@account_tokens), + 'name' => 'ChocoBillysGreens', 'email' => $emailBilly, - 'postcode' => 'E4 C12', + 'postcode' => 'ST20 0LG', 'password' => $passwordBilly, - 'fulladdress' => 'Chocobo Farm, Eastern Continent, Gaia' + 'street_name' => 'Chocobo Farm, Eastern Continent', + town => 'Gaia', }; $t->post_ok('/api/register' => json => $testJson) ->status_is(200) @@ -73,23 +58,22 @@ my $emailAdmin = 'admin@foodloop.net'; my $passwordAdmin = 'ethics'; $testJson = { 'usertype' => 'customer', - 'token' => shift(@accountTokens), - 'username' => 'admin', + 'token' => shift(@account_tokens), + 'name' => 'admin', 'email' => $emailAdmin, - 'postcode' => 'NW1 W01', + 'postcode' => 'HD5 9XU', 'password' => $passwordAdmin, - 'age' => '35-50' + 'age_range' => 2 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(200) ->json_is('/success', Mojo::JSON->true); print "test 4 - Making 'admin' an Admin\n"; -my $adminUserId = $t->app->db->selectrow_array("SELECT UserId FROM Users WHERE Email = ?", undef, ($emailAdmin)); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Administrators")}[0],0,"No admins"; -$t->app->db->prepare("INSERT INTO Administrators (UserId) VALUES (?)")->execute($adminUserId); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Administrators")}[0],1,"1 admin"; - +my $rufus_user = $schema->resultset('User')->find({ email => $emailAdmin }); +is $schema->resultset('Administrator')->count, 0, "No admins"; +$rufus_user->find_or_create_related('administrator', {}); +is $schema->resultset('Administrator')->count, 1, "1 admin"; ###################################################### @@ -106,10 +90,11 @@ $t->post_ok('/api/login' => json => $testJson) my $session_key = $t->tx->res->json('/session_key'); print "test 6 - add valid transaction (type 3: new organisation)\n"; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],0,"No unverified organisations."; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],0,"No unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisation (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified transactions." ; +is $schema->resultset('PendingOrganisation')->count, 0, "No unverified organisations"; +is $schema->resultset('PendingTransaction')->count, 0, "No unverified transactions"; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation"; +is $schema->resultset('Transaction')->count, 0, "No verified transactions"; + my $nameToTestTurtle = 'Turtle\'s Paradise'; my $json = { transaction_value => 20, @@ -124,12 +109,12 @@ my $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test $t->post_ok('/api/upload' => form => $upload ) ->status_is(200) ->json_is('/success', Mojo::JSON->true); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],1,"1 unverified organisation." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],1,"1 unverified transaction." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisations (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified transactions." ; +is $schema->resultset('PendingOrganisation')->count, 1, "1 unverified organisations"; +is $schema->resultset('PendingTransaction')->count, 1, "1 unverified transactions"; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation"; +is $schema->resultset('Transaction')->count, 0, "No verified transactions"; -my $newPendingTurtleOrgId = $t->app->schema->resultset('PendingOrganisation')->find({ name => $nameToTestTurtle })->pendingorganisationid; +my $newPendingTurtleOrgId = $t->app->schema->resultset('PendingOrganisation')->find({ name => $nameToTestTurtle })->id; print "Turtle Id: " . $newPendingTurtleOrgId . "\n"; @@ -155,10 +140,10 @@ $t->post_ok('/api/login' => json => $testJson) $session_key = $t->tx->res->json('/session_key'); print "test 9 - add valid transaction (type 3: new organisation)\n"; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],1,"1 unverified organisations." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],1,"1 unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisations (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified transactions." ; +is $schema->resultset('PendingOrganisation')->count, 1, "1 unverified organisations"; +is $schema->resultset('PendingTransaction')->count, 1, "1 unverified transactions"; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation"; +is $schema->resultset('Transaction')->count, 0, "No verified transactions"; my $nameToTestTurtlePartial = 'Turtle\'s Paradise2'; $json = { @@ -166,20 +151,20 @@ $json = { transaction_type => 3, organisation_name => $nameToTestTurtlePartial, street_name => "", - town => "", + town => "Turtlesville", postcode => "", session_key => $session_key, }; $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; $t->post_ok('/api/upload' => form => $upload ) - ->status_is(200) + ->status_is(200)->or($dump_error) ->json_is('/success', Mojo::JSON->true); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],2,"2 unverified organisations." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],2,"2 unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisations (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified transactions." ; +is $schema->resultset('PendingOrganisation')->count, 2, "2 unverified organisations"; +is $schema->resultset('PendingTransaction')->count, 2, "2 unverified transactions"; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation"; +is $schema->resultset('Transaction')->count, 0, "No verified transactions"; -my $newPendingTurtleOrgIdPartial = $t->app->schema->resultset('PendingOrganisation')->find({ name => $nameToTestTurtlePartial })->pendingorganisationid; +my $newPendingTurtleOrgIdPartial = $t->app->schema->resultset('PendingOrganisation')->find({ name => $nameToTestTurtlePartial })->id; print "Turtle Id 2: " . $newPendingTurtleOrgIdPartial . "\n"; #done_testing(); @@ -197,11 +182,10 @@ $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jp $t->post_ok('/api/upload' => form => $upload ) ->status_is(200) ->json_is('/success', Mojo::JSON->true); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],2,"2 unverified organisations." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],3,"3 unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisations (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified transactions." ; - +is $schema->resultset('PendingOrganisation')->count, 2, "2 unverified organisations"; +is $schema->resultset('PendingTransaction')->count, 3, "3 unverified transactions"; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation"; +is $schema->resultset('Transaction')->count, 0, "No verified transactions"; print "test 11 - add valid transaction (type 3: new organisation)\n"; my $nameToTestJunon = 'Store'; @@ -219,14 +203,13 @@ $t->post_ok('/api/upload' => form => $upload) ->status_is(200) ->json_is('/success', Mojo::JSON->true); -my $newPendingJunonOrgId = $t->app->schema->resultset('PendingOrganisation')->find({ name => $nameToTestJunon })->pendingorganisationid; +my $newPendingJunonOrgId = $t->app->schema->resultset('PendingOrganisation')->find({ name => $nameToTestJunon })->id; print "Junon Id: " . $newPendingJunonOrgId . "\n"; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],3,"3 unverified organisations." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],4,"4 unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisations (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified transactions." ; - +is $schema->resultset('PendingOrganisation')->count, 3, "3 unverified organisations"; +is $schema->resultset('PendingTransaction')->count, 4, "4 unverified transactions"; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation"; +is $schema->resultset('Transaction')->count, 0, "No verified transactions"; print "test 12 - add valid transaction (type 2: unvalidated organisation)\n"; $json = { @@ -239,11 +222,10 @@ $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jp $t->post_ok('/api/upload' => form => $upload ) ->status_is(200) ->json_is('/success', Mojo::JSON->true); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],3,"3 unverified organisations." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],5,"5 unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisations (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified transactions." ; - +is $schema->resultset('PendingOrganisation')->count, 3, "3 unverified organisations"; +is $schema->resultset('PendingTransaction')->count, 5, "5 unverified transactions"; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation"; +is $schema->resultset('Transaction')->count, 0, "No verified transactions"; print "test 13 - add valid transaction (type 2: unvalidated organisation)\n"; $json = { @@ -256,11 +238,10 @@ $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jp $t->post_ok('/api/upload' => form => $upload ) ->status_is(200) ->json_is('/success', Mojo::JSON->true); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],3,"3 unverified organisations." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],6,"6 unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisations (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified transactions." ; - +is $schema->resultset('PendingOrganisation')->count, 3, "3 unverified organisations"; +is $schema->resultset('PendingTransaction')->count, 6, "6 unverified transactions"; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation"; +is $schema->resultset('Transaction')->count, 0, "No verified transactions"; print "test 14 - Logout Choco Billy\n"; $t->post_ok('/api/logout', json => { session_key => $session_key } ) @@ -284,23 +265,23 @@ $t->post_ok('/api/login' => json => $testJson) $session_key = $t->tx->res->json('/session_key'); print "test 16 - Admin - Approve the correctly filled out organisation.\n"; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],3,"3 unverified organisations."; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],6,"6 unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],1,"1 verified organisation (choco billy)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],0,"No verified transactions."; +is $schema->resultset('PendingOrganisation')->count, 3, "3 unverified organisations"; +is $schema->resultset('PendingTransaction')->count, 6, "6 unverified transactions"; +is $schema->resultset('Organisation')->count, 1, "1 verified organisation"; +is $schema->resultset('Transaction')->count, 0, "No verified transactions"; $json = { - unvalidatedOrganisationId => $newPendingTurtleOrgId, + pending_organisation_id => $newPendingTurtleOrgId, session_key => $session_key, }; $t->post_ok('/api/admin-approve' => json => $json) ->status_is(200) ->json_is('/success', Mojo::JSON->true); -my $turtleValidatedId = $t->app->schema->resultset('Organisation')->find({ name => $nameToTestTurtle })->organisationalid; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],2,"2 unverified organisations."; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],5,"5 unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],2,"2 verified organisations (choco billy and turtle)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],1,"1 verified transaction."; +my $turtleValidatedId = $t->app->schema->resultset('Organisation')->find({ name => $nameToTestTurtle })->id; +is $schema->resultset('PendingOrganisation')->count, 2, "2 unverified organisations"; +is $schema->resultset('PendingTransaction')->count, 5, "5 unverified transactions"; +is $schema->resultset('Organisation')->count, 2, "2 verified organisation"; +is $schema->resultset('Transaction')->count, 1, "1 verified transactions"; print "test 17 - Logout Admin\n"; $t->post_ok('/api/logout', json => { session_key => $session_key } ) @@ -325,14 +306,14 @@ $session_key = $t->tx->res->json('/session_key'); print "test 19 - Attempt to merge own unvalidated organisation with validated one and fails.\n"; $json = { - unvalidatedOrganisationId => $newPendingTurtleOrgIdPartial, - validatedOrganisationId => $turtleValidatedId, + pending_organisation_id => $newPendingTurtleOrgIdPartial, + target_organisation_id => $turtleValidatedId, session_key => $session_key, }; $t->post_ok('/api/admin-merge' => json => $json) ->status_is(403) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/You are not an admin/i); + ->json_like('/message', qr/Not Authorised/i); print "test 20 - Logout Choco Billy\n"; $t->post_ok('/api/logout', json => { session_key => $session_key }) @@ -362,98 +343,105 @@ $t->post_ok('/api/admin-merge' => json => {}) ->json_like('/message', qr/JSON is missing/); -print "test 23 - unvalidatedOrganisationId missing.\n"; +print "test 23 - pending_organisation_id missing.\n"; $json = { - validatedOrganisationId => $turtleValidatedId, + target_organisation_id => $turtleValidatedId, session_key => $session_key, }; $t->post_ok('/api/admin-merge' => json => $json) ->status_is(400) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/unvalidatedOrganisationId is missing/i); + ->json_like('/message', qr/pending_organisation_id is missing/i); -print "test 24 - unvalidatedOrganisationId not number.\n"; +print "test 24 - pending_organisation_id not number.\n"; $json = { - unvalidatedOrganisationId => "ABC", - validatedOrganisationId => $turtleValidatedId, + pending_organisation_id => "ABC", + target_organisation_id => $turtleValidatedId, session_key => $session_key, }; $t->post_ok('/api/admin-merge' => json => $json) ->status_is(400) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/unvalidatedOrganisationId does not look like a number/i); + ->content_like(qr/pending_organisation_id is not a number/i); -print "test 25 - validatedOrganisationId missing.\n"; +print "test 25 - target_organisation_id missing.\n"; $json = { - unvalidatedOrganisationId => $newPendingTurtleOrgIdPartial, + pending_organisation_id => $newPendingTurtleOrgIdPartial, session_key => $session_key, }; $t->post_ok('/api/admin-merge' => json => $json) ->status_is(400) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/validatedOrganisationId is missing/i); + ->content_like(qr/target_organisation_id is missing/i); -print "test 26 - validatedOrganisationId not number.\n"; +print "test 26 - target_organisation_id not number.\n"; $json = { - unvalidatedOrganisationId => $newPendingTurtleOrgIdPartial, - validatedOrganisationId => "ABC", + pending_organisation_id => $newPendingTurtleOrgIdPartial, + target_organisation_id => "ABC", session_key => $session_key, }; $t->post_ok('/api/admin-merge' => json => $json) ->status_is(400) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/validatedOrganisationId does not look like a number/i); + ->content_like(qr/target_organisation_id is not a number/i); -print "test 27 - unvalidatedOrganisationId does not exist.\n"; -my ($maxPendingId) = $t->app->db->selectrow_array("SELECT MAX(PendingOrganisationId) FROM PendingOrganisations", undef,()); +print "test 27 - pending_organisation_id does not exist.\n"; +my $maxPendingId = $schema->resultset('PendingOrganisation')->get_column('id')->max; $json = { - unvalidatedOrganisationId => ($maxPendingId + 1), - validatedOrganisationId => $turtleValidatedId, + pending_organisation_id => ($maxPendingId + 1), + target_organisation_id => $turtleValidatedId, session_key => $session_key, }; $t->post_ok('/api/admin-merge' => json => $json) ->status_is(400) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/unvalidatedOrganisationId does not exist in the database/i); + ->content_like(qr/pending_organisation_id does not exist in the database/i); -print "test 28 - validatedOrganisationId does not exist.\n"; -my ($maxId) = $t->app->db->selectrow_array("SELECT MAX(OrganisationalId) FROM Organisations", undef,()); +print "test 28 - target_organisation_id does not exist.\n"; +my $maxId = $schema->resultset('Organisation')->get_column('id')->max; $json = { - unvalidatedOrganisationId => $newPendingTurtleOrgIdPartial, - validatedOrganisationId => ($maxId + 1), + pending_organisation_id => $newPendingTurtleOrgIdPartial, + target_organisation_id => ($maxId + 1), session_key => $session_key, }; $t->post_ok('/api/admin-merge' => json => $json) ->status_is(400) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/validatedOrganisationId does not exist in the database/i); + ->content_like(qr/target_organisation_id does not exist in the database/i); - -my ($name, $fullAddress, $postCode) = $t->app->db->selectrow_array("SELECT Name, FullAddress, PostCode FROM Organisations WHERE OrganisationalId = ?", undef, ($turtleValidatedId)); +my $turtle_result = $schema->resultset('Organisation')->find($turtleValidatedId); +my $old_name = $turtle_result->name; +my $old_street_name = $turtle_result->street_name; +my $old_postcode = $turtle_result->postcode; +my $old_town = $turtle_result->town; print "test 29 - valid merge.\n"; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],2,"2 unverified organisations."; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],5,"5 unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],2,"2 verified organisations (choco billy and turtle)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],1,"1 verified transaction."; +is $schema->resultset('PendingOrganisation')->count, 2, "2 unverified organisations"; +is $schema->resultset('PendingTransaction')->count, 5, "5 unverified transactions"; +is $schema->resultset('Organisation')->count, 2, "2 verified organisation"; +is $schema->resultset('Transaction')->count, 1, "1 verified transactions"; +is $turtle_result->transactions->count, 1, '1 transactions for turtle'; $json = { - unvalidatedOrganisationId => $newPendingTurtleOrgIdPartial, - validatedOrganisationId => $turtleValidatedId, + pending_organisation_id => $newPendingTurtleOrgIdPartial, + target_organisation_id => $turtleValidatedId, session_key => $session_key, }; $t->post_ok('/api/admin-merge' => json => $json) ->status_is(200) ->json_is('/success', Mojo::JSON->true); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingOrganisations", undef, ())}[0],1,"1 unverified organisation." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions", undef, ())}[0],3,"3 unverified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations", undef, ())}[0],2,"2 verified organisations (choco billy and turtle)" ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions", undef, ())}[0],3,"3 verified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions WHERE SellerOrganisationId_FK = ?", undef, ($turtleValidatedId))}[0],3,"3 verified transactions." ; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Organisations WHERE OrganisationalId = ? AND Name = ? AND FullAddress = ? AND PostCode = ?", undef, ($turtleValidatedId, $name, $fullAddress, $postCode))}[0],1,"Turtle exists with all orginal values."; +is $schema->resultset('PendingOrganisation')->count, 1, "1 unverified organisations"; +is $schema->resultset('PendingTransaction')->count, 3, "3 unverified transactions"; +is $schema->resultset('Organisation')->count, 2, "2 verified organisation"; +is $schema->resultset('Transaction')->count, 3, "3 verified transactions"; +is $turtle_result->transactions->count, 3, '3 transactions for turtle'; +is $turtle_result->name, $old_name, 'name unchanged'; +is $turtle_result->town, $old_town, 'town unchanged'; +is $turtle_result->postcode, $old_postcode, 'postcode unchanged'; +is $turtle_result->street_name, $old_street_name, 'street_name unchanged'; done_testing(); diff --git a/t/admin/login.t b/t/admin/login.t index 6110771..1f0eeff 100644 --- a/t/admin/login.t +++ b/t/admin/login.t @@ -27,15 +27,13 @@ $schema->deploy; $schema->resultset('User')->create({ email => 'admin@example.com', - hashedpassword => 'abc123', + password => 'abc123', administrator => {}, - joindate => DateTime->now, }); $schema->resultset('User')->create({ email => 'user@example.com', - hashedpassword => 'abc123', - joindate => DateTime->now, + password => 'abc123', }); is $schema->resultset('User')->count, 2, 'Users Created'; diff --git a/t/api/login.t b/t/api/login.t index f3382c0..74dda80 100644 --- a/t/api/login.t +++ b/t/api/login.t @@ -13,17 +13,17 @@ my $email = 'rufus@shinra.energy'; my $password = 'MakoGold'; $schema->resultset('AccountToken')->create({ - accounttokenname => $account_token + name => $account_token }); my $test_json = { 'usertype' => 'customer', 'token' => $account_token, - 'username' => 'RufusShinra', + 'name' => 'RufusShinra', 'email' => $email, 'postcode' => 'LA1 1AA', 'password' => $password, - 'age' => '20-35' + 'age_range' => 1 }; $t->post_ok('/api/register' => json => $test_json) ->status_is(200) diff --git a/t/api/user.t b/t/api/user.t new file mode 100644 index 0000000..774ab6f --- /dev/null +++ b/t/api/user.t @@ -0,0 +1,56 @@ +use Mojo::Base -strict; + +use Test::More; +use Mojo::JSON; +use Test::Pear::LocalLoop; +use DateTime; + +my $framework = Test::Pear::LocalLoop->new; +my $t = $framework->framework; +my $schema = $t->app->schema; + +my $account_token = 'a'; +my $email = 'test@example.com'; +my $password = 'abc123'; + +$schema->resultset('AccountToken')->create({ + name => $account_token +}); + +$framework->register_customer({ + 'token' => $account_token, + 'name' => 'Test User', + 'email' => $email, + 'postcode' => 'LA1 1AA', + 'password' => $password, + 'age_range' => 1 +}); + +my $session_key = $framework->login({ + email => $email, + password => $password, +}); + +my $json_no_date = { session_key => $session_key }; +$t->post_ok('/api/user/day', json => $json_no_date) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true); + +my $json_invalid_date = { + session_key => $session_key, + day => 'invalid', +}; +$t->post_ok('/api/user/day', json => $json_invalid_date) + ->status_is(400)->or($framework->dump_error) + ->json_is('/success', Mojo::JSON->false) + ->json_like('/message', qr/Invalid ISO8601 Datetime/); + +my $json_valid_date = { + session_key => $session_key, + day => $t->app->datetime_formatter->format_datetime(DateTime->now), +}; +$t->post_ok('/api/user/day', json => $json_valid_date) + ->status_is(200)->or($framework->dump_error) + ->json_is('/success', Mojo::JSON->true); + +done_testing; diff --git a/t/register.t b/t/register.t index 41671e1..a462f7c 100644 --- a/t/register.t +++ b/t/register.t @@ -7,6 +7,7 @@ use Test::Pear::LocalLoop; my $framework = Test::Pear::LocalLoop->new; my $t = $framework->framework; my $schema = $t->app->schema; +my $dump_error = sub { diag $t->tx->res->dom->at('pre[id="error"]')->text }; #Variables to be used for uniqueness when testing. 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'); @@ -14,13 +15,13 @@ my @emails = ('a@a.com', 'b@a.com', 'c@a.com', 'd@a.com', 'e@a.com', 'f@a.com', 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'); $schema->resultset('AccountToken')->populate([ - [ qw/ accounttokenname / ], + [ qw/ name / ], map { [ $_ ] } @tokens, ]); #No JSON sent $t->post_ok('/api/register') - ->status_is(400) + ->status_is(400)->or($dump_error) ->json_is('/success', Mojo::JSON->false) ->json_like('/message', qr/JSON is missing/i); @@ -32,11 +33,11 @@ $t->post_ok('/api/register' => json => $testJson) #token missing JSON $testJson = { 'usertype' => 'customer', - 'username' => shift(@names), + 'name' => shift(@names), 'email' => shift(@emails), 'postcode' => 'LA1 1AA', 'password' => 'Meh', - 'age' => '50+' + 'age_range' => 3 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(400) @@ -48,11 +49,11 @@ $t->post_ok('/api/register' => json => $testJson) $testJson = { 'usertype' => 'customer', 'token' => ' ', - 'username' => shift(@names), + 'name' => shift(@names), 'email' => shift(@emails), 'postcode' => 'LA1 1AA', 'password' => 'Meh', - 'age' => '50+' + 'age_range' => 3 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(401) @@ -60,64 +61,49 @@ $t->post_ok('/api/register' => json => $testJson) ->content_like(qr/token/i) ->content_like(qr/invalid/i); -#username missing JSON +#name missing JSON $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), 'email' => shift(@emails), 'postcode' => 'LA1 1AA', 'password' => 'Meh', - 'age' => '50+' + 'age_range' => 3 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(400) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/no username sent/i); + ->content_like(qr/no name sent/i); -#Blank username +#Blank name $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), - 'username' => '', + 'name' => '', 'email' => shift(@emails), 'postcode' => 'LA1 1AA', 'password' => 'Meh', - 'age' => '50+' + 'age_range' => 3 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(400) ->json_is('/success', Mojo::JSON->false) ->content_like(qr/blank/i) - ->content_like(qr/username/i); + ->content_like(qr/name/i); -#Not alpha numeric chars e.g. ! -$testJson = { - 'usertype' => 'customer', - 'token' => shift(@tokens), - 'username' => 'asa!', - 'email' => shift(@emails), - 'postcode' => 'LA1 1AA', - 'password' => 'Meh', - 'age' => '50+' -}; -$t->post_ok('/api/register' => json => $testJson) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/username/i); - -my $usernameToReuse = shift(@names); +my $nameToReuse = shift(@names); my $emailToReuse = shift(@emails); #Valid customer $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), - 'username' => $usernameToReuse, + 'name' => $nameToReuse, 'email' => $emailToReuse, 'postcode' => 'LA1 1AA', 'password' => 'Meh', - 'age' => '50+' + 'age_range' => 3 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(200) @@ -127,11 +113,11 @@ $t->post_ok('/api/register' => json => $testJson) $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), - 'username' => shift(@names), + 'name' => shift(@names), 'email' => shift(@emails), 'postcode' => 'LA1 1AA', 'password' => 'Meh', - 'age' => '35-50' + 'age_range' => 2 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(200) @@ -141,39 +127,24 @@ $t->post_ok('/api/register' => json => $testJson) $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), - 'username' => shift(@names), + 'name' => shift(@names), 'email' => shift(@emails), 'postcode' => 'LA1 1AA', 'password' => 'Meh', - 'age' => '20-35' + 'age_range' => 1 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(200) ->json_is('/success', Mojo::JSON->true); -#Username exists -$testJson = { - 'usertype' => 'customer', - 'token' => shift(@tokens), - 'username' => $usernameToReuse, - 'email' => shift(@emails), - 'postcode' => 'LA1 1AA', - 'password' => 'Meh', - 'age' => '50+' -}; -$t->post_ok('/api/register' => json => $testJson) - ->status_is(403) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/exists/i); - #email missing JSON $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), - 'username' => shift(@names), + 'name' => shift(@names), 'postcode' => 'LA1 1AA', 'password' => 'Meh', - 'age' => '50+' + 'age_range' => 3 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(400) @@ -184,11 +155,11 @@ $t->post_ok('/api/register' => json => $testJson) $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), - 'username' => shift(@names), + 'name' => shift(@names), 'email' => 'dfsd@.com', 'postcode' => 'LA1 1AA', 'password' => 'Meh', - 'age' => '35-50' + 'age_range' => 2 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(400) @@ -200,11 +171,11 @@ $t->post_ok('/api/register' => json => $testJson) $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), - 'username' => shift(@names), + 'name' => shift(@names), 'email' => 'dfsd@com', 'postcode' => 'LA1 1AA', 'password' => 'Meh', - 'age' => '35-50' + 'age_range' => 2 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(400) @@ -216,11 +187,11 @@ $t->post_ok('/api/register' => json => $testJson) $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), - 'username' => shift(@names), + 'name' => shift(@names), 'email' => $emailToReuse, 'postcode' => 'LA1 1AA', 'password' => 'Meh', - 'age' => '35-50' + 'age_range' => 2 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(403) @@ -232,10 +203,10 @@ $t->post_ok('/api/register' => json => $testJson) $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), - 'username' => shift(@names), + 'name' => shift(@names), 'email' => shift(@emails), 'password' => 'Meh', - 'age' => '50+' + 'age_range' => 3 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(400) @@ -248,10 +219,10 @@ $t->post_ok('/api/register' => json => $testJson) $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), - 'username' => shift(@names), + 'name' => shift(@names), 'email' => shift(@emails), 'postcode' => 'LA1 1AA', - 'age' => '50+' + 'age_range' => 3 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(400) @@ -263,11 +234,11 @@ $t->post_ok('/api/register' => json => $testJson) #usertype missing JSON $testJson = { 'token' => shift(@tokens), - 'username' => shift(@names), + 'name' => shift(@names), 'email' => shift(@emails), 'postcode' => 'LA1 1AA', 'password' => 'Meh', - 'age' => '50+' + 'age_range' => 3 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(400) @@ -278,7 +249,7 @@ $t->post_ok('/api/register' => json => $testJson) $testJson = { 'usertype' => 'organisation1', 'token' => shift(@tokens), - 'username' => shift(@names), + 'name' => shift(@names), 'email' => shift(@emails), 'postcode' => 'LA1 1AA', 'password' => 'Meh', @@ -291,11 +262,11 @@ $t->post_ok('/api/register' => json => $testJson) ->content_like(qr/invalid/i); -#age missing JSON +#age_range missing JSON $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), - 'username' => shift(@names), + 'name' => shift(@names), 'email' => shift(@emails), 'postcode' => 'LA1 1AA', 'password' => 'Meh', @@ -303,29 +274,29 @@ $testJson = { $t->post_ok('/api/register' => json => $testJson) ->status_is(400) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/no age sent/i); + ->content_like(qr/no age_range sent/i); #Age is invalid $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), - 'username' => shift(@names), + 'name' => shift(@names), 'email' => shift(@emails), 'postcode' => 'LA1 1AA', 'password' => 'Meh', - 'age' => 'invalid' + 'age_range' => 'invalid' }; $t->post_ok('/api/register' => json => $testJson) ->status_is(400) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/age/i) + ->content_like(qr/age_range/i) ->content_like(qr/invalid/i); #full address missing JSON $testJson = { 'usertype' => 'organisation', 'token' => shift(@tokens), - 'username' => shift(@names), + 'name' => shift(@names), 'email' => shift(@emails), 'postcode' => 'LA1 1AA', 'password' => 'Meh', @@ -333,7 +304,7 @@ $testJson = { $t->post_ok('/api/register' => json => $testJson) ->status_is(400) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/no fulladdress sent/i); + ->content_like(qr/no street_name sent/i); #TODO Validation of full address @@ -341,11 +312,12 @@ $t->post_ok('/api/register' => json => $testJson) $testJson = { 'usertype' => 'organisation', 'token' => shift(@tokens), - 'username' => shift(@names), + 'name' => shift(@names), 'email' => shift(@emails), 'postcode' => 'LA1 1AA', 'password' => 'Meh', - 'fulladdress' => 'mary lane testing....' + 'street_name' => 'mary lane testing....', + 'town' => 'Lancaster', }; $t->post_ok('/api/register' => json => $testJson) ->status_is(200) diff --git a/t/search.t b/t/search.t index e414785..b0aa1a8 100644 --- a/t/search.t +++ b/t/search.t @@ -1,63 +1,28 @@ use Mojo::Base -strict; + use Test::More; -use Test::Mojo; use Mojo::JSON; -use Text::ParseWords; +use Test::Pear::LocalLoop; +my $framework = Test::Pear::LocalLoop->new; +my $t = $framework->framework; +my $schema = $t->app->schema; +my $dump_error = sub { diag $t->tx->res->to_string }; -use FindBin; +my @account_tokens = ('a', 'b'); +$schema->resultset('AccountToken')->populate([ + [ qw/ name / ], + map { [ $_ ] } @account_tokens, +]); -BEGIN { - $ENV{MOJO_MODE} = 'testing'; - $ENV{MOJO_LOG_LEVEL} = 'debug'; -} - -my $t = Test::Mojo->new("Pear::LocalLoop"); - -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; -} - -$sqlDeployment = Mojo::File->new("$FindBin::Bin/../schema.sql")->slurp; -for (split ';', $sqlDeployment){ - $dbh->do($_) or die $dbh->errstr; -} - -my @accountTokens = ('a', 'b'); -my $tokenStatement = $dbh->prepare('INSERT INTO AccountTokens (AccountTokenName) VALUES (?)'); -foreach (@accountTokens){ - my $rowsAdded = $tokenStatement->execute($_); -} - -#TODO this should be done via the API but as that does not exist at the moment, just add them manually. -my $statement = $dbh->prepare("INSERT INTO Organisations (OrganisationalId, Name, FullAddress, PostCode) VALUES (?, ?, ?, ?)"); - -my $value = 1; -my ($name, $address, $postcode) = ("Avanti Bar & Restaurant","57 Main St, Kirkby Lonsdale, Cumbria","LA6 2AH"); -$statement->execute($value, $name, $address, $postcode); - -$value++; -($name, $address, $postcode) = ("Full House Noodle Bar","21 Common Garden St, Lancaster, Lancashire","LA1 1XD"); -$statement->execute($value, $name, $address, $postcode); - -$value++; -($name, $address, $postcode) = ("The Quay's Fishbar","1 Adcliffe Rd, Lancaster","LA1 1SS"); -$statement->execute($value, $name, $address, $postcode); - -$value++; -($name, $address, $postcode) = ("Dan's Fishop","56 North Rd, Lancaster","LA1 1LT"); -$statement->execute($value, $name, $address, $postcode); - -$value++; -($name, $address, $postcode) = ("Hodgeson's Chippy","96 Prospect St, Lancaster","LA1 3BH"); -$statement->execute($value, $name, $address, $postcode); - - -#This depends on "register.t", "login.t" and "upload.t" working. +$schema->resultset('Organisation')->populate([ + [ qw/ name street_name town postcode / ], + [ "Avanti Bar & Restaurant", "57 Main St", "Kirkby Lonsdale", "LA6 2AH" ], + [ "Full House Noodle Bar", "21 Common Garden St", "Lancaster", "LA1 1XD" ], + [ "The Quay's Fishbar", "1 Adcliffe Rd", "Lancaster", "LA1 1SS" ], + [ "Dan's Fishop", "56 North Rd", "Lancaster", "LA1 1LT" ], + [ "Hodgeson's Chippy", "96 Prospect St", "Lancaster", "LA1 3BH" ], +]); #test with a customer. print "test 1 - Create customer user account (Rufus)\n"; @@ -65,15 +30,15 @@ my $emailRufus = 'rufus@shinra.energy'; my $passwordRufus = 'MakoGold'; my $testJson = { 'usertype' => 'customer', - 'token' => shift(@accountTokens), - 'username' => 'RufusShinra', + 'token' => shift(@account_tokens), + 'name' => 'RufusShinra', 'email' => $emailRufus, - 'postcode' => 'LA1 1CF', + 'postcode' => 'RG26 5NU', 'password' => $passwordRufus, - 'age' => '20-35' + 'age_range' => 1 }; $t->post_ok('/api/register' => json => $testJson) - ->status_is(200) + ->status_is(200)->or($dump_error) ->json_is('/success', Mojo::JSON->true); #test with an organisation. @@ -82,12 +47,13 @@ my $emailBilly = 'choco.billy@chocofarm.org'; my $passwordBilly = 'Choco'; $testJson = { 'usertype' => 'organisation', - 'token' => shift(@accountTokens), - 'username' => 'ChocoBillysGreens', + 'token' => shift(@account_tokens), + 'name' => 'ChocoBillysGreens', 'email' => $emailBilly, 'postcode' => 'LA1 1HT', 'password' => $passwordBilly, - 'fulladdress' => 'Market St, Lancaster' + 'street_name' => 'Market St', + 'town' => 'Lancaster', }; $t->post_ok('/api/register' => json => $testJson) ->status_is(200) @@ -200,20 +166,11 @@ log_out(); print "test 10 - Login - Rufus (cookies, customer)\n"; login_rufus(); -print "test 11 - search blank\n"; -$t->post_ok('/api/search' => json => { - searchName => " ", - session_key => $session_key, - }) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/searchName is blank/i); - sub check_vars{ my ($searchTerm, $numValidated, $numUnvalidated) = @_; $t->post_ok('/api/search' => json => { - searchName => $searchTerm, + search_name => $searchTerm, session_key => $session_key, }) ->status_is(200) @@ -233,6 +190,9 @@ sub check_vars{ }; +print "test 11 - search blank\n"; +check_vars(" ", 5, 1); + print "test 12 - Testing expected values with 'booths'\n"; #Expect 0 validated and 0 unvalidated with "booths". check_vars("booths", 0, 0); diff --git a/t/upload.t b/t/upload.t index 25356a1..8973c8e 100644 --- a/t/upload.t +++ b/t/upload.t @@ -7,45 +7,42 @@ use Test::Pear::LocalLoop; my $framework = Test::Pear::LocalLoop->new; my $t = $framework->framework; my $schema = $t->app->schema; +my $dump_error = sub { diag $t->tx->res->dom->at('pre[id="error"]')->text }; -my @accountTokens = ('a', 'b', 'c'); +my @account_tokens = ('a', 'b', 'c'); $schema->resultset('AccountToken')->populate([ - [ 'accounttokenname' ], - map { [ $_ ] } @accountTokens, + [ 'name' ], + map { [ $_ ] } @account_tokens, ]); #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 $org_id_shinra = 1; my $org_rs = $schema->resultset('Organisation'); is $org_rs->count, 0, "No organisations"; $org_rs->create({ - organisationalid => $companyIdNumShinra, - name => $name, - fulladdress => $fullAddress, - postcode => $postcode, + id => $org_id_shinra, + name => 'Shinra Electric Power Company', + street_name => 'Sector 0, Midgar, Eastern Continent', + town => 'Gaia', + postcode => 'E1 M00', }); is $org_rs->count, 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', + 'token' => shift(@account_tokens), + 'name' => 'RufusShinra', 'email' => $emailRufus, - 'postcode' => 'E1 MP01', + 'postcode' => 'GU10 5SA', 'password' => $passwordRufus, - 'age' => '20-35' + 'age_range' => 1 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(200) @@ -56,12 +53,12 @@ my $emailHojo = 'hojo@shinra.energy'; my $passwordHojo = 'Mako'; $testJson = { 'usertype' => 'customer', - 'token' => shift(@accountTokens), - 'username' => 'ProfessorHojo', + 'token' => shift(@account_tokens), + 'name' => 'ProfessorHojo', 'email' => $emailHojo, - 'postcode' => 'E1 MP01', + 'postcode' => 'DE15 9LT', 'password' => $passwordHojo, - 'age' => '35-50' + 'age_range' => 1 }; $t->post_ok('/api/register' => json => $testJson) ->status_is(200) @@ -72,16 +69,18 @@ my $emailBilly = 'choco.billy@chocofarm.org'; my $passwordBilly = 'Choco'; $testJson = { 'usertype' => 'organisation', - 'token' => shift(@accountTokens), - 'username' => 'ChocoBillysGreens', + 'token' => shift(@account_tokens), + 'name' => 'ChocoBillysGreens', 'email' => $emailBilly, - 'postcode' => 'E4 C12', + 'postcode' => 'SO50 7NJ', 'password' => $passwordBilly, - 'fulladdress' => 'Chocobo Farm, Eastern Continent, Gaia' + 'street_name' => 'Chocobo Farm, Eastern Continent', + 'town' => 'Gaia', }; $t->post_ok('/api/register' => json => $testJson) ->status_is(200) - ->json_is('/success', Mojo::JSON->true); + ->json_is('/success', Mojo::JSON->true) + ->json_like('/message', qr/Registered Successfully/); ###################################################### @@ -109,7 +108,7 @@ $t->post_ok('/api/upload' => form => $upload ) print "test 6 - transaction_value missing\n"; my $json = { transaction_type => 1, - organisation_id => $companyIdNumShinra, + organisation_id => $org_id_shinra, session_key => $session_key, }; $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; @@ -122,7 +121,7 @@ print "test 7 - transaction_value non-numbers\n"; $json = { transaction_value => 'Abc', transaction_type => 1, - organisation_id => $companyIdNumShinra, + organisation_id => $org_id_shinra, session_key => $session_key, }; $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; @@ -135,7 +134,7 @@ print "test 8 - transaction_value equal to zero\n"; $json = { transaction_value => 0, transaction_type => 1, - organisation_id => $companyIdNumShinra, + organisation_id => $org_id_shinra, session_key => $session_key, }; $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; @@ -148,7 +147,7 @@ print "test 9 - transaction_value less than zero\n"; $json = { transaction_value => -1, transaction_type => 1, - organisation_id => $companyIdNumShinra, + organisation_id => $org_id_shinra, session_key => $session_key, }; $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; @@ -173,7 +172,7 @@ $json = { transaction_value => 10, transaction_type => 4, session_key => $session_key, -# organisation_id => $companyIdNumShinra +# organisation_id => $org_id_shinra }; $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; $t->post_ok('/api/upload' => form => $upload ) @@ -199,7 +198,7 @@ $json = { transaction_value => 10, transaction_type => 1, session_key => $session_key, -# organisation_id => $companyIdNumShinra +# organisation_id => $org_id_shinra }; $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; $t->post_ok('/api/upload' => form => $upload ) @@ -211,7 +210,7 @@ print "test 14 - organisation_id for non-existent id. (type 1: already validated $json = { transaction_value => 10, transaction_type => 1, - organisation_id => ($companyIdNumShinra + 100), + organisation_id => ($org_id_shinra + 100), session_key => $session_key, }; $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; @@ -221,11 +220,11 @@ $t->post_ok('/api/upload' => form => $upload ) ->content_like(qr/organisation_id 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"; +is $schema->resultset('Transaction')->count, 0, "no transactions"; $json = { transaction_value => 10, transaction_type => 1, - organisation_id => $companyIdNumShinra, + organisation_id => $org_id_shinra, session_key => $session_key, }; $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; @@ -233,7 +232,7 @@ $t->post_ok('/api/upload' => form => $upload ) ->status_is(200) ->json_is('/success', Mojo::JSON->true) ->json_like('/message', qr/Upload Successful/); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions")}[0],1,"1 transaction"; +is $schema->resultset('Transaction')->count, 1, "1 transaction"; # Add type 3 (new organisation) checking. @@ -253,8 +252,8 @@ $t->post_ok('/api/upload' => form => $upload ) ->content_like(qr/organisation_name 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"; +is $schema->resultset('PendingOrganisation')->count, 0, "No pending organisations"; +is $schema->resultset('PendingTransaction')->count, 0, "No pending transactions"; $json = { transaction_value => 10, @@ -270,8 +269,8 @@ $t->post_ok('/api/upload' => form => $upload ) ->status_is(200) ->json_is('/success', Mojo::JSON->true) ->json_like('/message', qr/Upload Successful/); -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"; +is $schema->resultset('PendingOrganisation')->count, 1, "1 pending organisations"; +is $schema->resultset('PendingTransaction')->count, 1, "1 pending transactions"; # Add type 2 (unverified organisation) checking. @@ -336,8 +335,8 @@ $session_key = $t->tx->res->json('/session_key'); print "test 23 - add valid transaction but for with account (type 2: existing organisation)\n"; my $org_result = $schema->resultset('PendingOrganisation')->find({ name => '7th Heaven' }); -my $unvalidatedOrganisationId = $org_result->pendingorganisationid; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions")}[0],1,"1 pending transaction"; +my $unvalidatedOrganisationId = $org_result->id; +is $schema->resultset('PendingTransaction')->count, 1, "1 pending transactions"; $json = { transaction_value => 10, transaction_type => 2, @@ -349,7 +348,7 @@ $t->post_ok('/api/upload' => form => $upload ) ->status_is(400) ->json_is('/success', Mojo::JSON->false) ->content_like(qr/organisation_id does not exist in the database/i); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions")}[0],1,"1 pending transaction"; +is $schema->resultset('PendingTransaction')->count, 1, "1 pending transactions"; print "test 24 - Logout Hojo\n"; $t->post_ok('/api/logout', json => { session_key => $session_key } ) @@ -373,7 +372,7 @@ $t->post_ok('/api/login' => json => $testJson) $session_key = $t->tx->res->json('/session_key'); 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"; +is $schema->resultset('PendingTransaction')->count, 1, "1 pending transactions"; $json = { transaction_value => 10, transaction_type => 2, @@ -385,7 +384,7 @@ $t->post_ok('/api/upload' => form => $upload ) ->status_is(200) ->json_is('/success', Mojo::JSON->true) ->json_like('/message', qr/Upload Successful/); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM PendingTransactions")}[0],2,"2 pending transaction"; +is $schema->resultset('PendingTransaction')->count, 2, "2 pending transactions"; print "test 27 - Logout Rufus\n"; @@ -410,11 +409,11 @@ $t->post_ok('/api/login' => json => $testJson) $session_key = $t->tx->res->json('/session_key'); print "test 29 - organisation buy from another organisation\n"; -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions")}[0],1,"1 transaction"; +is $schema->resultset('Transaction')->count, 1, "1 transaction"; $json = { transaction_value => 100000, transaction_type => 1, - organisation_id => $companyIdNumShinra, + organisation_id => $org_id_shinra, session_key => $session_key, }; $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; @@ -422,7 +421,7 @@ $t->post_ok('/api/upload' => form => $upload ) ->status_is(200) ->json_is('/success', Mojo::JSON->true) ->json_like('/message', qr/Upload Successful/); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Transactions")}[0],2,"2 transactions"; +is $schema->resultset('Transaction')->count, 2, "2 transaction"; done_testing(); diff --git a/t/user-history.t b/t/user-history.t deleted file mode 100644 index 3ff1ea2..0000000 --- a/t/user-history.t +++ /dev/null @@ -1,806 +0,0 @@ -use Mojo::Base -strict; -use Test::More skip_all => 'User History needs reworking'; -use Test::Mojo; -use Mojo::JSON qw(encode_json);; -use Time::Fake; -use Data::Dumper; -use DateTime; - -use FindBin; - -BEGIN { - $ENV{MOJO_MODE} = 'testing'; - $ENV{MOJO_LOG_LEVEL} = 'debug'; -} - -my $t = Test::Mojo->new("Pear::LocalLoop"); - -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($_); -} - -my $dateTimeNow = DateTime->now(); - -#Plus 2 days so you cannot have a bug where it goes past midnight when you run the test, plus one hour to remove odd error -my $dateTimeInitial = $dateTimeNow->clone()->truncate(to => day)->add(days => 2, hours => 1); -my $dateTimePlusTwoDays = $dateTimeInitial->clone()->add(days => 2); -my $dateTimePlusOneMonth = $dateTimeInitial->clone()->add(months => 1); -my $dateTimePlusOneYear = $dateTimeInitial->clone()->add(years => 1, days => 1); - -my $dateTimePlusThreeDays = $dateTimeInitial->clone()->add(days => 3); -my $dateTimePlusOneMonthMinusOneDay = $dateTimePlusOneMonth->clone()->subtract(days => 1); - -#Clock skew second diffs -my $dateTimeInitialDiff = $dateTimeInitial->delta_ms($dateTimeNow)->delta_minutes() * 60; -my $dateTimePlusTwoDaysSecondsDiff = $dateTimePlusTwoDays->delta_ms($dateTimeNow)->delta_minutes() * 60; -my $dateTimePlusOneMonthSecondsDiff = $dateTimePlusOneMonth->delta_ms($dateTimeNow)->delta_minutes() * 60; -my $dateTimePlusOneYearSecondsDiff = $dateTimePlusOneYear->delta_ms($dateTimeNow)->delta_minutes() * 60; - -#Change to the initial time. -Time::Fake->offset("+" . $dateTimeInitialDiff . "s"); - -#This depends on "register.t", "login.t", "upload.t" and "admin-approve.t" working. - -#Valid customer, this also tests that redirects are disabled for register. -print "test 1 - Create customer user account (Reno)\n"; -my $emailReno = 'reno@shinra.energy'; -my $passwordReno = 'turks'; -my $testJson = { - 'usertype' => 'customer', - 'token' => shift(@accountTokens), - 'username' => 'Reno', - 'email' => $emailReno, - 'postcode' => 'E1 MP01', - 'password' => $passwordReno, - 'age' => '20-35' -}; -$t->post_ok('/api/register' => json => $testJson) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true); - -print "test 2 - 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('/api/register' => json => $testJson) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true); - - -print "test 3 - Create admin account\n"; -my $emailAdmin = 'admin@foodloop.net'; -my $passwordAdmin = 'ethics'; -my $testJson = { - 'usertype' => 'customer', - 'token' => shift(@accountTokens), - 'username' => 'admin', - 'email' => $emailAdmin, - 'postcode' => 'NW1 W01', - 'password' => $passwordAdmin, - 'age' => '35-50' -}; -$t->post_ok('/api/register' => json => $testJson) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true); - -print "test 4 - Making 'admin' an Admin\n"; -my $adminUserId = $t->app->db->selectrow_array("SELECT UserId FROM Users WHERE Email = ?", undef, ($emailAdmin)); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Administrators")}[0],0,"No admins"; -$t->app->db->prepare("INSERT INTO Administrators (UserId) VALUES (?)")->execute($adminUserId); -is @{$t->app->db->selectrow_arrayref("SELECT COUNT(*) FROM Administrators")}[0],1,"1 admin"; - -sub logout { - $t->post_ok('/api/logout', json => { session_key => $session_key }) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true); -} - -my $session_key; - -sub login_reno { - $testJson = { - 'email' => $emailReno, - 'password' => $passwordReno, - }; - $t->post_ok('/api/login' => json => $testJson) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true); - $session_key = $t->tx->res->json('/session_key'); -} - -sub login_chocobilly { - $testJson = { - 'email' => $emailBilly, - 'password' => $passwordBilly, - }; - $t->post_ok('/api/login' => json => $testJson) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true); - $session_key = $t->tx->res->json('/session_key'); -} - -sub login_admin { - $testJson = { - 'email' => $emailAdmin, - 'password' => $passwordAdmin, - }; - $t->post_ok('/api/login' => json => $testJson) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true); - $session_key = $t->tx->res->json('/session_key'); -} - -print "test 5 - Login non-admin Reno\n"; -login_reno(); - - -print "test 6 - Reno spends at Turtle\'s Paradise\n"; -my $nameToTestTurtle = 'Turtle\'s Paradise'; -$json = { - transaction_value => 10, - transaction_type => 3, - organisation_name => $nameToTestTurtle, - street_name => "Town centre", - town => " Wutai", - postcode => "NW11 8AD", - session_key => $session_key, -}; -my $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; -$t->post_ok('/api/upload' => form => $upload ) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true); -my $unvalidatedOrganisationId = $t->app->schema->resultset('PendingOrganisation')->find({ name => $nameToTestTurtle })->pendingorganisationid; - -#Change to 2 days later -Time::Fake->offset("+" . $dateTimePlusTwoDaysSecondsDiff . "s"); - -print "test 7 - Reno spends at Turtle\'s Paradise, 2 days later, transaction 1/2\n"; -$json = { - transaction_value => 20, - transaction_type => 2, - organisation_id => $unvalidatedOrganisationId, - session_key => $session_key, -}; -my $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; -$t->post_ok('/api/upload' => form => $upload ) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true); - -print "test 8 - Reno spends at Turtle\'s Paradise, 2 days later, transaction 2/2\n"; -$json = { - transaction_value => 40, - transaction_type => 2, - organisation_id => $unvalidatedOrganisationId, - session_key => $session_key, -}; -my $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; -$t->post_ok('/api/upload' => form => $upload ) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true); - -print "test 9 - Logout non-admin Reno (time offset causes session to expire)\n"; -logout(); - -#Change to 1 month later -Time::Fake->offset("+" . $dateTimePlusOneMonthSecondsDiff . "s"); - -print "test 10 - Login non-admin Reno\n"; -login_reno(); - -print "test 11 - Reno spends at Turtle\'s Paradise, 1 month later\n"; -$json = { - transaction_value => 80, - transaction_type => 2, - organisation_id => $unvalidatedOrganisationId, - session_key => $session_key, -}; -my $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; -$t->post_ok('/api/upload' => form => $upload ) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true); - -print "test 12 - Logout non-admin Reno\n"; -logout(); - -#Change to 1 year (and a bit) later -Time::Fake->offset("+" . $dateTimePlusOneYearSecondsDiff . "s"); - -print "test 13 - Login non-admin Reno\n"; -login_reno(); - -print "test 14 - Reno spends at Turtle\'s Paradise, 1 year later\n"; -$json = { - transaction_value => 160, - transaction_type => 2, - organisation_id => $unvalidatedOrganisationId, - session_key => $session_key, -}; -my $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; -$t->post_ok('/api/upload' => form => $upload ) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true); - -print "test 15 - Logout non-admin Reno\n"; -logout(); - -#Change to 2 days later -Time::Fake->offset("+" . $dateTimePlusTwoDaysSecondsDiff . "s"); - -print "test 16 - Login Admin\n"; -login_admin(); - -print "test 17 - Admin approves Turtle\'s Paradise.\n"; -$json = { - unvalidatedOrganisationId => $unvalidatedOrganisationId, - session_key => $session_key, -}; -$t->post_ok('/api/admin-approve' => json => $json) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true); -my $validatedOrganisationId = $t->tx->res->json->{validatedOrganisationId}; - - -print "test 18 - Logout Admin\n"; -logout(); - -print "test 19 - Login non-admin Chocobilly\n"; -login_chocobilly(); - -print "test 20 - Chocobilly spends at Turtle\'s Paradise, 2 days later\n"; -#Added to test and see if the later values from different users merge together. They shouldn't -$json = { - transaction_value => 320, - transaction_type => 1, - organisation_id => $validatedOrganisationId, - session_key => $session_key, -}; -my $upload = {json => Mojo::JSON::encode_json($json), file => {file => './t/test.jpg'}}; -$t->post_ok('/api/upload' => form => $upload ) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true); - -print "test 21 - Logout non-admin Chocobilly\n"; -logout(); - -#Change back to 1 year (and a bit) later -Time::Fake->offset("+" . $dateTimePlusOneYearSecondsDiff . "s"); - -##Actual testing from here onwards. - -print "test 22 - Login non-admin Reno\n"; -login_reno(); - - -print "test 23 - No JSON\n"; -$t->post_ok('/api/user-history') - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->json_like('/message', qr/JSON is missing/); - -print "test 24 - retrieveType is missing\n"; -$json = { - dayNumber => $dateTimePlusThreeDays->day(), - monthNumber => $dateTimePlusThreeDays->month(), - year => $dateTimePlusThreeDays->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/retrieveType is missing/i); - -print "test 25 - retrieveType is not a number\n"; -$json = { - retrieveType => "A", - dayNumber => $dateTimePlusThreeDays->day(), - monthNumber => $dateTimePlusThreeDays->month(), - year => $dateTimePlusThreeDays->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/retrieveType does not look like a number/i); - -print "test 26 - retrieveType is not 1 or 2\n"; -$json = { - retrieveType => 0, - dayNumber => $dateTimePlusThreeDays->day(), - monthNumber => $dateTimePlusThreeDays->month(), - year => $dateTimePlusThreeDays->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/retrieveType can only be 1 or 2./i); - -#Single tests - -print "test 27 - single date - dayNumber is missing\n"; -$json = { - retrieveType => 1, - monthNumber => $dateTimePlusThreeDays->month(), - year => $dateTimePlusThreeDays->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/dayNumber is missing./i); - -print "test 28 - single date - dayNumber is not a number\n"; -$json = { - retrieveType => 1, - dayNumber => "A", - monthNumber => $dateTimePlusThreeDays->month(), - year => $dateTimePlusThreeDays->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/dayNumber does not look like a number./i); - -print "test 29 - single date - monthNumber is missing\n"; -$json = { - retrieveType => 1, - dayNumber => $dateTimePlusThreeDays->day(), - year => $dateTimePlusThreeDays->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/monthNumber is missing./i); - -print "test 30 - single date - monthNumber is not a number\n"; -$json = { - retrieveType => 1, - dayNumber => $dateTimePlusThreeDays->day(), - monthNumber => "ABC", - year => $dateTimePlusThreeDays->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/monthNumber does not look like a number./i); - -print "test 31 - single date - year is missing\n"; -$json = { - retrieveType => 1, - dayNumber => $dateTimePlusThreeDays->day(), - monthNumber => $dateTimePlusThreeDays->month(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/year is missing./i); - -print "test 32 - single date - year is not a number\n"; -$json = { - retrieveType => 1, - dayNumber => $dateTimePlusThreeDays->day(), - monthNumber => $dateTimePlusThreeDays->month(), - year => "I1", - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/year does not look like a number./i); - -print "test 33 - Invalid date\n"; -$json = { - retrieveType => 1, - dayNumber => $dateTimePlusThreeDays->day(), - monthNumber => ($dateTimePlusThreeDays->month() + 13), - year => $dateTimePlusThreeDays->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/date is invalid./i); - -#Range tests. - -print "test 34 - range date - startDayNumber is missing\n"; -$json = { - retrieveType => 2, - startMonthNumber => $dateTimeInitial->month(), - startYear => $dateTimeInitial->year(), - endDayNumber => $dateTimePlusOneYear->day(), - endMonthNumber => $dateTimePlusOneYear->month(), - endYear => $dateTimePlusOneYear->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/startDayNumber is missing./i); - -print "test 35 - range date - startDayNumber is not a number\n"; -$json = { - retrieveType => 2, - startDayNumber => "2ER", - startMonthNumber => $dateTimeInitial->month(), - startYear => $dateTimeInitial->year(), - endDayNumber => $dateTimePlusOneYear->day(), - endMonthNumber => $dateTimePlusOneYear->month(), - endYear => $dateTimePlusOneYear->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/startDayNumber does not look like a number./i); - - -print "test 36 - range date - startMonthNumber is missing\n"; -$json = { - retrieveType => 2, - startDayNumber => $dateTimeInitial->day(), - startYear => $dateTimeInitial->year(), - endDayNumber => $dateTimePlusOneYear->day(), - endMonthNumber => $dateTimePlusOneYear->month(), - endYear => $dateTimePlusOneYear->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/startMonthNumber is missing./i); - -print "test 37 - range date - startMonthNumber is not a number\n"; -$json = { - retrieveType => 2, - startDayNumber => $dateTimeInitial->day(), - startMonthNumber => "Text", - startYear => $dateTimeInitial->year(), - endDayNumber => $dateTimePlusOneYear->day(), - endMonthNumber => $dateTimePlusOneYear->month(), - endYear => $dateTimePlusOneYear->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/startMonthNumber does not look like a number./i); - -print "test 38 - range date - startYear is missing\n"; -$json = { - retrieveType => 2, - startDayNumber => $dateTimeInitial->day(), - startMonthNumber => $dateTimeInitial->month(), - endDayNumber => $dateTimePlusOneYear->day(), - endMonthNumber => $dateTimePlusOneYear->month(), - endYear => $dateTimePlusOneYear->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/startYear is missing./i); - -print "test 39 - range date - startYear is not a number\n"; -$json = { - retrieveType => 2, - startDayNumber => $dateTimeInitial->day(), - startMonthNumber => $dateTimeInitial->month(), - startYear => "Years2", - endDayNumber => $dateTimePlusOneYear->day(), - endMonthNumber => $dateTimePlusOneYear->month(), - endYear => $dateTimePlusOneYear->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/startYear does not look like a number./i); - -print "test 40 - Invalid start date\n"; -$json = { - retrieveType => 2, - startDayNumber => ($dateTimeInitial->day() + 60), - startMonthNumber => $dateTimeInitial->month(), - startYear => $dateTimeInitial->year(), - endDayNumber => $dateTimePlusOneYear->day(), - endMonthNumber => $dateTimePlusOneYear->month(), - endYear => $dateTimePlusOneYear->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/start date is invalid./i); - -## Valid data testing. - -print "test 41 - range date - endDayNumber is missing\n"; -$json = { - retrieveType => 2, - startDayNumber => $dateTimeInitial->day(), - startMonthNumber => $dateTimeInitial->month(), - startYear => $dateTimeInitial->year(), - endMonthNumber => $dateTimePlusOneYear->month(), - endYear => $dateTimePlusOneYear->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/endDayNumber is missing./i); - -print "test 42 - range date - endDayNumber is not a number\n"; -$json = { - retrieveType => 2, - startDayNumber => $dateTimeInitial->day(), - startMonthNumber => $dateTimeInitial->month(), - startYear => $dateTimeInitial->year(), - endDayNumber => "2EF", - endMonthNumber => $dateTimePlusOneYear->month(), - endYear => $dateTimePlusOneYear->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/endDayNumber does not look like a number./i); - -print "test 43 - range date - endMonthNumber is missing\n"; -$json = { - retrieveType => 2, - startDayNumber => $dateTimeInitial->day(), - startMonthNumber => $dateTimeInitial->month(), - startYear => $dateTimeInitial->year(), - endDayNumber => $dateTimePlusOneYear->day(), - endYear => $dateTimePlusOneYear->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/endMonthNumber is missing./i); - -print "test 44 - range date - endMonthNumber is not a number\n"; -$json = { - retrieveType => 2, - startDayNumber => $dateTimeInitial->day(), - startMonthNumber => $dateTimeInitial->month(), - startYear => $dateTimeInitial->year(), - endDayNumber => $dateTimePlusOneYear->day(), - endMonthNumber => "A5G", - endYear => $dateTimePlusOneYear->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/endMonthNumber does not look like a number./i); - -print "test 43 - range date - endYear is missing\n"; -$json = { - retrieveType => 2, - startDayNumber => $dateTimeInitial->day(), - startMonthNumber => $dateTimeInitial->month(), - startYear => $dateTimeInitial->year(), - endDayNumber => $dateTimePlusOneYear->day(), - endMonthNumber => $dateTimePlusOneYear->month(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/endYear is missing./i); - -print "test 44 - range date - endYear is not a number\n"; -$json = { - retrieveType => 2, - startDayNumber => $dateTimeInitial->day(), - startMonthNumber => $dateTimeInitial->month(), - startYear => $dateTimeInitial->year(), - endDayNumber => $dateTimePlusOneYear->day(), - endMonthNumber => $dateTimePlusOneYear->month(), - endYear => "ABC", - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/endYear does not look like a number./i); - -print "test 40 - Invalid end date\n"; -$json = { - retrieveType => 2, - startDayNumber => $dateTimeInitial->day(), - startMonthNumber => $dateTimeInitial->month(), - startYear => $dateTimeInitial->year(), - endDayNumber => ($dateTimePlusOneYear->day() - 60), - endMonthNumber => $dateTimePlusOneYear->month(), - endYear => $dateTimePlusOneYear->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(400) - ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/end date is invalid./i); - - -print "test 41 - Test single day with no transactions\n"; -my $expectedReturnedStats = {}; -$json = { - retrieveType => 1, - dayNumber => $dateTimePlusThreeDays->day(), - monthNumber => $dateTimePlusThreeDays->month(), - year => $dateTimePlusThreeDays->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true) - ->json_has('/microCurencySpent') - ->json_is('/microCurencySpent',$expectedReturnedStats); -my $spend = $t->tx->res->json->{microCurencySpent}; -print Dumper($spend) . "\n"; - -print "test 42 - Test single day with one transaction\n"; -$expectedReturnedStats = {}; -$expectedReturnedStats->{$dateTimeInitial->year}{$dateTimeInitial->month}{$dateTimeInitial->day} = 10; -$json = { - retrieveType => 1, - dayNumber => $dateTimeInitial->day(), - monthNumber => $dateTimeInitial->month(), - year => $dateTimeInitial->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true) - ->json_has('/microCurencySpent') - ->json_is('/microCurencySpent',$expectedReturnedStats)->or(sub { use Data::Dumper; diag Dumper $t->tx->res }); -my $spend = $t->tx->res->json->{microCurencySpent}; -print Dumper($spend) . "\n"; - -print "test 43 - Test single day with multiple transactions and user separateness\n"; -$expectedReturnedStats = {}; -$expectedReturnedStats->{$dateTimePlusTwoDays->year}{$dateTimePlusTwoDays->month}{$dateTimePlusTwoDays->day} = 60; -$json = { - retrieveType => 1, - dayNumber => $dateTimePlusTwoDays->day(), - monthNumber => $dateTimePlusTwoDays->month(), - year => $dateTimePlusTwoDays->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true) - ->json_has('/microCurencySpent') - ->json_is('/microCurencySpent',$expectedReturnedStats); -my $spend = $t->tx->res->json->{microCurencySpent}; -print Dumper($spend) . "\n"; - -print "test 44 - Test range with no transactions\n"; -#Empty range -$expectedReturnedStats = {}; -$json = { - retrieveType => 2, - startDayNumber => $dateTimePlusThreeDays->day(), - startMonthNumber => $dateTimePlusThreeDays->month(), - startYear => $dateTimePlusThreeDays->year(), - endDayNumber => $dateTimePlusOneMonthMinusOneDay->day(), - endMonthNumber => $dateTimePlusOneMonthMinusOneDay->month(), - endYear => $dateTimePlusOneMonthMinusOneDay->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true) - ->json_has('/microCurencySpent') - ->json_is('/microCurencySpent',$expectedReturnedStats); -my $spend = $t->tx->res->json->{microCurencySpent}; -print Dumper($spend) . "\n"; - -print "test 45 - Test range with multiple very similar dated transactions (2 day window), test multiple transactions on a day and user separateness\n"; -#Testing boundary condition one day before the next value. -$expectedReturnedStats = {}; -$expectedReturnedStats->{$dateTimeInitial->year}{$dateTimeInitial->month}{$dateTimeInitial->day} = 10; -$expectedReturnedStats->{$dateTimePlusTwoDays->year}{$dateTimePlusTwoDays->month}{$dateTimePlusTwoDays->day} = 60; -$json = { - retrieveType => 2, - startDayNumber => $dateTimeInitial->day(), - startMonthNumber => $dateTimeInitial->month(), - startYear => $dateTimeInitial->year(), - endDayNumber => $dateTimePlusOneMonthMinusOneDay->day(), - endMonthNumber => $dateTimePlusOneMonthMinusOneDay->month(), - endYear => $dateTimePlusOneMonthMinusOneDay->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true) - ->json_has('/microCurencySpent') - ->json_is('/microCurencySpent',$expectedReturnedStats); -my $spend = $t->tx->res->json->{microCurencySpent}; -print Dumper($spend) . "\n"; - -print "test 46 - Test range with multiple transactions spread over a few days, a month and a year, as well as user separateness\n"; -$expectedReturnedStats = {}; -$expectedReturnedStats->{$dateTimeInitial->year}{$dateTimeInitial->month}{$dateTimeInitial->day} = 10; -$expectedReturnedStats->{$dateTimePlusTwoDays->year}{$dateTimePlusTwoDays->month}{$dateTimePlusTwoDays->day} = 60; -$expectedReturnedStats->{$dateTimePlusOneMonth->year}{$dateTimePlusOneMonth->month}{$dateTimePlusOneMonth->day} = 80; -$expectedReturnedStats->{$dateTimePlusOneYear->year}{$dateTimePlusOneYear->month}{$dateTimePlusOneYear->day} = 160; -$json = { - retrieveType => 2, - startDayNumber => $dateTimeInitial->day(), - startMonthNumber => $dateTimeInitial->month(), - startYear => $dateTimeInitial->year(), - endDayNumber => $dateTimePlusOneYear->day(), - endMonthNumber => $dateTimePlusOneYear->month(), - endYear => $dateTimePlusOneYear->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true) - ->json_has('/microCurencySpent') - ->json_is('/microCurencySpent',$expectedReturnedStats); -my $spend = $t->tx->res->json->{microCurencySpent}; -print Dumper($spend) . "\n"; - -print "test 47 - Logout non-admin Reno\n"; -logout(); - -print "test 48 - Login non-admin Chocobilly\n"; -login_chocobilly(); - -print "test 49- Test user separateness under different user.\n"; -$expectedReturnedStats = {}; -$expectedReturnedStats->{$dateTimePlusTwoDays->year}{$dateTimePlusTwoDays->month}{$dateTimePlusTwoDays->day} = 320; -$json = { - retrieveType => 2, - startDayNumber => $dateTimeInitial->day(), - startMonthNumber => $dateTimeInitial->month(), - startYear => $dateTimeInitial->year(), - endDayNumber => $dateTimePlusOneYear->day(), - endMonthNumber => $dateTimePlusOneYear->month(), - endYear => $dateTimePlusOneYear->year(), - session_key => $session_key, -}; -$t->post_ok('/api/user-history' => json => $json) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true) - ->json_has('/microCurencySpent') - ->json_is('/microCurencySpent',$expectedReturnedStats); -my $spend = $t->tx->res->json->{microCurencySpent}; -print Dumper($spend) . "\n"; - -print "test 50 - Logout non-admin Chocobilly\n"; -logout(); - -done_testing(); diff --git a/templates/admin/home.html.ep b/templates/admin/home.html.ep index 5c539aa..ebc749b 100644 --- a/templates/admin/home.html.ep +++ b/templates/admin/home.html.ep @@ -23,4 +23,24 @@ +
+
+ Pending Organisations +
+
+

+ %= $pending_orgs +

+
+
+
+
+ Pending Transactions +
+
+

+ %= $pending_trans +

+
+
diff --git a/templates/admin/organisations/list.html.ep b/templates/admin/organisations/list.html.ep new file mode 100644 index 0000000..75e7670 --- /dev/null +++ b/templates/admin/organisations/list.html.ep @@ -0,0 +1,52 @@ +% layout 'admin'; +% title 'Organisations'; +% content_for javascript => begin +% end +% if ( my $error = flash 'error' ) { + +% } elsif ( my $success = flash 'success' ) { + +% } +
+
+
+

+ Valid Organisations +

+
+ % for my $valid_org ($valid_orgs_rs->all) { + +
+ %= $valid_org->name +
+
+ % } +
+
+
+
+
+

+ Pending Organisations +

+
+ % if ( $pending_orgs_rs->count == 0 ) { +
+ No Pending Organisations! +
+ % } else { + % for my $pending_org ($pending_orgs_rs->all) { + +
+ %= $pending_org->name +
+
+ % }} +
+
+
+
diff --git a/templates/admin/organisations/pending_read.html.ep b/templates/admin/organisations/pending_read.html.ep new file mode 100644 index 0000000..6f1c8c4 --- /dev/null +++ b/templates/admin/organisations/pending_read.html.ep @@ -0,0 +1,42 @@ +% layout 'admin'; +% title 'Organisations'; +% content_for javascript => begin +% end +% if ( my $error = flash 'error' ) { + +% } elsif ( my $success = flash 'success' ) { + +% } +
+

+ %= $pending_org->name +

+
    +
  • Street Name: <%= $pending_org->street_name %>
  • +
  • Town: <%= $pending_org->town %>
  • +
  • Postcode: <%= $pending_org->postcode %>
  • +
  • Approve Organisation
  • +
+
+
+

+ Transactions +

+
    + % for my $transaction ( $pending_org->transactions->all ) { +
  • +
    +
    +
    From: <%= $transaction->buyer->name %>
    +
    To: <%= $transaction->seller->name %>
    +
    Value: <%= $transaction->value %>
    +
    +
    +
  • + % } +
+
diff --git a/templates/admin/organisations/valid_read.html.ep b/templates/admin/organisations/valid_read.html.ep new file mode 100644 index 0000000..fccf361 --- /dev/null +++ b/templates/admin/organisations/valid_read.html.ep @@ -0,0 +1,41 @@ +% layout 'admin'; +% title 'Organisations'; +% content_for javascript => begin +% end +% if ( my $error = flash 'error' ) { + +% } elsif ( my $success = flash 'success' ) { + +% } +
+

+ %= $valid_org->name +

+
    +
  • Street Name: <%= $valid_org->street_name %>
  • +
  • Town: <%= $valid_org->town %>
  • +
  • Postcode: <%= $valid_org->postcode %>
  • +
+
+
+

+ Transactions +

+
    + % for my $transaction ( $valid_org->transactions->all ) { +
  • +
    +
    +
    From: <%= $transaction->buyer->name %>
    +
    To: <%= $transaction->seller->name %>
    +
    Value: <%= $transaction->value %>
    +
    +
    +
  • + % } +
+
diff --git a/templates/admin/tokens/index.html.ep b/templates/admin/tokens/index.html.ep index 6cece6e..772463a 100644 --- a/templates/admin/tokens/index.html.ep +++ b/templates/admin/tokens/index.html.ep @@ -14,7 +14,7 @@
- + @@ -23,9 +23,9 @@
% for my $token (@$tokens) { - +
- %= $token->{accounttokenname} + %= $token->{name}
- <%= content %> +
+ <%= content %> +
%= content_for 'javascript'; diff --git a/templates/register/index.html.ep b/templates/register/index.html.ep index e5eb1eb..e1aa6a9 100644 --- a/templates/register/index.html.ep +++ b/templates/register/index.html.ep @@ -73,8 +73,8 @@ body { diff --git a/templates/root/home.html.ep b/templates/root/home.html.ep index 4f0512a..54a8251 100644 --- a/templates/root/home.html.ep +++ b/templates/root/home.html.ep @@ -1,25 +1,37 @@ % layout 'user'; % title 'Home'; -% content_for css => begin - -% end % content_for javascript => begin +%= javascript '/static/user/js/home.js'; % end -
User Pages
+
+

Submit Receipt

+
+ + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+