diff --git a/db_tests/00003-application-dao.t b/db_tests/00003-application-dao.t index eed7280..51b7812 100644 --- a/db_tests/00003-application-dao.t +++ b/db_tests/00003-application-dao.t @@ -13,11 +13,12 @@ use DateTime; use Peace; use Peace::DB; -use Peace::Model::Developer; use Peace::DAO::Developer; -use Peace::Model::Application; use Peace::DAO::Application; +use Peace::Test::Mock::Model::Developer; +use Peace::Test::Mock::Model::Application; + { ## GIVEN my $current_date = DateTime->now; @@ -27,28 +28,15 @@ use Peace::DAO::Application; $peace->plugin( JSONConfig => { file => "$home/.config/peace/peace.conf" } ); my $dbh = Peace::DB->dbh( config => $config ); - my $secret_bcrypt = 'hola'; - my $developer = Peace::Model::Developer->new( - name => 'Larry', - surname => 'Wall', - email => 'larry@perl.org', - country => 'US', - verified => 0, - secret_bcrypt => $secret_bcrypt - ); + + my $developer = Peace::Test::Mock::Model::Developer->new; my $developer_dao = Peace::DAO::Developer->new( dbh => $dbh ); + $developer_dao->create( developer => $developer ); - my $application = Peace::Model::Application->new( - name => 'Desfronificator', - description => 'Desfronifies the files.', - url => 'desfronificator.example.com', - developer => $developer, - price => 0, - flatpak_builder_file => './resources/com.example.desfronificator.yml', - git_repo => - 'https://git.desfronificator.example.com/larry/desfronificator.git', - verified => 0, - ); + + my $application = Peace::Test::Mock::Model::Application->new; + $application->developer($developer); + my $application_dao = Peace::DAO::Application->new( dbh => $dbh ); ## WHEN @@ -68,37 +56,25 @@ use Peace::DAO::Application; JSONConfig => { file => "$home/.config/peace/peace.conf" } ); my $dbh = Peace::DB->dbh( config => $config ); my $secret_bcrypt = 'hola'; - my $developer = Peace::Model::Developer->new( - name => 'Larry', - surname => 'Wall', - email => 'larry@perl.org', - country => 'US', - verified => 0, - secret_bcrypt => $secret_bcrypt, - dbh => $dbh, - ); + + my $developer = Peace::Test::Mock::Model::Developer->new; my $developer_dao = Peace::DAO::Developer->new( dbh => $dbh ); + $developer_dao->create( developer => $developer ); - my $application = Peace::Model::Application->new( - name => 'Desfronificator', - description => 'Desfronifies the files.', - url => 'desfronificator.example.com', - developer => $developer, - price => 0, - flatpak_builder_file => './resources/com.example.desfronificator.yml', - git_repo => - 'https://git.desfronificator.example.com/larry/desfronificator.git', - verified => 0, - ); + + my $application = Peace::Test::Mock::Model::Application->new; + $application->developer($developer); + my $application_dao = Peace::DAO::Application->new( dbh => $dbh ); $application_dao->create( application => $application ); + $developer->{dbh} = $dbh; ## WHEN my $applications = $developer->applications; ## THEN - ok @$applications, 'Applications was at least a element.'; + ok @$applications, 'Applications has at least a element.'; ok $applications->[0]->isa('Peace::Model::Application'), 'Application is made of developer.'; } diff --git a/lib/Peace/DAO/Application.pm b/lib/Peace/DAO/Application.pm index 05c6dc7..5fc6c81 100644 --- a/lib/Peace/DAO/Application.pm +++ b/lib/Peace/DAO/Application.pm @@ -45,7 +45,7 @@ INSERT INTO applications (name, description, url, developer, price, git_repo, flatpak_builder_file, flatpak_repo, verified) -VALUES (?, ?, ?, ?, ?, ?, ?, ?) +VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING uuid; EOF my $result = $dbh->selectrow_hashref( diff --git a/lib/Peace/DAO/Release.pm b/lib/Peace/DAO/Release.pm new file mode 100644 index 0000000..5d8e23b --- /dev/null +++ b/lib/Peace/DAO/Release.pm @@ -0,0 +1,166 @@ +package Peace::DAO::Release; + +use v5.30.0; + +use strict; +use warnings; + +use Data::Dumper; + +use Params::ValidationCompiler qw/validation_for/; +use Types::Standard qw/HasMethods InstanceOf Str HashRef/; + +{ + my $validator = validation_for( + params => { + dbh => { type => HasMethods ['selectrow_hashref'], optional => 1 }, + } + ); + + sub new { + my $class = shift; + my %params = $validator->(@_); + + my $self = bless {}, $class; + $self->{dbh} = $params{dbh}; + return $self; + } +} + +{ + my $validator = validation_for( + params => { + release => { type => InstanceOf ['Peace::Model::Release'] }, + } + ); + + sub create { + my $self = shift; + my %params = $validator->(@_); + my $application = $params{release}; + my $dbh = $self->_dbh; + + my $insert = <<'EOF'; +INSERT INTO releases + (application, tag, name) +VALUES (?, ?, ?) +RETURNING uuid; +EOF + my $result = + $dbh->selectrow_hashref( $insert, undef, $release->application->uuid, + $release->tag, $release->name ); + my $uuid = $result->{uuid}; + my $new_release = $self->recover_by_uuid( uuid => $uuid ); + + $release->uuid( $new_release->uuid ); + $release->date_creation( $new_release->date_creation ); + + return $release; + } +} + +{ + my $validator = validation_for( + params => { + uuid => { type => Str }, + } + ); + + sub recover_by_uuid { + my $self = shift; + my %params = $validator->(@_); + my $dbh = $self->_dbh; + my $uuid = $params{uuid}; + my $result = $dbh->selectrow_hashref( <<'EOF', undef, $uuid ); +SELECT uuid, date_creation, + application, name, tag +FROM releases +WHERE uuid = ? +EOF + if ( !defined $result ) { + die "Release with uuid $uuid not found."; + } + return $self->_select_result_to_release($result); + } +} + +{ + my $validator = validation_for( params => [ { type => HashRef }, ] ); + + sub _select_result_to_application { + my $self = shift; + my ($result) = $validator->(@_); + if ( exists $result->{application} ) { + $result->{developer_uuid} = delete $result->{application}; + $result->{dbh} = $self->_dbh; + } + if ( exists $result->{date_creation} ) { + my $iso8601 = DateTime::Format::Pg->new; + $result->{date_creation} = + $iso8601->parse_datetime( $result->{date_creation} ); + } + my $release = Peace::Model::Release->new(%$result); + return $release; + } +} + +sub _dbh { + my $self = shift; + return $self->{dbh}; +} +1; +=encoding utf8 + +=head1 NAME + +Peace::DAO::Release - The database access object of releases. + +=head1 SYNOPSIS + + my $release_dao = Peace::DAO::Release->new( + dbh => $dbh + ); + + $release_dao->create( release => $release ); + + my $release = $release_dao->recover_by_uuid( uuid => $uuid ); + +=head1 DESCRIPTION + +Peace::DAO::Release allows you to do database operations over +L objects. + +=head1 INSTANCE METHODS + +Peace::DAO::Release implements the following intance methods: + +=head2 new + + my $release_dao = Peace::DAO::Release->new( + dbh => $dbh + ) + +Instances a Peace::DAO::Release object. + +=head1 METHODS + +Peace::DAO::Release implements the following methods: + +=head2 recover_by_uuid + + my $release = $release_dao->recover_by_uuid( + uuid => $uuid + ); + +Recovers a L by uuid. + +=head2 create + + $release_dao->create( release => $release ); + +Creates row in the table releases from a +L + +=head1 SEE ALSO + +L diff --git a/lib/Peace/Test/Mock/Model/Application.pm b/lib/Peace/Test/Mock/Model/Application.pm new file mode 100644 index 0000000..d3f9071 --- /dev/null +++ b/lib/Peace/Test/Mock/Model/Application.pm @@ -0,0 +1,55 @@ +package Peace::Test::Mock::Model::Application; + +use v5.30.0; + +use strict; +use warnings; + +use Peace::Model::Application; + +use Peace::Test::Mock::Model::Developer; + +sub new { + my $class = shift; + return Peace::Model::Application->new( + name => 'Desfronificator', + description => 'Desfronifies the files.', + url => 'desfronificator.example.com', + developer => Peace::Test::Mock::Model::Developer->new, + price => 0, + flatpak_builder_file => './resources/com.example.desfronificator.yml', + flatpak_repo => 'https://nightly.gnome.org/gnome-nightly.flatpakrepo', + git_repo => + 'https://git.desfronificator.example.com/larry/desfronificator.git', + verified => 0, + ); +} +1; + +=encoding utf8 + +=head1 NAME + +Peace::Test::Mock::Model::Application - Mock object for L. + +=head1 DESCRIPTION + +Peace::Test::Mock::Model::Application aims to reduce repeated code which +doesn't bring new things to tests by avoiding to add long lines +in order to create a L object on a +unrelated test by providing a stub one already created object. + +=head1 INSTANCE METHODS + +Peace::Test::Mock::Model::Application implements the following instance +methods: + +=head2 new + + my $application = Peace::Test::Mock::Model::Application->new; + +Returns a mock L object. + +=head1 SEE ALSO + +L diff --git a/lib/Peace/Test/Mock/Model/Developer.pm b/lib/Peace/Test/Mock/Model/Developer.pm new file mode 100644 index 0000000..a764adf --- /dev/null +++ b/lib/Peace/Test/Mock/Model/Developer.pm @@ -0,0 +1,52 @@ +package Peace::Test::Mock::Model::Developer; + +use v5.30.1; + +use strict; +use warnings; + +use DBI; + +use Peace::Model::Developer; + +sub new { + my $class = shift; + return Peace::Model::Developer->new( + name => 'Larry', + surname => 'Wall', + secret_bcrypt => 'hola', + email => 'larry@perl.org', + country => 'US', + verified => 0, + dbh => DBI->connect('dbi:Mock:'), + ); +} +1; +=encoding utf8 + +=head1 NAME + +Peace::Test::Mock::Model::Developer - Mock object for L. + +=head1 DESCRIPTION + +Peace::Test::Mock::Model::Developer aims to reduce repeated code which +doesn't bring new things to tests by avoiding to add long lines +in order to create a L object on a +unrelated test by providing a stub one already created object. + +=head1 INSTANCE METHODS + +Peace::Test::Mock::Model::Developer implements the following instance +methods: + +=head2 new + + my $developer = Peace::Test::Mock::Model::Developer->new; + +Returns a mock L object. + + +=head1 SEE ALSO + +L