Skip to content

Commit

Permalink
apps/comments: make sure comment can only be added with egreement and…
Browse files Browse the repository at this point in the history
… add tests
  • Loading branch information
fuzzylogic2000 committed Jul 5, 2022
1 parent 9918201 commit def1b37
Show file tree
Hide file tree
Showing 7 changed files with 411 additions and 24 deletions.
57 changes: 42 additions & 15 deletions adhocracy4/comments_async/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.urls import reverse
from django.urls.exceptions import NoReverseMatch
from django.utils.translation import gettext_lazy as _
from django_filters import rest_framework as filters
from rest_framework import mixins
from rest_framework import status
from rest_framework import viewsets
from rest_framework.exceptions import ValidationError
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response

Expand Down Expand Up @@ -113,15 +116,11 @@ def get_serializer_class(self):

def _save_terms_agreement(self):
if hasattr(settings, 'A4_USE_ORGANISATION_TERMS_OF_USE') \
and settings.A4_USE_ORGANISATION_TERMS_OF_USE:
and settings.A4_USE_ORGANISATION_TERMS_OF_USE \
and not self._user_has_agreed(self.request.user):
if 'agreed_terms_of_use' in self.request.data and \
self.request.data['agreed_terms_of_use']:
organisation_model = apps.get_model(
settings.A4_ORGANISATIONS_MODEL)
OrganisationTermsOfUse = apps.get_model(
organisation_model._meta.app_label,
'OrganisationTermsOfUse'
)
self.request.data['agreed_terms_of_use']:
OrganisationTermsOfUse = self._get_org_terms_model()
OrganisationTermsOfUse.objects.update_or_create(
user=self.request.user,
organisation=self.content_object.project.organisation,
Expand All @@ -130,6 +129,11 @@ def _save_terms_agreement(self):
self.request.data['agreed_terms_of_use']
}
)
else:
raise ValidationError({
'comment':
_("Please agree to the organisation's terms of use.")
})

def perform_create(self, serializer):
self._save_terms_agreement()
Expand Down Expand Up @@ -166,6 +170,27 @@ def rules_method_map(self):
)
)

def _get_org_terms_model(self):
"""Make sure, only used with A4_USE_ORGANISATION_TERMS_OF_USE."""
organisation_model = apps.get_model(
settings.A4_ORGANISATIONS_MODEL)
OrganisationTermsOfUse = apps.get_model(
organisation_model._meta.app_label,
'OrganisationTermsOfUse'
)
return OrganisationTermsOfUse

def _user_has_agreed(self, user):
OrganisationTermsOfUse = self._get_org_terms_model()
organisation = self.content_object.project.organisation
user_has_agreed = \
OrganisationTermsOfUse.objects.filter(
user=user,
organisation=organisation,
has_agreed=True
).exists()
return user_has_agreed

def destroy(self, request, *args, **kwargs):
comment = self.get_object()
if self.request.user == comment.creator:
Expand All @@ -192,16 +217,18 @@ def list(self, request, *args, **kwargs):
user_has_agreed = None
use_org_terms_of_use = True
organisation = self.content_object.project.organisation
org_terms_url = reverse(
'organisation-terms-of-use', kwargs={
'organisation_slug': organisation.slug
}
)
try:
org_terms_url = reverse(
'organisation-terms-of-use', kwargs={
'organisation_slug': organisation.slug
}
)
except NoReverseMatch:
raise NotImplementedError('Add org terms of use view.')
if hasattr(request, 'user'):
user = request.user
if user.is_authenticated:
user_has_agreed = \
user.has_agreed_on_org_terms(organisation)
user_has_agreed = self._user_has_agreed(user)
response.data['user_has_agreed'] = user_has_agreed
response.data['org_terms_url'] = org_terms_url
response.data['use_org_terms_of_use'] = use_org_terms_of_use
Expand Down
9 changes: 9 additions & 0 deletions tests/apps/organisations/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from adhocracy4.test.factories import UserFactory
from tests.apps.organisations.models import Member
from tests.apps.organisations.models import Organisation
from tests.apps.organisations.models import OrganisationTermsOfUse


class OrganisationFactory(factory.django.DjangoModelFactory):
Expand Down Expand Up @@ -33,3 +34,11 @@ class Meta:

member = factory.SubFactory(USER_FACTORY)
organisation = factory.SubFactory(ORGANISATION_FACTORY)


class OrganisationTermsOfUseFactory(factory.django.DjangoModelFactory):
class Meta:
model = OrganisationTermsOfUse

user = factory.SubFactory(UserFactory)
organisation = factory.SubFactory(OrganisationFactory)
28 changes: 28 additions & 0 deletions tests/apps/organisations/migrations/0003_organisationtermsofuse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 3.2.13 on 2022-06-21 14:14

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('a4test_organisations', '0002_member'),
]

operations = [
migrations.CreateModel(
name='OrganisationTermsOfUse',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('has_agreed', models.BooleanField(default=False)),
('organisation', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to=settings.A4_ORGANISATIONS_MODEL)),
('user', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'unique_together': {('user', 'organisation')},
},
),
]
33 changes: 28 additions & 5 deletions tests/apps/organisations/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Organisation(models.Model):
)
groups = models.ManyToManyField(
Group,
blank=True
blank=True,
)

def __str__(self):
Expand All @@ -38,10 +38,33 @@ def get_absolute_url(self):


class Member(models.Model):
member = models.ForeignKey(User,
on_delete=models.CASCADE)
organisation = models.ForeignKey(settings.A4_ORGANISATIONS_MODEL,
on_delete=models.CASCADE)
member = models.ForeignKey(
User,
on_delete=models.CASCADE,
)
organisation = models.ForeignKey(
settings.A4_ORGANISATIONS_MODEL,
on_delete=models.CASCADE,
)

class Meta:
unique_together = [('member', 'organisation')]


class OrganisationTermsOfUse(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
editable=False,
)
organisation = models.ForeignKey(
settings.A4_ORGANISATIONS_MODEL,
on_delete=models.CASCADE,
editable=False,
)
has_agreed = models.BooleanField(
default=False,
)

class Meta:
unique_together = [('user', 'organisation')]
6 changes: 2 additions & 4 deletions tests/comments/test_async_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,10 +346,6 @@ def test_fields(user, apiclient, question_ct, question):
with active_phase(question.module, AskPhase):
apiclient.post(url, data, format='json')

url = reverse(
'comments_async-list',
kwargs={'content_type': question_ct.pk,
'object_pk': question.pk})
response = apiclient.get(url)

assert len(response.data) == 8
Expand All @@ -361,6 +357,8 @@ def test_fields(user, apiclient, question_ct, question):
assert 'would_have_commenting_permission' in response.data
assert 'project_is_public' in response.data
assert response.data['count'] == 1
assert 'use_org_terms_of_use' in response.data
assert not response.data['use_org_terms_of_use']

commentDict = response.data['results'][0]
assert len(commentDict) == 21
Expand Down
Loading

0 comments on commit def1b37

Please sign in to comment.