From d44966e092fd0796ae305d66c69436f69e2cc6ce Mon Sep 17 00:00:00 2001
From: Lari Taskula <lari.taskula@jns.fi>
Date: Fri, 21 Oct 2016 17:26:24 +0300
Subject: [PATCH] Bug 17499: Add Koha-objects for messaging preferences
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Content-Type: text/plain; charset=utf-8
This patch adds Koha-objects for messaging preferences. This patch does not
add any extra logic into these objects.
Includes test coverage for basic usage.
To test:
1. prove t/db_dependent/Koha/Patron/Message/*
Signed-off-by: Marc Véron <veron@veron.ch>
Signed-off-by: Josef Moravec <josef.moravec@gmail.com>
Bug 17499: Add useful Koha::Exceptions
This patch adds some basic Koha::Exceptions that will be useful.
Signed-off-by: Marc Véron <veron@veron.ch>
Signed-off-by: Josef Moravec <josef.moravec@gmail.com>
Bug 17499: Add basic validation for messaging preference
This patch adds simple validation for messaging preferences.
The validation includes
- check that only either borrowernumber or categorycode is given, but not both
- throw exception if patron for the given borrowernumber is not found
- throw exception if category for the given categorycode is not found
- throw exception if days in advance cannot be configured
- throw exception if days in advance configuration is invalid (value between 0-30)
- throw exception if digest is not available
To test:
1. Run t/db_dependent/Koha/Patron/Message/Preferences.t
Signed-off-by: Marc Véron <veron@veron.ch>
Signed-off-by: Josef Moravec <josef.moravec@gmail.com>
Bug 17499: Throw an exception on duplicate messaging preference
When trying to add a duplicate messaging preference that has the same
borrowernumber or category, and message_attribute_id as another preference,
throw Koha::Exceptions::DuplicateObject.
To test:
1. Run t/db_dependent/Koha/Patron/Message/Preferences.t
Signed-off-by: Marc Véron <veron@veron.ch>
Signed-off-by: Josef Moravec <josef.moravec@gmail.com>
Bug 17499: Add a method for getting messaging options
This patch adds a method for getting available messaging options.
To test:
1. Run t/db_dependent/Koha/Patron/Message/Preferences.t
Signed-off-by: Marc Véron <veron@veron.ch>
Signed-off-by: Josef Moravec <josef.moravec@gmail.com>
Bug 17499: Add a method for setting default messaging preferences
This patch adds a method Koha::Patron::Message::Preference->new_from_default that
can be used to add category's default messaging preferences to patron for a given
message type.
Example call:
Koha::Patron::Message::Preference->new_from_default({
borrowernumber => 123,
categorycode => "ABC",
message_attribute_id => 1,
});
Also adds a simple method for Koha::Patron, set_default_messaging_preferences.
Usage: $patron->set_default_messaging_preferences()
To test:
1. Run t/db_dependent/Koha/Patron/Message/Preferences.t
Signed-off-by: Marc Véron <veron@veron.ch>
Signed-off-by: Josef Moravec <josef.moravec@gmail.com>
Bug 17499: Improve object usability by enabling direct access to transport preferences
Since messaging preference is a feature that has multiple related database tables,
usage via Koha-objects is sometimes frustrating.
This patch adds a feature for Koha::Patron::Message::Preference which enables
access to message transport preferences directly via this object. It allows us
to skip calls to Koha::Patron::Message::Transport::Preference(s) because we can
now get and set via K::P::M::Preference.
Get:
$preference->message_transport_types
Returns a hashref, where each key is stored transport type and value for the key
is letter code for the transport.
Set:
$preference->set({ message_transport_types => ['sms'] }) or
$preference->message_transport_types('email', 'sms') or
$preference->message_transport_types(['email', 'sms'])
Returns $self (Koha::Patron::Message::Preference object)
To test:
1. Run t/db_dependent/Koha/Patron/Message/Preferences.t
Signed-off-by: Marc Véron <veron@veron.ch>
Signed-off-by: Josef Moravec <josef.moravec@gmail.com>
Bug 17499: Simplify searching by message_name
This patch adds optional search & find parameter message_name for
Koha::Patron::Message::Preferences->search and ->find. This simplifies object
usage by allowing us to skip joins or finding the attribute id ourselves.
prove -v t/db_dependent/Koha/Patron/Message/Preferences.t turns green
Signed-off-by: Marc Véron <veron@veron.ch>
Signed-off-by: Josef Moravec <josef.moravec@gmail.com>
Bug 17499: (follow-up) Bugfix for validation
- Bugfix for days_in_advance and wants_digest validation. Have to check definedness
of value instead the value itself.
- Fixes broken tests caused by above update.
- Adding a missing unit test for wants_digest validation
- Minor edits to exception messages.
- Throwing exception for invalid message_attribute_id. Incl. unit test
Tested again, prove -v t/db_dependent/Koha/Patron/Message/Preferences.t turns green
prove -v t/db_dependent/Koha/Patron/Message/* turns green
Signed-off-by: Marc Véron <veron@veron.ch>
Signed-off-by: Josef Moravec <josef.moravec@gmail.com>
Bug 17499: (follow-up) Bugfix for validation, 2
Remove duplicate validation for digest availability. This is already checked in
$preference->validate().
Set values for current object before validating messaging transport types, not
the other way around as it was before this patch.
Also prevents a crash when patron has messaging transport type selected for
a message for which it should not be available. This patch logs it with as
a warning, and only throws an exception when attempting to set it.
To test:
1. prove t/db_dependent/Koha/Patron/Message/*
Signed-off-by: Josef Moravec <josef.moravec@gmail.com>
Bug 17499: (follow-up) Add information on digest being the only option to get_options
If a library wants to force digest on a message type, add this information to
Koha::Patron::Message::Preferences->get_options.
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Squashed 11 commits during QA.
---
Koha/Exceptions.pm | 18 +-
Koha/Patron.pm | 35 +
Koha/Patron/Message/Attribute.pm | 50 ++
Koha/Patron/Message/Attributes.pm | 55 ++
Koha/Patron/Message/Preference.pm | 450 +++++++++++++
Koha/Patron/Message/Preferences.pm | 146 +++++
Koha/Patron/Message/Transport.pm | 50 ++
Koha/Patron/Message/Transport/Preference.pm | 51 ++
Koha/Patron/Message/Transport/Preferences.pm | 56 ++
Koha/Patron/Message/Transport/Type.pm | 51 ++
Koha/Patron/Message/Transport/Types.pm | 56 ++
Koha/Patron/Message/Transports.pm | 55 ++
t/db_dependent/Koha/Patron/Message/Attributes.t | 74 +++
t/db_dependent/Koha/Patron/Message/Preferences.t | 704 +++++++++++++++++++++
.../Koha/Patron/Message/Transport/Preferences.t | 179 ++++++
.../Koha/Patron/Message/Transport/Types.t | 54 ++
t/db_dependent/Koha/Patron/Message/Transports.t | 119 ++++
17 files changed, 2202 insertions(+), 1 deletion(-)
create mode 100644 Koha/Patron/Message/Attribute.pm
create mode 100644 Koha/Patron/Message/Attributes.pm
create mode 100644 Koha/Patron/Message/Preference.pm
create mode 100644 Koha/Patron/Message/Preferences.pm
create mode 100644 Koha/Patron/Message/Transport.pm
create mode 100644 Koha/Patron/Message/Transport/Preference.pm
create mode 100644 Koha/Patron/Message/Transport/Preferences.pm
create mode 100644 Koha/Patron/Message/Transport/Type.pm
create mode 100644 Koha/Patron/Message/Transport/Types.pm
create mode 100644 Koha/Patron/Message/Transports.pm
create mode 100644 t/db_dependent/Koha/Patron/Message/Attributes.t
create mode 100644 t/db_dependent/Koha/Patron/Message/Preferences.t
create mode 100644 t/db_dependent/Koha/Patron/Message/Transport/Preferences.t
create mode 100644 t/db_dependent/Koha/Patron/Message/Transport/Types.t
create mode 100644 t/db_dependent/Koha/Patron/Message/Transports.t
diff --git a/Koha/Exceptions.pm b/Koha/Exceptions.pm
index 60b9e6a..793aafa 100644
--- a/Koha/Exceptions.pm
+++ b/Koha/Exceptions.pm
@@ -8,6 +8,12 @@ use Exception::Class (
'Koha::Exceptions::Exception' => {
description => 'Something went wrong!',
},
+
+ 'Koha::Exceptions::BadParameter' => {
+ isa => 'Koha::Exceptions::Exception',
+ description => 'Bad given parameter',
+ fields => ['parameter'],
+ },
'Koha::Exceptions::DuplicateObject' => {
isa => 'Koha::Exceptions::Exception',
description => 'Same object already exists',
@@ -22,7 +28,13 @@ use Exception::Class (
},
'Koha::Exceptions::MissingParameter' => {
isa => 'Koha::Exceptions::Exception',
- description => 'A required parameter is missing'
+ description => 'A required parameter is missing',
+ fields => ['parameter'],
+ },
+ 'Koha::Exceptions::TooManyParameters' => {
+ isa => 'Koha::Exceptions::Exception',
+ description => 'Too many parameters given',
+ fields => ['parameter'],
},
'Koha::Exceptions::WrongParameter' => {
isa => 'Koha::Exceptions::Exception',
@@ -32,6 +44,10 @@ use Exception::Class (
isa => 'Koha::Exceptions::Exception',
description => 'General problem adding a library limit'
},
+ 'Koha::Exceptions::UnknownObject' => {
+ isa => 'Koha::Exceptions::Exception',
+ description => 'Object cannot be found or is not known',
+ },
# Virtualshelves exceptions
'Koha::Exceptions::Virtualshelves::DuplicateObject' => {
isa => 'Koha::Exceptions::DuplicateObject',
diff --git a/Koha/Patron.pm b/Koha/Patron.pm
index f7970ea..9b2f11a 100644
--- a/Koha/Patron.pm
+++ b/Koha/Patron.pm
@@ -33,6 +33,7 @@ use Koha::Patron::Categories;
use Koha::Patron::HouseboundProfile;
use Koha::Patron::HouseboundRole;
use Koha::Patron::Images;
+use Koha::Patron::Message::Preferences;
use Koha::Patrons;
use Koha::Virtualshelves;
use Koha::Club::Enrollments;
@@ -654,6 +655,40 @@ sub account_locked {
and $self->login_attempts >= $FailedLoginAttempts )? 1 : 0;
}
+=head3 set_default_messaging_preferences
+
+ $patron->set_default_messaging_preferences
+
+Sets default messaging preferences on patron.
+
+See Koha::Patron::Message::Preference(s) for more documentation, especially on
+thrown exceptions.
+
+=cut
+
+sub set_default_messaging_preferences {
+ my ($self, $categorycode) = @_;
+
+ my $options = Koha::Patron::Message::Preferences->get_options;
+
+ foreach my $option (@$options) {
+ # Check that this option has preference configuration for this category
+ unless (Koha::Patron::Message::Preferences->search({
+ message_attribute_id => $option->{message_attribute_id},
+ categorycode => $categorycode || $self->categorycode,
+ })->count) {
+ next;
+ }
+ Koha::Patron::Message::Preference->new_from_default({
+ borrowernumber => $self->borrowernumber,
+ categorycode => $categorycode || $self->categorycode,
+ message_attribute_id => $option->{message_attribute_id},
+ })->store;
+ }
+
+ return $self;
+}
+
=head3 type
=cut
diff --git a/Koha/Patron/Message/Attribute.pm b/Koha/Patron/Message/Attribute.pm
new file mode 100644
index 0000000..9d9004c
--- /dev/null
+++ b/Koha/Patron/Message/Attribute.pm
@@ -0,0 +1,50 @@
+package Koha::Patron::Message::Attribute;
+
+# Copyright Koha-Suomi Oy 2016
+#
+# 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.a
+#
+# 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, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use Koha::Database;
+
+use base qw(Koha::Object);
+
+=head1 NAME
+
+Koha::Patron::Message::Attribute - Koha Patron Message Attribute object class
+
+=head1 API
+
+=head2 Class Methods
+
+=cut
+
+=head3 type
+
+=cut
+
+sub _type {
+ return 'MessageAttribute';
+}
+
+=head1 AUTHOR
+
+Lari Taskula <lari.taskula@jns.fi>
+
+=cut
+
+1;
diff --git a/Koha/Patron/Message/Attributes.pm b/Koha/Patron/Message/Attributes.pm
new file mode 100644
index 0000000..a2df4e6
--- /dev/null
+++ b/Koha/Patron/Message/Attributes.pm
@@ -0,0 +1,55 @@
+package Koha::Patron::Message::Attributes;
+
+# Copyright Koha-Suomi Oy 2016
+#
+# 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, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use Koha::Database;
+use Koha::Patron::Message::Attribute;
+
+use base qw(Koha::Objects);
+
+=head1 NAME
+
+Koha::Patron::Message::Attributes - Koha Patron Message Attributes object class
+
+=head1 API
+
+=head2 Class Methods
+
+=cut
+
+=head3 type
+
+=cut
+
+sub _type {
+ return 'MessageAttribute';
+}
+
+sub object_class {
+ return 'Koha::Patron::Message::Attribute';
+}
+
+=head1 AUTHOR
+
+Lari Taskula <lari.taskula@jns.fi>
+
+=cut
+
+1;
diff --git a/Koha/Patron/Message/Preference.pm b/Koha/Patron/Message/Preference.pm
new file mode 100644
index 0000000..6fb7fb8
--- /dev/null
+++ b/Koha/Patron/Message/Preference.pm
@@ -0,0 +1,450 @@
+package Koha::Patron::Message::Preference;
+
+# Copyright Koha-Suomi Oy 2016
+#
+# 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.a
+#
+# 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, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use Koha::Database;
+use Koha::Exceptions;
+use Koha::Patron::Categories;
+use Koha::Patron::Message::Attributes;
+use Koha::Patron::Message::Preferences;
+use Koha::Patron::Message::Transport::Preferences;
+use Koha::Patron::Message::Transport::Types;
+use Koha::Patron::Message::Transports;
+use Koha::Patrons;
+
+use base qw(Koha::Object);
+
+=head1 NAME
+
+Koha::Patron::Message::Preference - Koha Patron Message Preference object class
+
+=head1 API
+
+=head2 Class Methods
+
+=cut
+
+=head3 new
+
+my $preference = Koha::Patron::Message::Preference->new({
+ borrowernumber => 123,
+ #categorycode => 'ABC',
+ message_attribute_id => 4,
+ message_transport_types => ['email', 'sms'], # see documentation below
+ wants_digest => 1,
+ days_in_advance => 7,
+});
+
+Takes either borrowernumber or categorycode, but not both.
+
+days_in_advance may not be available. See message_attributes table for takes_days
+configuration.
+
+wants_digest may not be available. See message_transports table for is_digest
+configuration.
+
+You can instantiate a new object without custom validation errors, but when
+storing, validation may throw exceptions. See C<validate()> for more
+documentation.
+
+C<message_transport_types> is a parameter that is not actually a column in this
+Koha-object. Given this parameter, the message transport types will be added as
+related transport types for this object. For get and set, you can access them via
+subroutine C<message_transport_types()> in this class.
+
+=cut
+
+sub new {
+ my ($class, $params) = @_;
+
+ my $types = $params->{'message_transport_types'};
+ delete $params->{'message_transport_types'};
+
+ my $self = $class->SUPER::new($params);
+
+ $self->_set_message_transport_types($types);
+
+ return $self;
+}
+
+=head3 new_from_default
+
+my $preference = Koha::Patron::Message::Preference->new_from_default({
+ borrowernumber => 123,
+ categorycode => 'ABC', # if not given, patron's categorycode will be used
+ message_attribute_id => 1,
+});
+
+NOTE: This subroutine initializes and STORES the object (in order to set
+message transport types for the preference), so no need to call ->store when
+preferences are initialized via this method.
+
+Stores default messaging preference for C<categorycode> to patron for given
+C<message_attribute_id>.
+
+Throws Koha::Exceptions::MissingParameter if any of following is missing:
+- borrowernumber
+- message_attribute_id
+
+Throws Koha::Exceptions::UnknownObject if default preferences are not found.
+
+=cut
+
+sub new_from_default {
+ my ($class, $params) = @_;
+
+ my @required = qw(borrowernumber message_attribute_id);
+ foreach my $p (@required) {
+ Koha::Exceptions::MissingParameter->throw(
+ error => 'Missing required parameter.',
+ parameter => $p,
+ ) unless exists $params->{$p};
+ }
+ unless ($params->{'categorycode'}) {
+ my $patron = Koha::Patrons->find($params->{borrowernumber});
+ $params->{'categorycode'} = $patron->categorycode;
+ }
+
+ my $default = Koha::Patron::Message::Preferences->find({
+ categorycode => $params->{'categorycode'},
+ message_attribute_id => $params->{'message_attribute_id'},
+ });
+ Koha::Exceptions::UnknownObject->throw(
+ error => 'Default messaging preference for given categorycode and'
+ .' message_attribute_id cannot be found.',
+ ) unless $default;
+ $default = $default->unblessed;
+
+ # Add a new messaging preference for patron
+ my $self = $class->SUPER::new({
+ borrowernumber => $params->{'borrowernumber'},
+ message_attribute_id => $default->{'message_attribute_id'},
+ days_in_advance => $default->{'days_in_advance'},
+ wants_digest => $default->{'wants_digest'},
+ })->store;
+
+ # Set default messaging transport types
+ my $default_transport_types =
+ Koha::Patron::Message::Transport::Preferences->search({
+ borrower_message_preference_id =>
+ $default->{'borrower_message_preference_id'}
+ });
+ while (my $transport = $default_transport_types->next) {
+ Koha::Patron::Message::Transport::Preference->new({
+ borrower_message_preference_id => $self->borrower_message_preference_id,
+ message_transport_type => $transport->message_transport_type,
+ })->store;
+ }
+
+ return $self;
+}
+
+=head3 message_name
+
+$preference->message_name
+
+Gets message_name for this messaging preference.
+
+Setter not implemented.
+
+=cut
+
+sub message_name {
+ my ($self) = @_;
+
+ if ($self->{'_message_name'}) {
+ return $self->{'_message_name'};
+ }
+ $self->{'_message_name'} = Koha::Patron::Message::Attributes->find({
+ message_attribute_id => $self->message_attribute_id,
+ })->message_name;
+ return $self->{'_message_name'};
+}
+
+=head3 message_transport_types
+
+$preference->message_transport_types
+Returns a HASHREF of message transport types for this messaging preference, e.g.
+if ($preference->message_transport_types->{'email'}) {
+ # email is one of the transport preferences
+}
+
+$preference->message_transport_types('email', 'sms');
+Sets the given message transport types for this messaging preference
+
+=cut
+
+sub message_transport_types {
+ my $self = shift;
+
+ unless (@_) {
+ if ($self->{'_message_transport_types'}) {
+ return $self->{'_message_transport_types'};
+ }
+ map {
+ my $transport = Koha::Patron::Message::Transports->find({
+ message_attribute_id => $self->message_attribute_id,
+ message_transport_type => $_->message_transport_type,
+ is_digest => $self->wants_digest
+ });
+ unless ($transport) {
+ my $logger = Koha::Logger->get;
+ $logger->warn(
+ $self->message_name . ' has no transport with '.
+ $_->message_transport_type . ' (digest: '.
+ ($self->wants_digest ? 'yes':'no').').'
+ );
+ }
+ $self->{'_message_transport_types'}->{$_->message_transport_type}
+ = $transport ? $transport->letter_code : ' ';
+ }
+ Koha::Patron::Message::Transport::Preferences->search({
+ borrower_message_preference_id => $self->borrower_message_preference_id,
+ })->as_list;
+ return $self->{'_message_transport_types'} || {};
+ }
+ else {
+ $self->_set_message_transport_types(@_);
+ return $self;
+ }
+}
+
+=head3 set
+
+$preference->set({
+ message_transport_types => ['sms', 'phone'],
+ wants_digest => 0,
+})->store;
+
+Sets preference object values and additionally message_transport_types if given.
+
+=cut
+
+sub set {
+ my ($self, $params) = @_;
+
+ my $mtt = $params->{'message_transport_types'};
+ delete $params->{'message_transport_types'};
+
+ $self->SUPER::set($params) if $params;
+ if ($mtt) {
+ $self->message_transport_types($mtt);
+ }
+
+ return $self;
+}
+
+=head3 store
+
+Makes a validation before actual Koha::Object->store so that proper exceptions
+can be thrown. See C<validate()> for documentation about exceptions.
+
+=cut
+
+sub store {
+ my $self = shift;
+
+ $self->validate->SUPER::store(@_);
+
+ # store message transport types
+ if (exists $self->{'_message_transport_types'}) {
+ Koha::Patron::Message::Transport::Preferences->search({
+ borrower_message_preference_id =>
+ $self->borrower_message_preference_id,
+ })->delete;
+ foreach my $type (keys %{$self->{'_message_transport_types'}}) {
+ Koha::Patron::Message::Transport::Preference->new({
+ borrower_message_preference_id =>
+ $self->borrower_message_preference_id,
+ message_transport_type => $type,
+ })->store;
+ }
+ }
+
+ return $self;
+}
+
+=head3 validate
+
+Makes a basic validation for object.
+
+Throws following exceptions regarding parameters.
+- Koha::Exceptions::MissingParameter
+- Koha::Exceptions::TooManyParameters
+- Koha::Exceptions::BadParameter
+
+See $_->parameter to identify the parameter causing the exception.
+
+Throws Koha::Exceptions::DuplicateObject if this preference already exists.
+
+Returns Koha::Patron::Message::Preference object.
+
+=cut
+
+sub validate {
+ my ($self) = @_;
+
+ if ($self->borrowernumber && $self->categorycode) {
+ Koha::Exceptions::TooManyParameters->throw(
+ error => 'Both borrowernumber and category given, only one accepted',
+ parameter => ['borrowernumber', 'categorycode'],
+ );
+ }
+ if (!$self->borrowernumber && !$self->categorycode) {
+ Koha::Exceptions::MissingParameter->throw(
+ error => 'borrowernumber or category required, none given',
+ parameter => ['borrowernumber', 'categorycode'],
+ );
+ }
+ if ($self->borrowernumber) {
+ Koha::Exceptions::BadParameter->throw(
+ error => 'Patron not found.',
+ parameter => 'borrowernumber',
+ ) unless Koha::Patrons->find($self->borrowernumber);
+ }
+ if ($self->categorycode) {
+ Koha::Exceptions::BadParameter->throw(
+ error => 'Category not found.',
+ parameter => 'categorycode',
+ ) unless Koha::Patron::Categories->find($self->categorycode);
+ }
+
+ if (!$self->in_storage) {
+ my $previous = Koha::Patron::Message::Preferences->search({
+ borrowernumber => $self->borrowernumber,
+ categorycode => $self->categorycode,
+ message_attribute_id => $self->message_attribute_id,
+ });
+ if ($previous->count) {
+ Koha::Exceptions::DuplicateObject->throw(
+ error => 'A preference for this borrower/category and'
+ .' message_attribute_id already exists',
+ );
+ }
+ }
+
+ my $attr = Koha::Patron::Message::Attributes->find(
+ $self->message_attribute_id
+ );
+ unless ($attr) {
+ Koha::Exceptions::BadParameter->throw(
+ error => 'Message attribute with id '.$self->message_attribute_id
+ .' not found',
+ parameter => 'message_attribute_id'
+ );
+ }
+ if (defined $self->days_in_advance) {
+ if ($attr && $attr->takes_days == 0) {
+ Koha::Exceptions::BadParameter->throw(
+ error => 'days_in_advance cannot be defined for '.
+ $attr->message_name . '.',
+ parameter => 'days_in_advance',
+ );
+ }
+ elsif ($self->days_in_advance < 0 || $self->days_in_advance > 30) {
+ Koha::Exceptions::BadParameter->throw(
+ error => 'days_in_advance has to be a value between 0-30 for '.
+ $attr->message_name . '.',
+ parameter => 'days_in_advance',
+ );
+ }
+ }
+ if (defined $self->wants_digest) {
+ my $transports = Koha::Patron::Message::Transports->search({
+ message_attribute_id => $self->message_attribute_id,
+ is_digest => $self->wants_digest ? 1 : 0,
+ });
+ Koha::Exceptions::BadParameter->throw(
+ error => (!$self->wants_digest ? 'No d' : 'D').'igest not available '.
+ 'for '.$attr->message_name.'.',
+ parameter => 'wants_digest',
+ ) if $transports->count == 0;
+ }
+
+ return $self;
+}
+
+sub _set_message_transport_types {
+ my $self = shift;
+
+ return unless $_[0];
+
+ $self->{'_message_transport_types'} = undef;
+ my $types = ref $_[0] eq "ARRAY" ? $_[0] : [@_];
+ return unless $types;
+ $self->_validate_message_transport_types({ message_transport_types => $types });
+ foreach my $type (@$types) {
+ unless (exists $self->{'_message_transport_types'}->{$type}) {
+ my $transport = Koha::Patron::Message::Transports->find({
+ message_attribute_id => $self->message_attribute_id,
+ message_transport_type => $type
+ });
+ unless ($transport) {
+ Koha::Exceptions::BadParameter->throw(
+ error => 'No transport configured for '.$self->message_name.
+ " transport type $type.",
+ parameter => 'message_transport_types'
+ );
+ }
+ $self->{'_message_transport_types'}->{$type}
+ = $transport->letter_code;
+ }
+ }
+ return $self;
+}
+
+sub _validate_message_transport_types {
+ my ($self, $params) = @_;
+
+ if (ref($params) eq 'HASH' && $params->{'message_transport_types'}) {
+ if (ref($params->{'message_transport_types'}) ne 'ARRAY') {
+ $params->{'message_transport_types'} = [$params->{'message_transport_types'}];
+ }
+ my $types = $params->{'message_transport_types'};
+
+ foreach my $type (@{$types}) {
+ unless (Koha::Patron::Message::Transport::Types->find({
+ message_transport_type => $type
+ })) {
+ Koha::Exceptions::BadParameter->throw(
+ error => "Message transport type '$type' does not exist",
+ parameter => 'message_transport_types',
+ );
+ }
+ }
+ return $types;
+ }
+}
+
+=head3 type
+
+=cut
+
+sub _type {
+ return 'BorrowerMessagePreference';
+}
+
+=head1 AUTHOR
+
+Lari Taskula <lari.taskula@jns.fi>
+
+=cut
+
+1;
diff --git a/Koha/Patron/Message/Preferences.pm b/Koha/Patron/Message/Preferences.pm
new file mode 100644
index 0000000..500bb85
--- /dev/null
+++ b/Koha/Patron/Message/Preferences.pm
@@ -0,0 +1,146 @@
+package Koha::Patron::Message::Preferences;
+
+# Copyright Koha-Suomi Oy 2016
+#
+# 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, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use Koha::Database;
+use Koha::Patron::Message::Attributes;
+use Koha::Patron::Message::Preference;
+use Koha::Patron::Message::Transports;
+
+use base qw(Koha::Objects);
+
+=head1 NAME
+
+Koha::Patron::Message::Preferences - Koha Patron Message Preferences object class
+
+=head1 API
+
+=head2 Class Methods
+
+=cut
+
+=head3 find_with_message_name
+
+Koha::Patron::Message::Preferences->find_with_message_name({
+ borrowernumber => 123,
+ message_name => 'Hold_Filled',
+});
+
+Converts C<message_name> into C<message_attribute_id> and continues find.
+
+=cut
+
+sub find_with_message_name {
+ my ($self, $id) = @_;
+
+ if (ref($id) eq "HASH" && $id->{'message_name'}) {
+ my $attr = Koha::Patron::Message::Attributes->find({
+ message_name => $id->{'message_name'},
+ });
+ $id->{'message_attribute_id'} = ($attr) ?
+ $attr->message_attribute_id : undef;
+ delete $id->{'message_name'};
+ }
+
+ return $self->SUPER::find($id);
+}
+
+=head3 get_options
+
+my $messaging_options = Koha::Patron::Message::Preferences->get_options
+
+Returns an ARRAYref of HASHrefs on available messaging options.
+
+=cut
+
+sub get_options {
+ my ($self) = @_;
+
+ my $transports = Koha::Patron::Message::Transports->search(undef,
+ {
+ join => ['message_attribute'],
+ '+select' => ['message_attribute.message_name', 'message_attribute.takes_days'],
+ '+as' => ['message_name', 'takes_days'],
+ });
+
+ my $choices;
+ while (my $transport = $transports->next) {
+ my $name = $transport->get_column('message_name');
+ $choices->{$name}->{'message_attribute_id'} = $transport->message_attribute_id;
+ $choices->{$name}->{'message_name'} = $name;
+ $choices->{$name}->{'takes_days'} = $transport->get_column('takes_days');
+ $choices->{$name}->{'has_digest'} = $transport->is_digest ? 1 : 0;
+ $choices->{$name}->{'has_digest_off'} = !$transport->is_digest ? 1 : 0;
+ $choices->{$name}->{'transport_'.$transport->get_column('message_transport_type')} = ' ';
+ }
+
+ my @return = values %$choices;
+ @return = sort { $a->{message_attribute_id} <=> $b->{message_attribute_id} } @return;
+
+ return \@return;
+}
+
+=head3 search
+
+Koha::Patron::Message::Preferences->search_with_message_name({
+ borrowernumber => 123,
+ message_name => 'Hold_Filled',
+});
+
+Converts C<message_name> into C<message_attribute_id> and continues search. Use
+Koha::Patron::Message::Preferences->search with a proper join for more complicated
+searches.
+
+=cut
+
+sub search_with_message_name {
+ my ($self, $params, $attributes) = @_;
+
+ if (ref($params) eq "HASH" && $params->{'message_name'}) {
+ my $attr = Koha::Patron::Message::Attributes->find({
+ message_name => $params->{'message_name'},
+ });
+ $params->{'message_attribute_id'} = ($attr) ?
+ $attr->message_attribute_id : undef;
+ delete $params->{'message_name'};
+ }
+
+ return $self->SUPER::search($params, $attributes);
+}
+
+=head3 type
+
+=cut
+
+sub _type {
+ return 'BorrowerMessagePreference';
+}
+
+sub object_class {
+ return 'Koha::Patron::Message::Preference';
+}
+
+=head1 AUTHOR
+
+Lari Taskula <lari.taskula@jns.fi>
+
+=cut
+
+1;
diff --git a/Koha/Patron/Message/Transport.pm b/Koha/Patron/Message/Transport.pm
new file mode 100644
index 0000000..ca0906e
--- /dev/null
+++ b/Koha/Patron/Message/Transport.pm
@@ -0,0 +1,50 @@
+package Koha::Patron::Message::Transport;
+
+# Copyright Koha-Suomi Oy 2016
+#
+# 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.a
+#
+# 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, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use Koha::Database;
+
+use base qw(Koha::Object);
+
+=head1 NAME
+
+Koha::Patron::Message::Transport - Koha Patron Message Transport object class
+
+=head1 API
+
+=head2 Class Methods
+
+=cut
+
+=head3 type
+
+=cut
+
+sub _type {
+ return 'MessageTransport';
+}
+
+=head1 AUTHOR
+
+Lari Taskula <lari.taskula@jns.fi>
+
+=cut
+
+1;
diff --git a/Koha/Patron/Message/Transport/Preference.pm b/Koha/Patron/Message/Transport/Preference.pm
new file mode 100644
index 0000000..fe0ddeb
--- /dev/null
+++ b/Koha/Patron/Message/Transport/Preference.pm
@@ -0,0 +1,51 @@
+package Koha::Patron::Message::Transport::Preference;
+
+# Copyright Koha-Suomi Oy 2016
+#
+# 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.a
+#
+# 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, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use Koha::Database;
+
+use base qw(Koha::Object);
+
+=head1 NAME
+
+Koha::Patron::Message::Transport::Preference - Koha Patron Message Transport
+Preference object class
+
+=head1 API
+
+=head2 Class Methods
+
+=cut
+
+=head3 type
+
+=cut
+
+sub _type {
+ return 'BorrowerMessageTransportPreference';
+}
+
+=head1 AUTHOR
+
+Lari Taskula <lari.taskula@jns.fi>
+
+=cut
+
+1;
diff --git a/Koha/Patron/Message/Transport/Preferences.pm b/Koha/Patron/Message/Transport/Preferences.pm
new file mode 100644
index 0000000..aabd851
--- /dev/null
+++ b/Koha/Patron/Message/Transport/Preferences.pm
@@ -0,0 +1,56 @@
+package Koha::Patron::Message::Transport::Preferences;
+
+# Copyright Koha-Suomi Oy 2016
+#
+# 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, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use Koha::Database;
+use Koha::Patron::Message::Transport::Preference;
+
+use base qw(Koha::Objects);
+
+=head1 NAME
+
+Koha::Patron::Message::Transport::Preferences - Koha Patron Message Transport
+Preferences object class
+
+=head1 API
+
+=head2 Class Methods
+
+=cut
+
+=head3 type
+
+=cut
+
+sub _type {
+ return 'BorrowerMessageTransportPreference';
+}
+
+sub object_class {
+ return 'Koha::Patron::Message::Transport::Preference';
+}
+
+=head1 AUTHOR
+
+Lari Taskula <lari.taskula@jns.fi>
+
+=cut
+
+1;
diff --git a/Koha/Patron/Message/Transport/Type.pm b/Koha/Patron/Message/Transport/Type.pm
new file mode 100644
index 0000000..4a52a10
--- /dev/null
+++ b/Koha/Patron/Message/Transport/Type.pm
@@ -0,0 +1,51 @@
+package Koha::Patron::Message::Transport::Type;
+
+# Copyright Koha-Suomi Oy 2016
+#
+# 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.a
+#
+# 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, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use Koha::Database;
+
+use base qw(Koha::Object);
+
+=head1 NAME
+
+Koha::Patron::Message::Transport::Type - Koha Patron Message Transport Type
+object class
+
+=head1 API
+
+=head2 Class Methods
+
+=cut
+
+=head3 type
+
+=cut
+
+sub _type {
+ return 'MessageTransportType';
+}
+
+=head1 AUTHOR
+
+Lari Taskula <lari.taskula@jns.fi>
+
+=cut
+
+1;
diff --git a/Koha/Patron/Message/Transport/Types.pm b/Koha/Patron/Message/Transport/Types.pm
new file mode 100644
index 0000000..2633ea3
--- /dev/null
+++ b/Koha/Patron/Message/Transport/Types.pm
@@ -0,0 +1,56 @@
+package Koha::Patron::Message::Transport::Types;
+
+# Copyright Koha-Suomi Oy 2016
+#
+# 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, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use Koha::Database;
+use Koha::Patron::Message::Transport::Type;
+
+use base qw(Koha::Objects);
+
+=head1 NAME
+
+Koha::Patron::Message::Transport::Types - Koha Patron Message Transport Types
+object class
+
+=head1 API
+
+=head2 Class Methods
+
+=cut
+
+=head3 type
+
+=cut
+
+sub _type {
+ return 'MessageTransportType';
+}
+
+sub object_class {
+ return 'Koha::Patron::Message::Transport::Type';
+}
+
+=head1 AUTHOR
+
+Lari Taskula <lari.taskula@jns.fi>
+
+=cut
+
+1;
diff --git a/Koha/Patron/Message/Transports.pm b/Koha/Patron/Message/Transports.pm
new file mode 100644
index 0000000..b6aee32
--- /dev/null
+++ b/Koha/Patron/Message/Transports.pm
@@ -0,0 +1,55 @@
+package Koha::Patron::Message::Transports;
+
+# Copyright Koha-Suomi Oy 2016
+#
+# 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, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use Koha::Database;
+use Koha::Patron::Message::Transport;
+
+use base qw(Koha::Objects);
+
+=head1 NAME
+
+Koha::Patron::Message::Transports - Koha Patron Message Transports object class
+
+=head1 API
+
+=head2 Class Methods
+
+=cut
+
+=head3 type
+
+=cut
+
+sub _type {
+ return 'MessageTransport';
+}
+
+sub object_class {
+ return 'Koha::Patron::Message::Transport';
+}
+
+=head1 AUTHOR
+
+Lari Taskula <lari.taskula@jns.fi>
+
+=cut
+
+1;
diff --git a/t/db_dependent/Koha/Patron/Message/Attributes.t b/t/db_dependent/Koha/Patron/Message/Attributes.t
new file mode 100644
index 0000000..836b4f0
--- /dev/null
+++ b/t/db_dependent/Koha/Patron/Message/Attributes.t
@@ -0,0 +1,74 @@
+#!/usr/bin/perl
+
+# Copyright 2017 Koha-Suomi Oy
+#
+# 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 Test::More tests => 2;
+
+use Koha::Database;
+
+my $schema = Koha::Database->new->schema;
+
+subtest 'Test class imports' => sub {
+ plan tests => 2;
+
+ use_ok('Koha::Patron::Message::Attribute');
+ use_ok('Koha::Patron::Message::Attributes');
+};
+
+subtest 'Test Koha::Patron::Message::Attributes' => sub {
+ plan tests => 6;
+
+ $schema->storage->txn_begin;
+
+ Koha::Patron::Message::Attribute->new({
+ message_name => 'Test_Attribute'
+ })->store;
+ Koha::Patron::Message::Attribute->new({
+ message_name => 'Test_Attribute2',
+ takes_days => 1
+ })->store;
+
+ my $attribute = Koha::Patron::Message::Attributes->find({
+ message_name => 'Test_Attribute' });
+ my $attribute2 = Koha::Patron::Message::Attributes->find({
+ message_name => 'Test_Attribute2' });
+
+ is($attribute->message_name, 'Test_Attribute',
+ 'Added a new messaging attribute.');
+ is($attribute->takes_days, 0,
+ 'For that messaging attribute, takes_days is disabled by default.');
+ is($attribute2->message_name, 'Test_Attribute2',
+ 'Added another messaging attribute.');
+ is($attribute2->takes_days, 1,
+ 'takes_days is enabled for that message attribute (as expected).');
+
+ $attribute->delete;
+ $attribute2->delete;
+ is(Koha::Patron::Message::Attributes->find({
+ message_name => 'Test_Attribute' }), undef,
+ 'Deleted the first message attribute.');
+ is(Koha::Patron::Message::Attributes->find({
+ message_name => 'Test_Attribute2' }), undef,
+ 'Deleted the second message attribute.');
+
+ $schema->storage->txn_rollback;
+};
+
+1;
diff --git a/t/db_dependent/Koha/Patron/Message/Preferences.t b/t/db_dependent/Koha/Patron/Message/Preferences.t
new file mode 100644
index 0000000..c38545e
--- /dev/null
+++ b/t/db_dependent/Koha/Patron/Message/Preferences.t
@@ -0,0 +1,704 @@
+#!/usr/bin/perl
+
+# Copyright 2017 Koha-Suomi Oy
+#
+# 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 Test::More tests => 7;
+
+use t::lib::Mocks;
+use t::lib::TestBuilder;
+
+use C4::Context;
+
+use Koha::Notice::Templates;
+use Koha::Patron::Categories;
+use Koha::Patron::Message::Attributes;
+use Koha::Patron::Message::Transport::Types;
+use Koha::Patron::Message::Transports;
+use Koha::Patrons;
+
+use File::Temp qw/tempfile/;
+use Log::Log4perl;
+
+my $schema = Koha::Database->new->schema;
+my $builder = t::lib::TestBuilder->new;
+
+subtest 'Test class imports' => sub {
+ plan tests => 2;
+
+ use_ok('Koha::Patron::Message::Preference');
+ use_ok('Koha::Patron::Message::Preferences');
+};
+
+subtest 'Test Koha::Patron::Message::Preferences' => sub {
+ plan tests => 2;
+
+ $schema->storage->txn_begin;
+
+ my $attribute = build_a_test_attribute();
+ my $letter = build_a_test_letter();
+ my $mtt = build_a_test_transport_type();
+ Koha::Patron::Message::Transport->new({
+ message_attribute_id => $attribute->message_attribute_id,
+ message_transport_type => $mtt->message_transport_type,
+ is_digest => 0,
+ letter_module => $letter->module,
+ letter_code => $letter->code,
+ })->store;
+
+ subtest 'Test for a patron' => sub {
+ plan tests => 3;
+
+ my $patron = build_a_test_patron();
+ Koha::Patron::Message::Preference->new({
+ borrowernumber => $patron->borrowernumber,
+ message_attribute_id => $attribute->message_attribute_id,
+ wants_digest => 0,
+ days_in_advance => undef,
+ })->store;
+
+ my $preference = Koha::Patron::Message::Preferences->find({
+ borrowernumber => $patron->borrowernumber,
+ message_attribute_id => $attribute->message_attribute_id
+ });
+ ok($preference->borrower_message_preference_id > 0,
+ 'Added a new messaging preference for patron.');
+
+ subtest 'Test set not throwing an exception on duplicate object' => sub {
+ plan tests => 1;
+
+ Koha::Patron::Message::Attributes->find({
+ message_attribute_id => $attribute->message_attribute_id
+ })->set({ takes_days => 1 })->store;
+ $preference->set({ days_in_advance => 1 })->store;
+ is(ref($preference), 'Koha::Patron::Message::Preference',
+ 'Updating the preference does not cause duplicate object exception');
+ };
+
+ $preference->delete;
+ is(Koha::Patron::Message::Preferences->search({
+ borrowernumber => $patron->borrowernumber,
+ message_attribute_id => $attribute->message_attribute_id
+ })->count, 0, 'Deleted the messaging preference.');
+ };
+
+ subtest 'Test for a category' => sub {
+ my $category = build_a_test_category();
+ Koha::Patron::Message::Preference->new({
+ categorycode => $category->categorycode,
+ message_attribute_id => $attribute->message_attribute_id,
+ wants_digest => 0,
+ days_in_advance => undef,
+ })->store;
+
+ my $preference = Koha::Patron::Message::Preferences->find({
+ categorycode => $category->categorycode,
+ message_attribute_id => $attribute->message_attribute_id
+ });
+ ok($preference->borrower_message_preference_id > 0,
+ 'Added a new messaging preference for category.');
+
+ $preference->delete;
+ is(Koha::Patron::Message::Preferences->search({
+ categorycode => $category->categorycode,
+ message_attribute_id => $attribute->message_attribute_id
+ })->count, 0, 'Deleted the messaging preference.');
+ };
+
+ $schema->storage->txn_rollback;
+};
+
+subtest 'Test Koha::Patron::Message::Preferences->get_options' => sub {
+ plan tests => 2;
+
+ subtest 'Test method availability and return value' => sub {
+ plan tests => 3;
+
+ ok(Koha::Patron::Message::Preferences->can('get_options'),
+ 'Method get_options is available.');
+ ok(my $options = Koha::Patron::Message::Preferences->get_options,
+ 'Called get_options successfully.');
+ is(ref($options), 'ARRAY', 'get_options returns a ARRAYref');
+ };
+
+ subtest 'Make sure options are correct' => sub {
+ $schema->storage->txn_begin;
+ my $options = Koha::Patron::Message::Preferences->get_options;
+
+ foreach my $option (@$options) {
+ my $n = $option->{'message_name'};
+ my $attr = Koha::Patron::Message::Attributes->find($option->{'message_attribute_id'});
+ is($option->{'message_attribute_id'}, $attr->message_attribute_id,
+ '$n: message_attribute_id is set');
+ is($option->{'message_name'}, $attr->message_name, '$n: message_name is set');
+ is($option->{'takes_days'}, $attr->takes_days, '$n: takes_days is set');
+ my $transports = Koha::Patron::Message::Transports->search({
+ message_attribute_id => $option->{'message_attribute_id'},
+ is_digest => $option->{'has_digest'} || 0,
+ });
+ while (my $trnzport = $transports->next) {
+ is($option->{'has_digest'} || 0, $trnzport->is_digest, '$n: has_digest is set for '.$trnzport->message_transport_type);
+ is($option->{'transport_'.$trnzport->message_transport_type}, ' ', '$n: transport_'.$trnzport->message_transport_type.' is set');
+ }
+ }
+
+ $schema->storage->txn_rollback;
+ };
+};
+
+subtest 'Add preferences from defaults' => sub {
+ plan tests => 3;
+
+ $schema->storage->txn_begin;
+
+ my $patron = build_a_test_patron();
+ my ($default, $mtt1, $mtt2) = build_a_test_category_preference({
+ patron => $patron,
+ });
+ ok(Koha::Patron::Message::Preference->new_from_default({
+ borrowernumber => $patron->borrowernumber,
+ categorycode => $patron->categorycode,
+ message_attribute_id => $default->message_attribute_id,
+ })->store, 'Added a default preference to patron.');
+ ok(my $pref = Koha::Patron::Message::Preferences->find({
+ borrowernumber => $patron->borrowernumber,
+ message_attribute_id => $default->message_attribute_id,
+ }), 'Found the default preference from patron.');
+ is(Koha::Patron::Message::Transport::Preferences->search({
+ borrower_message_preference_id => $pref->borrower_message_preference_id
+ })->count, 2, 'Found the two transport types that we set earlier');
+
+ $schema->storage->txn_rollback;
+};
+
+subtest 'Test Koha::Patron::Message::Preference->message_transport_types' => sub {
+ plan tests => 4;
+
+ ok(Koha::Patron::Message::Preference->can('message_transport_types'),
+ 'Method message_transport_types available');
+
+ subtest 'get message_transport_types' => sub {
+ plan tests => 5;
+
+ $schema->storage->txn_begin;
+
+ my $patron = build_a_test_patron();
+ my ($preference, $mtt1, $mtt2) = build_a_test_complete_preference({
+ patron => $patron
+ });
+ Koha::Patron::Message::Transport::Preferences->search({
+ borrower_message_preference_id => $preference->borrower_message_preference_id,
+ })->delete;
+ Koha::Patron::Message::Transport::Preference->new({
+ borrower_message_preference_id => $preference->borrower_message_preference_id,
+ message_transport_type => $mtt1->message_transport_type,
+ })->store;
+ Koha::Patron::Message::Transport::Preference->new({
+ borrower_message_preference_id => $preference->borrower_message_preference_id,
+ message_transport_type => $mtt2->message_transport_type,
+ })->store;
+ my $stored_transports = Koha::Patron::Message::Transport::Preferences->search({
+ borrower_message_preference_id => $preference->borrower_message_preference_id,
+ });
+ my $transport1 = Koha::Patron::Message::Transports->find({
+ message_attribute_id => $preference->message_attribute_id,
+ message_transport_type => $mtt1->message_transport_type,
+ });
+ my $transport2 = Koha::Patron::Message::Transports->find({
+ message_attribute_id => $preference->message_attribute_id,
+ message_transport_type => $mtt2->message_transport_type,
+ });
+ my $transports = $preference->message_transport_types;
+ is(keys %{$transports}, $stored_transports->count,
+ '->message_transport_types gets correct amount of transport types.');
+ is($transports->{$stored_transports->next->message_transport_type},
+ $transport1->letter_code, 'Found correct message transport type and letter code.');
+ is($transports->{$stored_transports->next->message_transport_type},
+ $transport2->letter_code, 'Found correct message transport type and letter code.');
+ ok(!$preference->message_transport_types->{'nonexistent'},
+ 'Didn\'t find nonexistent transport type.');
+
+ subtest 'test logging of warnings by invalid message transport type' => sub {
+ plan tests => 2;
+
+ my $log = mytempfile();
+ my $conf = mytempfile( <<"HERE"
+log4perl.logger.opac = WARN, OPAC
+log4perl.appender.OPAC=Log::Log4perl::Appender::TestBuffer
+log4perl.appender.OPAC.filename=$log
+log4perl.appender.OPAC.mode=append
+log4perl.appender.OPAC.layout=SimpleLayout
+log4perl.logger.intranet = WARN, INTRANET
+log4perl.appender.INTRANET=Log::Log4perl::Appender::TestBuffer
+log4perl.appender.INTRANET.filename=$log
+log4perl.appender.INTRANET.mode=append
+log4perl.appender.INTRANET.layout=SimpleLayout
+HERE
+ );
+ t::lib::Mocks::mock_config('log4perl_conf', $conf);
+ my $appenders = Log::Log4perl->appenders;
+ my $appender = Log::Log4perl->appenders->{OPAC};
+
+ my $pref = Koha::Patron::Message::Preferences->find(
+ $preference->borrower_message_preference_id
+ );
+ my $transports = $pref->message_transport_types;
+ is($appender, undef, 'Nothing in buffer yet');
+
+ my $mtt_new = build_a_test_transport_type();
+ Koha::Patron::Message::Transport::Preference->new({
+ borrower_message_preference_id =>
+ $pref->borrower_message_preference_id,
+ message_transport_type => $mtt_new->message_transport_type,
+ })->store;
+ $pref = Koha::Patron::Message::Preferences->find(
+ $pref->borrower_message_preference_id
+ );
+ $transports = $pref->message_transport_types;
+ $appender = Log::Log4perl->appenders->{OPAC};
+ my $name = $pref->message_name;
+ my $tt = $mtt_new->message_transport_type;
+ like($appender->buffer, qr/WARN - $name has no transport with $tt/,
+ 'Logged invalid message transport type');
+ };
+
+ $schema->storage->txn_rollback;
+ };
+
+ subtest 'set message_transport_types' => sub {
+ plan tests => 6;
+
+ $schema->storage->txn_begin;
+
+ my $patron = build_a_test_patron();
+ my ($preference, $mtt1, $mtt2) = build_a_test_complete_preference({
+ patron => $patron
+ });
+
+ my $mtt1_str = $mtt1->message_transport_type;
+ my $mtt2_str = $mtt2->message_transport_type;
+ # 1/3, use message_transport_types(list)
+ Koha::Patron::Message::Transport::Preferences->search({
+ borrower_message_preference_id => $preference->borrower_message_preference_id,
+ })->delete;
+ ok($preference->message_transport_types($mtt1_str, $mtt2_str)->store,
+ '1/3 Set returned true.');
+ my $stored_transports = Koha::Patron::Message::Transport::Preferences->search({
+ borrower_message_preference_id => $preference->borrower_message_preference_id,
+ '-or' => [
+ message_transport_type => $mtt1_str,
+ message_transport_type => $mtt2_str
+ ]
+ });
+ is($stored_transports->count, 2, 'Two transports selected');
+
+ # 2/3, use message_transport_types(ARRAYREF)
+ Koha::Patron::Message::Transport::Preferences->search({
+ borrower_message_preference_id => $preference->borrower_message_preference_id,
+ })->delete;
+ ok($preference->message_transport_types([$mtt1_str, $mtt2_str])->store,
+ '2/3 Set returned true.');
+ $stored_transports = Koha::Patron::Message::Transport::Preferences->search({
+ borrower_message_preference_id => $preference->borrower_message_preference_id,
+ '-or' => [
+ message_transport_type => $mtt1_str,
+ message_transport_type => $mtt2_str
+ ]
+ });
+ is($stored_transports->count, 2, 'Two transports selected');
+
+ # 3/3, use set({ message_transport_types => ARRAYREF })
+ Koha::Patron::Message::Transport::Preferences->search({
+ borrower_message_preference_id => $preference->borrower_message_preference_id,
+ })->delete;
+ ok($preference->set({
+ message_transport_types => [$mtt1_str, $mtt2_str]})->store,
+ '3/3 Set returned true.');
+ $stored_transports = Koha::Patron::Message::Transport::Preferences->search({
+ borrower_message_preference_id => $preference->borrower_message_preference_id,
+ '-or' => [
+ message_transport_type => $mtt1_str,
+ message_transport_type => $mtt2_str
+ ]
+ });
+ is($stored_transports->count, 2, 'Two transports selected');
+
+ $schema->storage->txn_rollback;
+ };
+
+ subtest 'new message_transport_types' => sub {
+ plan tests => 3;
+
+ $schema->storage->txn_begin;
+
+ my $patron = build_a_test_patron();
+ my $letter = build_a_test_letter();
+ my $attribute = build_a_test_attribute();
+ my $mtt = build_a_test_transport_type();
+ Koha::Patron::Message::Transport->new({
+ message_attribute_id => $attribute->message_attribute_id,
+ message_transport_type => $mtt->message_transport_type,
+ is_digest => 0,
+ letter_module => $letter->module,
+ letter_code => $letter->code,
+ })->store;
+ ok(my $preference = Koha::Patron::Message::Preference->new({
+ borrowernumber => $patron->borrowernumber,
+ message_attribute_id => $attribute->message_attribute_id,
+ wants_digest => 0,
+ days_in_advance => undef,
+ message_transport_types => $mtt->message_transport_type,
+ })->store, 'Added a new messaging preference and transport types to patron.');
+ ok($preference->message_transport_types->{$mtt->message_transport_type},
+ 'The transport type is stored in the object.');
+ my $stored_transports = Koha::Patron::Message::Transport::Preferences->search({
+ borrower_message_preference_id => $preference->borrower_message_preference_id,
+ });
+ is($stored_transports->next->message_transport_type, $mtt->message_transport_type,
+ 'The transport type is stored in the database.');
+
+ $schema->storage->txn_rollback;
+ };
+};
+
+subtest 'Test Koha::Patron::Message::Preference->message_name' => sub {
+ plan tests => 1;
+
+ $schema->storage->txn_begin;
+
+ my $patron = build_a_test_patron();
+ my $attribute = build_a_test_attribute();
+ my ($preference, $mtt1, $mtt2) = build_a_test_complete_preference({
+ patron => $patron,
+ attr => $attribute,
+ });
+ my $message_name_pref = Koha::Patron::Message::Preferences->search_with_message_name({
+ borrowernumber => $patron->{'borrowernumber'},
+ message_name => $attribute->message_name,
+ })->next;
+ is($message_name_pref->message_name, $attribute->message_name, "Found preference with message_name");
+
+ $schema->storage->txn_rollback;
+};
+
+subtest 'Test adding a new preference with invalid parameters' => sub {
+ plan tests => 4;
+
+ subtest 'Missing parameters' => sub {
+ plan tests => 1;
+
+ eval { Koha::Patron::Message::Preference->new->store };
+ is(ref $@, 'Koha::Exceptions::MissingParameter',
+ 'Adding a message preference without parameters'
+ .' => Koha::Exceptions::MissingParameter');
+ };
+
+ subtest 'Too many parameters' => sub {
+ plan tests => 1;
+
+ $schema->storage->txn_begin;
+
+ my $patron = build_a_test_patron();
+ eval { Koha::Patron::Message::Preference->new({
+ borrowernumber => $patron->borrowernumber,
+ categorycode => $patron->categorycode,
+ })->store };
+ is(ref $@, 'Koha::Exceptions::TooManyParameters',
+ 'Adding a message preference for both borrowernumber and categorycode'
+ .' => Koha::Exceptions::TooManyParameters');
+
+ $schema->storage->txn_rollback;
+ };
+
+ subtest 'Bad parameter' => sub {
+ plan tests => 19;
+
+ $schema->storage->txn_begin;
+
+ eval { Koha::Patron::Message::Preference->new({
+ borrowernumber => -999,
+ })->store };
+ is(ref $@, 'Koha::Exceptions::BadParameter',
+ 'Adding a message preference with invalid borrowernumber'
+ .' => Koha::Exceptions::BadParameter');
+ is ($@->parameter, 'borrowernumber', 'The previous exception tells us it'
+ .' was the borrowernumber.');
+
+ eval { Koha::Patron::Message::Preference->new({
+ categorycode => 'nonexistent',
+ })->store };
+ is(ref $@, 'Koha::Exceptions::BadParameter',
+ 'Adding a message preference with invalid categorycode'
+ .' => Koha::Exceptions::BadParameter');
+ is($@->parameter, 'categorycode', 'The previous exception tells us it'
+ .' was the categorycode.');
+
+ my $attribute = build_a_test_attribute({ takes_days => 0 });
+ my $patron = build_a_test_patron();
+ eval { Koha::Patron::Message::Preference->new({
+ borrowernumber => $patron->borrowernumber,
+ message_attribute_id => $attribute->message_attribute_id,
+ days_in_advance => 10,
+ })->store };
+ is(ref $@, 'Koha::Exceptions::BadParameter',
+ 'Adding a message preference with days in advance option when not'
+ .' available => Koha::Exceptions::BadParameter');
+ is($@->parameter, 'days_in_advance', 'The previous exception tells us it'
+ .' was the days_in_advance.');
+
+ $attribute->set({ takes_days => 1 })->store;
+ eval { Koha::Patron::Message::Preference->new({
+ borrowernumber => $patron->borrowernumber,
+ message_attribute_id => $attribute->message_attribute_id,
+ days_in_advance => 31,
+ })->store };
+ is(ref $@, 'Koha::Exceptions::BadParameter',
+ 'Adding a message preference with days in advance option too large'
+ .' => Koha::Exceptions::BadParameter');
+ is($@->parameter, 'days_in_advance', 'The previous exception tells us it'
+ .' was the days_in_advance.');
+
+ eval { Koha::Patron::Message::Preference->new({
+ borrowernumber => $patron->borrowernumber,
+ message_transport_types => ['nonexistent']
+ })->store };
+ is (ref $@, 'Koha::Exceptions::BadParameter',
+ 'Adding a message preference with invalid message_transport_type'
+ .' => Koha::Exceptions::BadParameter');
+ is ($@->parameter, 'message_transport_types', 'The previous exception '
+ .'tells us it was the message_transport_types.');
+
+ my $mtt_new = build_a_test_transport_type();
+ eval {
+ Koha::Patron::Message::Preference->new({
+ borrowernumber => $patron->borrowernumber,
+ message_attribute_id => $attribute->message_attribute_id,
+ message_transport_types => [$mtt_new->message_transport_type],
+ wants_digest => 1,
+ })->store };
+ is (ref $@, 'Koha::Exceptions::BadParameter',
+ 'Adding a message preference with invalid message_transport_type'
+ .' => Koha::Exceptions::BadParameter');
+ is ($@->parameter, 'message_transport_types', 'The previous exception '
+ .'tells us it was the message_transport_types.');
+ like ($@->error, qr/^No transport configured/, 'Exception is because of '
+ .'given message_transport_type is not a valid option.');
+
+ eval {
+ Koha::Patron::Message::Preference->new({
+ borrowernumber => $patron->borrowernumber,
+ message_attribute_id => $attribute->message_attribute_id,
+ message_transport_types => [],
+ wants_digest => 1,
+ })->store };
+ is (ref $@, 'Koha::Exceptions::BadParameter',
+ 'Adding a message preference with invalid message_transport_type'
+ .' => Koha::Exceptions::BadParameter');
+ is ($@->parameter, 'wants_digest', 'The previous exception tells us it'
+ .' was the wants_digest');
+ like ($@->error, qr/^Digest not available/, 'Exception s because of given'
+ .' digest is not available for this transport.');
+
+ eval {
+ Koha::Patron::Message::Preference->new({
+ borrowernumber => $patron->borrowernumber,
+ message_attribute_id => -1,
+ message_transport_types => [],
+ })->store };
+ is (ref $@, 'Koha::Exceptions::BadParameter',
+ 'Adding a message preference with invalid message_transport_type'
+ .' => Koha::Exceptions::BadParameter');
+ is ($@->parameter, 'message_attribute_id', 'The previous exception tells'
+ .' us it was the message_attribute_id');
+ like ($@->error, qr/^Message attribute with id -1 not found/, 'Exception '
+ .' is because of given message attribute id is not found.');
+
+ $schema->storage->txn_rollback;
+ };
+
+ subtest 'Duplicate object' => sub {
+ plan tests => 2;
+
+ $schema->storage->txn_begin;
+
+ my $attribute = build_a_test_attribute();
+ my $letter = build_a_test_letter();
+ my $mtt = build_a_test_transport_type();
+ Koha::Patron::Message::Transport->new({
+ message_attribute_id => $attribute->message_attribute_id,
+ message_transport_type => $mtt->message_transport_type,
+ is_digest => 0,
+ letter_module => $letter->module,
+ letter_code => $letter->code,
+ })->store;
+ my $patron = build_a_test_patron();
+ my $preference = Koha::Patron::Message::Preference->new({
+ borrowernumber => $patron->borrowernumber,
+ message_attribute_id => $attribute->message_attribute_id,
+ wants_digest => 0,
+ days_in_advance => undef,
+ })->store;
+ ok($preference->borrower_message_preference_id,
+ 'Added a new messaging preference for patron.');
+ eval { Koha::Patron::Message::Preference->new({
+ borrowernumber => $patron->borrowernumber,
+ message_attribute_id => $attribute->message_attribute_id,
+ wants_digest => 0,
+ days_in_advance => undef,
+ })->store };
+ is(ref $@, 'Koha::Exceptions::DuplicateObject',
+ 'Adding a duplicate preference'
+ .' => Koha::Exceptions::DuplicateObject');
+
+ $schema->storage->txn_rollback;
+ };
+};
+
+sub build_a_test_attribute {
+ my ($params) = @_;
+
+ $params->{takes_days} = $params->{takes_days} && $params->{takes_days} > 0
+ ? 1 : 0;
+
+ my $attribute = $builder->build({
+ source => 'MessageAttribute',
+ value => $params,
+ });
+
+ return Koha::Patron::Message::Attributes->find(
+ $attribute->{message_attribute_id}
+ );
+}
+
+sub build_a_test_category {
+ my $categorycode = $builder->build({
+ source => 'Category' })->{categorycode};
+
+ return Koha::Patron::Categories->find($categorycode);
+}
+
+sub build_a_test_letter {
+ my ($params) = @_;
+
+ my $mtt = $params->{mtt} ? $params->{mtt} : 'email';
+ my $branchcode = $builder->build({
+ source => 'Branch' })->{branchcode};
+ my $letter = $builder->build({
+ source => 'Letter',
+ value => {
+ branchcode => '',
+ is_html => 0,
+ message_transport_type => $mtt
+ }
+ });
+
+ return Koha::Notice::Templates->find({
+ module => $letter->{module},
+ code => $letter->{code},
+ branchcode => $letter->{branchcode},
+ });
+}
+
+sub build_a_test_patron {
+ my $categorycode = $builder->build({
+ source => 'Category' })->{categorycode};
+ my $branchcode = $builder->build({
+ source => 'Branch' })->{branchcode};
+ my $borrowernumber = $builder->build({
+ source => 'Borrower' })->{borrowernumber};
+
+ return Koha::Patrons->find($borrowernumber);
+}
+
+sub build_a_test_transport_type {
+ my $mtt = $builder->build({
+ source => 'MessageTransportType' });
+
+ return Koha::Patron::Message::Transport::Types->find(
+ $mtt->{message_transport_type}
+ );
+}
+
+sub build_a_test_category_preference {
+ my ($params) = @_;
+
+ my $patron = $params->{patron};
+ my $attr = $params->{attr}
+ ? $params->{attr}
+ : build_a_test_attribute($params->{days_in_advance});
+
+ my $letter = $params->{letter} ? $params->{letter} : build_a_test_letter();
+ my $mtt1 = $params->{mtt1} ? $params->{mtt1} : build_a_test_transport_type();
+ my $mtt2 = $params->{mtt2} ? $params->{mtt2} : build_a_test_transport_type();
+
+ Koha::Patron::Message::Transport->new({
+ message_attribute_id => $attr->message_attribute_id,
+ message_transport_type => $mtt1->message_transport_type,
+ is_digest => $params->{digest} ? 1 : 0,
+ letter_module => $letter->module,
+ letter_code => $letter->code,
+ })->store;
+
+ Koha::Patron::Message::Transport->new({
+ message_attribute_id => $attr->message_attribute_id,
+ message_transport_type => $mtt2->message_transport_type,
+ is_digest => $params->{digest} ? 1 : 0,
+ letter_module => $letter->module,
+ letter_code => $letter->code,
+ })->store;
+
+ my $default = Koha::Patron::Message::Preference->new({
+ categorycode => $patron->categorycode,
+ message_attribute_id => $attr->message_attribute_id,
+ wants_digest => $params->{digest} ? 1 : 0,
+ days_in_advance => $params->{days_in_advance}
+ ? $params->{days_in_advance} : undef,
+ })->store;
+
+ Koha::Patron::Message::Transport::Preference->new({
+ borrower_message_preference_id => $default->borrower_message_preference_id,
+ message_transport_type => $mtt1->message_transport_type,
+ })->store;
+ Koha::Patron::Message::Transport::Preference->new({
+ borrower_message_preference_id => $default->borrower_message_preference_id,
+ message_transport_type => $mtt2->message_transport_type,
+ })->store;
+
+ return ($default, $mtt1, $mtt2);
+}
+
+sub build_a_test_complete_preference {
+ my ($params) = @_;
+
+ my ($default, $mtt1, $mtt2) = build_a_test_category_preference($params);
+ my $patron = $params->{patron};
+ $patron->set_default_messaging_preferences;
+ return (Koha::Patron::Message::Preferences->search({
+ borrowernumber => $patron->borrowernumber
+ })->next, $mtt1, $mtt2);
+}
+
+sub mytempfile {
+ my ( $fh, $fn ) = tempfile( SUFFIX => '.logger.test', UNLINK => 1 );
+ print $fh $_[0]//'';
+ close $fh;
+ return $fn;
+}
+
+1;
diff --git a/t/db_dependent/Koha/Patron/Message/Transport/Preferences.t b/t/db_dependent/Koha/Patron/Message/Transport/Preferences.t
new file mode 100644
index 0000000..0cdf809
--- /dev/null
+++ b/t/db_dependent/Koha/Patron/Message/Transport/Preferences.t
@@ -0,0 +1,179 @@
+#!/usr/bin/perl
+
+# Copyright 2017 Koha-Suomi Oy
+#
+# 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 Test::More tests => 2;
+
+use t::lib::Mocks;
+use t::lib::TestBuilder;
+
+use Koha::Notice::Templates;
+use Koha::Patron::Categories;
+use Koha::Patron::Message::Attributes;
+use Koha::Patron::Message::Preferences;
+use Koha::Patron::Message::Transport::Types;
+use Koha::Patron::Message::Transports;
+use Koha::Patrons;
+
+my $schema = Koha::Database->new->schema;
+my $builder = t::lib::TestBuilder->new;
+
+subtest 'Test class imports' => sub {
+ plan tests => 2;
+
+ use_ok('Koha::Patron::Message::Transport::Preference');
+ use_ok('Koha::Patron::Message::Transport::Preferences');
+};
+
+subtest 'Test Koha::Patron::Message::Transport::Preferences' => sub {
+ plan tests => 2;
+
+ $schema->storage->txn_begin;
+
+ my $attribute = build_a_test_attribute();
+ my $mtt = build_a_test_transport_type();
+ my $letter = build_a_test_letter({
+ mtt => $mtt->message_transport_type
+ });
+ Koha::Patron::Message::Transport->new({
+ message_attribute_id => $attribute->message_attribute_id,
+ message_transport_type => $mtt->message_transport_type,
+ is_digest => 0,
+ letter_module => $letter->module,
+ letter_code => $letter->code,
+ })->store;
+
+ subtest 'For a patron' => sub {
+ my $patron = build_a_test_patron();
+ my $preference = Koha::Patron::Message::Preference->new({
+ borrowernumber => $patron->borrowernumber,
+ message_attribute_id => $attribute->message_attribute_id,
+ wants_digest => 0,
+ days_in_advance => undef,
+ })->store;
+
+ my $pref_id = $preference->borrower_message_preference_id;
+ my $transport_pref = Koha::Patron::Message::Transport::Preference->new({
+ borrower_message_preference_id => $pref_id,
+ message_transport_type => $mtt->message_transport_type,
+ })->store;
+ is(ref($transport_pref), 'Koha::Patron::Message::Transport::Preference',
+ 'Added a new messaging transport preference for patron.');
+
+ $transport_pref->delete;
+ is(Koha::Patron::Message::Transport::Preferences->search({
+ borrower_message_preference_id => $pref_id,
+ message_transport_type => $mtt->message_transport_type,
+ })->count, 0, 'Deleted the messaging transport preference.');
+ };
+
+ subtest 'For a category' => sub {
+ my $category = build_a_test_category();
+ my $preference = Koha::Patron::Message::Preference->new({
+ categorycode => $category->categorycode,
+ message_attribute_id => $attribute->message_attribute_id,
+ wants_digest => 0,
+ days_in_advance => undef,
+ })->store;
+
+ my $pref_id = $preference->borrower_message_preference_id;
+ my $transport_pref = Koha::Patron::Message::Transport::Preference->new({
+ borrower_message_preference_id => $pref_id,
+ message_transport_type => $mtt->message_transport_type,
+ })->store;
+ is(ref($transport_pref), 'Koha::Patron::Message::Transport::Preference',
+ 'Added a new messaging transport preference for category.');
+
+ $transport_pref->delete;
+ is(Koha::Patron::Message::Transport::Preferences->search({
+ borrower_message_preference_id => $pref_id,
+ message_transport_type => $mtt->message_transport_type,
+ })->count, 0, 'Deleted the messaging transport preference.');
+ };
+
+ $schema->storage->txn_rollback;
+};
+
+sub build_a_test_attribute {
+ my ($params) = @_;
+
+ $params->{takes_days} = $params->{takes_days} && $params->{takes_days} > 0
+ ? 1 : 0;
+
+ my $attribute = $builder->build({
+ source => 'MessageAttribute',
+ value => $params,
+ });
+
+ return Koha::Patron::Message::Attributes->find(
+ $attribute->{message_attribute_id}
+ );
+}
+
+sub build_a_test_category {
+ my $categorycode = $builder->build({
+ source => 'Category' })->{categorycode};
+
+ return Koha::Patron::Categories->find($categorycode);
+}
+
+sub build_a_test_letter {
+ my ($params) = @_;
+
+ my $mtt = $params->{mtt} ? $params->{mtt} : 'email';
+ my $branchcode = $builder->build({
+ source => 'Branch' })->{branchcode};
+ my $letter = $builder->build({
+ source => 'Letter',
+ value => {
+ branchcode => '',
+ is_html => 0,
+ message_transport_type => $mtt
+ }
+ });
+
+ return Koha::Notice::Templates->find({
+ module => $letter->{module},
+ code => $letter->{code},
+ branchcode => $letter->{branchcode},
+ });
+}
+
+sub build_a_test_patron {
+ my $categorycode = $builder->build({
+ source => 'Category' })->{categorycode};
+ my $branchcode = $builder->build({
+ source => 'Branch' })->{branchcode};
+ my $borrowernumber = $builder->build({
+ source => 'Borrower' })->{borrowernumber};
+
+ return Koha::Patrons->find($borrowernumber);
+}
+
+sub build_a_test_transport_type {
+ my $mtt = $builder->build({
+ source => 'MessageTransportType' });
+
+ return Koha::Patron::Message::Transport::Types->find(
+ $mtt->{message_transport_type}
+ );
+}
+
+1;
diff --git a/t/db_dependent/Koha/Patron/Message/Transport/Types.t b/t/db_dependent/Koha/Patron/Message/Transport/Types.t
new file mode 100644
index 0000000..cbba32b
--- /dev/null
+++ b/t/db_dependent/Koha/Patron/Message/Transport/Types.t
@@ -0,0 +1,54 @@
+#!/usr/bin/perl
+
+# Copyright 2017 Koha-Suomi Oy
+#
+# 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 Test::More tests => 2;
+
+use Koha::Database;
+
+my $schema = Koha::Database->new->schema;
+
+subtest 'Test class imports' => sub {
+ plan tests => 2;
+
+ use_ok('Koha::Patron::Message::Transport::Type');
+ use_ok('Koha::Patron::Message::Transport::Types');
+};
+
+subtest 'Test Koha::Patron::Message::Transport::Types' => sub {
+ plan tests => 2;
+
+ $schema->storage->txn_begin;
+
+ my $transport_type = Koha::Patron::Message::Transport::Type->new({
+ message_transport_type => 'test'
+ })->store;
+
+ is($transport_type->message_transport_type, 'test',
+ 'Added a new message transport type.');
+
+ $transport_type->delete;
+ is(Koha::Patron::Message::Transport::Types->find('test'), undef,
+ 'Deleted the message transport type.');
+
+ $schema->storage->txn_rollback;
+};
+
+1;
diff --git a/t/db_dependent/Koha/Patron/Message/Transports.t b/t/db_dependent/Koha/Patron/Message/Transports.t
new file mode 100644
index 0000000..b9296fd
--- /dev/null
+++ b/t/db_dependent/Koha/Patron/Message/Transports.t
@@ -0,0 +1,119 @@
+#!/usr/bin/perl
+
+# Copyright 2017 Koha-Suomi Oy
+#
+# 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 Test::More tests => 2;
+
+use t::lib::TestBuilder;
+
+use Koha::Notice::Templates;
+use Koha::Patron::Message::Attributes;
+use Koha::Patron::Message::Transport::Types;
+
+my $schema = Koha::Database->new->schema;
+my $builder = t::lib::TestBuilder->new;
+
+subtest 'Test class imports' => sub {
+ plan tests => 2;
+
+ use_ok('Koha::Patron::Message::Transport');
+ use_ok('Koha::Patron::Message::Transports');
+};
+
+subtest 'Test Koha::Patron::Message::Transports' => sub {
+ plan tests => 2;
+
+ $schema->storage->txn_begin;
+
+ my $attribute = build_a_test_attribute();
+ my $mtt = build_a_test_transport_type();
+ my $letter = build_a_test_letter({
+ mtt => $mtt->message_transport_type
+ });
+
+ my $transport = Koha::Patron::Message::Transport->new({
+ message_attribute_id => $attribute->message_attribute_id,
+ message_transport_type => $mtt->message_transport_type,
+ is_digest => 0,
+ letter_module => $letter->module,
+ letter_code => $letter->code,
+ })->store;
+
+ is($transport->message_attribute_id, $attribute->message_attribute_id,
+ 'Added a new messaging transport.');
+
+ $transport->delete;
+ is(Koha::Patron::Message::Transports->search({
+ message_attribute_id => $attribute->message_attribute_id,
+ message_transport_type => $mtt->message_transport_type,
+ is_digest => 0
+ })->count, 0, 'Deleted the messaging transport.');
+
+ $schema->storage->txn_rollback;
+};
+
+sub build_a_test_attribute {
+ my ($params) = @_;
+
+ $params->{takes_days} = $params->{takes_days} && $params->{takes_days} > 0
+ ? 1 : 0;
+
+ my $attribute = $builder->build({
+ source => 'MessageAttribute',
+ value => $params,
+ });
+
+ return Koha::Patron::Message::Attributes->find(
+ $attribute->{message_attribute_id}
+ );
+}
+
+sub build_a_test_letter {
+ my ($params) = @_;
+
+ my $mtt = $params->{mtt} ? $params->{mtt} : 'email';
+ my $branchcode = $builder->build({
+ source => 'Branch' })->{branchcode};
+ my $letter = $builder->build({
+ source => 'Letter',
+ value => {
+ branchcode => '',
+ is_html => 0,
+ message_transport_type => $mtt
+ }
+ });
+
+ return Koha::Notice::Templates->find({
+ module => $letter->{module},
+ code => $letter->{code},
+ branchcode => $letter->{branchcode},
+ });
+}
+
+sub build_a_test_transport_type {
+ my $mtt = $builder->build({
+ source => 'MessageTransportType' });
+
+ return Koha::Patron::Message::Transport::Types->find(
+ $mtt->{message_transport_type}
+ );
+}
+
+1;
--
2.1.4