Bugzilla – Attachment 149546 Details for
Bug 33360
SendQueuedMessages: Improve limit behavior and add domain limits
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 33360: Add Koha::Notice::Util for mail domain limits
Bug-33360-Add-KohaNoticeUtil-for-mail-domain-limit.patch (text/plain), 9.82 KB, created by
Marcel de Rooy
on 2023-04-12 13:45:00 UTC
(
hide
)
Description:
Bug 33360: Add Koha::Notice::Util for mail domain limits
Filename:
MIME Type:
Creator:
Marcel de Rooy
Created:
2023-04-12 13:45:00 UTC
Size:
9.82 KB
patch
obsolete
>From ab4d478894783f3e57c913a2a99f41059c460162 Mon Sep 17 00:00:00 2001 >From: Marcel de Rooy <m.de.rooy@rijksmuseum.nl> >Date: Thu, 30 Mar 2023 14:56:55 +0200 >Subject: [PATCH] Bug 33360: Add Koha::Notice::Util for mail domain limits >Content-Type: text/plain; charset=utf-8 > >Ground work in new module. >Includes unit test. > >Test plan: >Run t/db_dependent/Koha/Notice_Util.t > >Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl> >--- > Koha/Notice/Util.pm | 109 ++++++++++++++++++++++++++++++ > t/db_dependent/Koha/Notice_Util.t | 109 ++++++++++++++++++++++++++++++ > 2 files changed, 218 insertions(+) > create mode 100644 Koha/Notice/Util.pm > create mode 100755 t/db_dependent/Koha/Notice_Util.t > >diff --git a/Koha/Notice/Util.pm b/Koha/Notice/Util.pm >new file mode 100644 >index 0000000000..401a155548 >--- /dev/null >+++ b/Koha/Notice/Util.pm >@@ -0,0 +1,109 @@ >+package Koha::Notice::Util; >+ >+# Copyright Rijksmuseum 2023 >+# >+# 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 <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use Data::Dumper qw/Dumper/; >+ >+use C4::Context; >+use Koha::DateUtils qw/dt_from_string/; >+use Koha::Notice::Messages; >+ >+=head1 NAME >+ >+Koha::Notice::Util - Utility class related to Koha notice messages >+ >+=head1 CLASS METHODS >+ >+=head2 load_domain_limits >+ >+ my $domain_limits = Koha::Notice::Util->load_domain_limits; >+ >+=cut >+ >+sub load_domain_limits { >+ my ( $class ) = @_; >+ >+ my $domain_limits; >+ my $entry = C4::Context->config('message_domain_limits'); >+ if( ref($entry) eq 'HASH' ) { >+ if( exists $entry->{domain} ) { >+ # Turn single hash entry into array >+ $domain_limits = ref($entry->{domain}) eq 'HASH' >+ ? [ $entry->{domain} ] >+ : $entry->{domain}; >+ # Convert to hash structure by domain name >+ $domain_limits = { map { lc $_->{name}, { limit => $_->{limit}, unit => $_->{unit}, count => 0 }} @$domain_limits }; >+ } >+ } >+ return _fill_domain_counts($domain_limits); >+} >+ >+=head2 exceeds_limit >+ >+ my $boolean = Koha::Notice::Util->exceeds_limit( $to_address, $domain_limits ); >+ >+=cut >+ >+sub exceeds_limit { >+ my ( $class, $to_address, $domain_limits ) = @_; >+ return 0 if !$domain_limits; >+ my $domain = q{}; >+ $domain = lc $1 if $to_address && $to_address =~ /@(.*)/; >+ return 0 if !exists $domain_limits->{$domain}; >+ return 1 if $domain_limits->{$domain}->{count} >= $domain_limits->{$domain}->{limit}; >+ $domain_limits->{$domain}->{count}++; >+ warn "Sending messages: domain $domain reached limit of ". >+ $domain_limits->{$domain}->{limit}. '/'. $domain_limits->{$domain}->{unit} >+ if $domain_limits->{$domain}->{count} == $domain_limits->{$domain}->{limit}; >+ return 0; >+} >+ >+=head1 PRIVATE METHODS >+ >+=cut >+ >+sub _fill_domain_counts { >+ my ( $limits ) = @_; >+ return $limits if !$limits; >+ my $dt_parser = Koha::Database->new->schema->storage->datetime_parser; >+ foreach my $domain ( keys %$limits ) { >+ my $start_dt = _convert_unit( undef, $limits->{$domain}->{unit} ); >+ $limits->{$domain}->{count} = Koha::Notice::Messages->search({ >+ message_transport_type => 'email', >+ status => 'sent', >+ to_address => { 'LIKE', '%'.$domain }, >+ updated_on => { '>=', $dt_parser->format_datetime($start_dt) }, # FIXME Would be nice if possible via filter_by_last_update >+ })->count; >+ } >+ return $limits; >+} >+ >+sub _convert_unit { # unit should be like \d+(m|h|d) >+ my ( $dt, $unit ) = @_; >+ $dt //= dt_from_string(); >+ if( $unit && $unit =~ /(\d+)([mhd])/ ) { >+ my $abbrev = { m => 'minutes', h => 'hours', d => 'days' }; >+ foreach my $h ( 0, 1 ) { # try hour before too when subtract fails (like: change to summertime) >+ eval { $dt->subtract( hours => $h )->subtract( $abbrev->{$2} => $1 ) } and last; >+ } >+ } >+ return $dt; >+} >+ >+1; >diff --git a/t/db_dependent/Koha/Notice_Util.t b/t/db_dependent/Koha/Notice_Util.t >new file mode 100755 >index 0000000000..0129fe65c1 >--- /dev/null >+++ b/t/db_dependent/Koha/Notice_Util.t >@@ -0,0 +1,109 @@ >+#!/usr/bin/perl >+ >+# Copyright 2023 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 <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+#use Data::Dumper qw/Dumper/; >+use Test::More tests => 2; >+use Test::MockModule; >+use Test::Warn; >+ >+use C4::Context; >+use Koha::Database; >+use Koha::DateUtils qw/dt_from_string/; >+use Koha::Notice::Util; >+ >+use t::lib::TestBuilder; >+use t::lib::Mocks; >+ >+my $schema = Koha::Database->new->schema; >+$schema->storage->txn_begin; >+ >+my $builder = t::lib::TestBuilder->new; >+ >+subtest 'load_domain_limits' => sub { >+ plan tests => 12; >+ >+ my $domain_limits; >+ t::lib::Mocks::mock_config( 'message_domain_limits', undef ); >+ is( Koha::Notice::Util->load_domain_limits, undef, 'koha-conf does not contain entry' ); >+ t::lib::Mocks::mock_config( 'message_domain_limits', q{} ); >+ is( Koha::Notice::Util->load_domain_limits, undef, 'koha-conf contains blank entry' ); >+ t::lib::Mocks::mock_config( 'message_domain_limits', { domain => { name => 'A', limit => 2, unit => '1d' } } ); >+ $domain_limits = Koha::Notice::Util->load_domain_limits; >+ is( keys %$domain_limits, 1, 'koha-conf contains one domain' ); >+ is( $domain_limits->{a}->{limit}, 2, 'check limit of first entry' ); >+ is( $domain_limits->{a}->{unit}, '1d', 'check unit of first entry' ); >+ t::lib::Mocks::mock_config( 'message_domain_limits', >+ { domain => [ { name => 'A', limit => 2, unit => '2d' }, { name => 'B', limit => 3, unit => '3h' } ] }, >+ ); >+ $domain_limits = Koha::Notice::Util->load_domain_limits; >+ is( keys %$domain_limits, 2, 'koha-conf contains two domains' ); >+ is( $domain_limits->{b}->{limit}, 3, 'check limit of second entry' ); >+ >+ # Check counting >+ my @values = ( message_transport_type => 'email', status => 'sent' ); >+ my $today = dt_from_string(); >+ $builder->build_object({ class => 'Koha::Notice::Messages', >+ value => { @values, to_address => 'a@A', updated_on => $today->clone->subtract( hours => 36 ) }}); >+ $builder->build_object({ class => 'Koha::Notice::Messages', >+ value => { @values, to_address => 'b@A', updated_on => $today->clone->subtract( hours => 49 ) }}); >+ $builder->build_object({ class => 'Koha::Notice::Messages', >+ value => { @values, to_address => 'c@A', updated_on => $today->clone->subtract( days => 3 ) }}); >+ $domain_limits = Koha::Notice::Util->load_domain_limits; >+ is( $domain_limits->{a}->{count}, 1, 'Three messages to A, 1 within unit of 2d' ); >+ t::lib::Mocks::mock_config( 'message_domain_limits', >+ { domain => [ { name => 'A', limit => 2, unit => '50h' }, { name => 'B', limit => 3, unit => '3h' } ] }, >+ ); >+ $domain_limits = Koha::Notice::Util->load_domain_limits; >+ is( $domain_limits->{a}->{count}, 2, 'Three messages to A, 2 within unit of 50h' ); >+ >+ # Date subtraction - edge case (start of summer time) >+ my $mock_context = Test::MockModule->new('C4::Context'); >+ $mock_context->mock( 'tz', sub { return DateTime::TimeZone->new( name => 'Europe/Amsterdam' )} ); >+ my $dt = dt_from_string( '2023-03-31 02:30:00', 'iso', '+02:00' ); >+ is( Koha::Notice::Util::_convert_unit( $dt, '4d')->stringify, '2023-03-27T02:30:00', '02:30 is fine' ); >+ is( Koha::Notice::Util::_convert_unit( $dt, '1d')->stringify, '2023-03-26T01:30:00', 'Moved 02:30 to 01:30' ); >+ # Test bad unit >+ is( Koha::Notice::Util::_convert_unit( $dt, 'y')->stringify, '2023-03-26T01:30:00', 'No further shift for bad unit' ); >+ $mock_context->unmock('tz'); >+}; >+ >+subtest 'exceeds_limit' => sub { >+ plan tests => 6; >+ >+ my $domain_limits; >+ >+ t::lib::Mocks::mock_config( 'message_domain_limits', undef ); >+ $domain_limits = Koha::Notice::Util->load_domain_limits; >+ is( Koha::Notice::Util->exceeds_limit( 'marcel@koha.nl', $domain_limits ), 0, 'False when having no limits' ); >+ >+ t::lib::Mocks::mock_config( 'message_domain_limits', >+ { domain => [ { name => 'A', limit => 0, unit => '1d' }, { name => 'B', limit => 1, unit => '5h' } ] }, >+ ); >+ $domain_limits = Koha::Notice::Util->load_domain_limits; >+ is( Koha::Notice::Util->exceeds_limit( '1@A', $domain_limits ), 1, 'Limit for A already reached' ); >+ my $result; >+ warning_like { $result = Koha::Notice::Util->exceeds_limit( '2@B', $domain_limits ) } >+ qr/Sending messages: domain b reached limit/, 'Check warn for reaching limit'; >+ is( $result, 0, 'Limit for B not yet exceeded' ); >+ is( Koha::Notice::Util->exceeds_limit( '3@B', $domain_limits ), 1, 'Limit for B already reached' ); >+ is( Koha::Notice::Util->exceeds_limit( '4@C', $domain_limits ), 0, 'No limits for C' ); >+}; >+ >+$schema->storage->txn_rollback; >-- >2.30.2
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 33360
:
149256
|
149257
|
149258
|
149546
|
149547
|
149548
|
149549
|
149550
|
149551
|
149552
|
149645
|
149646
|
149647
|
149648
|
149649
|
149650
|
149651
|
149662
|
149663
|
149664
|
149665
|
149666
|
149667
|
149668