def test_sort_order(self):
     """
     Test: _sort_order orders a list of cycles by start date
     When: Called with a list of cycles
     """
     # Note: This test assumes self.test_cycle_data is ordered
     local_cycle_data = [self.test_cycle_data[1], self.test_cycle_data[2], self.test_cycle_data[0]]
     sdp = SchedulerDataProcessor()
     result = sdp._sort_by_date(local_cycle_data)
     self.assertEqual(self.test_cycle_data, result)
 def test_conversion_with_invalid_args(self):
     """
     Test: A KeyError is thrown
     When: convert_raw_to_structured is called and a cycle attribute is missing
     """
     local_cycle_data = self.test_cycle_data.copy()
     local_cycle_data[0].pop("start")
     sdp = SchedulerDataProcessor()
     with self.assertRaises(KeyError):
         sdp.convert_raw_to_structured(local_cycle_data, self.test_maintenance_dict.values())
 def test_clean_with_invalid_name(self):
     """
     Test: _clean_data removes the cycle with an invalid name
     When: Called with data containing a cycle with an invalid name
     """
     # Note: Assumes all other entries in test_cycle_data are valid
     local_cycle_data = self.test_cycle_data.copy()
     local_cycle_data[0]["name"] = "invalid"
     sdp = SchedulerDataProcessor()
     result = sdp._clean_data(local_cycle_data)
     self.assertTrue(len(result) == len(local_cycle_data) - 1)
 def test_pre_process_with_valid_data(self, mocked_sort_by_date, mocked_clean_data):
     """
     Test: _pre_process calls both _clean_data and _sort_by_date twice (once for each
     data-set given) and returns 2 lists
     When: Called with valid data-sets
     """
     sdp = SchedulerDataProcessor()
     result = sdp._pre_process(self.test_cycle_data, self.test_maintenance_dict.values())
     self.assertEqual(2, mocked_sort_by_date.call_count)
     self.assertEqual(2, mocked_clean_data.call_count)
     self.assertEqual(2, len(result))
 def test_clean_with_invalid_date(self):
     """
     Test: _clean_data removes the cycle with an invalid date
     When: Called with data containing a cycle with a date 1 day
     before the earliest possible (specified by the SchedulerDataProcessor)
     """
     sdp = SchedulerDataProcessor()
     local_cycle_data = self.test_cycle_data.copy()
     earlier_than_possible = sdp._earliest_possible_date + relativedelta(days=-1)
     local_cycle_data[0]["start"] = earlier_than_possible
     result = sdp._clean_data(local_cycle_data)
     self.assertEqual(len(local_cycle_data) - 1, len(result))
    def test_process_with_maintenance_after_cycles(self, mocked_md_warning):
        """
        Test: _process calls _md_warning, and doesn't add the current maintenance day to any cycle
        When: _process encounters a maintenance day start value *later* than any cycle end date
        """
        sdp = SchedulerDataProcessor()
        cycles = sdp._process(self.test_cycle_data, [self.test_maintenance_dict["after_cycles"]])

        (_, kwargs) = mocked_md_warning.call_args
        self.assertEqual(kwargs["md_data"], self.test_maintenance_dict["after_cycles"])
        self.assertEqual(kwargs["cycle_before"], self.create_cycle_from_dict(self.test_cycle_data[2]))
        self.assertIsNone(kwargs["cycle_after"])

        self.check_process_output(cycles, len(self.test_cycle_data))
    def test_process_with_maintenance_between_cycles(self, mocked_md_warning):
        """
        Test: _process calls _md_warning, and doesn't add the current maintenance day to any cycle
        When: _process encounters a maintenance day start value *in-between* the previous cycle end
        date and current cycle start date
        """
        local_cycle_data = self.test_cycle_data.copy()
        local_cycle_data[0]["end"] = local_cycle_data[0]["start"] + relativedelta(days=1)
        sdp = SchedulerDataProcessor()
        cycles = sdp._process(self.test_cycle_data, [self.test_maintenance_dict["within_first_cycle"]])

        (_, kwargs) = mocked_md_warning.call_args
        self.assertEqual(kwargs["md_data"], self.test_maintenance_dict["within_first_cycle"])
        self.assertEqual(kwargs["cycle_before"], self.create_cycle_from_dict(self.test_cycle_data[0]))
        self.assertEqual(kwargs["cycle_after"], self.create_cycle_from_dict(self.test_cycle_data[1]))

        self.check_process_output(cycles, len(self.test_cycle_data))
 def test_process_with_maintenance_within_cycles(self, mocked_md_warning):
     """
     Test: _process adds the current maintenance day to the appropriate cycle
     When: _process encounters a maintenance day which starts and ends within
     the given cycle's start and end dates
     """
     sdp = SchedulerDataProcessor()
     cycles = sdp._process(self.test_cycle_data, [self.test_maintenance_dict["within_first_cycle"]])
     mocked_md_warning.assert_not_called()
     self.assertEqual(len(self.test_cycle_data), len(cycles))
     for cycle in cycles:
         self.assertIsInstance(cycle, Cycle)
         if cycle is not cycles[0]:
             self.assertEqual(0, len(cycle.maintenance_days))
     self.assertEqual(1, len(cycles[0].maintenance_days))
     m_day = cycles[0].maintenance_days.pop()
     self.assertTrue(m_day.start == self.test_maintenance_dict["within_first_cycle"]["start"]
                     and m_day.end == self.test_maintenance_dict["within_first_cycle"]["end"])
 def test_init(self):
     """
     Test: Class variables are created and set
     When: SchedulerDataProcessor is initialised
     """
     sdp = SchedulerDataProcessor()
     self.assertIsInstance(sdp._earliest_possible_date, datetime)
     self.assertIsInstance(sdp._cycle_name_regex, str)
     self.assertIsInstance(sdp._datetime_fields, list)
     self.assertIsInstance(sdp._sort_by_field, str)