From ce025fb187e076bb3b5095c73f6621265b6f8752 Mon Sep 17 00:00:00 2001 From: Tomas Cohen Arazi Date: Mon, 3 Aug 2020 14:23:24 -0300 Subject: [PATCH] Bug 26129: Add Koha::Configuration(s) classes This patch adds the Koha::Configuration(s) classes and tests. It is similar to the Koha::CirculationRules(s) classes, but with simpler use cases for now. There's no special handling for '*' as it is expected to be passed undef instead. It allows to set arbitrary configuration entries either globally or for specific library_id, category_id or item_type. Attribute names match the ones agreed for the API. To test: 1. Apply this patches 2. Run: $ updatedatabase => SUCCESS: The atomic update is applied correctly 3. Run: $ reset_all => SUCCESS: kohastructure.sql is loaded without issues 4. Run: $ kshell k$ prove t/db_dependent/Koha/Configurations.t => SUCCESS: Tests pass! 5. Sign off :-D Sponsored-by: ByWater Solutions --- Koha/Configuration.pm | 90 +++++++++ Koha/Configurations.pm | 255 ++++++++++++++++++++++++ t/db_dependent/Koha/Configurations.t | 283 +++++++++++++++++++++++++++ 3 files changed, 628 insertions(+) create mode 100644 Koha/Configuration.pm create mode 100644 Koha/Configurations.pm create mode 100644 t/db_dependent/Koha/Configurations.t diff --git a/Koha/Configuration.pm b/Koha/Configuration.pm new file mode 100644 index 0000000000..90575e9372 --- /dev/null +++ b/Koha/Configuration.pm @@ -0,0 +1,90 @@ +package Koha::Configuration; + +# Copyright Theke Solutions 2020 +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use base qw(Koha::Object); + +use Koha::Libraries; +use Koha::Patron::Categories; +use Koha::ItemTypes; + +=head1 NAME + +Koha::Configuration - Koha Configuration object class + +=head1 API + +=head2 Class methods + +=cut + +=head3 library + +Returns a Koha::Library object if the configuration entry is tied to a specific library. + +=cut + +sub library { + my ($self) = @_; + + my $library_rs = $self->_result->library; + return unless $library_rs; + return Koha::Library->_new_from_dbic( $library_rs ); +} + +=head3 category + +Returns a Koha::Patron::Category if the configuration entry is tied to a specific category. + +=cut + +sub category { + my ($self) = @_; + + my $category_rs = $self->_result->category; + return unless $category_rs; + return Koha::Patron::Category->_new_from_dbic( $category_rs ); +} + +=head3 item_type + +Returns a Koha::ItemType if the configuration entry is tied to a specific item type. + +=cut + +sub item_type { + my ($self) = @_; + + my $item_type_rs = $self->_result->item_type; + return unless $item_type_rs; + return Koha::ItemType->_new_from_dbic( $item_type_rs ); +} + +=head2 Internal methods + +=head3 _type + +=cut + +sub _type { + return 'Configuration'; +} + +1; diff --git a/Koha/Configurations.pm b/Koha/Configurations.pm new file mode 100644 index 0000000000..b53d8da733 --- /dev/null +++ b/Koha/Configurations.pm @@ -0,0 +1,255 @@ +package Koha::Configurations; + +# Copyright Theke Solutions 2020 +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Koha::Configuration; +use Koha::Exceptions; + +use base qw(Koha::Objects); + +=head1 NAME + +Koha::Configurations - Koha Configuration Object set class + +=head1 API + +=head2 Class methods + +=head3 get_effective_config + + my $config = Koha::Configurations->get_effective_config( + { + name => $name, + library_id => $library_id, + category_id => $category_id, + item_type => $item_type + } + ); + +Get the effective configuration value for I, given the specified parameters. +B means no specific parameter needs to be queried. + +I is mandatory and an exception will be thrownif omitted. + +=cut + +sub get_effective_config { + my ( $self, $params ) = @_; + + my $name = $params->{name}; + Koha::Exceptions::MissingParameter->throw( + "Required parameter 'name' missing") + unless $name; + + $params->{category_id} //= undef; + $params->{library_id} //= undef; + $params->{item_type} //= undef; + + my $category_id = $params->{category_id}; + my $item_type = $params->{item_type}; + my $library_id = $params->{library_id}; + + my $order_by = $params->{order_by} + // { -desc => [ 'library_id', 'category_id', 'item_type' ] }; + + my $search_params; + $search_params->{name} = $name; + + $search_params->{category_id} = + defined $category_id ? [ $category_id, undef ] : undef; + $search_params->{item_type} = + defined $item_type ? [ $item_type, undef ] : undef; + $search_params->{library_id} = + defined $library_id ? [ $library_id, undef ] : undef; + + my $config = $self->search( + $search_params, + { + order_by => $order_by, + rows => 1, + } + )->single; + + return $config; +} + +=head3 get_effective_configs + + my $configs = Koha::Configurations->get_effective_configs( + { + names => [ + 'smtp_host', + 'smtp_port', + 'smtp_ssl' + ], + library_id => $library_id, + category_id => $category_id, + item_type => $item_type + } + ); + +Get the effective configuration values for the specified I, given the specified +parameters. B means no specific parameter needs to be queried. + +=cut + +sub get_effective_configs { + my ( $self, $params ) = @_; + + my $names = $params->{names}; + my $category_id = $params->{category_id}; + my $item_type = $params->{item_type}; + my $library_id = $params->{library_id}; + + my $configs; + foreach my $name (@$names) { + my $effective_conf = $self->get_effective_conf( + { + name => $name, + category_id => $category_id, + item_type => $item_type, + library_id => $library_id, + } + ); + + $configs->{$name} = $effective_conf->get_value if $effective_conf; + } + + return $configs; +} + +=head3 set_config + + my $config = Koha::Configurations->set_config( + { + name => $name, + library_id => $library_id, + category_id => $category_id, + item_type => $item_type, + type => $config_entry_type + } + ); + +Sets the configuration value for I, given the specified parameters. +B means no specific parameter needs to be queried. + +I and I are mandatory and an exception will be thrownif omitted. + +B can currently take the following values: +- text +- boolean +- integer + +=cut + +sub set_config { + my ( $self, $params ) = @_; + + for my $mandatory_parameter (qw( name value )) { + Koha::Exceptions::MissingParameter->throw( + "Required parameter '$mandatory_parameter' missing") + unless exists $params->{$mandatory_parameter}; + } + + my $library_id = $params->{library_id}; + my $category_id = $params->{category_id}; + my $item_type = $params->{item_type}; + my $name = $params->{name}; + my $value = $params->{value}; + my $type = $params->{type}; + + my $config = $self->search( + { + name => $name, + library_id => $library_id, + category_id => $category_id, + item_type => $item_type, + } + )->next(); + + if ($config) { + $config->set( { value => $value } )->store; + } + else { + $config = Koha::Configuration->new( + { + library_id => $library_id, + category_id => $category_id, + item_type => $item_type, + name => $name, + value => $value, + type => $type + } + )->store; + } + + return $config; +} + +=head3 set_configs + +=cut + +sub set_configs { + my ( $self, $params ) = @_; + + my %set_params; + $set_params{library_id} = $params->{library_id} + if exists $params->{library_id}; + $set_params{category_id} = $params->{category_id} + if exists $params->{category_id}; + $set_params{item_type} = $params->{item_type} + if exists $params->{item_type}; + my $configs = $params->{configs}; + + my $config_objects = []; + while ( my ( $rule_name, $rule_value ) = each %$configs ) { + my $config_object = Koha::Configurations->set_config( + { + %set_params, + name => $rule_name, + value => $rule_value, + } + ); + push( @$config_objects, $config_object ); + } + + return $config_objects; +} + +=head2 Internal methods + +=head3 _type + +=cut + +sub _type { + return 'Configuration'; +} + +=head3 object_class + +=cut + +sub object_class { + return 'Koha::Configuration'; +} + +1; diff --git a/t/db_dependent/Koha/Configurations.t b/t/db_dependent/Koha/Configurations.t new file mode 100644 index 0000000000..cefac904b9 --- /dev/null +++ b/t/db_dependent/Koha/Configurations.t @@ -0,0 +1,283 @@ +#!/usr/bin/perl + +# Copyright 2020 Koha Development team +# +# This file is part of Koha +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Test::More tests => 1; +use Test::Exception; + +use Koha::Configurations; +use Koha::Database; + +use t::lib::TestBuilder; +use t::lib::Mocks; + +my $schema = Koha::Database->new->schema; +my $builder = t::lib::TestBuilder->new; + +subtest 'set_config + get_effective_config' => sub { + + plan tests => 17; + + $schema->storage->txn_begin; + + my $category_id = $builder->build_object( { class => 'Koha::Patron::Categories' } )->categorycode; + my $item_type = $builder->build_object( { class => 'Koha::ItemTypes' } )->itemtype; + my $library_id = $builder->build_object( { class => 'Koha::Libraries' } )->branchcode; + my $library_id_2 = $builder->build_object( { class => 'Koha::Libraries' } )->branchcode; + + my $name = 'smtp_server'; + my $default_value = 'localhost'; + + my $server_1 = 'smtp.demo1.edu'; + my $server_2 = 'smtp.demo2.edu'; + my $server_3 = 'smtp.demo3.edu'; + my $server_4 = 'smtp.demo4.edu'; + my $server_5 = 'smtp.demo5.edu'; + my $server_6 = 'smtp.demo6.edu'; + my $server_7 = 'smtp.demo7.edu'; + + my $config; + + Koha::Configurations->delete; + + throws_ok { Koha::Configurations->get_effective_config } + 'Koha::Exceptions::MissingParameter', + "Exception should be raised if get_effective_config is called without name parameter"; + + $config = Koha::Configurations->get_effective_config( + { + library_id => $library_id, + category_id => $category_id, + item_type => $item_type, + name => $name, + } + ); + is( $config, undef, 'Undef should be returned if no rule exist' ); + + # Set a default value + Koha::Configurations->set_config( + { + library_id => undef, + category_id => undef, + item_type => undef, + name => $name, + value => $default_value, + } + ); + + $config = Koha::Configurations->get_effective_config( + { + library_id => undef, + category_id => undef, + item_type => undef, + name => $name, + } + ); + is( $config->value, $default_value, 'undef means default' ); + + Koha::Configurations->set_config( + { + library_id => undef, + category_id => undef, + item_type => $item_type, + name => $name, + value => $server_1, + } + ); + + $config = Koha::Configurations->get_effective_config( + { + library_id => $library_id, + category_id => $category_id, + item_type => $item_type, + name => $name, + } + ); + is( $config->value, $server_1, + 'More specific rule is returned when item_type is given' ); + + $config = Koha::Configurations->get_effective_config( + { + library_id => $library_id_2, + category_id => undef, + item_type => undef, + name => $name, + } + ); + is( $config->value, $default_value, + 'Default rule is returned if there is no rule for this library_id' ); + + Koha::Configurations->set_config( + { + library_id => undef, + category_id => $category_id, + item_type => undef, + name => $name, + value => $server_2, + } + ); + + $config = Koha::Configurations->get_effective_config( + { + + library_id => $library_id, + category_id => $category_id, + item_type => $item_type, + name => $name, + } + ); + is( $config->value, $server_2, + 'More specific rule is returned when category_id exists' ); + + Koha::Configurations->set_config( + { + library_id => undef, + category_id => $category_id, + item_type => $item_type, + name => $name, + value => $server_3, + } + ); + $config = Koha::Configurations->get_effective_config( + { + library_id => $library_id, + category_id => $category_id, + item_type => $item_type, + name => $name, + } + ); + is( $config->value, $server_3, + 'More specific rule is returned when category_id and item_type exist' ); + + Koha::Configurations->set_config( + { + library_id => $library_id, + category_id => undef, + item_type => undef, + name => $name, + value => $server_4, + } + ); + $config = Koha::Configurations->get_effective_config( + { + library_id => $library_id, + category_id => $category_id, + item_type => $item_type, + name => $name, + } + ); + is( $config->value, $server_4, + 'More specific rule is returned when library_id exists' ); + + Koha::Configurations->set_config( + { + library_id => $library_id, + category_id => undef, + item_type => $item_type, + name => $name, + value => $server_5, + } + ); + $config = Koha::Configurations->get_effective_config( + { + library_id => $library_id, + category_id => $category_id, + item_type => $item_type, + name => $name, + } + ); + is( $config->value, $server_5, + 'More specific rule is returned when library_id and item_type exists' ); + + Koha::Configurations->set_config( + { + library_id => $library_id, + category_id => $category_id, + item_type => undef, + name => $name, + value => $server_6, + } + ); + $config = Koha::Configurations->get_effective_config( + { + library_id => $library_id, + category_id => $category_id, + item_type => $item_type, + name => $name, + } + ); + is( $config->value, $server_6, + 'More specific rule is returned when library_id and category_id exist' + ); + + Koha::Configurations->set_config( + { + library_id => $library_id, + category_id => $category_id, + item_type => $item_type, + name => $name, + value => $server_7, + } + ); + $config = Koha::Configurations->get_effective_config( + { + library_id => $library_id, + category_id => $category_id, + item_type => $item_type, + name => $name, + } + ); + is( $config->value, $server_7, + 'More specific rule is returned when library_id, category_id and item_type exist' + ); + + my $library_configs = Koha::Configurations->search({ library_id => $library_id }); + is( $library_configs->count, 4, "We added 8 rules"); + $library_configs->delete; + is( $library_configs->count, 0, "We deleted 8 rules"); + + throws_ok { + Koha::Configurations->set_config( + { + library_id => $library_id, + category_id => $category_id, + item_type => $item_type, + value => $server_7, + } + ); + } 'Koha::Exceptions::MissingParameter', 'Exceptions thrown on missing parameter'; + + is( "$@", "Required parameter 'name' missing", "Expected exception message" ); + + throws_ok { + Koha::Configurations->set_config( + { + library_id => $library_id, + category_id => $category_id, + item_type => $item_type, + name => $name, + } + ); + } 'Koha::Exceptions::MissingParameter', 'Exceptions thrown on missing parameter'; + + is( "$@", "Required parameter 'value' missing", "Expected exception message" ); + + $schema->storage->txn_rollback; +}; -- 2.28.0