Repository: peopledoc/workalendar
Pull request #25 (2019-04-12 12:28:42)

Australia: Family & Community Day
Family & Community Day follows a "weird" non-mathematical rule

https://en.wikipedia.org/wiki/Family_Day

~~Will try to find a better way to handle this.~~

This PR explicits a bit better how this day is assigned, and adds a few tests to make sure that boundaries are correctly respected.



Patch:
diff --git a/Changelog.md b/Changelog.md
index 7a4ad3e..bbcc2bc 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -2,7 +2,7 @@
 
 ## master
 
-Nothing here yet.
+- Added a few refactors and tests for Australia Capital Territory holiday named "Family & Community Day", that lasted from 2007 to 2017 (#25).
 
 ## v4.3.1 (2019-05-03)
 
diff --git a/workalendar/oceania/australia.py b/workalendar/oceania/australia.py
index b751af5..3b675e1 100644
--- a/workalendar/oceania/australia.py
+++ b/workalendar/oceania/australia.py
@@ -97,16 +97,27 @@ class AustralianCapitalTerritory(Australia):
     include_labour_day_october = True
     include_boxing_day = True
 
+    _family_community_label = "Family & Community Day"
+
     def get_family_community_day(self, year):
-        # Since this day is picked unsing the school year calendar, there's no
-        # mathematical way yet to provide it surely
+        """
+        Return Family & Community Day.
 
-        # Family & Community Day was celebrated on the first Tuesday of
-        # November in 2007, 2008 and 2009
+        see: https://en.wikipedia.org/wiki/Family_Day#Australia
+        """
+        # Since this day is picked unsing the school year calendar, there's no
+        # mathematical way yet to compute it.
 
+        # This public holiday was declared in 2007. [..]
         # Per Holidays (Reconciliation Day) Amendment Bill 2017, 2017 is the
         # last year that ACT will celebrate family and community day. It is
-        # being replaced by Reconciliaton day
+        # being replaced by Reconciliaton day.
+        if year < 2007 or year > 2018:
+            # This would be interpreted as "this holiday must not be added"
+            return None
+
+        # Family & Community Day was celebrated on the first Tuesday of
+        # November in 2007, 2008 and 2009
         if year in (2007, 2008, 2009):
             day = AustralianCapitalTerritory.get_nth_weekday_in_month(
                 year, 11, TUE)
@@ -121,18 +132,28 @@ class AustralianCapitalTerritory(Australia):
             day = AustralianCapitalTerritory.get_nth_weekday_in_month(
                 year, 10, MON, 2)
         else:
+            # If for some reason the year is not correctly provided
+            # (not and int, or whatever)
             return None
-        return (day, "Family & Community Day")
+
+        return (day, self._family_community_label)
 
     def get_reconciliation_day(self, year):
-        if year >= 2018:
-            reconciliation_day = date(year, 5, 27)
-            if reconciliation_day.weekday() == MON:
-                return (reconciliation_day, "Reconciliation Day")
-            else:
-                shift = AustralianCapitalTerritory.get_first_weekday_after(
-                    reconciliation_day, MON)
-                return shift, "Reconciliation Day Shift"
+        """
+        Return Reconciliaton Day.
+
+        As of 2018, it replaces Family & Community Day.
+        """
+        if year < 2018:
+            return None
+
+        reconciliation_day = date(year, 5, 27)
+        if reconciliation_day.weekday() == MON:
+            return (reconciliation_day, "Reconciliation Day")
+        else:
+            shift = AustralianCapitalTerritory.get_first_weekday_after(
+                reconciliation_day, MON)
+            return shift, "Reconciliation Day Shift"
 
     def get_variable_days(self, year):
         days = super(AustralianCapitalTerritory, self).get_variable_days(year)


Test patch:
diff --git a/workalendar/tests/test_oceania.py b/workalendar/tests/test_oceania.py
index b18abeb..4816b7d 100644
--- a/workalendar/tests/test_oceania.py
+++ b/workalendar/tests/test_oceania.py
@@ -63,10 +63,38 @@ class AustraliaCapitalTerritoryTest(AustraliaTest):
         self.assertIn(date(2013, 3, 30), holidays)  # Easter Saturday
         self.assertIn(date(2013, 4, 1), holidays)  # Easter Monday
         self.assertIn(date(2013, 6, 10), holidays)  # Queen's Bday
-        self.assertIn(date(2013, 9, 30), holidays)
+        self.assertIn(date(2013, 9, 30), holidays)  # Family & Community day
         self.assertIn(date(2013, 10, 7), holidays)  # Labour day october
         self.assertIn(date(2013, 12, 26), holidays)  # Boxing day
 
+    def test_family_community_day_before_2007(self):
+        # There were no Family and Community day before 2007
+        for year in range(1970, 2007):
+            self.assertIsNone(self.cal.get_family_community_day(year))
+            holidays = self.cal.holidays(year)
+            holidays = dict(holidays)
+            labels = holidays.values()
+            self.assertNotIn(self.cal._family_community_label, labels)
+
+    def test_family_community_day_2007_2017_presence(self):
+        # Family & Community day was included [2007 -> 2017]
+        for year in range(2007, 2018):
+            self.assertIsNotNone(self.cal.get_family_community_day(year))
+            holidays = self.cal.holidays(year)
+            holidays = dict(holidays)
+            labels = holidays.values()
+            self.assertIn(self.cal._family_community_label, labels)
+
+    def test_family_community_day_after_2017(self):
+        # Starting of 2018 this day would no longer exist
+        for year in range(2018, date.today().year + 1):
+            self.assertIsNone(self.cal.get_family_community_day(year))
+            holidays = self.cal.holidays(year)
+            holidays = dict(holidays)
+            labels = holidays.values()
+            print(labels)
+            self.assertNotIn(self.cal._family_community_label, labels)
+
     def test_reconciliation_day(self):
         reconciliation_day = self.cal.get_reconciliation_day(2017)
         self.assertIsNone(reconciliation_day)