From caba684536a8aad136a7d203fe445cefac777169 Mon Sep 17 00:00:00 2001
From: Mehdi Hamidi <mehdi.hamidi@inlibro.com>
Date: Mon, 16 Jan 2017 10:07:51 -0500
Subject: [PATCH] Bug 17015 - Tests for DiscreteCalendar

---
 t/db_dependent/DiscreteCalendar.t | 302 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 302 insertions(+)
 create mode 100644 t/db_dependent/DiscreteCalendar.t

diff --git a/t/db_dependent/DiscreteCalendar.t b/t/db_dependent/DiscreteCalendar.t
new file mode 100644
index 0000000..b320d9d
--- /dev/null
+++ b/t/db_dependent/DiscreteCalendar.t
@@ -0,0 +1,302 @@
+#!/usr/bin/perl
+
+# Copyright 2015 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 Test::More tests => 47;
+use Test::MockModule;
+
+use C4::Context;
+use C4::Output;
+use Koha::DateUtils;
+use Koha::DiscreteCalendar;
+
+
+my $module_context = new Test::MockModule('C4::Context');
+my $today = DateTime->today;
+my $schema = Koha::Database->new->schema;
+$schema->storage->txn_begin;
+
+my $branch1 = "Library1";
+my $branch2 = "Library2";
+
+$schema->resultset('DiscreteCalendar')->search({
+    branchcode  =>'DFLT'
+})->update_all({
+    isopened    => 1,
+    holidaytype => '',
+    note        => '',
+    openhour    => '08:00:00',
+    closehour   => '16:00:00'
+});
+
+#Added entries for the branches.
+Koha::DiscreteCalendar->new( branchcode => 'DFLT' )->add_new_branch('DFLT', $branch1);
+Koha::DiscreteCalendar->new( branchcode => 'DFLT' )->add_new_branch('DFLT', $branch2);
+
+isnt($branch1,'', "First branch to do tests. BranchCode => $branch1");
+isnt($branch1,'', "Second branch  to do tests. BranchCode => $branch2");
+
+#2 Calendars to make sure branches are treated separately.
+my $calendar = Koha::DiscreteCalendar->new(branchcode => $branch1);
+my $calendar2 = Koha::DiscreteCalendar->new(branchcode => $branch2);
+
+my $unique_holiday = DateTime->today;
+$calendar->edit_holiday("Single holiday Today", '', "E", '', '', $unique_holiday, $unique_holiday);
+is($calendar->isOpened($unique_holiday), 0, "Branch closed today : $unique_holiday");
+
+my @unique_holidays = $calendar->get_unique_holidays();
+is(scalar @unique_holidays, 1, "Set of exception holidays at 1");
+
+my $days_between_start = DateTime->today;
+my $days_between_end = DateTime->today->add(days => 6);
+my $days_between = $calendar->days_between($days_between_start, $days_between_end)->in_units('days');
+is($days_between, 5, "Days between skips holiday");
+
+my $repeatable_holiday = DateTime->today->add(days => 1);
+$calendar->edit_holiday("repeatable", '', "R", '', '', $repeatable_holiday, $repeatable_holiday);
+is($calendar->isOpened($repeatable_holiday), 0, "Branch not opened on $repeatable_holiday");
+
+my @repeatable_holidays = $calendar->get_repeatable_holidays();
+is(scalar @repeatable_holidays, 1, "Set of repeatable holidays at 1");
+
+# 1 being mysql DAYOFWEEK() for Sunday
+$calendar->edit_holiday("Weekly",1, "W", '', '', $today, $today);
+my @weekly_holidays = $calendar->get_week_days_holidays();
+is(scalar @weekly_holidays, 1, "Set of weekly holidays at 1");
+
+my $sunday = DateTime->today->add(days =>( 7 - $today->day_of_week));
+is($calendar->isOpened($sunday), 0, "Branch not opened on " . $sunday->day_name ."s");
+
+my $unique_holiday_range_start = DateTime->today->add(days => 2);
+my $unique_holiday_range_end = DateTime->today->add(days => 7);
+$calendar->edit_holiday("Single holiday range", '', "E", '', '', $unique_holiday_range_start, $unique_holiday_range_end);
+@unique_holidays = $calendar->get_unique_holidays();
+is(scalar @unique_holidays, 7, "Set of exception holidays at 7");
+
+my $repeatable_holiday_range_start = DateTime->today->add(days => 8);
+my $repeatable_holiday_range_end = DateTime->today->add(days => 13);
+$calendar->edit_holiday("Repeatable holiday range", '', "R", '', '', $repeatable_holiday_range_start, $repeatable_holiday_range_end);
+@repeatable_holidays = $calendar->get_repeatable_holidays();
+is(scalar @repeatable_holidays, 7, "Set of repeatable holidays at 7");
+
+#Hourly loan
+# ex :
+# item due      : 2017-01-24 11:00:00
+# item returned : 2017-01-26 10:00:00
+# Branch closed : 2017-01-25
+# Open/close hours : 8AM to 4PM (8h day)
+# Hours due : 5 hours on 2017-01-24 + 2 hours on 2017-01-26 = 7hours
+
+my $open_hours_since_start = DateTime->today->add(days => 40, hours => 11);
+my $open_hours_since_end = DateTime->today->add(days => 42, hours => 10);
+my $holiday_between =  DateTime->today->add(days => 41);
+$calendar->edit_holiday('', '', 'none', '', '', $open_hours_since_start, $open_hours_since_end);
+
+$calendar->edit_holiday("Single holiday", '', "E", '', '', $holiday_between,$holiday_between);
+my $open_hours_between = $calendar->open_hours_between($open_hours_since_start, $open_hours_since_end);
+is($open_hours_between, 7, "7 Hours open between $open_hours_since_start and $open_hours_since_end");
+
+my $christmas = DateTime->new(
+    year  => $today->year(),
+    month => 12,
+    day   => 25,
+);
+$calendar->edit_holiday("Christmas", '', "R", '', '', $christmas, $christmas);
+is($calendar->isOpened($christmas), 0, "Branch closed on Christmas : $christmas");
+
+my $newyear = DateTime->new(
+    year  => $today->year() +1,
+    month => 1,
+    day   => 1,
+);
+
+$calendar->edit_holiday("New Year", '', "R", '', '', $newyear, $newyear);
+is($calendar->isOpened($newyear), 0, "Branch closed on New Year : $newyear");
+
+#Hours between :
+my $date_due = DateTime->today->add(days =>1);
+my $date_returned = DateTime->today->add(hours => 8);
+my $hours_between = $calendar->hours_between($date_due, $date_returned);
+
+is($hours_between->in_units('hours'), 16, "Date due $date_due, returned $date_returned, 16 hours in advance");
+
+$date_due = DateTime->today->add(days =>1);
+$date_returned = DateTime->today->add(days => 2, hours=> 8);
+$hours_between = $calendar->hours_between($date_due, $date_returned);
+
+is($hours_between->in_units('hours'), -16, "Date due $date_due, returned $date_returned, 16 hours late");
+
+
+#delete holidays
+is($calendar->isOpened($today), 0, "Today is closed");
+$calendar->edit_holiday('', '', 'none', '', '', $unique_holiday, $unique_holiday);
+is($calendar->isOpened($today), 1, "Today's holiday was removed");
+
+my $new_open_hours = '08:00';
+$calendar->edit_holiday('', '', '', $new_open_hours, '', $today, $today);
+is($calendar->get_date_info($today, $branch1)->{openhour}, '08:00:00', "Open hour changed to 08:00:00");
+
+isnt($calendar->get_date_info($today, $branch1)->{closehour}, '', "Close hour not removed");
+
+my $delete_range_end = DateTime->today->add(days => 30);
+$calendar->edit_holiday('', '', 'none', '', '', $today, $delete_range_end);
+
+
+is($calendar->isOpened($today), 1, "Today's holiday was already removed");
+is($calendar->isOpened(DateTime->today->add(days => 1)), 1, "Tomorrow's holiday was removed");
+is($calendar->isOpened($delete_range_end), 1, "End of range holiday was removed");
+
+#Check if other branch was affected
+my @unique_holidays_branch2 = $calendar2->get_unique_holidays();
+is(scalar @unique_holidays_branch2, 0, "Set of exception holidays at 0 for branch => $branch2");
+my @repeatable_holidays_branch2 = $calendar2->get_repeatable_holidays();
+is(scalar @repeatable_holidays_branch2, 0, "Set of repeatable holidays at 0 for branch => $branch2");
+my @weekly_holidays_branch2 = $calendar2->get_week_days_holidays();
+is(scalar @weekly_holidays_branch2, 0, "Set of weekly holidays at 0 for branch => $branch2");
+
+
+#Tests for addDate()
+
+my $one_day_dur = DateTime::Duration->new( days => 1 );
+my $negative_one_day_dur = DateTime::Duration->new( days => - 1 );
+my $two_day_dur = DateTime::Duration->new( days => 2 );
+my $seven_day_dur = DateTime::Duration->new( days => 7 );
+
+#Preference useDaysMode Calendar
+$calendar->{days_mode} = 'Calendar';
+$unique_holiday->add(days => 1);
+my $tomorrow = DateTime->today->add(days => 1);
+$calendar->edit_holiday("Single holiday Today", '', "E", '', '', $tomorrow, $tomorrow);
+
+is($calendar->addDate( $today, $one_day_dur, 'days' )->ymd(),
+    $today->add(days => 2)->ymd(),
+    'Single day add (Calendar)' );
+
+is($calendar->addDate( $today, $two_day_dur, 'days' )->ymd(),
+    $today->add(days => 2)->ymd(),
+    'Two days add, skips holiday (Calendar)' );
+
+cmp_ok($calendar->addDate( $today, $seven_day_dur, 'days' )->ymd(), 'eq',
+    $today->add(days => 7)->ymd(),
+    'Add 7 days (Calendar)' );
+#Closed Sunday
+$calendar->edit_holiday("Weekly",1, "W", '', '', $today, $today);
+is( $calendar->addDate( $sunday, $one_day_dur, 'days' )->day_of_week, 1,
+    'addDate skips closed Sunday (Calendar)' );
+#to remove the closed sundays
+$today = DateTime->today;
+$calendar->edit_holiday('', '', 'none', '', '', $today, $delete_range_end);
+
+is( $calendar->addDate($today, $negative_one_day_dur , 'days')->ymd(),
+    $today->add(days => - 1)->ymd(),
+    'Negative call to addDate (Calendar)' );
+
+#Preference useDaysMode DateDue
+$calendar->{days_mode} = 'Datedue';
+#clean everything
+$today = DateTime->today;
+$calendar->edit_holiday('', '', 'none', '', '', $today, $delete_range_end);
+$calendar->edit_holiday("Single holiday Today", '', "E", '', '', $tomorrow, $tomorrow);
+
+is($calendar->addDate( $today, $one_day_dur, 'days' )->ymd(),
+    $today->add(days => 2)->ymd(),
+    'Single day add' );
+
+is($calendar->addDate( $today, $two_day_dur, 'days' )->ymd(),
+    $today->add(days => 2)->ymd(),
+    'Two days add, skips holiday (Datedue)' );
+
+cmp_ok($calendar->addDate( $today, $seven_day_dur, 'days' )->ymd(), 'eq',
+    $today->add(days => 7)->ymd(),
+    'Add 7 days (Datedue)' );
+#Closed Sunday
+$calendar->edit_holiday("Weekly",1, "W", '', '', $today, $today);
+is( $calendar->addDate( $sunday, $one_day_dur, 'days' )->day_of_week, 1,
+    'addDate skips closed Sunday (Datedue)' );
+#to remove the closed sundays
+$today = DateTime->today;
+$calendar->edit_holiday('', '', 'none', '', '', $today, $delete_range_end);
+
+is( $calendar->addDate($today, $negative_one_day_dur , 'days')->ymd(),
+    $today->add(days => - 1)->ymd(),
+    'Negative call to addDate (Datedue)' );
+
+#Preference useDaysMode Days
+$calendar->{days_mode} = 'Days';
+#clean everything
+$today = DateTime->today;
+$calendar->edit_holiday('', '', 'none', '', '', $today, $delete_range_end);
+$calendar->edit_holiday("Single holiday Today", '', "E", '', '', $tomorrow, $tomorrow);
+is($calendar->addDate( $today, $one_day_dur, 'days' )->ymd(),
+    $today->add(days => 1)->ymd(),
+    'Single day add' );
+
+is($calendar->addDate( $today, $two_day_dur, 'days' )->ymd(),
+    $today->add(days => 2)->ymd(),
+    'Two days add, skips holiday (Days)' );
+
+cmp_ok($calendar->addDate( $today, $seven_day_dur, 'days' )->ymd(), 'eq',
+    $today->add(days => 7)->ymd(),
+    'Add 7 days (Days)' );
+#Closed Sunday
+$calendar->edit_holiday("Weekly",1, "W", '', '', $today, $today);
+is( $calendar->addDate( $sunday, $one_day_dur, 'days' )->day_of_week, 1,
+    'addDate skips closed Sunday (Days)' );
+
+is( $calendar->addDate($today, $negative_one_day_dur , 'days')->ymd(),
+    $today->add(days => - 1)->ymd(),
+    'Negative call to addDate (Days)' );
+
+#Days_forward
+
+#clean the range
+$today = DateTime->today;
+$calendar->edit_holiday('', '', 'none', '', '', $today, DateTime->today->add(days => 20));
+my $forwarded_dt = $calendar->days_forward($today, 10);
+
+my $expected = $today->clone;
+$expected->add(days => 10);
+is($forwarded_dt->ymd, $expected->ymd, 'With no holiday on the perioddays_forward should add 10 days');
+
+#Added a holiday
+$unique_holiday = DateTime->today->add(days => 15);
+$calendar->edit_holiday("Single holiday Today", '', "E", '', '',$unique_holiday, $unique_holiday);
+$forwarded_dt = $calendar->days_forward($today, 20);
+
+$expected->add(days => 11);
+is($forwarded_dt->ymd, $expected->ymd, 'With holiday on the perioddays_forward should add 20 days + 1 day for holiday');
+
+$forwarded_dt = $calendar->days_forward($today, 0);
+is($forwarded_dt->ymd, $today->ymd, '0 day should return start dt');
+
+$forwarded_dt = $calendar->days_forward($today, -2);
+is($forwarded_dt->ymd, $today->ymd, 'negative day should return start dt');
+
+#copying a branch to an other
+is($calendar2->isOpened($tomorrow), 1, "$branch2 opened tomorrow");
+#Added a goliday tomorrow for branch1
+$calendar->edit_holiday("Single holiday Today", '', "E", '', '', $tomorrow, $tomorrow);
+#Copy dates from branch1 to branch2
+$calendar->copyToBranch($branch2);
+#Check if branch2 is also closed tomorrow after copying from branch1
+is($calendar2->isOpened($tomorrow), 0, "$branch2 close tomorrow after copying from $branch1");
+
+$schema->storage->txn_rollback;
+
+1;
-- 
1.9.1