Fix conflict detection
Fix conflict detection by providing finer rules. Meetings on alternating weeks no longer conflict. Meetings on overlapping times now conflict. Add proper tests to check all combinations. Change-Id: I069cdd40fecb5fd7a2ab828a495bdf627ca1a811
This commit is contained in:
parent
d6963905f1
commit
40f12c0d63
|
@ -28,15 +28,17 @@ class Schedule(object):
|
||||||
self.time = datetime.datetime.strptime(sched_yaml['time'], '%H%M')
|
self.time = datetime.datetime.strptime(sched_yaml['time'], '%H%M')
|
||||||
self.day = sched_yaml['day']
|
self.day = sched_yaml['day']
|
||||||
self.irc = sched_yaml['irc']
|
self.irc = sched_yaml['irc']
|
||||||
|
self.freq = sched_yaml['frequency']
|
||||||
self.recurrence = supported_recurrences[sched_yaml['frequency']]
|
self.recurrence = supported_recurrences[sched_yaml['frequency']]
|
||||||
|
|
||||||
def __eq__(self, other):
|
def conflicts(self, other):
|
||||||
#TODO(ttx): This is a bit overzealous (it will report as conflict
|
"""Checks for conflicting schedules."""
|
||||||
# biweekly-odd/biweekly-even on same date/hour/irc) so this should be
|
alternating = set(['biweekly-odd', 'biweekly-even'])
|
||||||
# revamped especially if we want to add more complex recurrence rules
|
return (
|
||||||
return ((self.day == other.day) and
|
((self.day == other.day) and
|
||||||
(self.time == other.time) and
|
(abs(self.time - other.time) < datetime.timedelta(hours=1)) and
|
||||||
(self.irc == other.irc))
|
(self.irc == other.irc)) and
|
||||||
|
(set([self.freq, other.freq]) != alternating))
|
||||||
|
|
||||||
|
|
||||||
class Meeting(object):
|
class Meeting(object):
|
||||||
|
@ -106,7 +108,7 @@ def check_for_meeting_conflicts(meetings):
|
||||||
other_schedules = meetings[j].schedules
|
other_schedules = meetings[j].schedules
|
||||||
for schedule in schedules:
|
for schedule in schedules:
|
||||||
for other_schedule in other_schedules:
|
for other_schedule in other_schedules:
|
||||||
if schedule == other_schedule:
|
if schedule.conflicts(other_schedule):
|
||||||
msg_dict = {'one': schedule.filefrom,
|
msg_dict = {'one': schedule.filefrom,
|
||||||
'two': other_schedule.filefrom}
|
'two': other_schedule.filefrom}
|
||||||
raise MeetingConflictError(
|
raise MeetingConflictError(
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
"""Sample meeting data to use for testing."""
|
"""Sample meeting data to use for testing."""
|
||||||
|
|
||||||
FIRST_MEETING_YAML = """
|
WEEKLY_MEETING = """
|
||||||
project: OpenStack Subteam Meeting
|
project: OpenStack Subteam Meeting
|
||||||
schedule:
|
schedule:
|
||||||
- time: '1200'
|
- time: '1200'
|
||||||
|
@ -28,10 +28,10 @@ agenda: |
|
||||||
* Top bugs this week
|
* Top bugs this week
|
||||||
"""
|
"""
|
||||||
|
|
||||||
SECOND_MEETING_YAML = """
|
CONFLICTING_WEEKLY_MEETING = """
|
||||||
project: OpenStack Subteam Meeting 2
|
project: OpenStack Subteam Meeting 2
|
||||||
schedule:
|
schedule:
|
||||||
- time: '1200'
|
- time: '1230'
|
||||||
day: Wednesday
|
day: Wednesday
|
||||||
irc: openstack-meeting
|
irc: openstack-meeting
|
||||||
frequency: weekly
|
frequency: weekly
|
||||||
|
@ -42,7 +42,7 @@ agenda: |
|
||||||
* New features
|
* New features
|
||||||
"""
|
"""
|
||||||
|
|
||||||
THIRD_MEETING_YAML = """
|
WEEKLY_OTHER_CHANNEL_MEETING = """
|
||||||
project: OpenStack Subteam Meeting 3
|
project: OpenStack Subteam Meeting 3
|
||||||
schedule:
|
schedule:
|
||||||
- time: '1200'
|
- time: '1200'
|
||||||
|
@ -56,13 +56,40 @@ agenda: |
|
||||||
* New features
|
* New features
|
||||||
"""
|
"""
|
||||||
|
|
||||||
BIWEEKLY_MEETING_YAML = """
|
ALTERNATING_MEETING = """
|
||||||
project: OpenStack Subteam Meeting
|
project: OpenStack Subteam Meeting
|
||||||
schedule:
|
schedule:
|
||||||
- time: '1200'
|
- time: '1200'
|
||||||
day: Wednesday
|
day: Wednesday
|
||||||
irc: openstack-meeting
|
irc: openstack-meeting
|
||||||
frequency: biweekly-even
|
frequency: biweekly-even
|
||||||
|
- time: '2200'
|
||||||
|
day: Wednesday
|
||||||
|
irc: openstack-meeting
|
||||||
|
frequency: biweekly-odd
|
||||||
|
chair: Jane Developer
|
||||||
|
description: >
|
||||||
|
Weekly meeting for Subteam project.
|
||||||
|
agenda: |
|
||||||
|
* Top bugs this week
|
||||||
|
"""
|
||||||
|
|
||||||
|
BIWEEKLY_EVEN_MEETING = """
|
||||||
|
project: OpenStack Subteam 12 Meeting
|
||||||
|
schedule:
|
||||||
|
- time: '2200'
|
||||||
|
day: Wednesday
|
||||||
|
irc: openstack-meeting
|
||||||
|
frequency: biweekly-even
|
||||||
|
chair: Jane Developer
|
||||||
|
description: >
|
||||||
|
Weekly meeting for Subteam project.
|
||||||
|
agenda: |
|
||||||
|
* Top bugs this week
|
||||||
|
"""
|
||||||
|
|
||||||
|
BIWEEKLY_ODD_MEETING = """
|
||||||
|
project: OpenStack Subteam 12 Meeting
|
||||||
schedule:
|
schedule:
|
||||||
- time: '2200'
|
- time: '2200'
|
||||||
day: Wednesday
|
day: Wednesday
|
||||||
|
|
|
@ -19,24 +19,46 @@ from yaml2ical.tests import sample_data
|
||||||
class MeetingTestCase(unittest.TestCase):
|
class MeetingTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def test_load_yaml_file(self):
|
def test_load_yaml_file(self):
|
||||||
m = meeting.load_meetings(sample_data.FIRST_MEETING_YAML)[0]
|
m = meeting.load_meetings(sample_data.WEEKLY_MEETING)[0]
|
||||||
self.assertEqual('OpenStack Subteam Meeting', m.project)
|
self.assertEqual('OpenStack Subteam Meeting', m.project)
|
||||||
self.assertEqual('Joe Developer', m.chair)
|
self.assertEqual('Joe Developer', m.chair)
|
||||||
self.assertEqual('Weekly meeting for Subteam project.\n',
|
self.assertEqual('Weekly meeting for Subteam project.\n',
|
||||||
m.description)
|
m.description)
|
||||||
|
|
||||||
def test_exception_raised_when_conflict_detected(self):
|
def should_be_conflicting(self, yaml1, yaml2):
|
||||||
"""Exception is raised when a meeting conflict is detected."""
|
"""Exception is raised when meetings should conflict."""
|
||||||
meeting_one = meeting.load_meetings(sample_data.FIRST_MEETING_YAML)
|
meeting_one = meeting.load_meetings(yaml1)
|
||||||
meeting_two = meeting.load_meetings(sample_data.SECOND_MEETING_YAML)
|
meeting_two = meeting.load_meetings(yaml2)
|
||||||
meeting_list = [meeting_one.pop(), meeting_two.pop()]
|
meeting_list = [meeting_one.pop(), meeting_two.pop()]
|
||||||
self.assertRaises(meeting.MeetingConflictError,
|
self.assertRaises(meeting.MeetingConflictError,
|
||||||
meeting.check_for_meeting_conflicts,
|
meeting.check_for_meeting_conflicts,
|
||||||
meeting_list)
|
meeting_list)
|
||||||
|
|
||||||
def test_no_exception_raised_with_diff_irc_rooms(self):
|
def should_not_conflict(self, yaml1, yaml2):
|
||||||
"""No exception raised when using different IRC rooms."""
|
"""No exception raised when meetings shouldn't conflict."""
|
||||||
meeting_one = meeting.load_meetings(sample_data.FIRST_MEETING_YAML)
|
meeting_one = meeting.load_meetings(yaml1)
|
||||||
meeting_two = meeting.load_meetings(sample_data.THIRD_MEETING_YAML)
|
meeting_two = meeting.load_meetings(yaml2)
|
||||||
meeting_list = [meeting_one.pop(), meeting_two.pop()]
|
meeting_list = [meeting_one.pop(), meeting_two.pop()]
|
||||||
meeting.check_for_meeting_conflicts(meeting_list)
|
meeting.check_for_meeting_conflicts(meeting_list)
|
||||||
|
|
||||||
|
def test_weekly_conflict(self):
|
||||||
|
self.should_be_conflicting(
|
||||||
|
sample_data.WEEKLY_MEETING,
|
||||||
|
sample_data.CONFLICTING_WEEKLY_MEETING)
|
||||||
|
self.should_not_conflict(
|
||||||
|
sample_data.WEEKLY_MEETING,
|
||||||
|
sample_data.WEEKLY_OTHER_CHANNEL_MEETING)
|
||||||
|
|
||||||
|
def test_biweekly_conflict(self):
|
||||||
|
self.should_be_conflicting(
|
||||||
|
sample_data.WEEKLY_MEETING,
|
||||||
|
sample_data.ALTERNATING_MEETING)
|
||||||
|
self.should_not_conflict(
|
||||||
|
sample_data.ALTERNATING_MEETING,
|
||||||
|
sample_data.BIWEEKLY_EVEN_MEETING)
|
||||||
|
self.should_be_conflicting(
|
||||||
|
sample_data.ALTERNATING_MEETING,
|
||||||
|
sample_data.BIWEEKLY_ODD_MEETING)
|
||||||
|
self.should_not_conflict(
|
||||||
|
sample_data.BIWEEKLY_ODD_MEETING,
|
||||||
|
sample_data.BIWEEKLY_EVEN_MEETING)
|
||||||
|
|
Loading…
Reference in New Issue