def test_clean_duplicate_entry(self): DiningEntryUser.objects.create(dining_list=self.dining_list, user=self.user, created_by=self.user) entry = DiningEntryUser(dining_list=self.dining_list, user=self.user, created_by=self.user) self.assertRaises(ValidationError, entry.full_clean)
def setUp(self): # Not in setUpTestData to ensure that it is fresh for every test case self.dining_list = DiningList.objects.create( date=date(2089, 1, 1), association=self.association, sign_up_deadline=datetime(2088, 1, 1, tzinfo=timezone.utc)) self.dining_list.owners.add(self.user) self.dining_entry = DiningEntryUser(dining_list=self.dining_list, created_by=self.user2) self.post_data = {'user': str(self.user2.pk)} self.form = DiningEntryUserCreateForm(self.post_data, instance=self.dining_entry)
def post(self, request, *args, **kwargs): # This post method always redirects, does not show the form again on validation errors, so that we don't have # to write HTML for displaying these errors (they are already in a Django message). # Do form shenanigans if 'add_external' in request.POST: entry = DiningEntryExternal(user=request.user, dining_list=self.dining_list, created_by=request.user) form = DiningEntryExternalCreateForm(request.POST, instance=entry) else: entry = DiningEntryUser(dining_list=self.dining_list, created_by=request.user) form = DiningEntryUserCreateForm(request.POST, instance=entry) if form.is_valid(): entry = form.save() # Construct success message if isinstance(entry, DiningEntryUser): if entry.user == request.user: msg = "You successfully joined the dining list" else: # Send mail to the diner send_templated_mail('mail/dining_entry_added_by', entry.user, context={ 'entry': entry, 'dining_list': entry.dining_list }, request=request) msg = "You successfully added {} to the dining list".format( entry.user.get_short_name()) else: msg = "You successfully added {} to the dining list".format( entry.name) messages.success(request, msg) else: # Apply error messages for field, errors in form.errors.items(): for error in errors: messages.error( request, "{}: {}".format(field, error) if field != NON_FIELD_ERRORS else error) # Redirect to next if provided, else to the diner list if successful, else to self next_url = request.GET.get('next') if next_url and is_safe_url(next_url, request.get_host()): return HttpResponseRedirect(next_url) if form.is_valid(): # Todo: Check if user is on multiple dining lists today, then show warning? return HttpResponseRedirect(self.reverse('slot_list')) return HttpResponseRedirect(self.reverse('entry_add'))
def test_race_condition_max_diners(self): """Tries to do a race condition on the maximum number of diners. Note! As long as this test passes, the race condition is present! Ideally therefore you'd want this test case to fail. """ self.dining_list.max_diners = 1 # Try creating 2 entries using race condition entry1 = DiningEntryUser(dining_list=self.dining_list, user=self.user2, created_by=self.user2) entry2 = DiningEntryUser(dining_list=self.dining_list, user=self.user2, created_by=self.user2) form1 = DiningEntryUserCreateForm(self.post_data, instance=entry1) form2 = DiningEntryUserCreateForm(self.post_data, instance=entry2) self.assertTrue(form1.is_valid()) # Both forms should be valid self.assertTrue(form2.is_valid()) form1.save() # Since they're both valid, they'll both get saved form2.save() # Now there are 2 entries of the same user and with max_diners being 1 self.assertEqual(2, DiningEntryUser.objects.all().count())
def setUp(self): self.user1 = User.objects.create_user('ankie', email='*****@*****.**') self.user2 = User.objects.create_user('noortje', email='*****@*****.**') self.association = Association.objects.create(name='C&M') self.dining_list = DiningList.objects.create( date=date(2100, 1, 1), association=self.association, sign_up_deadline=datetime(2100, 1, 1, tzinfo=timezone.utc)) self.dining_list.owners.add(self.user1) self.entry = DiningEntryUser(user=self.user2, created_by=self.user2, dining_list=self.dining_list) self.form = DiningEntryDeleteForm(self.entry, self.user2, {})
def save(self, commit=True): instance = super().save(commit=commit) if commit: # Make creator owner instance.owners.add(self.creator) # Create dining entry for creator user = self.creator entry_form = DiningEntryUserCreateForm({'user': str(user.pk)}, instance=DiningEntryUser( created_by=user, dining_list=instance)) if entry_form.is_valid(): entry_form.save() else: warnings.warn( "Couldn't create dining entry while creating dining list") return instance
def test_clean_valid_entry(self): entry = DiningEntryUser(dining_list=self.dining_list, user=self.user, created_by=self.user) entry.full_clean() # No ValidationError
def cant_join_reason(dining_list, user): """Returns the reason why someone can't join (raises exception when they can join).""" entry = DiningEntryUser(dining_list=dining_list, created_by=user) form = DiningEntryUserCreateForm({'user': str(user.pk)}, instance=entry) return form.non_field_errors()[0]
def can_join(dining_list, user): # Try creating an entry entry = DiningEntryUser(dining_list=dining_list, created_by=user) form = DiningEntryUserCreateForm({'user': str(user.pk)}, instance=entry) return form.is_valid()