✨(contacts) list profile contacts from same org
Allow the contact API to list "profile" contacts for user of the same organization.
This commit is contained in:
@@ -12,8 +12,9 @@ and this project adheres to
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- ✨(contacts) return profile contact from same organization
|
||||||
- ✨(dimail) automate allows requests to dimail
|
- ✨(dimail) automate allows requests to dimail
|
||||||
- ✨(contacts) add notes & force full_name #565
|
- ✨(contacts) add notes & force full_name #565
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|||||||
@@ -139,19 +139,21 @@ class ContactViewSet(
|
|||||||
queryset = models.Contact.objects.all()
|
queryset = models.Contact.objects.all()
|
||||||
serializer_class = serializers.ContactSerializer
|
serializer_class = serializers.ContactSerializer
|
||||||
throttle_classes = [BurstRateThrottle, SustainedRateThrottle]
|
throttle_classes = [BurstRateThrottle, SustainedRateThrottle]
|
||||||
|
ordering_fields = ["full_name", "short_name", "created_at"]
|
||||||
|
ordering = ["full_name"]
|
||||||
|
|
||||||
def list(self, request, *args, **kwargs):
|
def list(self, request, *args, **kwargs):
|
||||||
"""Limit listed users by a query with throttle protection."""
|
"""Limit listed users by a query with throttle protection."""
|
||||||
user = self.request.user
|
user = self.request.user
|
||||||
queryset = self.filter_queryset(self.get_queryset())
|
queryset = self.filter_queryset(self.get_queryset())
|
||||||
|
|
||||||
# Exclude contacts that:
|
# List only contacts that:
|
||||||
queryset = queryset.filter(
|
queryset = queryset.filter(
|
||||||
# - belong to another user (keep public and owned contacts)
|
# - are owned by the user
|
||||||
Q(owner__isnull=True) | Q(owner=user),
|
Q(owner=user)
|
||||||
# - are profile contacts for a user
|
# - are profile contacts for a user from the same organization
|
||||||
user__isnull=True,
|
| Q(user__organization_id=user.organization_id),
|
||||||
# - are overriden base contacts
|
# - are not overriden by another contact
|
||||||
overridden_by__isnull=True,
|
overridden_by__isnull=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,16 @@ class ContactFactory(BaseContactFactory):
|
|||||||
owner = factory.SubFactory("core.factories.UserFactory")
|
owner = factory.SubFactory("core.factories.UserFactory")
|
||||||
|
|
||||||
|
|
||||||
|
class ProfileContactFactory(BaseContactFactory):
|
||||||
|
"""A factory to create profile contacts for a user"""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = models.Contact
|
||||||
|
|
||||||
|
owner = factory.SelfAttribute(".user")
|
||||||
|
user = factory.SubFactory("core.factories.UserFactory")
|
||||||
|
|
||||||
|
|
||||||
class OverrideContactFactory(BaseContactFactory):
|
class OverrideContactFactory(BaseContactFactory):
|
||||||
"""A factory to create contacts for a user"""
|
"""A factory to create contacts for a user"""
|
||||||
|
|
||||||
|
|||||||
@@ -27,18 +27,32 @@ def test_api_contacts_list_authenticated_no_query():
|
|||||||
Authenticated users should be able to list contacts without applying a query.
|
Authenticated users should be able to list contacts without applying a query.
|
||||||
Profile and overridden contacts should be excluded.
|
Profile and overridden contacts should be excluded.
|
||||||
"""
|
"""
|
||||||
user = factories.UserFactory()
|
organization = factories.OrganizationFactory(with_registration_id=True)
|
||||||
factories.ContactFactory(owner=user, user=user)
|
user = factories.UserFactory(organization=organization)
|
||||||
|
|
||||||
# Let's have 5 contacts in database:
|
# The user's profile contact should be listed (why not)
|
||||||
assert user.profile_contact is not None # Excluded because profile contact
|
user_profile_contact = factories.ContactFactory(
|
||||||
base_contact = factories.BaseContactFactory() # Excluded because overridden
|
owner=user, user=user, full_name="Dave Bowman"
|
||||||
factories.ContactFactory(
|
)
|
||||||
override=base_contact
|
|
||||||
) # Excluded because belongs to other user
|
# A contact that belongs to another user should not be listed
|
||||||
contact2 = factories.ContactFactory(
|
factories.ContactFactory()
|
||||||
override=base_contact, owner=user, full_name="Bernard"
|
# even if from the same organization
|
||||||
) # Included
|
factories.ContactFactory(owner__organization=organization)
|
||||||
|
|
||||||
|
# A profile contact should not be listed if from another organization
|
||||||
|
factories.ProfileContactFactory()
|
||||||
|
|
||||||
|
# A profile contact for someone in the same organization should be listed
|
||||||
|
profile_contact = factories.ProfileContactFactory(
|
||||||
|
user__organization=organization, full_name="Frank Poole"
|
||||||
|
)
|
||||||
|
|
||||||
|
# An overridden contact should not be listed, but the override must be
|
||||||
|
overriden_contact = factories.ProfileContactFactory(user__organization=organization)
|
||||||
|
override_contact = factories.ContactFactory(
|
||||||
|
owner=user, override=overriden_contact, full_name="Nicole Foole"
|
||||||
|
)
|
||||||
|
|
||||||
client = APIClient()
|
client = APIClient()
|
||||||
client.force_login(user)
|
client.force_login(user)
|
||||||
@@ -48,13 +62,31 @@ def test_api_contacts_list_authenticated_no_query():
|
|||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.json() == [
|
assert response.json() == [
|
||||||
{
|
{
|
||||||
"id": str(contact2.id),
|
"id": str(user_profile_contact.pk),
|
||||||
"override": str(base_contact.id),
|
"override": None,
|
||||||
"owner": str(contact2.owner.id),
|
"owner": str(user.pk),
|
||||||
"data": contact2.data,
|
"data": user_profile_contact.data,
|
||||||
"full_name": contact2.full_name,
|
"full_name": user_profile_contact.full_name,
|
||||||
"notes": "",
|
"notes": "",
|
||||||
"short_name": contact2.short_name,
|
"short_name": user_profile_contact.short_name,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": str(profile_contact.pk),
|
||||||
|
"override": None,
|
||||||
|
"owner": str(profile_contact.user.pk),
|
||||||
|
"data": profile_contact.data,
|
||||||
|
"full_name": profile_contact.full_name,
|
||||||
|
"notes": "",
|
||||||
|
"short_name": profile_contact.short_name,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": str(override_contact.pk),
|
||||||
|
"override": str(overriden_contact.pk),
|
||||||
|
"owner": str(user.pk),
|
||||||
|
"data": override_contact.data,
|
||||||
|
"full_name": override_contact.full_name,
|
||||||
|
"notes": "",
|
||||||
|
"short_name": override_contact.short_name,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user