def test_invalid_frequency_recurrence_object_raises(): with pytest.raises(recurrence.SerializationError): EventWithNoNulls.objects.create(recurs=Recurrence( rrules=[Rule('fish')])) with pytest.raises(recurrence.SerializationError): EventWithNoNulls.objects.create(recurs=Recurrence(rrules=[Rule(42)]))
def test_invalid_interval_recurrence_object_raises(): with pytest.raises(recurrence.SerializationError): EventWithNoNulls.objects.create(recurs=Recurrence( rrules=[Rule(recurrence.DAILY, interval=0)])) with pytest.raises(recurrence.SerializationError): EventWithNoNulls.objects.create(recurs=Recurrence( rrules=[Rule(recurrence.DAILY, interval='cat')]))
def test_rule_to_text_yearly_byday(): assert Rule( recurrence.YEARLY, byday=[1, 3], ).to_text() == 'annually, on the Tuesday, Thursday' assert Rule( recurrence.YEARLY, byday=[1, 3], ).to_text(True) == 'annually, on the Tue, Thu'
def test_rule_to_text_yearly_bymonth(): assert Rule( recurrence.YEARLY, bymonth=[1, 3], ).to_text() == 'annually, each January, March' assert Rule( recurrence.YEARLY, bymonth=[1, 3], ).to_text(True) == 'annually, each Jan, Mar'
def test_rule_to_text_occurences(): assert Rule( recurrence.MONTHLY, bysetpos=[5], byday=recurrence.FR ).to_text() == 'monthly, on the fifth Friday' assert Rule( recurrence.MONTHLY, bysetpos=[4], byday=recurrence.FR ).to_text(True) == 'monthly, on the 4th Fri'
def test_strip_dtstart_and_dtend_if_required(self): """Test that naive datetimes will get converted to UTC and returned as UTC.""" rule = Rule(recurrence.WEEKLY) limits = Recurrence(dtstart=datetime(2014, 1, 1, 0, 0, 0), dtend=datetime(2014, 2, 3, 0, 0, 0), rrules=[rule]) value = recurrence.serialize(limits) field = RecurrenceField() cleaned_value = field.clean(value) assert cleaned_value.rrules == [rule] assert cleaned_value.dtstart == datetime(2014, 1, 1, 0, 0, 0, tzinfo=pytz.utc) assert cleaned_value.dtend == datetime(2014, 2, 3, 0, 0, 0, tzinfo=pytz.utc) field = RecurrenceField(accept_dtstart=False, accept_dtend=False) cleaned_value = field.clean(value) assert cleaned_value != limits assert cleaned_value.dtstart is None assert cleaned_value.dtend is None
def test_check_allowable_frequencies(): rule = Rule( recurrence.WEEKLY ) limits = Recurrence( rrules=[rule] ) value = recurrence.serialize(limits) field = RecurrenceField(frequencies=[ recurrence.WEEKLY ]) field.clean(value) field = RecurrenceField(frequencies=[ recurrence.YEARLY ]) with pytest.raises(forms.ValidationError) as e: field.clean(value) assert e.value.messages[0] == "Invalid frequency." limits = Recurrence( exrules=[rule] ) value = recurrence.serialize(limits) with pytest.raises(forms.ValidationError) as e: field.clean(value) assert e.value.messages[0] == "Invalid frequency."
def test_include_dtstart_from_field(): rule = Rule( recurrence.WEEKLY, byday=recurrence.MONDAY ) limits = Recurrence( rrules=[rule] ) value = recurrence.serialize(limits) model_field = recurrence.fields.RecurrenceField() # Test with include_dtstart=True (default) rec_obj = model_field.to_python(value) assert rec_obj == limits # 2nd of August (dtstart) is expected but only for inc=True assert rec_obj.between(datetime(2015, 8, 2), datetime(2015, 8, 11), inc=True, dtstart=datetime(2015, 8, 2)) == [ datetime(2015, 8, 2, 0, 0), datetime(2015, 8, 3, 0, 0), datetime(2015, 8, 10, 0, 0)] assert rec_obj.between(datetime(2015, 8, 2), datetime(2015, 8, 11), inc=False, dtstart=datetime(2015, 8, 2)) == [ datetime(2015, 8, 3, 0, 0), datetime(2015, 8, 10, 0, 0)] model_field = recurrence.fields.RecurrenceField(include_dtstart=False) # Test with include_dtstart=False rec_obj = model_field.to_python(value) assert rec_obj == limits # 2nd of August (dtstart) is not expected regardless of inc assert rec_obj.between(datetime(2015, 8, 2), datetime(2015, 8, 11), inc=True, dtstart=datetime(2015, 8, 2)) == [ datetime(2015, 8, 3, 0, 0), datetime(2015, 8, 10, 0, 0)] assert rec_obj.between(datetime(2015, 8, 2), datetime(2015, 8, 11), inc=False, dtstart=datetime(2015, 8, 2)) == [ datetime(2015, 8, 3, 0, 0), datetime(2015, 8, 10, 0, 0)]
def test_invalid_count_recurrence_object_raises(): with pytest.raises(ValidationError): EventWithNoNulls.objects.create( recurs=Recurrence( rrules=[Rule(recurrence.DAILY, count='fish')] ) )
def test_invalid_byday_recurrence_object_raises(): with pytest.raises(ValidationError): EventWithNoNulls.objects.create( recurs=Recurrence( rrules=[Rule(recurrence.DAILY, byday='house')] ) )
def test_invalid_wkst_recurrence_object_raises(): with pytest.raises(recurrence.SerializationError): EventWithNoNulls.objects.create( recurs=Recurrence( rrules=[Rule(recurrence.DAILY, wkst=17)] ) )
def test_invalid_bymonth_too_high_recurrence_object_raises(): with pytest.raises(recurrence.SerializationError): EventWithNoNulls.objects.create( recurs=Recurrence( rrules=[Rule(recurrence.DAILY, bymonth=[1, 32])] ) )
def test_invalid_bymonth_toolow_recurrence_object_raises(): with pytest.raises(ValidationError): EventWithNoNulls.objects.create( recurs=Recurrence( rrules=[Rule(recurrence.DAILY, bymonth=[0, ])] ) )
def test_invalid_exclusion_interval_recurrence_object_raises(): with pytest.raises(ValidationError): EventWithNoNulls.objects.create( recurs=Recurrence( exrules=[Rule(recurrence.DAILY, interval=0)] ) )
def test_recurrence_object_is_saved(): rule = Rule(recurrence.WEEKLY) limits = Recurrence(dtstart=datetime(2014, 1, 1, 0, 0, 0), dtend=datetime(2014, 2, 3, 0, 0, 0), rrules=[rule]) event = EventWithNoNulls.objects.create(recurs=limits) instances = event.recurs.between(datetime(2010, 1, 1, 0, 0, 0), datetime(2020, 12, 31, 0, 0, 0)) assert instances == [ datetime(2014, 1, 1, 0, 0), datetime(2014, 1, 8, 0, 0), datetime(2014, 1, 15, 0, 0), datetime(2014, 1, 22, 0, 0), datetime(2014, 1, 29, 0, 0), ] event = EventWithNoNulls.objects.get(pk=event.pk) assert event.recurs == limits assert event.recurs.between(datetime(2010, 1, 1, 0, 0, 0), datetime(2020, 12, 31, 0, 0, 0)) == instances
def test_aware_until_gets_converted_to_utc(self): tz = pytz.timezone('America/Adak') until = datetime(2014, 1, 1, 0, 0, 0, tzinfo=tz) recurs = Recurrence(rrules=[Rule(recurrence.DAILY, until=until)], ) value = recurrence.serialize(recurs) field = RecurrenceField() cleaned_value = field.clean(value) assert cleaned_value.rrules[0].until == until.astimezone(pytz.utc)
def test_rule_serialization(): rule = Rule( recurrence.WEEKLY ) serialized = recurrence.serialize(rule) assert 'RRULE:FREQ=WEEKLY' == serialized assert recurrence.deserialize(serialized) == Recurrence(rrules=[rule])
def test_occurrences_with_start_and_end_weekly_tuesdays(): rule = Rule(recurrence.WEEKLY, byday=recurrence.TU) pattern = Recurrence(dtstart=datetime(2015, 1, 1, 0, 0, 0), dtend=datetime(2015, 1, 8, 0, 0, 0), rrules=[rule]) occurrences = [instance for instance in pattern.occurrences()] assert occurrences == [ datetime(2015, 1, 6, 0, 0, 0), ]
def test_exclusion_rule(): inclusion_rule = Rule(recurrence.DAILY) exclusion_rule = Rule(recurrence.WEEKLY, byday=recurrence.THURSDAY) pattern = Recurrence(dtstart=datetime(2014, 1, 2, 0, 0, 0), dtend=datetime(2014, 1, 4, 0, 0, 0), rrules=[inclusion_rule], exrules=[exclusion_rule]) occurrences = [instance for instance in pattern.occurrences()] assert occurrences == [ datetime(2014, 1, 3, 0, 0, 0), datetime(2014, 1, 4, 0, 0, 0), ] assert 2 == pattern.count()
def test_check_max_rrules(): rule = Rule(recurrence.WEEKLY) limits = Recurrence(rrules=[rule]) value = recurrence.serialize(limits) field = RecurrenceField(max_rrules=0) with pytest.raises(forms.ValidationError) as e: field.clean(value) assert e.value.messages[0] == "Max rules exceeded. The limit is 0"
def test_complex_rule_serialization_with_weekday_instance(): rule = Rule( recurrence.WEEKLY, interval=17, wkst=recurrence.to_weekday(1), count=7, byday=[recurrence.to_weekday('-1MO'), recurrence.to_weekday('TU')], bymonth=[1, 3]) serialized = recurrence.serialize(rule) assert ('RRULE:FREQ=WEEKLY;INTERVAL=17;WKST=TU;' 'COUNT=7;BYDAY=-1MO,TU;BYMONTH=1,3') == serialized assert recurrence.deserialize(serialized) == Recurrence(rrules=[rule])
def test_naive_until_gets_converted_to_utc(self): recurs = Recurrence(rrules=[ Rule(recurrence.DAILY, until=datetime(2014, 1, 1, 0, 0, 0)) ], ) value = recurrence.serialize(recurs) field = RecurrenceField() cleaned_value = field.clean(value) assert cleaned_value.rrules[0].until == datetime(2014, 1, 1, 0, 0, 0, tzinfo=pytz.utc)
def test_bug_in_count_and_until_rule_serialization(): # This tests a bug in the way we serialize rules with instance # counts and an until date. We should really raise a # ValidationError in validate if you specify both, but we # currently don't. Once we start doing this, this test can be # modified to check an exception is raised. rule = Rule(recurrence.WEEKLY, count=7, until=datetime(2014, 10, 31, 0, 0, 0)) serialized = recurrence.serialize(rule) # Note that we've got no UNTIL value here assert 'RRULE:FREQ=WEEKLY;COUNT=7' == serialized
def test_recurrence_object_is_saved(self): """Test that naive datetimes will get converted to UTC and returned as UTC""" rule = Rule(recurrence.WEEKLY) limits = Recurrence(dtstart=datetime(2014, 1, 1, 0, 0, 0), dtend=datetime(2014, 2, 3, 0, 0, 0), rrules=[rule]) event = EventWithNoNulls.objects.create(recurs=limits) event.refresh_from_db() instances = event.recurs.between( datetime(2010, 1, 1, 0, 0, 0, tzinfo=pytz.utc), datetime(2020, 12, 31, 0, 0, 0, tzinfo=pytz.utc)) assert instances == [ datetime(2014, 1, 1, 0, 0, tzinfo=pytz.utc), datetime(2014, 1, 8, 0, 0, tzinfo=pytz.utc), datetime(2014, 1, 15, 0, 0, tzinfo=pytz.utc), datetime(2014, 1, 22, 0, 0, tzinfo=pytz.utc), datetime(2014, 1, 29, 0, 0, tzinfo=pytz.utc), datetime(2014, 2, 3, 0, 0, tzinfo=pytz.utc) # We always get dtend ] event = EventWithNoNulls.objects.get(pk=event.pk) expected_limits = Recurrence(dtstart=datetime(2014, 1, 1, 0, 0, 0, tzinfo=pytz.utc), dtend=datetime(2014, 2, 3, 0, 0, 0, tzinfo=pytz.utc), rrules=[rule]) assert event.recurs == expected_limits assert event.recurs.between( datetime(2010, 1, 1, 0, 0, 0, tzinfo=pytz.utc), datetime(2020, 12, 31, 0, 0, 0, tzinfo=pytz.utc)) == instances
def test_exclusion_date(): rule = Rule(recurrence.DAILY) pattern = Recurrence(dtstart=datetime(2014, 1, 2, 0, 0, 0), dtend=datetime(2014, 1, 4, 0, 0, 0), rrules=[rule], exdates=[datetime(2014, 1, 3, 0, 0, 0)]) occurrences = [instance for instance in pattern.occurrences()] assert occurrences == [ datetime(2014, 1, 2, 0, 0, 0), datetime(2014, 1, 4, 0, 0, 0), ] assert 2 == pattern.count()
def test_strip_dtstart_and_dtend_if_required(): rule = Rule(recurrence.WEEKLY) limits = Recurrence(dtstart=datetime(2014, 1, 1, 0, 0, 0), dtend=datetime(2014, 2, 3, 0, 0, 0), rrules=[rule]) value = recurrence.serialize(limits) field = RecurrenceField() cleaned_value = field.clean(value) assert cleaned_value == limits assert cleaned_value.dtstart == datetime(2014, 1, 1, 0, 0, 0) assert cleaned_value.dtend == datetime(2014, 2, 3, 0, 0, 0) field = RecurrenceField(accept_dtstart=False, accept_dtend=False) cleaned_value = field.clean(value) assert cleaned_value != limits assert cleaned_value.dtstart is None assert cleaned_value.dtend is None
def test_occurrences_until(): rule = Rule(recurrence.DAILY, until=datetime(2014, 1, 3, 0, 0, 0)) pattern = Recurrence(rrules=[rule]) occurrences = [ instance for instance in pattern.occurrences( dtstart=datetime(2014, 1, 1, 0, 0, 0), dtend=datetime(2014, 1, 5, 0, 0, 0), ) ] assert occurrences == [ datetime(2014, 1, 1, 0, 0, 0), datetime(2014, 1, 2, 0, 0, 0), datetime(2014, 1, 3, 0, 0, 0), # We always get dtend, for reasons that aren't entirely clear datetime(2014, 1, 5, 0, 0, 0), ] assert 4 == pattern.count( dtstart=datetime(2014, 1, 1, 0, 0, 0), dtend=datetime(2014, 1, 5, 0, 0, 0), ) occurrences = [ instance for instance in pattern.occurrences( dtstart=datetime(2014, 1, 1, 0, 0, 0), dtend=datetime(2014, 1, 2, 0, 0, 0), ) ] assert occurrences == [ datetime(2014, 1, 1, 0, 0, 0), datetime(2014, 1, 2, 0, 0, 0), ] assert 2 == pattern.count( dtstart=datetime(2014, 1, 1, 0, 0, 0), dtend=datetime(2014, 1, 2, 0, 0, 0), )
def test_include_dtstart_from_object(): rule = Rule(recurrence.WEEKLY, byday=recurrence.MONDAY) limits = Recurrence( # include_dtstart=True (default) rrules=[rule]) assert limits.between(datetime(2015, 8, 2), datetime(2015, 8, 11), inc=True, dtstart=datetime(2015, 8, 2)) == [ datetime(2015, 8, 2, 0, 0), datetime(2015, 8, 3, 0, 0), datetime(2015, 8, 10, 0, 0) ] assert limits.between(datetime(2015, 8, 2), datetime(2015, 8, 11), inc=False, dtstart=datetime(2015, 8, 2)) == [ datetime(2015, 8, 3, 0, 0), datetime(2015, 8, 10, 0, 0) ] limits = Recurrence( # include_dtstart=False (dtstart is expected to not be included) include_dtstart=False, rrules=[rule]) assert limits.between(datetime(2015, 8, 2), datetime(2015, 8, 11), inc=True, dtstart=datetime(2015, 8, 2)) == [ datetime(2015, 8, 3, 0, 0), datetime(2015, 8, 10, 0, 0) ] assert limits.between(datetime(2015, 8, 2), datetime(2015, 8, 11), inc=False, dtstart=datetime(2015, 8, 2)) == [ datetime(2015, 8, 3, 0, 0), datetime(2015, 8, 10, 0, 0) ]
def test_occurrences_until(): rule = Rule(recurrence.DAILY, until=datetime(2014, 1, 3, 0, 0, 0)) pattern = Recurrence(rrules=[rule]) occurrences = [ instance for instance in pattern.occurrences( dtstart=datetime(2014, 1, 1, 0, 0, 0), dtend=datetime(2014, 1, 5, 0, 0, 0), ) ] assert occurrences == [ datetime(2014, 1, 1, 0, 0, 0), datetime(2014, 1, 2, 0, 0, 0), datetime(2014, 1, 3, 0, 0, 0), ] assert 3 == pattern.count( dtstart=datetime(2014, 1, 1, 0, 0, 0), dtend=datetime(2014, 1, 5, 0, 0, 0), ) occurrences = [ instance for instance in pattern.occurrences( dtstart=datetime(2014, 1, 1, 0, 0, 0), dtend=datetime(2014, 1, 2, 0, 0, 0), ) ] assert occurrences == [ datetime(2014, 1, 1, 0, 0, 0), datetime(2014, 1, 2, 0, 0, 0), ] assert 2 == pattern.count( dtstart=datetime(2014, 1, 1, 0, 0, 0), dtend=datetime(2014, 1, 2, 0, 0, 0), )
from datetime import datetime from recurrence import Recurrence, Rule import recurrence RULE = Rule(recurrence.DAILY) PATTERN = Recurrence(dtstart=datetime(2014, 1, 2, 0, 0, 0), dtend=datetime(2014, 1, 3, 0, 0, 0), rrules=[RULE]) def test_occurrences_with_start_and_end_weekly_tuesdays(): rule = Rule(recurrence.WEEKLY, byday=recurrence.TU) pattern = Recurrence(dtstart=datetime(2015, 1, 1, 0, 0, 0), dtend=datetime(2015, 1, 8, 0, 0, 0), rrules=[rule]) occurrences = [instance for instance in pattern.occurrences()] assert occurrences == [ datetime(2015, 1, 6, 0, 0, 0), ] def test_occurrences_with_implicit_start_and_end(): occurrences = [instance for instance in PATTERN.occurrences()] assert occurrences == [ datetime(2014, 1, 2, 0, 0, 0), datetime(2014, 1, 3, 0, 0, 0), ] assert 2 == PATTERN.count()