Fixing errors in customer, adding developer.

Improving migrations, adding/fixing tests.
This commit is contained in:
sergiotarxz 2022-03-15 02:45:16 +01:00
parent 4a3a3b9e36
commit b2758ddf96
10 changed files with 386 additions and 36 deletions

View File

@ -12,6 +12,8 @@ my $build = Module::Build->new(
'DBI' => 0, 'DBI' => 0,
'DBD::Pg' => 0, 'DBD::Pg' => 0,
'DBD::Mock' => 0, 'DBD::Mock' => 0,
'DateTime' => 0,
'DateTime::Format::Pg' => 0,
}, },
install_path => { install_path => {
'templates' => "$HOME/.local/share/peace/template", 'templates' => "$HOME/.local/share/peace/template",

View File

@ -0,0 +1,36 @@
#!/usr/bin/env perl
use v5.30.0;
use strict;
use warnings;
use Test::Most tests => 2;
use DateTime;
use Peace;
use Peace::DB;
use Peace::Model::Customer;
use Peace::DAO::Customer;
{
## GIVEN
my $current_date = DateTime->now;
my $peace = Peace->new;
my $home = $ENV{HOME};
my $config =
$peace->plugin(
JSONConfig => { file => "$home/.config/peace/peace.conf" } );
my $dbh = Peace::DB->dbh( config => $config );
my $secret_bcrypt = 'hola';
my $customer = Peace::Model::Customer->new( secret_bcrypt => $secret_bcrypt );
my $customer_dao = Peace::DAO::Customer->new( dbh => $dbh );
## WHEN
$customer_dao->create( customer => $customer );
## THEN
ok $customer->uuid, 'Generated uuid.';
ok $customer->date_creation > $current_date, 'The date is recent.';
}

View File

@ -8,6 +8,8 @@ use warnings;
use Params::ValidationCompiler qw/validation_for/; use Params::ValidationCompiler qw/validation_for/;
use Types::Standard qw/HasMethods InstanceOf Str/; use Types::Standard qw/HasMethods InstanceOf Str/;
use DateTime::Format::Pg;
{ {
my $validator = validation_for( my $validator = validation_for(
params => { params => {
@ -38,19 +40,15 @@ use Types::Standard qw/HasMethods InstanceOf Str/;
my $customer = $params{customer}; my $customer = $params{customer};
my $dbh = $self->_dbh; my $dbh = $self->_dbh;
my $insert = <<'EOF'; my $insert = <<'EOF';
INSERT INTO customers (secret) VALUES (?) RETURNING uuid; INSERT INTO customers (secret_bcrypt) VALUES (?) RETURNING uuid;
EOF EOF
my $result = my $result =
$dbh->selectrow_hashref( $insert, undef, $customer->secret ); $dbh->selectrow_hashref( $insert, undef, $customer->secret_bcrypt );
my $uuid = $result->{uuid}; my $uuid = $result->{uuid};
$customer->uuid($uuid); $customer->uuid($uuid);
my $new_customer = $self->recover_by_uuid( uuid => $uuid ); my $new_customer = $self->recover_by_uuid( uuid => $uuid );
$customer->secret( $new_customer->secret )
if defined $new_customer->secret;
$customer->date_creation( $new_customer->date_creation ) $customer->date_creation( $new_customer->date_creation )
if defined $new_customer->date_creation; if defined $new_customer->date_creation;
$customer->stripe_id( $new_customer->stripe_id )
if defined $new_customer->stripe_id;
return $customer; return $customer;
} }
} }
@ -70,8 +68,13 @@ EOF
my $uuid = $params{uuid}; my $uuid = $params{uuid};
my $result = $dbh->selectrow_hashref( <<'EOF', undef, $uuid ); my $result = $dbh->selectrow_hashref( <<'EOF', undef, $uuid );
SELECT uuid, date_creation, secret, stripe_id FROM customer WHERE uuid = ?; SELECT uuid, date_creation, secret_bcrypt, stripe_id FROM customers WHERE uuid = ?;
EOF EOF
if ( exists $result->{date_creation} ) {
my $iso8601 = DateTime::Format::Pg->new;
$result->{date_creation} =
$iso8601->parse_datetime( $result->{date_creation} );
}
for my $key ( keys %$result ) { for my $key ( keys %$result ) {
delete $result->{$key} unless defined $result->{$key}; delete $result->{$key} unless defined $result->{$key};
} }

View File

@ -0,0 +1,83 @@
package Peace::DAO::Developer;
use v5.30.0;
use strict;
use warnings;
use Params::ValidationCompiler qw/validation_for/;
use Types::Standard qw/HasMethods InstanceOf Str/;
{
my $validator = validation_for(
params => {
dbh => { type => HasMethods ['selectall_arrayref'] },
}
);
sub new {
my $class = shift;
my %params = $validator->(@_);
my $self = bless {}, $class;
$self->{dbh} = $params{dbh};
return $self;
}
}
{
my $validator = validation_for(
params => {
developer => { type => InstanceOf ['Peace::Model::Developer'] },
}
);
sub create {
my $self = shift;
my %params = $validator->(@_);
my $developer = $params{developer};
my $dbh = $self->_dbh;
my $insert = <<'EOF';
INSERT INTO developers (secret_bcrypt, name, surname, email, country, verified)
VALUES (?, ?, ?, ?, ?, ?)
RETURNING uuid;
EOF
my $result = $dbh->selectrow_hashref(
$insert, undef, $developer->secret,
$developer->name, $developer->surname, $developer->email,
$developer->country, $developer->verified
);
my $uuid = $result->{uuid};
$developer->uuid($uuid);
my $new_developer = $self->recover_by_uuid( uuid => $uuid );
$developer->date_creation( $new_developer->date_creation )
if defined $new_developer->date_creation;
return $developer;
}
}
{
my $validator = validation_for(
params => {
uuid => { type => Str },
}
);
sub recover_by_uuid {
my $self = shift;
my %params = $validator->(@_);
my $uuid = $params{uuid};
my $dbh = $self->_dbh;
my $result = $dbh->selectrow_hashref( <<'EOF', undef, $uuid );
SELECT uuid, date_creation, secret_bcrypt, name, surname, email, stripe_id, country, verified
FROM customer
WHERE uuid = ?;
EOF
for my $key (keys %$result) {
delete $result->{$key} unless defined $result->{$key};
}
my $developer = Peace::Model::Developer->new(%$result);
return $developer;
}
}
1;

View File

@ -20,13 +20,14 @@ my @migrations = (
'CREATE TABLE customers ( 'CREATE TABLE customers (
uuid UUID NOT NULL DEFAULT gen_random_uuid(), uuid UUID NOT NULL DEFAULT gen_random_uuid(),
date_creation timestamp DEFAULT NOW(), date_creation timestamp DEFAULT NOW(),
secret TEXT NOT NULL, secret_bcrypt TEXT NOT NULL,
stripe_id TEXT, stripe_id TEXT,
PRIMARY KEY (uuid) PRIMARY KEY (uuid)
);', );',
'CREATE TABLE developers ( 'CREATE TABLE developers (
uuid UUID NOT NULL DEFAULT gen_random_uuid(), uuid UUID NOT NULL DEFAULT gen_random_uuid(),
date_creation timestamp DEFAULT NOW(), date_creation timestamp DEFAULT NOW(),
secret_bcrypt TEXT NOT NULL,
name TEXT NOT NULL, name TEXT NOT NULL,
surname TEXT NOT NULL, surname TEXT NOT NULL,
email TEXT NOT NULL, email TEXT NOT NULL,
@ -127,14 +128,14 @@ sub run_migrations {
for my $migration (@needed_migrations) { for my $migration (@needed_migrations) {
$dbh->do($migration); $dbh->do($migration);
my $update_result = my $update_result =
$dbh->do( 'UPDATE options SET value = ? WHERE key = \'migration\';', $dbh->do( <<'EOF', undef, ++$current_migration );
undef, ++$current_migration ); UPDATE options SET value = ? WHERE key = 'migration';
EOF
unless ( defined $update_result ) { unless ( defined $update_result && 0+$update_result ) {
$dbh->do( say $dbh->do( <<'EOF', undef, $current_migration);
'INSERT INTO options (key, value) VALUES (\"migration\", ?)', INSERT INTO options (key, value) VALUES ('migration', ?);
undef, $current_migration EOF
);
} }
} }
} }

View File

@ -14,7 +14,7 @@ use DateTime;
params => { params => {
uuid => { type => Str, optional => 1 }, uuid => { type => Str, optional => 1 },
date_creation => { type => InstanceOf ['DateTime'], optional => 1 }, date_creation => { type => InstanceOf ['DateTime'], optional => 1 },
secret => { type => Str }, secret_bcrypt => { type => Str },
stripe_id => { type => Str, optional => 1 }, stripe_id => { type => Str, optional => 1 },
} }
); );
@ -60,13 +60,13 @@ use DateTime;
my $validator = my $validator =
validation_for( params => [ { type => Str, optional => 1 } ] ); validation_for( params => [ { type => Str, optional => 1 } ] );
sub secret { sub secret_bcrypt {
my $self = shift; my $self = shift;
if (@_) { if (@_) {
my ($new_secret) = $validator->(@_); my ($new_secret_bcrypt) = $validator->(@_);
$self->{secret} = $new_secret; $self->{secret_bcrypt} = $new_secret_bcrypt;
} }
return $self->{secret}; return $self->{secret_bcrypt};
} }
} }

View File

@ -0,0 +1,161 @@
package Peace::Model::Developer;
use v5.30.0;
use strict;
use warnings;
use Params::ValidationCompiler qw/validation_for/;
use Types::Standard qw/Str InstanceOf Bool/;
use DateTime;
{
my $validator = validation_for(
params => {
uuid => { type => Str, optional => 1 },
date_creation => { type => InstanceOf ['DateTime'], optional => 1 },
secret_bcrypt => { type => Str },
name => { type => Str },
surname => { type => Str },
email => { type => Str },
stripe_id => { type => Str, optional => 1 },
country => { type => Str },
verified => { type => Bool },
}
);
sub new {
my $class = shift;
my %params = $validator->(@_);
my $self = bless {%params}, $class;
return $self;
}
}
{
my $validator =
validation_for( params => [ { type => Str, optional => 1 } ] );
sub uuid {
my $self = shift;
if (@_) {
my ($new_uuid) = $validator->(@_);
$self->{uuid} = $new_uuid;
}
return $self->{uuid};
}
}
{
my $validator =
validation_for(
params => [ { type => InstanceOf ['DateTime'], optional => 1 } ] );
sub date_creation {
my $self = shift;
if (@_) {
my ($new_date_creation) = $validator->(@_);
$self->{date_creation} = $new_date_creation;
}
return $self->{date_creation};
}
}
{
my $validator =
validation_for( params => [ { type => Str, optional => 1 } ] );
sub secret_bcrypt {
my $self = shift;
if (@_) {
my ($new_secret_bcrypt) = $validator->(@_);
$self->{secret_bcrypt} = $new_secret_bcrypt;
}
return $self->{secret_bcrypt};
}
}
{
my $validator =
validation_for( params => [ { type => Str, optional => 1 } ] );
sub name {
my $self = shift;
if (@_) {
my ($new_name) = $validator->(@_);
$self->{name} = $new_name;
}
return $self->{name};
}
}
{
my $validator =
validation_for( params => [ { type => Str, optional => 1 } ] );
sub surname {
my $self = shift;
if (@_) {
my ($new_surname) = $validator->(@_);
$self->{surname} = $new_surname;
}
return $self->{surname};
}
}
{
my $validator =
validation_for( params => [ { type => Str, optional => 1 } ] );
sub email {
my $self = shift;
if (@_) {
my ($new_email) = $validator->(@_);
$self->{email} = $new_email;
}
return $self->{email};
}
}
{
my $validator =
validation_for( params => [ { type => Str, optional => 1 } ] );
sub stripe_id {
my $self = shift;
if (@_) {
my ($new_stripe_id) = $validator->(@_);
$self->{stripe_id} = $new_stripe_id;
}
return $self->{stripe_id};
}
}
{
my $validator =
validation_for( params => [ { type => Str, optional => 1 } ] );
sub country {
my $self = shift;
if (@_) {
my ($new_country) = $validator->(@_);
$self->{country} = $new_country;
}
return $self->{country};
}
}
{
my $validator =
validation_for( params => [ { type => Bool, optional => 1 } ] );
sub verified {
my $self = shift;
if (@_) {
my ($new_verified) = $validator->(@_);
$self->{verified} = $new_verified;
}
return $self->{verified};
}
}
1;

View File

@ -11,21 +11,21 @@ BEGIN {
{ {
## GIVEN ## GIVEN
my $secret = 'hola'; my $secret_bcrypt = 'hola';
## WHEN ## WHEN
my $customer = Peace::Model::Customer->new( secret => $secret ); my $customer = Peace::Model::Customer->new( secret_bcrypt => $secret_bcrypt );
## THEN ## THEN
ok $customer->isa('Peace::Model::Customer'), ok $customer->isa('Peace::Model::Customer'),
'Instanced customer is made of Peace::Model::Customer.'; 'Instanced customer is made of Peace::Model::Customer.';
is $customer->secret, $secret, 'Secret is correctly setup'; is $customer->secret_bcrypt, $secret_bcrypt, 'Secret is correctly setup';
is $customer->uuid, undef, 'Uuid is undef.'; is $customer->uuid, undef, 'Uuid is undef.';
} }
{ {
## GIVEN ## GIVEN
my $secret = 'hola'; my $secret_bcrypt = 'hola';
my $uuid = 'example'; my $uuid = 'example';
my $customer = Peace::Model::Customer->new( secret => $secret ); my $customer = Peace::Model::Customer->new( secret_bcrypt => $secret_bcrypt );
## WHEN ## WHEN
$customer->uuid($uuid); $customer->uuid($uuid);

View File

@ -17,11 +17,11 @@ BEGIN {
{ {
## GIVEN ## GIVEN
my $sql = <<'EOF'; my $sql = <<'EOF';
INSERT INTO customers (secret) VALUES (?) RETURNING uuid; INSERT INTO customers (secret_bcrypt) VALUES (?) RETURNING uuid;
EOF EOF
my $uuid = 'hola'; my $uuid = 'hola';
my $dbh = DBI->connect( 'DBI:Mock:', '', '' ); my $dbh = DBI->connect( 'DBI:Mock:', '', '' );
my $customer = Peace::Model::Customer->new( secret => 'hola' ); my $customer = Peace::Model::Customer->new( secret_bcrypt => 'hola' );
my $customer_dao = Peace::DAO::Customer->new( dbh => $dbh ); my $customer_dao = Peace::DAO::Customer->new( dbh => $dbh );
$dbh->{mock_add_resultset} = { $dbh->{mock_add_resultset} = {
@ -29,11 +29,14 @@ EOF
results => [ ['uuid'], [$uuid], ] results => [ ['uuid'], [$uuid], ]
}; };
$sql = <<'EOF'; $sql = <<'EOF';
SELECT uuid, date_creation, secret, stripe_id FROM customer WHERE uuid = ?; SELECT uuid, date_creation, secret_bcrypt, stripe_id FROM customer WHERE uuid = ?;
EOF EOF
$dbh->{mock_add_resultset} = { $dbh->{mock_add_resultset} = {
sql => $sql, sql => $sql,
results => [ ['uuid', 'secret', 'date_creation', 'stripe_id'], [$uuid, 'hola', undef, undef] ], results => [
[ 'uuid', 'secret_bcrypt', 'date_creation', 'stripe_id' ],
[ $uuid, 'hola', undef, undef ]
],
}; };
## WHEN ## WHEN
$customer_dao->create( customer => $customer ); $customer_dao->create( customer => $customer );
@ -44,21 +47,21 @@ EOF
{ {
## GIVEN ## GIVEN
my $dbh = DBI->connect( 'DBI:Mock:', '', '' ); my $dbh = DBI->connect( 'DBI:Mock:', '', '' );
my $customer_dao = Peace::DAO::Customer->new( dbh => $dbh ); my $customer_dao = Peace::DAO::Customer->new( dbh => $dbh );
my $sql = <<'EOF'; my $sql = <<'EOF';
SELECT uuid, date_creation, secret, stripe_id FROM customer WHERE uuid = ?; SELECT uuid, date_creation, secret_bcrypt, stripe_id FROM customer WHERE uuid = ?;
EOF EOF
my $uuid = 'hola'; my $uuid = 'hola';
my $date_creation = DateTime->now; my $date_creation = DateTime->now;
my $secret = 'hola'; my $secret_bcrypt = 'hola';
my $stripe_id = undef; my $stripe_id = undef;
$dbh->{mock_add_resultset} = { $dbh->{mock_add_resultset} = {
sql => $sql, sql => $sql,
results => [ results => [
[ 'uuid', 'date_creation', 'secret', 'stripe_id' ], [ 'uuid', 'date_creation', 'secret_bcrypt', 'stripe_id' ],
[ $uuid, $date_creation, $secret, $stripe_id ], [ $uuid, $date_creation, $secret_bcrypt, $stripe_id ],
] ]
}; };
@ -69,7 +72,8 @@ EOF
is $customer->uuid, $uuid, 'Uuid is recovered correctly'; is $customer->uuid, $uuid, 'Uuid is recovered correctly';
is $customer->date_creation, $date_creation, is $customer->date_creation, $date_creation,
'Date creation is recovered correctly'; 'Date creation is recovered correctly';
is $customer->secret, $secret, 'Secret is recovered correctly'; is $customer->secret_bcrypt, $secret_bcrypt,
'Secret is recovered correctly';
is $customer->stripe_id, $stripe_id, 'Secret is recovered correctly'; is $customer->stripe_id, $stripe_id, 'Secret is recovered correctly';
} }

60
t/00005-developer-model.t Normal file
View File

@ -0,0 +1,60 @@
use v5.30.0;
use strict;
use warnings;
use Test::Most tests => 5;
BEGIN {
use_ok 'Peace::Model::Developer';
}
{
## GIVEN
my $secret_bcrypt = 'hola';
my $name = 'Larry';
my $surname = 'Wall';
my $email = 'larry@perl.org';
my $country = 'US';
my $verified = 0;
## WHEN
my $developer = Peace::Model::Developer->new(
secret_bcrypt => $secret_bcrypt,
name => $name,
surname => $surname,
email => $email,
country => $country,
verified => $verified,
);
## THEN
ok $developer->isa('Peace::Model::Developer'),
'Instanced developer is made of Peace::Model::Developer.';
is $developer->secret_bcrypt, $secret_bcrypt, 'Secret is correctly setup';
is $developer->uuid, undef, 'Uuid is undef.';
}
{
## GIVEN
my $uuid = 'example';
my $secret_bcrypt = 'hola';
my $name = 'Larry';
my $surname = 'Wall';
my $email = 'larry@perl.org';
my $country = 'US';
my $verified = 0;
my $developer = Peace::Model::Developer->new(
secret_bcrypt => $secret_bcrypt,
name => $name,
surname => $surname,
email => $email,
country => $country,
verified => $verified
);
## WHEN
$developer->uuid($uuid);
## THEN
is $developer->uuid, $uuid, 'Uuid can be set.';
}