def save_model(self, request, obj, form, change): super(SlotAdmin, self).save_model(request, obj, form, change) if not change and form.cleaned_data['additional'] > 0: # We add the requested additional slots # All created slot will have the same length as the slot just # created , and we specify them as a sequence using # "previous_slot" so tweaking start times is simple. prev = obj end = datetime.datetime.combine(prev.day.date, prev.end_time) start = datetime.datetime.combine(prev.day.date, prev.get_start_time()) slot_len = end - start for loop in range(form.cleaned_data['additional']): end = end + slot_len new_slot = Slot(day=prev.day, previous_slot=prev, end_time=end.time()) new_slot.save() msgdict = {'obj': force_text(new_slot)} msg = _("Additional slot %(obj)s added sucessfully") % msgdict if hasattr(request, '_messages'): # Don't add messages unless we have a suitable request # Needed during testing, and possibly in other cases self.message_user(request, msg, messages.SUCCESS) prev = new_slot
def test_save_model_change_slot(self): """Test save_model changing a slot""" slot = Slot(day=self.day, start_time=D.time(11, 0, 0), end_time=D.time(12, 30, 0)) # end_time is chosen as 12:30 so it stays valid through all the # subsequent fiddling slot.save() # check that it's saved in the database self.assertEqual(Slot.objects.count(), 1) request = HttpRequest() dummy = make_dummy_form(0) slot.start_time = D.time(12, 0, 0) self.assertEqual(Slot.objects.filter(start_time=D.time(11, 0, 0)).count(), 1) self.admin.save_model(request, slot, dummy, True) # Check that the database has changed self.assertEqual(Slot.objects.filter(start_time=D.time(11, 0, 0)).count(), 0) self.assertEqual(Slot.objects.count(), 1) slot2 = Slot.objects.filter(start_time=D.time(12, 0, 0)).get() self.assertEqual(slot, slot2) # Check that setting additional has no influence on the change path dummy = make_dummy_form(3) slot.start_time = D.time(11, 0, 0) self.assertEqual(Slot.objects.filter(start_time=D.time(11, 0, 0)).count(), 0) self.admin.save_model(request, slot, dummy, True) # Still only 1 object self.assertEqual(Slot.objects.count(), 1) # And it has been updated self.assertEqual(Slot.objects.filter(start_time=D.time(12, 0, 0)).count(), 0) self.assertEqual(Slot.objects.filter(start_time=D.time(11, 0, 0)).count(), 1)
def test_queryset_day_time(self): """Test queries with slots created purely by day + start_time""" slots = {} slots[self.day1] = [ Slot(day=self.day1, start_time=D.time(11, 0, 0), end_time=D.time(12, 00, 0)) ] slots[self.day2] = [ Slot(day=self.day2, start_time=D.time(11, 0, 0), end_time=D.time(12, 00, 0)) ] # Day1 slots for x in range(12, 17): slots[self.day1].append( Slot(day=self.day1, start_time=D.time(x, 0, 0), end_time=D.time(x + 1, 0, 0))) if x < 15: # Fewer slots for day 2 slots[self.day2].append( Slot(day=self.day2, start_time=D.time(x, 0, 0), end_time=D.time(x + 1, 0, 0))) for d in slots: for s in slots[d]: s.save() # Check Null filter TestFilter = self._make_day_filter(None) self.assertEqual(list(TestFilter.queryset(None, Slot.objects.all())), list(Slot.objects.all())) # Test Day1 TestFilter = self._make_day_filter(self.day1) queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set(slots[self.day1])) # Test Day2 TestFilter = self._make_day_filter(self.day2) queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set(slots[self.day2])) # Check no match case TestFilter = self._make_day_filter(self.day3) queries = list(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, []) # Check for slots starting at 11:00 TestFilter = self._make_time_filter('11:00') # Should be the first slot of each day queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set([slots[self.day1][0], slots[self.day2][0]])) TestFilter = self._make_time_filter('12:00') # Should be the second slot of each day queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set([slots[self.day1][1], slots[self.day2][1]]))
def test_queryset_prev_slot(self): """Test lookup with a chain of previous slots.""" slots = {} prev = Slot(day=self.day1, start_time=D.time(11, 0, 0), end_time=D.time(12, 00, 0)) prev.save() slots[self.day1] = [prev] prev = Slot(day=self.day2, start_time=D.time(11, 0, 0), end_time=D.time(12, 00, 0)) prev.save() slots[self.day2] = [prev] # Day1 slots for x in range(12, 17): prev1 = slots[self.day1][-1] slots[self.day1].append( Slot(previous_slot=prev1, end_time=D.time(x + 1, 0, 0))) slots[self.day1][-1].save() if x < 15: prev2 = slots[self.day2][-1] # Fewer slots for day 2 slots[self.day2].append( Slot(previous_slot=prev2, end_time=D.time(x + 1, 0, 0))) slots[self.day2][-1].save() # Check Null filter TestFilter = self._make_day_filter(None) self.assertEqual(list(TestFilter.queryset(None, Slot.objects.all())), list(Slot.objects.all())) # Test Day1 TestFilter = self._make_day_filter(self.day1) queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set(slots[self.day1])) # Test Day2 TestFilter = self._make_day_filter(self.day2) queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set(slots[self.day2])) # Check no match case TestFilter = self._make_day_filter(self.day3) queries = list(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, []) # Check for slots starting at 11:00 TestFilter = self._make_time_filter('11:00') # Should be the first slot of each day queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set([slots[self.day1][0], slots[self.day2][0]])) TestFilter = self._make_time_filter('12:00') # Should be the second slot of each day queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set([slots[self.day1][1], slots[self.day2][1]]))
def test_queryset_prev_slot(self): """Test lookup with a chain of previous slots.""" slots = {} prev = Slot(start_time=D.datetime(2013, 9, 22, 11, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 12, 00, 0, tzinfo=timezone.utc)) prev.save() slots[self.block1] = [prev] prev = Slot(start_time=D.datetime(2013, 9, 23, 11, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 23, 12, 00, 0, tzinfo=timezone.utc)) prev.save() slots[self.block2] = [prev] # ScheduleBlock1 slots for x in range(12, 17): prev1 = slots[self.block1][-1] slots[self.block1].append(Slot(previous_slot=prev1, end_time=D.datetime(2013, 9, 22, x+1, 0, 0, tzinfo=timezone.utc))) slots[self.block1][-1].save() if x < 15: prev2 = slots[self.block2][-1] # Fewer slots for day 2 slots[self.block2].append(Slot(previous_slot=prev2, end_time=D.datetime(2013, 9, 22, x+1, 0, 0, tzinfo=timezone.utc))) slots[self.block2][-1].save() # Check Null filter TestFilter = self._make_block_filter(None) self.assertEqual(list(TestFilter.queryset(None, Slot.objects.all())), list(Slot.objects.all())) # Test ScheduleBlock1 TestFilter = self._make_block_filter(self.block1) queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set(slots[self.block1])) # Test ScheduleBlock2 TestFilter = self._make_block_filter(self.block2) queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set(slots[self.block2])) # Check no match case TestFilter = self._make_block_filter(self.block3) queries = list(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, []) # Check for slots starting at 11:00 TestFilter = self._make_time_filter('11:00') # Should be the first slot of each day queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set([slots[self.block1][0], slots[self.block2][0]])) TestFilter = self._make_time_filter('12:00') # Should be the second slot of each day queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set([slots[self.block1][1], slots[self.block2][1]]))
def test_queryset_day_time(self): """Test queries with slots created purely by day + start_time""" slots = {} slots[self.block1] = [Slot(start_time=D.datetime(2013, 9, 22, 11, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 12, 00, 0, tzinfo=timezone.utc))] slots[self.block2] = [Slot(start_time=D.datetime(2013, 9, 23, 11, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 23, 12, 00, 0, tzinfo=timezone.utc))] # ScheduleBlock1 slots for x in range(12, 17): slots[self.block1].append(Slot( start_time=D.datetime(2013, 9, 22, x, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, x+1, 0, 0, tzinfo=timezone.utc))) if x < 15: # Fewer slots for day 2 slots[self.block2].append(Slot( start_time=D.datetime(2013, 9, 23, x, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 23, x+1, 0, 0, tzinfo=timezone.utc))) for d in slots: for s in slots[d]: s.save() # Check Null filter TestFilter = self._make_block_filter(None) self.assertEqual(list(TestFilter.queryset(None, Slot.objects.all())), list(Slot.objects.all())) # Test ScheduleBlock1 TestFilter = self._make_block_filter(self.block1) queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set(slots[self.block1])) # Test ScheduleBlock2 TestFilter = self._make_block_filter(self.block2) queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set(slots[self.block2])) # Check no match case TestFilter = self._make_block_filter(self.block3) queries = list(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, []) # Check for slots starting at 11:00 TestFilter = self._make_time_filter('11:00') # Should be the first slot of each day queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set([slots[self.block1][0], slots[self.block2][0]])) TestFilter = self._make_time_filter('12:00') # Should be the second slot of each day queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set([slots[self.block1][1], slots[self.block2][1]]))
def test_save_model_single_new(self): """Test save_model creating a new slot, but no additional slots""" slot = Slot(start_time=D.datetime(2013, 9, 22, 11, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 11, 30, 0, tzinfo=timezone.utc)) # check that it's not saved in the database yet self.assertEqual(Slot.objects.count(), 0) request = HttpRequest() dummy = make_dummy_form(0) self.admin.save_model(request, slot, dummy, False) # check that it's now been saved in the database self.assertEqual(Slot.objects.count(), 1) slot2 = Slot.objects.filter(start_time=D.datetime( 2013, 9, 22, 11, 0, 0, tzinfo=timezone.utc)).get() self.assertEqual(slot, slot2)
def test_save_model_new_additional(self): """Test save_model changing a new slot with some additional slots""" slot = Slot(day=self.day, start_time=D.time(11, 0, 0), end_time=D.time(11, 30, 0)) # check that it's not saved in the database self.assertEqual(Slot.objects.count(), 0) request = HttpRequest() dummy = make_dummy_form(3) self.admin.save_model(request, slot, dummy, False) self.assertEqual(Slot.objects.count(), 4) # check the hierachy is created correctly slot1 = Slot.objects.filter(previous_slot=slot).get() self.assertEqual(slot1.get_start_time(), slot.end_time) self.assertEqual(slot1.end_time, D.time(12, 0, 0)) slot2 = Slot.objects.filter(previous_slot=slot1).get() self.assertEqual(slot2.get_start_time(), slot1.end_time) self.assertEqual(slot2.end_time, D.time(12, 30, 0)) self.assertEqual(slot2.day, slot.day) slot3 = Slot.objects.filter(previous_slot=slot2).get() self.assertEqual(slot3.get_start_time(), slot2.end_time) self.assertEqual(slot3.end_time, D.time(13, 00, 0)) self.assertEqual(slot3.day, slot.day) # repeat checks with a different length of slot slot = Slot(day=self.day, previous_slot=slot3, end_time=D.time(14, 30, 0)) dummy = make_dummy_form(4) self.admin.save_model(request, slot, dummy, False) self.assertEqual(Slot.objects.count(), 9) slot1 = Slot.objects.filter(previous_slot=slot).get() self.assertEqual(slot1.get_start_time(), slot.end_time) self.assertEqual(slot1.end_time, D.time(16, 0, 0)) slot2 = Slot.objects.filter(previous_slot=slot1).get() self.assertEqual(slot2.get_start_time(), slot1.end_time) self.assertEqual(slot2.end_time, D.time(17, 30, 0)) self.assertEqual(slot2.day, slot.day) slot3 = Slot.objects.filter(previous_slot=slot2).get() self.assertEqual(slot3.get_start_time(), slot2.end_time) self.assertEqual(slot3.end_time, D.time(19, 00, 0)) self.assertEqual(slot3.day, slot.day) slot4 = Slot.objects.filter(previous_slot=slot3).get() self.assertEqual(slot4.get_start_time(), slot3.end_time) self.assertEqual(slot4.end_time, D.time(20, 30, 0)) self.assertEqual(slot4.day, slot.day)
def test_save_model_prev_slot_additional(self): """Test save_model changing a new slot with some additional slots, starting from a slot specified via previous slot""" prev_slot = Slot(start_time=D.datetime(2013, 9, 22, 11, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 11, 30, 0, tzinfo=timezone.utc)) prev_slot.save() self.assertEqual(Slot.objects.count(), 1) slot = Slot(previous_slot=prev_slot, end_time=D.datetime(2013, 9, 22, 12, 00, 0, tzinfo=timezone.utc)) # Check that newly added slot isn't in the database self.assertEqual(Slot.objects.count(), 1) request = HttpRequest() dummy = make_dummy_form(2) self.admin.save_model(request, slot, dummy, False) self.assertEqual(Slot.objects.count(), 4) # check the hierachy is created correctly slot1 = Slot.objects.filter(previous_slot=slot).get() self.assertEqual(slot1.get_start_time(), slot.end_time) self.assertEqual( slot1.end_time, D.datetime(2013, 9, 22, 12, 30, 0, tzinfo=timezone.utc)) slot2 = Slot.objects.filter(previous_slot=slot1).get() self.assertEqual(slot2.get_start_time(), slot1.end_time) self.assertEqual( slot2.end_time, D.datetime(2013, 9, 22, 13, 00, 0, tzinfo=timezone.utc))
def test_invalid_slot(self): """Test that slots must have start time > end_time""" # Same day block1 = ScheduleBlock.objects.create( start_time=D.datetime(2013, 9, 22, 9, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 19, 0, 0, tzinfo=timezone.utc)) slot1 = Slot(start_time=D.datetime(2013, 9, 22, 11, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 10, 0, 0, tzinfo=timezone.utc)) self.assertRaises(ValidationError, slot1.clean) block2 = ScheduleBlock.objects.create( start_time=D.datetime(2013, 9, 24, 9, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 25, 19, 0, 0, tzinfo=timezone.utc)) # Different day, slot2 = Slot(start_time=D.datetime(2013, 9, 25, 1, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 24, 3, 0, 0, tzinfo=timezone.utc)) self.assertRaises(ValidationError, slot2.clean) block1.delete() block2.delete()
def test_save_model_change_slot(self): """Test save_model changing a slot""" slot = Slot(start_time=D.datetime(2013, 9, 22, 11, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 12, 30, 0, tzinfo=timezone.utc)) # end_time is chosen as 12:30 so it stays valid through all the # subsequent fiddling slot.save() # check that it's saved in the database self.assertEqual(Slot.objects.count(), 1) request = HttpRequest() dummy = make_dummy_form(0) slot.start_time = D.datetime(2013, 9, 22, 12, 0, 0, tzinfo=timezone.utc) self.assertEqual( Slot.objects.filter(start_time=D.datetime(2013, 9, 22, 11, 0, 0, tzinfo=timezone.utc)).count(), 1) self.admin.save_model(request, slot, dummy, True) # Check that the database has changed self.assertEqual( Slot.objects.filter(start_time=D.datetime(2013, 9, 22, 11, 0, 0, tzinfo=timezone.utc)).count(), 0) self.assertEqual(Slot.objects.count(), 1) slot2 = Slot.objects.filter(start_time=D.datetime(2013, 9, 22, 12, 0, 0, tzinfo=timezone.utc)).get() self.assertEqual(slot, slot2) # Check that setting additional has no influence on the change path dummy = make_dummy_form(3) slot.start_time = D.datetime(2013, 9, 22, 11, 0, 0, tzinfo=timezone.utc) self.assertEqual( Slot.objects.filter(start_time=D.datetime(2013, 9, 22, 11, 0, 0, tzinfo=timezone.utc)).count(), 0) self.admin.save_model(request, slot, dummy, True) # Still only 1 object self.assertEqual(Slot.objects.count(), 1) # And it has been updated self.assertEqual( Slot.objects.filter(start_time=D.datetime(2013, 9, 22, 12, 0, 0, tzinfo=timezone.utc)).count(), 0) self.assertEqual( Slot.objects.filter(start_time=D.datetime(2013, 9, 22, 11, 0, 0, tzinfo=timezone.utc)).count(), 1)
def save_model(self, request, obj, form, change): super(SlotAdmin, self).save_model(request, obj, form, change) if not change and form.cleaned_data['additional']: # We add the requested additional slots # All created slot will have the same length as the slot just # created , and we specify them as a sequence using # "previous_slot" so tweaking start times is simple. prev = obj end = prev.end_time start = prev.get_start_time() slot_len = end - start for loop in range(form.cleaned_data['additional']): end = end + slot_len new_slot = Slot(previous_slot=prev, end_time=end) # Make sure we're valid before adding to the database try: new_slot.full_clean() new_slot.save() msgdict = {'obj': force_text(new_slot)} msg = _("Additional slot %(obj)s added sucessfully") % msgdict if hasattr(request, '_messages'): # Don't add messages unless we have a suitable request # Needed during testing, and possibly in other cases self.message_user(request, msg, messages.SUCCESS) prev = new_slot except ValidationError as err: msg = _("Failed to create new slot - %s" % err) if hasattr(request, '_messages'): self.message_user(request, msg, messages.ERROR) else: # Useful in testing raise break
def test_save_model_prev_slot_additional(self): """Test save_model changing a new slot with some additional slots, starting from a slot specified via previous slot""" prev_slot = Slot(day=self.day, start_time=D.time(11, 0, 0), end_time=D.time(11, 30, 0)) prev_slot.save() self.assertEqual(Slot.objects.count(), 1) slot = Slot(previous_slot=prev_slot, end_time=D.time(12, 00, 0)) # Check that newly added slot isn't in the database self.assertEqual(Slot.objects.count(), 1) request = HttpRequest() dummy = make_dummy_form(2) self.admin.save_model(request, slot, dummy, False) self.assertEqual(Slot.objects.count(), 4) # check the hierachy is created correctly slot1 = Slot.objects.filter(previous_slot=slot).get() self.assertEqual(slot1.get_start_time(), slot.end_time) self.assertEqual(slot1.end_time, D.time(12, 30, 0)) slot2 = Slot.objects.filter(previous_slot=slot1).get() self.assertEqual(slot2.get_start_time(), slot1.end_time) self.assertEqual(slot2.end_time, D.time(13, 00, 0))
def test_midnight(self): """Test that we can assign slots that span midnight to a block that spans midnight.""" block1 = ScheduleBlock.objects.create( start_time=D.datetime(2013, 9, 22, 9, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 23, 8, 0, 0, tzinfo=timezone.utc)) slot1 = Slot(start_time=D.datetime(2013, 9, 22, 23, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 23, 1, 0, 0, tzinfo=timezone.utc)) self.assertEqual(slot1.get_block(), block1) self.assertEqual(slot1.get_duration(), {'hours': 2, 'minutes': 0}) block1.delete()
def test_queryset_prev_slot(self): """Test lookup with a chain of previous slots.""" slots = {} prev = Slot(day=self.day1, start_time=D.time(11, 0, 0), end_time=D.time(12, 00, 0)) prev.save() slots[self.day1] = [prev] prev = Slot(day=self.day2, start_time=D.time(11, 0, 0), end_time=D.time(12, 00, 0)) prev.save() slots[self.day2] = [prev] # Day1 slots for x in range(12, 17): prev1 = slots[self.day1][-1] slots[self.day1].append(Slot(previous_slot=prev1, end_time=D.time(x+1, 0, 0))) slots[self.day1][-1].save() if x < 15: prev2 = slots[self.day2][-1] # Fewer slots for day 2 slots[self.day2].append(Slot(previous_slot=prev2, end_time=D.time(x+1, 0, 0))) slots[self.day2][-1].save() # Check Null filter TestFilter = self._make_day_filter(None) self.assertEqual(list(TestFilter.queryset(None, Slot.objects.all())), list(Slot.objects.all())) # Test Day1 TestFilter = self._make_day_filter(self.day1) queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set(slots[self.day1])) # Test Day2 TestFilter = self._make_day_filter(self.day2) queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set(slots[self.day2])) # Check no match case TestFilter = self._make_day_filter(self.day3) queries = list(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, []) # Check for slots starting at 11:00 TestFilter = self._make_time_filter('11:00') # Should be the first slot of each day queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set([slots[self.day1][0], slots[self.day2][0]])) TestFilter = self._make_time_filter('12:00') # Should be the second slot of each day queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set([slots[self.day1][1], slots[self.day2][1]]))
def test_queryset_mixed(self): """Test with a mix of day+time and previous slot cases.""" slots = {} prev = Slot(day=self.day1, start_time=D.time(11, 0, 0), end_time=D.time(12, 00, 0)) prev.save() slots[self.day1] = [prev] prev = Slot(day=self.day2, start_time=D.time(11, 0, 0), end_time=D.time(12, 00, 0)) prev.save() slots[self.day2] = [prev] # Day1 slots for x in range(12, 20): prev1 = slots[self.day1][-1] if x % 2: slots[self.day1].append(Slot(previous_slot=prev1, end_time=D.time(x+1, 0, 0))) else: slots[self.day1].append(Slot(day=self.day1, start_time=D.time(x, 0, 0), end_time=D.time(x+1, 0, 0))) slots[self.day1][-1].save() prev2 = slots[self.day2][-1] if x % 5: slots[self.day2].append(Slot(previous_slot=prev2, end_time=D.time(x+1, 0, 0))) else: slots[self.day2].append(Slot(day=self.day2, start_time=D.time(x, 0, 0), end_time=D.time(x+1, 0, 0))) slots[self.day2][-1].save() # Check Null filter TestFilter = self._make_day_filter(None) self.assertEqual(list(TestFilter.queryset(None, Slot.objects.all())), list(Slot.objects.all())) # Test Day1 TestFilter = self._make_day_filter(self.day1) queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set(slots[self.day1])) # Test Day2 TestFilter = self._make_day_filter(self.day2) queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set(slots[self.day2])) # Check no match case TestFilter = self._make_day_filter(self.day3) queries = list(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, [])
def test_invalid_slot_block(self): """Test that we can't create a slot outside the block's times""" block1 = ScheduleBlock.objects.create( start_time=D.datetime(2013, 9, 22, 9, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 18, 0, 0, tzinfo=timezone.utc)) # Totally after slot1 = Slot(start_time=D.datetime(2013, 9, 22, 23, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 23, 1, 0, 0, tzinfo=timezone.utc)) self.assertRaises(ValidationError, slot1.clean) # Totally before slot2 = Slot(start_time=D.datetime(2013, 9, 21, 23, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 21, 1, 0, 0, tzinfo=timezone.utc)) self.assertRaises(ValidationError, slot2.clean) # Overlaps the end slot3 = Slot(start_time=D.datetime(2013, 9, 22, 17, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 19, 0, 0, tzinfo=timezone.utc)) self.assertRaises(ValidationError, slot3.clean) # Overlaps the start slot4 = Slot(start_time=D.datetime(2013, 9, 22, 7, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 10, 0, 0, tzinfo=timezone.utc)) self.assertRaises(ValidationError, slot4.clean)
def test_queryset_mixed(self): """Test with a mix of day+time and previous slot cases.""" slots = {} prev = Slot(day=self.day1, start_time=D.time(11, 0, 0), end_time=D.time(12, 00, 0)) prev.save() slots[self.day1] = [prev] prev = Slot(day=self.day2, start_time=D.time(11, 0, 0), end_time=D.time(12, 00, 0)) prev.save() slots[self.day2] = [prev] # Day1 slots for x in range(12, 20): prev1 = slots[self.day1][-1] if x % 2: slots[self.day1].append( Slot(previous_slot=prev1, end_time=D.time(x + 1, 0, 0))) else: slots[self.day1].append( Slot(day=self.day1, start_time=D.time(x, 0, 0), end_time=D.time(x + 1, 0, 0))) slots[self.day1][-1].save() prev2 = slots[self.day2][-1] if x % 5: slots[self.day2].append( Slot(previous_slot=prev2, end_time=D.time(x + 1, 0, 0))) else: slots[self.day2].append( Slot(day=self.day2, start_time=D.time(x, 0, 0), end_time=D.time(x + 1, 0, 0))) slots[self.day2][-1].save() # Check Null filter TestFilter = self._make_day_filter(None) self.assertEqual(list(TestFilter.queryset(None, Slot.objects.all())), list(Slot.objects.all())) # Test Day1 TestFilter = self._make_day_filter(self.day1) queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set(slots[self.day1])) # Test Day2 TestFilter = self._make_day_filter(self.day2) queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set(slots[self.day2])) # Check no match case TestFilter = self._make_day_filter(self.day3) queries = list(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, [])
def test_previous_overlaps(self): """Test that we handle overlap checks involving editing previous slots correctly.""" block1 = ScheduleBlock.objects.create( start_time=D.datetime(2013, 9, 26, 9, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 26, 19, 0, 0, tzinfo=timezone.utc)) slot1 = Slot(start_time=D.datetime(2013, 9, 26, 10, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 26, 12, 0, 0, tzinfo=timezone.utc)) slot1.clean() slot1.save() slot2 = Slot(previous_slot=slot1, end_time=D.datetime(2013, 9, 26, 13, 0, 0, tzinfo=timezone.utc)) slot2.clean() slot2.save() # Check that updating slot1's end_time to 12:30 works as expected slot1.end_time = D.datetime(2013, 9, 26, 12, 30, 0, tzinfo=timezone.utc) slot1.clean() slot1.save() self.assertEqual( slot2.get_start_time(), D.datetime(2013, 9, 26, 12, 30, 0, tzinfo=timezone.utc)) # Check that updating slot1's end_time to 13:30 fails, though slot1.end_time = D.datetime(2013, 9, 26, 13, 30, 0, tzinfo=timezone.utc) self.assertRaises(ValidationError, slot1.clean)
def test_simple(self): """Test we can assign slots to a Block that spans only few hours.""" block1 = ScheduleBlock.objects.create( start_time=D.datetime(2013, 9, 22, 9, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 19, 0, 0, tzinfo=timezone.utc)) slot1 = Slot(start_time=D.datetime(2013, 9, 22, 9, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 10, 20, 0, tzinfo=timezone.utc)) self.assertEqual(slot1.get_block(), block1) self.assertEqual(slot1.get_duration(), {'hours': 1, 'minutes': 20}) # Check end and start times slot2 = Slot(start_time=D.datetime(2013, 9, 22, 12, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 13, 0, 0, tzinfo=timezone.utc)) slot3 = Slot(start_time=D.datetime(2013, 9, 22, 18, 30, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 19, 0, 0, tzinfo=timezone.utc)) self.assertEqual(slot2.get_block(), block1) self.assertEqual(slot2.get_duration(), {'hours': 1, 'minutes': 0}) self.assertEqual(slot3.get_block(), block1) self.assertEqual(slot3.get_duration(), {'hours': 0, 'minutes': 30}) block1.delete()
def test_time_filter_lookups(self): """Test that filter lookups are sane.""" # Add some slots slot1 = Slot(day=self.day1, start_time=D.time(11, 0, 0), end_time=D.time(12, 00, 0)) slot2 = Slot(day=self.day2, start_time=D.time(11, 0, 0), end_time=D.time(12, 00, 0)) slot3 = Slot(day=self.day1, start_time=D.time(12, 0, 0), end_time=D.time(13, 0, 0)) slot4 = Slot(day=self.day1, start_time=D.time(13, 0, 0), end_time=D.time(14, 0, 0)) slot1.save() slot2.save() slot3.save() slot4.save() TestFilter = self._make_time_filter('11:00') # Check lookup details lookups = list(TestFilter.lookups(None, self.admin)) self.assertEqual(len(lookups), 3) self.assertEqual(lookups[0], ('11:00', '11:00')) TestFilter = self._make_time_filter('12:00') lookups2 = list(TestFilter.lookups(None, self.admin)) self.assertEqual(lookups, lookups2)
def test_changing_slots(self): """Test that we can update slots and get the correct validation behaviour.""" block1 = ScheduleBlock.objects.create( start_time=D.datetime(2013, 9, 26, 9, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 26, 19, 0, 0, tzinfo=timezone.utc)) slot1 = Slot(start_time=D.datetime(2013, 9, 26, 10, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 26, 12, 0, 0, tzinfo=timezone.utc)) slot1.clean() slot1.save() # This should work slot1.start_time = D.datetime(2013, 9, 26, 9, 0, 0, tzinfo=timezone.utc) slot1.clean() slot1.save() slot1.end_time = D.datetime(2013, 9, 26, 11, 0, 0, tzinfo=timezone.utc) slot1.clean() slot1.save() # This should fail slot1.start_time = D.datetime(2013, 9, 26, 12, 0, 0, tzinfo=timezone.utc) self.assertRaises(ValidationError, slot1.clean) slot1.delete() block1.delete()
def test_queryset_mixed(self): """Test with a mix of day+time and previous slot cases.""" slots = {} prev = Slot(start_time=D.datetime(2013, 9, 22, 11, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 12, 00, 0, tzinfo=timezone.utc)) prev.save() slots[self.block1] = [prev] prev = Slot(start_time=D.datetime(2013, 9, 23, 11, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 23, 12, 00, 0, tzinfo=timezone.utc)) prev.save() slots[self.block2] = [prev] # ScheduleBlock1 slots for x in range(12, 20): prev1 = slots[self.block1][-1] if x % 2: slots[self.block1].append(Slot(previous_slot=prev1, end_time=D.datetime(2013, 9, 22, x+1, 0, 0, tzinfo=timezone.utc))) else: slots[self.block1].append(Slot(start_time=D.datetime(2013, 9, 22, x, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, x+1, 0, 0, tzinfo=timezone.utc))) slots[self.block1][-1].save() prev2 = slots[self.block2][-1] if x % 5: slots[self.block2].append(Slot(previous_slot=prev2, end_time=D.datetime(2013, 9, 23, x+1, 0, 0, tzinfo=timezone.utc))) else: slots[self.block2].append(Slot(start_time=D.datetime(2013, 9, 23, x, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 23, x+1, 0, 0, tzinfo=timezone.utc))) slots[self.block2][-1].save() # Check Null filter TestFilter = self._make_block_filter(None) self.assertEqual(list(TestFilter.queryset(None, Slot.objects.all())), list(Slot.objects.all())) # Test ScheduleBlock1 TestFilter = self._make_block_filter(self.block1) queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set(slots[self.block1])) # Test ScheduleBlock2 TestFilter = self._make_block_filter(self.block2) queries = set(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, set(slots[self.block2])) # Check no match case TestFilter = self._make_block_filter(self.block3) queries = list(TestFilter.queryset(None, Slot.objects.all())) self.assertEqual(queries, [])
def test_overlapping_slots(self): """Test that we can't create overlapping slots.""" block1 = ScheduleBlock.objects.create( start_time=D.datetime(2013, 9, 26, 9, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 26, 19, 0, 0, tzinfo=timezone.utc)) slot1 = Slot(start_time=D.datetime(2013, 9, 26, 10, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 26, 12, 0, 0, tzinfo=timezone.utc)) slot1.clean() slot1.save() # Start time is in the middle of slot1 slot2 = Slot(start_time=D.datetime(2013, 9, 26, 11, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 26, 13, 0, 0, tzinfo=timezone.utc)) self.assertRaises(ValidationError, slot2.clean) # End time is in the middle of slot2 slot2 = Slot(start_time=D.datetime(2013, 9, 26, 9, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 26, 11, 0, 0, tzinfo=timezone.utc)) self.assertRaises(ValidationError, slot2.clean) # Slot 2 totally encloses slot 1 slot2 = Slot(start_time=D.datetime(2013, 9, 26, 9, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 26, 13, 0, 0, tzinfo=timezone.utc)) self.assertRaises(ValidationError, slot2.clean) # Slot 2 totally included in slot 1 slot2 = Slot(start_time=D.datetime(2013, 9, 26, 11, 30, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 26, 12, 30, 0, tzinfo=timezone.utc)) self.assertRaises(ValidationError, slot2.clean) # Slot 2 has the same times as slot 1 slot2 = Slot(start_time=D.datetime(2013, 9, 26, 11, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 26, 13, 0, 0, tzinfo=timezone.utc)) self.assertRaises(ValidationError, slot2.clean) # Check we don't raise errors on slots that touch as intended # slot 1 start time is slot 2's end time slot2 = Slot(start_time=D.datetime(2013, 9, 26, 9, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 26, 10, 0, 0, tzinfo=timezone.utc)) slot2.clean() slot2.save() # slot 1 end time is slot 2's start time slot3 = Slot(start_time=D.datetime(2013, 9, 26, 12, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 26, 13, 0, 0, tzinfo=timezone.utc)) slot3.clean() slot1.delete() slot2.delete() block1.delete()
def test_time_filter_lookups(self): """Test that filter lookups are sane.""" # Add some slots slot1 = Slot(start_time=D.datetime(2013, 9, 22, 11, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 12, 00, 0, tzinfo=timezone.utc)) slot2 = Slot(start_time=D.datetime(2013, 9, 23, 11, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 23, 12, 00, 0, tzinfo=timezone.utc)) slot3 = Slot(start_time=D.datetime(2013, 9, 22, 12, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 13, 0, 0, tzinfo=timezone.utc)) slot4 = Slot(start_time=D.datetime(2013, 9, 22, 13, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 14, 0, 0, tzinfo=timezone.utc)) slot1.save() slot2.save() slot3.save() slot4.save() TestFilter = self._make_time_filter('11:00') # Check lookup details lookups = list(TestFilter.lookups(None, self.admin)) print(lookups) self.assertEqual(len(lookups), 3) self.assertEqual(lookups[0], ('11:00', '11:00')) TestFilter = self._make_time_filter('12:00') lookups2 = list(TestFilter.lookups(None, self.admin)) self.assertEqual(lookups, lookups2)