def test_param_text_match(self): self.cal = ICalendarFile([EXAMPLE_VCALENDAR_WITH_PARAM], "text/calendar") filter = CalendarFilter(None) filter.filter_subcomponent("VCALENDAR").filter_subcomponent( "VTODO" ).filter_property("CREATED").filter_parameter("TZID").filter_text_match( b"America/Blah" ) self.assertEqual( filter.index_keys(), [ ["C=VCALENDAR/C=VTODO/P=CREATED/A=TZID"], ["C=VCALENDAR/C=VTODO/P=CREATED"], ], ) self.assertFalse( filter.check_from_indexes( "file", {"C=VCALENDAR/C=VTODO/P=CREATED/A=TZID": [b"America/Denver"]}, ) ) self.assertFalse(filter.check("file", self.cal)) filter = CalendarFilter(None) filter.filter_subcomponent("VCALENDAR").filter_subcomponent( "VTODO" ).filter_property("CREATED").filter_parameter("TZID").filter_text_match( b"America/Denver" ) self.assertTrue( filter.check_from_indexes( "file", {"C=VCALENDAR/C=VTODO/P=CREATED/A=TZID": [b"America/Denver"]}, ) ) self.assertTrue(filter.check("file", self.cal))
def test_extract_no_uid(self): fi = ICalendarFile([EXAMPLE_VCALENDAR_NO_UID], 'text/calendar') fi.validate() self.assertEqual(["Missing required field UID"], list(validate_calendar(fi.calendar, strict=True))) self.assertEqual([], list(validate_calendar(fi.calendar, strict=False))) self.assertRaises(KeyError, fi.get_uid)
def test_invalid_character(self): fi = ICalendarFile([EXAMPLE_VCALENDAR_INVALID_CHAR], "text/calendar") self.assertRaises(InvalidFileContents, fi.validate) self.assertEqual( ["Invalid character b'\\\\x0c' in field SUMMARY"], list(validate_calendar(fi.calendar, strict=False)), )
def test_param_text_match(self): self.cal = ICalendarFile([EXAMPLE_VCALENDAR_WITH_PARAM], 'text/calendar') filter = CalendarFilter(None) filter.filter_subcomponent('VCALENDAR').filter_subcomponent( 'VTODO').filter_property('CREATED').filter_parameter( 'TZID').filter_text_match(b'America/Blah') self.assertEqual(filter.index_keys(), [['C=VCALENDAR/C=VTODO/P=CREATED/A=TZID'], ['C=VCALENDAR/C=VTODO/P=CREATED']]) self.assertFalse( filter.check_from_indexes( 'file', {'C=VCALENDAR/C=VTODO/P=CREATED/A=TZID': [b'America/Denver']})) self.assertFalse(filter.check('file', self.cal)) filter = CalendarFilter(None) filter.filter_subcomponent('VCALENDAR').filter_subcomponent( 'VTODO').filter_property('CREATED').filter_parameter( 'TZID').filter_text_match(b'America/Denver') self.assertTrue( filter.check_from_indexes( 'file', {'C=VCALENDAR/C=VTODO/P=CREATED/A=TZID': [b'America/Denver']})) self.assertTrue(filter.check('file', self.cal))
def test_extract_str(self): fi = ICalendarFile([EXAMPLE_VCALENDAR1], 'text/calendar') self.assertEqual('bdc22720-b9e1-42c9-89c2-a85405d8fbff', fi.get_uid()) fi.validate()
def test_extract_no_uid(self): fi = ICalendarFile([EXAMPLE_VCALENDAR_NO_UID], 'text/calendar') self.assertRaises(KeyError, fi.get_uid)
def setUp(self): self.cal = ICalendarFile([EXAMPLE_VCALENDAR1], "text/calendar")
class CalendarFilterTests(unittest.TestCase): def setUp(self): self.cal = ICalendarFile([EXAMPLE_VCALENDAR1], "text/calendar") def test_simple_comp_filter(self): filter = CalendarFilter(None) filter.filter_subcomponent("VCALENDAR").filter_subcomponent("VEVENT") self.assertEqual(filter.index_keys(), [["C=VCALENDAR/C=VEVENT"]]) self.assertEqual( self.cal.get_indexes(["C=VCALENDAR/C=VEVENT", "C=VCALENDAR/C=VTODO"]), {"C=VCALENDAR/C=VEVENT": [], "C=VCALENDAR/C=VTODO": [True]}, ) self.assertFalse( filter.check_from_indexes( "file", {"C=VCALENDAR/C=VEVENT": [], "C=VCALENDAR/C=VTODO": [True]}, ) ) self.assertFalse(filter.check("file", self.cal)) filter = CalendarFilter(None) filter.filter_subcomponent("VCALENDAR").filter_subcomponent("VTODO") self.assertTrue(filter.check("file", self.cal)) self.assertTrue( filter.check_from_indexes( "file", {"C=VCALENDAR/C=VEVENT": [], "C=VCALENDAR/C=VTODO": [True]}, ) ) def test_simple_comp_missing_filter(self): filter = CalendarFilter(None) filter.filter_subcomponent("VCALENDAR").filter_subcomponent( "VTODO", is_not_defined=True ) self.assertEqual( filter.index_keys(), [["C=VCALENDAR/C=VTODO"], ["C=VCALENDAR"]] ) self.assertFalse( filter.check_from_indexes( "file", { "C=VCALENDAR": [True], "C=VCALENDAR/C=VEVENT": [], "C=VCALENDAR/C=VTODO": [True], }, ) ) self.assertFalse(filter.check("file", self.cal)) filter = CalendarFilter(None) filter.filter_subcomponent("VCALENDAR").filter_subcomponent( "VEVENT", is_not_defined=True ) self.assertTrue(filter.check("file", self.cal)) self.assertTrue( filter.check_from_indexes( "file", { "C=VCALENDAR": [True], "C=VCALENDAR/C=VEVENT": [], "C=VCALENDAR/C=VTODO": [True], }, ) ) def test_prop_presence_filter(self): filter = CalendarFilter(None) filter.filter_subcomponent("VCALENDAR").filter_subcomponent( "VTODO" ).filter_property("X-SUMMARY") self.assertEqual(filter.index_keys(), [["C=VCALENDAR/C=VTODO/P=X-SUMMARY"]]) self.assertFalse( filter.check_from_indexes("file", {"C=VCALENDAR/C=VTODO/P=X-SUMMARY": []}) ) self.assertFalse(filter.check("file", self.cal)) filter = CalendarFilter(None) filter.filter_subcomponent("VCALENDAR").filter_subcomponent( "VTODO" ).filter_property("SUMMARY") self.assertTrue( filter.check_from_indexes( "file", {"C=VCALENDAR/C=VTODO/P=SUMMARY": [b"do something"]} ) ) self.assertTrue(filter.check("file", self.cal)) def test_prop_explicitly_missing_filter(self): filter = CalendarFilter(None) filter.filter_subcomponent("VCALENDAR").filter_subcomponent( "VEVENT" ).filter_property("X-SUMMARY", is_not_defined=True) self.assertEqual( filter.index_keys(), [["C=VCALENDAR/C=VEVENT/P=X-SUMMARY"], ["C=VCALENDAR/C=VEVENT"]], ) self.assertFalse( filter.check_from_indexes( "file", { "C=VCALENDAR/C=VEVENT/P=X-SUMMARY": [], "C=VCALENDAR/C=VEVENT": [], }, ) ) self.assertFalse(filter.check("file", self.cal)) filter = CalendarFilter(None) filter.filter_subcomponent("VCALENDAR").filter_subcomponent( "VTODO" ).filter_property("X-SUMMARY", is_not_defined=True) self.assertTrue( filter.check_from_indexes( "file", { "C=VCALENDAR/C=VTODO/P=X-SUMMARY": [], "C=VCALENDAR/C=VTODO": [True], }, ) ) self.assertTrue(filter.check("file", self.cal)) def test_prop_text_match(self): filter = CalendarFilter(None) filter.filter_subcomponent("VCALENDAR").filter_subcomponent( "VTODO" ).filter_property("SUMMARY").filter_text_match(b"do something different") self.assertEqual(filter.index_keys(), [["C=VCALENDAR/C=VTODO/P=SUMMARY"]]) self.assertFalse( filter.check_from_indexes( "file", {"C=VCALENDAR/C=VTODO/P=SUMMARY": [b"do something"]} ) ) self.assertFalse(filter.check("file", self.cal)) filter = CalendarFilter(None) filter.filter_subcomponent("VCALENDAR").filter_subcomponent( "VTODO" ).filter_property("SUMMARY").filter_text_match(b"do something") self.assertTrue( filter.check_from_indexes( "file", {"C=VCALENDAR/C=VTODO/P=SUMMARY": [b"do something"]} ) ) self.assertTrue(filter.check("file", self.cal)) def test_param_text_match(self): self.cal = ICalendarFile([EXAMPLE_VCALENDAR_WITH_PARAM], "text/calendar") filter = CalendarFilter(None) filter.filter_subcomponent("VCALENDAR").filter_subcomponent( "VTODO" ).filter_property("CREATED").filter_parameter("TZID").filter_text_match( b"America/Blah" ) self.assertEqual( filter.index_keys(), [ ["C=VCALENDAR/C=VTODO/P=CREATED/A=TZID"], ["C=VCALENDAR/C=VTODO/P=CREATED"], ], ) self.assertFalse( filter.check_from_indexes( "file", {"C=VCALENDAR/C=VTODO/P=CREATED/A=TZID": [b"America/Denver"]}, ) ) self.assertFalse(filter.check("file", self.cal)) filter = CalendarFilter(None) filter.filter_subcomponent("VCALENDAR").filter_subcomponent( "VTODO" ).filter_property("CREATED").filter_parameter("TZID").filter_text_match( b"America/Denver" ) self.assertTrue( filter.check_from_indexes( "file", {"C=VCALENDAR/C=VTODO/P=CREATED/A=TZID": [b"America/Denver"]}, ) ) self.assertTrue(filter.check("file", self.cal)) def _tzify(self, dt): return as_tz_aware_ts(dt, pytz.utc) def test_prop_apply_time_range(self): filter = CalendarFilter(self._tzify) filter.filter_subcomponent("VCALENDAR").filter_subcomponent( "VTODO" ).filter_property("CREATED").filter_time_range( self._tzify(datetime(2019, 3, 10, 22, 35, 12)), self._tzify(datetime(2019, 3, 18, 22, 35, 12)), ) self.assertEqual(filter.index_keys(), [["C=VCALENDAR/C=VTODO/P=CREATED"]]) self.assertFalse( filter.check_from_indexes( "file", {"C=VCALENDAR/C=VTODO/P=CREATED": ["20150314T223512Z"]} ) ) self.assertFalse(filter.check("file", self.cal)) filter = CalendarFilter(self._tzify) filter.filter_subcomponent("VCALENDAR").filter_subcomponent( "VTODO" ).filter_property("CREATED").filter_time_range( self._tzify(datetime(2015, 3, 10, 22, 35, 12)), self._tzify(datetime(2015, 3, 18, 22, 35, 12)), ) self.assertTrue( filter.check_from_indexes( "file", {"C=VCALENDAR/C=VTODO/P=CREATED": ["20150314T223512Z"]} ) ) self.assertTrue(filter.check("file", self.cal)) def test_comp_apply_time_range(self): filter = CalendarFilter(self._tzify) filter.filter_subcomponent("VCALENDAR").filter_subcomponent( "VTODO" ).filter_time_range( self._tzify(datetime(2015, 3, 3, 22, 35, 12)), self._tzify(datetime(2015, 3, 10, 22, 35, 12)), ) self.assertEqual( filter.index_keys(), [ ["C=VCALENDAR/C=VTODO/P=DTSTART"], ["C=VCALENDAR/C=VTODO/P=DUE"], ["C=VCALENDAR/C=VTODO/P=DURATION"], ["C=VCALENDAR/C=VTODO/P=CREATED"], ["C=VCALENDAR/C=VTODO/P=COMPLETED"], ["C=VCALENDAR/C=VTODO"], ], ) self.assertFalse( filter.check_from_indexes( "file", { "C=VCALENDAR/C=VTODO/P=CREATED": ["20150314T223512Z"], "C=VCALENDAR/C=VTODO": [True], "C=VCALENDAR/C=VTODO/P=DUE": [], "C=VCALENDAR/C=VTODO/P=DURATION": [], "C=VCALENDAR/C=VTODO/P=COMPLETED": [], "C=VCALENDAR/C=VTODO/P=DTSTART": [], }, ) ) self.assertFalse(filter.check("file", self.cal)) filter = CalendarFilter(self._tzify) filter.filter_subcomponent("VCALENDAR").filter_subcomponent( "VTODO" ).filter_time_range( self._tzify(datetime(2015, 3, 10, 22, 35, 12)), self._tzify(datetime(2015, 3, 18, 22, 35, 12)), ) self.assertTrue( filter.check_from_indexes( "file", { "C=VCALENDAR/C=VTODO/P=CREATED": ["20150314T223512Z"], "C=VCALENDAR/C=VTODO": [True], "C=VCALENDAR/C=VTODO/P=DUE": [], "C=VCALENDAR/C=VTODO/P=DURATION": [], "C=VCALENDAR/C=VTODO/P=COMPLETED": [], "C=VCALENDAR/C=VTODO/P=DTSTART": [], }, ) ) self.assertTrue(filter.check("file", self.cal))
class CalendarFilterTests(unittest.TestCase): def setUp(self): self.cal = ICalendarFile([EXAMPLE_VCALENDAR1], 'text/calendar') def test_simple_comp_filter(self): filter = CalendarFilter(None) filter.filter_subcomponent('VCALENDAR').filter_subcomponent('VEVENT') self.assertEqual(filter.index_keys(), [['C=VCALENDAR/C=VEVENT']]) self.assertEqual( self.cal.get_indexes( ['C=VCALENDAR/C=VEVENT', 'C=VCALENDAR/C=VTODO']), { 'C=VCALENDAR/C=VEVENT': [], 'C=VCALENDAR/C=VTODO': [True] }) self.assertFalse( filter.check_from_indexes('file', { 'C=VCALENDAR/C=VEVENT': [], 'C=VCALENDAR/C=VTODO': [True] })) self.assertFalse(filter.check('file', self.cal)) filter = CalendarFilter(None) filter.filter_subcomponent('VCALENDAR').filter_subcomponent('VTODO') self.assertTrue(filter.check('file', self.cal)) self.assertTrue( filter.check_from_indexes('file', { 'C=VCALENDAR/C=VEVENT': [], 'C=VCALENDAR/C=VTODO': [True] })) def test_simple_comp_missing_filter(self): filter = CalendarFilter(None) filter.filter_subcomponent('VCALENDAR').filter_subcomponent( 'VTODO', is_not_defined=True) self.assertEqual(filter.index_keys(), [['C=VCALENDAR/C=VTODO'], ['C=VCALENDAR']]) self.assertFalse( filter.check_from_indexes( 'file', { 'C=VCALENDAR': [True], 'C=VCALENDAR/C=VEVENT': [], 'C=VCALENDAR/C=VTODO': [True] })) self.assertFalse(filter.check('file', self.cal)) filter = CalendarFilter(None) filter.filter_subcomponent('VCALENDAR').filter_subcomponent( 'VEVENT', is_not_defined=True) self.assertTrue(filter.check('file', self.cal)) self.assertTrue( filter.check_from_indexes( 'file', { 'C=VCALENDAR': [True], 'C=VCALENDAR/C=VEVENT': [], 'C=VCALENDAR/C=VTODO': [True] })) def test_prop_presence_filter(self): filter = CalendarFilter(None) filter.filter_subcomponent('VCALENDAR').filter_subcomponent( 'VTODO').filter_property('X-SUMMARY') self.assertEqual(filter.index_keys(), [['C=VCALENDAR/C=VTODO/P=X-SUMMARY']]) self.assertFalse( filter.check_from_indexes('file', {'C=VCALENDAR/C=VTODO/P=X-SUMMARY': []})) self.assertFalse(filter.check('file', self.cal)) filter = CalendarFilter(None) filter.filter_subcomponent('VCALENDAR').filter_subcomponent( 'VTODO').filter_property('SUMMARY') self.assertTrue( filter.check_from_indexes( 'file', {'C=VCALENDAR/C=VTODO/P=SUMMARY': [b'do something']})) self.assertTrue(filter.check('file', self.cal)) def test_prop_explicitly_missing_filter(self): filter = CalendarFilter(None) filter.filter_subcomponent('VCALENDAR').filter_subcomponent( 'VEVENT').filter_property('X-SUMMARY', is_not_defined=True) self.assertEqual( filter.index_keys(), [['C=VCALENDAR/C=VEVENT/P=X-SUMMARY'], ['C=VCALENDAR/C=VEVENT']]) self.assertFalse( filter.check_from_indexes('file', { 'C=VCALENDAR/C=VEVENT/P=X-SUMMARY': [], 'C=VCALENDAR/C=VEVENT': [] })) self.assertFalse(filter.check('file', self.cal)) filter = CalendarFilter(None) filter.filter_subcomponent('VCALENDAR').filter_subcomponent( 'VTODO').filter_property('X-SUMMARY', is_not_defined=True) self.assertTrue( filter.check_from_indexes( 'file', { 'C=VCALENDAR/C=VTODO/P=X-SUMMARY': [], 'C=VCALENDAR/C=VTODO': [True] })) self.assertTrue(filter.check('file', self.cal)) def test_prop_text_match(self): filter = CalendarFilter(None) filter.filter_subcomponent('VCALENDAR').filter_subcomponent( 'VTODO').filter_property('SUMMARY').filter_text_match( b'do something different') self.assertEqual(filter.index_keys(), [['C=VCALENDAR/C=VTODO/P=SUMMARY']]) self.assertFalse( filter.check_from_indexes( 'file', {'C=VCALENDAR/C=VTODO/P=SUMMARY': [b'do something']})) self.assertFalse(filter.check('file', self.cal)) filter = CalendarFilter(None) filter.filter_subcomponent('VCALENDAR').filter_subcomponent( 'VTODO').filter_property('SUMMARY').filter_text_match( b'do something') self.assertTrue( filter.check_from_indexes( 'file', {'C=VCALENDAR/C=VTODO/P=SUMMARY': [b'do something']})) self.assertTrue(filter.check('file', self.cal)) def test_param_text_match(self): self.cal = ICalendarFile([EXAMPLE_VCALENDAR_WITH_PARAM], 'text/calendar') filter = CalendarFilter(None) filter.filter_subcomponent('VCALENDAR').filter_subcomponent( 'VTODO').filter_property('CREATED').filter_parameter( 'TZID').filter_text_match(b'America/Blah') self.assertEqual(filter.index_keys(), [['C=VCALENDAR/C=VTODO/P=CREATED/A=TZID'], ['C=VCALENDAR/C=VTODO/P=CREATED']]) self.assertFalse( filter.check_from_indexes( 'file', {'C=VCALENDAR/C=VTODO/P=CREATED/A=TZID': [b'America/Denver']})) self.assertFalse(filter.check('file', self.cal)) filter = CalendarFilter(None) filter.filter_subcomponent('VCALENDAR').filter_subcomponent( 'VTODO').filter_property('CREATED').filter_parameter( 'TZID').filter_text_match(b'America/Denver') self.assertTrue( filter.check_from_indexes( 'file', {'C=VCALENDAR/C=VTODO/P=CREATED/A=TZID': [b'America/Denver']})) self.assertTrue(filter.check('file', self.cal)) def _tzify(self, dt): return as_tz_aware_ts(dt, pytz.utc) def test_prop_apply_time_range(self): filter = CalendarFilter(self._tzify) filter.filter_subcomponent('VCALENDAR').filter_subcomponent( 'VTODO').filter_property('CREATED').filter_time_range( self._tzify(datetime(2019, 3, 10, 22, 35, 12)), self._tzify(datetime(2019, 3, 18, 22, 35, 12))) self.assertEqual(filter.index_keys(), [['C=VCALENDAR/C=VTODO/P=CREATED']]) self.assertFalse( filter.check_from_indexes( 'file', {'C=VCALENDAR/C=VTODO/P=CREATED': ['20150314T223512Z']})) self.assertFalse(filter.check('file', self.cal)) filter = CalendarFilter(self._tzify) filter.filter_subcomponent('VCALENDAR').filter_subcomponent( 'VTODO').filter_property('CREATED').filter_time_range( self._tzify(datetime(2015, 3, 10, 22, 35, 12)), self._tzify(datetime(2015, 3, 18, 22, 35, 12))) self.assertTrue( filter.check_from_indexes( 'file', {'C=VCALENDAR/C=VTODO/P=CREATED': ['20150314T223512Z']})) self.assertTrue(filter.check('file', self.cal)) def test_comp_apply_time_range(self): filter = CalendarFilter(self._tzify) filter.filter_subcomponent('VCALENDAR').filter_subcomponent( 'VTODO').filter_time_range( self._tzify(datetime(2015, 3, 3, 22, 35, 12)), self._tzify(datetime(2015, 3, 10, 22, 35, 12))) self.assertEqual( filter.index_keys(), [['C=VCALENDAR/C=VTODO/P=DTSTART'], ['C=VCALENDAR/C=VTODO/P=DUE'], ['C=VCALENDAR/C=VTODO/P=DURATION'], ['C=VCALENDAR/C=VTODO/P=CREATED'], ['C=VCALENDAR/C=VTODO/P=COMPLETED'], ['C=VCALENDAR/C=VTODO']]) self.assertFalse( filter.check_from_indexes( 'file', { 'C=VCALENDAR/C=VTODO/P=CREATED': ['20150314T223512Z'], 'C=VCALENDAR/C=VTODO': [True], 'C=VCALENDAR/C=VTODO/P=DUE': [], 'C=VCALENDAR/C=VTODO/P=DURATION': [], 'C=VCALENDAR/C=VTODO/P=COMPLETED': [], 'C=VCALENDAR/C=VTODO/P=DTSTART': [], })) self.assertFalse(filter.check('file', self.cal)) filter = CalendarFilter(self._tzify) filter.filter_subcomponent('VCALENDAR').filter_subcomponent( 'VTODO').filter_time_range( self._tzify(datetime(2015, 3, 10, 22, 35, 12)), self._tzify(datetime(2015, 3, 18, 22, 35, 12))) self.assertTrue( filter.check_from_indexes( 'file', { 'C=VCALENDAR/C=VTODO/P=CREATED': ['20150314T223512Z'], 'C=VCALENDAR/C=VTODO': [True], 'C=VCALENDAR/C=VTODO/P=DUE': [], 'C=VCALENDAR/C=VTODO/P=DURATION': [], 'C=VCALENDAR/C=VTODO/P=COMPLETED': [], 'C=VCALENDAR/C=VTODO/P=DTSTART': [], })) self.assertTrue(filter.check('file', self.cal))