From 6c93fd075e4ed965603ba8bae5a2304aa23db9aa Mon Sep 17 00:00:00 2001
From: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Date: Mon, 4 Mar 2019 09:26:33 +0000
Subject: [PATCH] Bug 22443: Increase test coverage of get_expiry_date

This method did not test for 'special' dates, i.e. handling for leap
years.

Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
---
 t/db_dependent/Koha/Patron/Categories.t | 53 +++++++++++++++++--------
 1 file changed, 37 insertions(+), 16 deletions(-)

diff --git a/t/db_dependent/Koha/Patron/Categories.t b/t/db_dependent/Koha/Patron/Categories.t
index 58882a493e..d5602524c4 100644
--- a/t/db_dependent/Koha/Patron/Categories.t
+++ b/t/db_dependent/Koha/Patron/Categories.t
@@ -20,6 +20,7 @@
 use Modern::Perl;
 
 use Test::More tests => 10;
+use Time::Fake;
 
 use C4::Context;
 use Koha::Database;
@@ -61,28 +62,48 @@ is( $retrieved_category_1->checkprevcheckout, 'inherit', 'Koha::Patron::Category
 is( $retrieved_category_2->checkprevcheckout, 'inherit', 'Koha::Patron::Category->store should default checkprevcheckout to inherit' );
 
 subtest 'get_expiry_date' => sub {
-    plan tests => 5;
-    my $next_month = dt_from_string->add( months => 1 );
-    my $next_year = dt_from_string->add( months => 12 );
-    my $yesterday = dt_from_string->add( days => -1 );
+    plan tests => 19;
+
+    my $enrolementperioddate = dt_from_string()->add( months => 12);
     my $category = Koha::Patron::Category->new({
-        categorycode => 'mycat',
-        category_type => 'A',
-        description  => 'mycatdesc',
-        enrolmentperiod => undef,
-        enrolmentperioddate => $next_month,
+        categorycode          => 'mycat',
+          category_type       => 'A',
+          description         => 'mycatdesc',
+          enrolmentperiod     => undef,
+          enrolmentperioddate => $enrolementperioddate,
     })->store;
-    is( $category->get_expiry_date, $next_month, 'Without enrolmentperiod and parameter, ->get_expiry_date should return enrolmentperioddate' );
-    is( $category->get_expiry_date( $next_year ), $next_month, 'Without enrolmentperiod, ->get_expiry_date should return enrolmentperiodadate even if a parameter is given' );
-
-    $category->enrolmentperiod( 12 )->store;
-    is( t::lib::Dates::compare($category->get_expiry_date, $next_year), 0, 'With enrolmentperiod defined and no parameter, ->get_expiry_date should return today + enrolmentperiod' );
-    is( t::lib::Dates::compare($category->get_expiry_date( $yesterday ), $next_year->clone->add( days => -1 )), 0, 'With enrolmentperiod defined and a date given in parameter, ->get_expiry_date should take this date + enrolmentperiod' );
 
     my $hardcoded_date = '2000-01-31';
-    is( t::lib::Dates::compare($category->get_expiry_date( $hardcoded_date ), dt_from_string( $hardcoded_date )->add( months => 12 )), 0, 'get_expiry_date accepts strings as well'  );
+    is( $category->get_expiry_date, $enrolementperioddate, 'Without enrolmentperiod and parameter, ->get_expiry_date should return enrolmentperioddate' );
+    is( $category->get_expiry_date( $hardcoded_date ), $enrolementperioddate, 'Without enrolmentperiod, ->get_expiry_date should return enrolmentperiodadate even if a parameter is given' );
 
+    $category->enrolmentperiod( 12 )->store;
+    is( t::lib::Dates::compare($category->get_expiry_date( $hardcoded_date ), dt_from_string( $hardcoded_date )->add( months => 12 )), 0, 'get_expiry_date accepts strings as well'  );
     $category->delete;
+
+    for my $date ( '2016-03-31', '2016-11-30', '2019-01-31',  '2019-03-01', '2020-02-28', '2020-01-31', '2020-02-29', dt_from_string()->truncate( to => 'day') ) {
+        my $dt = dt_from_string( $date, 'iso' );
+        Time::Fake->offset( $dt->epoch );
+
+        $enrolementperioddate = $dt->clone->add( months => 1 , end_of_month => 'limit' )->truncate( to => 'day' );
+        $category = Koha::Patron::Category->new({
+            categorycode          => 'mycat',
+              category_type       => 'A',
+              description         => 'mycatdesc',
+              enrolmentperiod     => 12,
+              enrolmentperioddate => $enrolementperioddate,
+        })->store;
+   
+        my $a_year_later  = $dt->clone->add( months => 12, end_of_month => 'limit' )->truncate( to => 'day' );
+        my $a_day_earlier = $dt->clone->subtract( days => 1, end_of_month => 'limit' )->truncate( to => 'day' );
+        my $a_day_earlier_plus_a_year = $a_day_earlier->clone->add( months => 12, end_of_month => 'limit' )->truncate( to => 'day' );
+   
+        is( t::lib::Dates::compare($category->get_expiry_date, $a_year_later), 0, 'With enrolmentperiod defined and no parameter, ->get_expiry_date should return today + enrolmentperiod' );
+        is( t::lib::Dates::compare($category->get_expiry_date( $a_day_earlier ), $a_day_earlier_plus_a_year), 0, 'With enrolmentperiod defined and a date given in parameter, ->get_expiry_date should take this date + enrolmentperiod' );
+    
+        $category->delete;
+        Time::Fake->reset;
+    }
 };
 
 subtest 'BlockExpiredPatronOpacActions' => sub {
-- 
2.20.1