diff --git a/wcivf/apps/feedback/forms.py b/wcivf/apps/feedback/forms.py index c3446c843..285eb07a6 100644 --- a/wcivf/apps/feedback/forms.py +++ b/wcivf/apps/feedback/forms.py @@ -1,14 +1,17 @@ -import uuid - from django import forms -from .models import Feedback, FOUND_USEFUL_CHOICES, VOTE_CHOICES +from .models import ( + Feedback, + FOUND_USEFUL_CHOICES, + VOTE_CHOICES, + generate_feedback_token, +) class FeedbackForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(FeedbackForm, self).__init__(*args, **kwargs) - self.fields["token"].initial = uuid.uuid4().hex + self.fields["token"].initial = generate_feedback_token() class Meta: model = Feedback diff --git a/wcivf/apps/feedback/migrations/0007_alter_feedback_token.py b/wcivf/apps/feedback/migrations/0007_alter_feedback_token.py new file mode 100644 index 000000000..646e28272 --- /dev/null +++ b/wcivf/apps/feedback/migrations/0007_alter_feedback_token.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.3 on 2023-07-18 16:38 + +from django.db import migrations, models +import feedback.models + + +class Migration(migrations.Migration): + dependencies = [ + ("feedback", "0006_feedback_flagged_as_spam"), + ] + + operations = [ + migrations.AlterField( + model_name="feedback", + name="token", + field=models.CharField( + blank=True, + default=feedback.models.generate_feedback_token, + max_length=100, + ), + ), + ] diff --git a/wcivf/apps/feedback/models.py b/wcivf/apps/feedback/models.py index 97f6ead19..7a57e0f07 100644 --- a/wcivf/apps/feedback/models.py +++ b/wcivf/apps/feedback/models.py @@ -1,3 +1,5 @@ +import uuid + from django.db import models from django_extensions.db.models import TimeStampedModel @@ -7,6 +9,10 @@ VOTE_CHOICES = (("YES", _("Yes")), ("NO", _("No"))) +def generate_feedback_token(): + return uuid.uuid4().hex + + class Feedback(TimeStampedModel): found_useful = models.CharField( blank=True, max_length=100, choices=FOUND_USEFUL_CHOICES @@ -15,5 +21,7 @@ class Feedback(TimeStampedModel): sources = models.TextField(blank=True) comments = models.TextField(blank=True) source_url = models.CharField(blank=True, max_length=800) - token = models.CharField(blank=True, max_length=100) + token = models.CharField( + blank=True, max_length=100, default=generate_feedback_token + ) flagged_as_spam = models.BooleanField(default=False) diff --git a/wcivf/apps/feedback/tests/test_views.py b/wcivf/apps/feedback/tests/test_views.py new file mode 100644 index 000000000..78a432f48 --- /dev/null +++ b/wcivf/apps/feedback/tests/test_views.py @@ -0,0 +1,42 @@ +# Test: FeedbackFormViewTests +from django.urls import reverse +from django.test import TestCase +from feedback.views import FeedbackFormView +from feedback.models import Feedback + + +class FeedbackFormViewTests(TestCase, FeedbackFormView): + def setUp(self): + self.existing_feedback = Feedback() + self.existing_feedback.save() + + def test_token_set_by_default(self): + request = self.client.get(reverse("feedback_form_view")) + new_token = request.context_data["object"].token + assert new_token + assert new_token != self.existing_feedback.token + + def test_submit_form_saves_feedback(self): + assert Feedback.objects.count() == 1 + req = self.client.post( + reverse("feedback_form_view"), + { + "found_useful": "YES", + "vote": "YES", + "source_url": "https://example.com", + "token": "123", + }, + ) + assert req.status_code == 302 + assert Feedback.objects.count() == 2 + + self.client.post( + reverse("feedback_form_view"), + { + "found_useful": "YES", + "vote": "YES", + "source_url": "https://example.com", + "token": "123", + }, + ) + assert Feedback.objects.count() == 2 diff --git a/wcivf/apps/feedback/views.py b/wcivf/apps/feedback/views.py index 996a86261..bb5035e97 100644 --- a/wcivf/apps/feedback/views.py +++ b/wcivf/apps/feedback/views.py @@ -1,3 +1,4 @@ +from django.utils import timezone from django.http import HttpResponse from django.views.generic import View, UpdateView from django.utils.http import url_has_allowed_host_and_scheme @@ -24,16 +25,19 @@ def is_spam(self): ) return akismet.check( self.request.META["REMOTE_ADDR"], - self.request.META["HTTP_USER_AGENT"], comment_content=self.request.POST.get("comments"), ) def get_object(self, queryset=None): token = self.request.POST.get("token") try: - return Feedback.objects.get(token=token) + return Feedback.objects.get( + token=token, created__date=timezone.datetime.today() + ) except Feedback.DoesNotExist: - return Feedback(token=token) + if token: + return Feedback(token=token) + return Feedback() def get_success_url(self): messages.success(