diff --git a/src/backend/core/tests/contacts/__init__.py b/src/backend/core/tests/contacts/__init__.py new file mode 100644 index 0000000..62cb749 --- /dev/null +++ b/src/backend/core/tests/contacts/__init__.py @@ -0,0 +1 @@ +"""Contacts tests package.""" diff --git a/src/backend/core/tests/contacts/test_core_api_contacts_create.py b/src/backend/core/tests/contacts/test_core_api_contacts_create.py index 1168a38..5182e45 100644 --- a/src/backend/core/tests/contacts/test_core_api_contacts_create.py +++ b/src/backend/core/tests/contacts/test_core_api_contacts_create.py @@ -52,269 +52,6 @@ CONTACT_DATA = { } -def test_api_contacts_list_anonymous(): - """Anonymous users should not be allowed to list contacts.""" - factories.ContactFactory.create_batch(2) - - response = APIClient().get("/api/v1.0/contacts/") - - assert response.status_code == 401 - assert response.json() == { - "detail": "Authentication credentials were not provided." - } - - -def test_api_contacts_list_authenticated_no_query(): - """ - Authenticated users should be able to list contacts without applying a query. - Profile and overridden contacts should be excluded. - """ - user = factories.UserFactory() - factories.ContactFactory(owner=user, user=user) - - # Let's have 5 contacts in database: - assert user.profile_contact is not None # Excluded because profile contact - base_contact = factories.BaseContactFactory() # Excluded because overridden - factories.ContactFactory( - override=base_contact - ) # Excluded because belongs to other user - contact2 = factories.ContactFactory( - override=base_contact, owner=user, full_name="Bernard" - ) # Included - - client = APIClient() - client.force_login(user) - - response = client.get("/api/v1.0/contacts/") - - assert response.status_code == 200 - assert response.json() == [ - { - "id": str(contact2.id), - "override": str(base_contact.id), - "owner": str(contact2.owner.id), - "data": contact2.data, - "full_name": contact2.full_name, - "notes": "", - "short_name": contact2.short_name, - }, - ] - - -def test_api_contacts_list_authenticated_by_full_name(): - """ - Authenticated users should be able to search users with a case insensitive and - partial query on the full name. - """ - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="David Bowman") - nicole = factories.BaseContactFactory(full_name="Nicole Foole") - frank = factories.BaseContactFactory(full_name="Frank Poole") - factories.BaseContactFactory(full_name="Heywood Floyd") - - # Full query should work - client = APIClient() - client.force_login(user) - - response = client.get("/api/v1.0/contacts/?q=David%20Bowman") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Partial query should work - response = client.get("/api/v1.0/contacts/?q=ank") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(frank.id)] - - response = client.get("/api/v1.0/contacts/?q=ole") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(frank.id), str(nicole.id)] - - response = client.get("/api/v1.0/contacts/?q=ool") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(frank.id), str(nicole.id)] - - -def test_api_contacts_list_authenticated_uppercase_content(): - """Upper case content should be found by lower case query.""" - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="EEE", short_name="AAA") - - # Unaccented full name - client = APIClient() - client.force_login(user) - - response = client.get("/api/v1.0/contacts/?q=eee") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Unaccented short name - response = client.get("/api/v1.0/contacts/?q=aaa") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - -def test_api_contacts_list_authenticated_capital_query(): - """Upper case query should find lower case content.""" - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="eee", short_name="aaa") - - client = APIClient() - client.force_login(user) - - # Unaccented full name - response = client.get("/api/v1.0/contacts/?q=EEE") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Unaccented short name - response = client.get("/api/v1.0/contacts/?q=AAA") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - -def test_api_contacts_list_authenticated_accented_content(): - """Accented content should be found by unaccented query.""" - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="ééé", short_name="ààà") - - client = APIClient() - client.force_login(user) - - # Unaccented full name - response = client.get("/api/v1.0/contacts/?q=eee") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Unaccented short name - response = client.get("/api/v1.0/contacts/?q=aaa") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - -def test_api_contacts_list_authenticated_accented_query(): - """Accented query should find unaccented content.""" - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="eee", short_name="aaa") - - client = APIClient() - client.force_login(user) - - # Unaccented full name - response = client.get("/api/v1.0/contacts/?q=ééé") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Unaccented short name - response = client.get("/api/v1.0/contacts/?q=ààà") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - -def test_api_contacts_retrieve_anonymous(): - """Anonymous users should not be allowed to retrieve a user.""" - client = APIClient() - contact = factories.ContactFactory() - response = client.get(f"/api/v1.0/contacts/{contact.id!s}/") - - assert response.status_code == 401 - assert response.json() == { - "detail": "Authentication credentials were not provided." - } - - -def test_api_contacts_retrieve_authenticated_owned(): - """ - Authenticated users should be allowed to retrieve a contact they own. - """ - user = factories.UserFactory() - contact = factories.ContactFactory(owner=user) - - client = APIClient() - client.force_login(user) - - response = client.get(f"/api/v1.0/contacts/{contact.id!s}/") - - assert response.status_code == 200 - assert response.json() == { - "id": str(contact.id), - "override": None, - "owner": str(contact.owner.id), - "data": contact.data, - "full_name": contact.full_name, - "notes": "", - "short_name": contact.short_name, - } - - -def test_api_contacts_retrieve_authenticated_public(): - """ - Authenticated users should be able to retrieve public contacts. - """ - user = factories.UserFactory() - contact = factories.BaseContactFactory() - - client = APIClient() - client.force_login(user) - - response = client.get(f"/api/v1.0/contacts/{contact.id!s}/") - assert response.status_code == 200 - assert response.json() == { - "id": str(contact.id), - "override": None, - "owner": None, - "data": contact.data, - "full_name": contact.full_name, - "notes": "", - "short_name": contact.short_name, - } - - -def test_api_contacts_retrieve_authenticated_other(): - """ - Authenticated users should not be allowed to retrieve another user's contacts. - """ - user = factories.UserFactory() - contact = factories.ContactFactory() - - client = APIClient() - client.force_login(user) - - response = client.get(f"/api/v1.0/contacts/{contact.id!s}/") - assert response.status_code == 403 - assert response.json() == { - "detail": "You do not have permission to perform this action." - } - - def test_api_contacts_create_anonymous_forbidden(): """Anonymous users should not be able to create contacts via the API.""" response = APIClient().post( diff --git a/src/backend/core/tests/contacts/test_core_api_contacts_delete.py b/src/backend/core/tests/contacts/test_core_api_contacts_delete.py index 1168a38..343e52c 100644 --- a/src/backend/core/tests/contacts/test_core_api_contacts_delete.py +++ b/src/backend/core/tests/contacts/test_core_api_contacts_delete.py @@ -2,599 +2,14 @@ Test contacts API endpoints in People's core app. """ -from django.test.utils import override_settings - import pytest from rest_framework.test import APIClient from core import factories, models -from core.api.client import serializers pytestmark = pytest.mark.django_db -CONTACT_DATA = { - "emails": [ - {"type": "Work", "value": "john.doe@work.com"}, - {"type": "Home", "value": "john.doe@home.com"}, - ], - "phones": [ - {"type": "Work", "value": "(123) 456-7890"}, - {"type": "Other", "value": "(987) 654-3210"}, - ], - "addresses": [ - { - "type": "Home", - "street": "123 Main St", - "city": "Cityville", - "state": "CA", - "zip": "12345", - "country": "USA", - } - ], - "links": [ - {"type": "Blog", "value": "http://personalwebsite.com"}, - {"type": "Website", "value": "http://workwebsite.com"}, - ], - "customFields": {"custom_field_1": "value1", "custom_field_2": "value2"}, - "organizations": [ - { - "name": "ACME Corporation", - "department": "IT", - "jobTitle": "Software Engineer", - }, - { - "name": "XYZ Ltd", - "department": "Marketing", - "jobTitle": "Marketing Specialist", - }, - ], -} - - -def test_api_contacts_list_anonymous(): - """Anonymous users should not be allowed to list contacts.""" - factories.ContactFactory.create_batch(2) - - response = APIClient().get("/api/v1.0/contacts/") - - assert response.status_code == 401 - assert response.json() == { - "detail": "Authentication credentials were not provided." - } - - -def test_api_contacts_list_authenticated_no_query(): - """ - Authenticated users should be able to list contacts without applying a query. - Profile and overridden contacts should be excluded. - """ - user = factories.UserFactory() - factories.ContactFactory(owner=user, user=user) - - # Let's have 5 contacts in database: - assert user.profile_contact is not None # Excluded because profile contact - base_contact = factories.BaseContactFactory() # Excluded because overridden - factories.ContactFactory( - override=base_contact - ) # Excluded because belongs to other user - contact2 = factories.ContactFactory( - override=base_contact, owner=user, full_name="Bernard" - ) # Included - - client = APIClient() - client.force_login(user) - - response = client.get("/api/v1.0/contacts/") - - assert response.status_code == 200 - assert response.json() == [ - { - "id": str(contact2.id), - "override": str(base_contact.id), - "owner": str(contact2.owner.id), - "data": contact2.data, - "full_name": contact2.full_name, - "notes": "", - "short_name": contact2.short_name, - }, - ] - - -def test_api_contacts_list_authenticated_by_full_name(): - """ - Authenticated users should be able to search users with a case insensitive and - partial query on the full name. - """ - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="David Bowman") - nicole = factories.BaseContactFactory(full_name="Nicole Foole") - frank = factories.BaseContactFactory(full_name="Frank Poole") - factories.BaseContactFactory(full_name="Heywood Floyd") - - # Full query should work - client = APIClient() - client.force_login(user) - - response = client.get("/api/v1.0/contacts/?q=David%20Bowman") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Partial query should work - response = client.get("/api/v1.0/contacts/?q=ank") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(frank.id)] - - response = client.get("/api/v1.0/contacts/?q=ole") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(frank.id), str(nicole.id)] - - response = client.get("/api/v1.0/contacts/?q=ool") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(frank.id), str(nicole.id)] - - -def test_api_contacts_list_authenticated_uppercase_content(): - """Upper case content should be found by lower case query.""" - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="EEE", short_name="AAA") - - # Unaccented full name - client = APIClient() - client.force_login(user) - - response = client.get("/api/v1.0/contacts/?q=eee") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Unaccented short name - response = client.get("/api/v1.0/contacts/?q=aaa") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - -def test_api_contacts_list_authenticated_capital_query(): - """Upper case query should find lower case content.""" - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="eee", short_name="aaa") - - client = APIClient() - client.force_login(user) - - # Unaccented full name - response = client.get("/api/v1.0/contacts/?q=EEE") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Unaccented short name - response = client.get("/api/v1.0/contacts/?q=AAA") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - -def test_api_contacts_list_authenticated_accented_content(): - """Accented content should be found by unaccented query.""" - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="ééé", short_name="ààà") - - client = APIClient() - client.force_login(user) - - # Unaccented full name - response = client.get("/api/v1.0/contacts/?q=eee") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Unaccented short name - response = client.get("/api/v1.0/contacts/?q=aaa") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - -def test_api_contacts_list_authenticated_accented_query(): - """Accented query should find unaccented content.""" - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="eee", short_name="aaa") - - client = APIClient() - client.force_login(user) - - # Unaccented full name - response = client.get("/api/v1.0/contacts/?q=ééé") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Unaccented short name - response = client.get("/api/v1.0/contacts/?q=ààà") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - -def test_api_contacts_retrieve_anonymous(): - """Anonymous users should not be allowed to retrieve a user.""" - client = APIClient() - contact = factories.ContactFactory() - response = client.get(f"/api/v1.0/contacts/{contact.id!s}/") - - assert response.status_code == 401 - assert response.json() == { - "detail": "Authentication credentials were not provided." - } - - -def test_api_contacts_retrieve_authenticated_owned(): - """ - Authenticated users should be allowed to retrieve a contact they own. - """ - user = factories.UserFactory() - contact = factories.ContactFactory(owner=user) - - client = APIClient() - client.force_login(user) - - response = client.get(f"/api/v1.0/contacts/{contact.id!s}/") - - assert response.status_code == 200 - assert response.json() == { - "id": str(contact.id), - "override": None, - "owner": str(contact.owner.id), - "data": contact.data, - "full_name": contact.full_name, - "notes": "", - "short_name": contact.short_name, - } - - -def test_api_contacts_retrieve_authenticated_public(): - """ - Authenticated users should be able to retrieve public contacts. - """ - user = factories.UserFactory() - contact = factories.BaseContactFactory() - - client = APIClient() - client.force_login(user) - - response = client.get(f"/api/v1.0/contacts/{contact.id!s}/") - assert response.status_code == 200 - assert response.json() == { - "id": str(contact.id), - "override": None, - "owner": None, - "data": contact.data, - "full_name": contact.full_name, - "notes": "", - "short_name": contact.short_name, - } - - -def test_api_contacts_retrieve_authenticated_other(): - """ - Authenticated users should not be allowed to retrieve another user's contacts. - """ - user = factories.UserFactory() - contact = factories.ContactFactory() - - client = APIClient() - client.force_login(user) - - response = client.get(f"/api/v1.0/contacts/{contact.id!s}/") - assert response.status_code == 403 - assert response.json() == { - "detail": "You do not have permission to perform this action." - } - - -def test_api_contacts_create_anonymous_forbidden(): - """Anonymous users should not be able to create contacts via the API.""" - response = APIClient().post( - "/api/v1.0/contacts/", - { - "full_name": "David", - "short_name": "Bowman", - }, - ) - assert response.status_code == 401 - assert not models.Contact.objects.exists() - - -def test_api_contacts_create_authenticated_missing_base(): - """Authenticated user should be able to create contact without override.""" - user = factories.UserFactory() - - client = APIClient() - client.force_login(user) - - response = client.post( - "/api/v1.0/contacts/", - { - "full_name": "David Bowman", - "short_name": "Dave", - "data": {}, - }, - format="json", - ) - assert response.status_code == 201 - - new_contact = models.Contact.objects.get(owner=user) - - assert response.json() == { - "override": None, - "data": {}, - "full_name": "David Bowman", - "id": str(new_contact.pk), - "notes": "", - "owner": str(user.pk), - "short_name": "Dave", - } - - -def test_api_contacts_create_authenticated_successful(): - """Authenticated users should be able to create contacts.""" - user = factories.UserFactory() - base_contact = factories.BaseContactFactory() - - client = APIClient() - client.force_login(user) - - # Existing override for another user should not interfere - factories.ContactFactory(override=base_contact) - - response = client.post( - "/api/v1.0/contacts/", - { - "override": str(base_contact.id), - "full_name": "David Bowman", - "short_name": "Dave", - "data": CONTACT_DATA, - }, - format="json", - ) - - assert response.status_code == 201 - assert models.Contact.objects.count() == 3 - - contact = models.Contact.objects.get(owner=user) - assert response.json() == { - "id": str(contact.id), - "override": str(base_contact.id), - "data": CONTACT_DATA, - "full_name": "David Bowman", - "notes": "", - "owner": str(user.id), - "short_name": "Dave", - } - - assert contact.full_name == "David Bowman" - assert contact.short_name == "Dave" - assert contact.data == CONTACT_DATA - assert contact.override == base_contact - assert contact.owner == user - - -@override_settings(ALLOW_API_USER_CREATE=True) -def test_api_contacts_create_authenticated_existing_override(): - """ - Trying to create a contact overriding a contact that is already overridden by the user - should receive a 400 error. - """ - user = factories.UserFactory() - base_contact = factories.BaseContactFactory() - factories.ContactFactory(override=base_contact, owner=user) - - client = APIClient() - client.force_login(user) - - response = client.post( - "/api/v1.0/contacts/", - { - "override": str(base_contact.id), - "full_name": "David Bowman", - "notes": "", - "short_name": "Dave", - "data": CONTACT_DATA, - }, - format="json", - ) - - assert response.status_code == 400 - assert models.Contact.objects.count() == 2 - - assert response.json() == { - "__all__": ["Contact with this Owner and Override already exists."] - } - - -def test_api_contacts_create_authenticated_successful_with_notes(): - """Authenticated users should be able to create contacts with notes.""" - user = factories.UserFactory() - - client = APIClient() - client.force_login(user) - - response = client.post( - "/api/v1.0/contacts/", - { - "full_name": "David Bowman", - "short_name": "Dave", - "data": CONTACT_DATA, - "notes": "This is a note", - }, - format="json", - ) - - assert response.status_code == 201 - assert models.Contact.objects.count() == 1 - - contact = models.Contact.objects.get(owner=user) - assert response.json() == { - "id": str(contact.id), - "override": None, - "data": CONTACT_DATA, - "full_name": "David Bowman", - "notes": "This is a note", - "owner": str(user.id), - "short_name": "Dave", - } - - assert contact.full_name == "David Bowman" - assert contact.short_name == "Dave" - assert contact.data == CONTACT_DATA - assert contact.owner == user - assert contact.notes == "This is a note" - - -def test_api_contacts_update_anonymous(): - """Anonymous users should not be allowed to update a contact.""" - contact = factories.ContactFactory() - old_contact_values = serializers.ContactSerializer(instance=contact).data - - new_contact_values = serializers.ContactSerializer( - instance=factories.ContactFactory() - ).data - new_contact_values["override"] = str(factories.ContactFactory().id) - response = APIClient().put( - f"/api/v1.0/contacts/{contact.id!s}/", - new_contact_values, - format="json", - ) - assert response.status_code == 401 - assert response.json() == { - "detail": "Authentication credentials were not provided." - } - - contact.refresh_from_db() - contact_values = serializers.ContactSerializer(instance=contact).data - assert contact_values == old_contact_values - - -def test_api_contacts_update_authenticated_owned(): - """ - Authenticated users should be allowed to update their own contacts. - """ - user = factories.UserFactory() - - client = APIClient() - client.force_login(user) - - contact = factories.ContactFactory(owner=user) # Owned by the logged-in user - old_contact_values = serializers.ContactSerializer(instance=contact).data - - new_contact_values = serializers.ContactSerializer( - instance=factories.ContactFactory() - ).data - new_contact_values["override"] = str(factories.ContactFactory().id) - - response = client.put( - f"/api/v1.0/contacts/{contact.id!s}/", - new_contact_values, - format="json", - ) - - assert response.status_code == 200 - - contact.refresh_from_db() - contact_values = serializers.ContactSerializer(instance=contact).data - for key, value in contact_values.items(): - if key in ["override", "owner", "id"]: - assert value == old_contact_values[key] - else: - assert value == new_contact_values[key] - - -def test_api_contacts_update_authenticated_profile(): - """ - Authenticated users should be allowed to update their profile contact. - """ - user = factories.UserFactory() - - client = APIClient() - client.force_login(user) - - contact = factories.ContactFactory(owner=user, user=user) - - old_contact_values = serializers.ContactSerializer(instance=contact).data - new_contact_values = serializers.ContactSerializer( - instance=factories.ContactFactory() - ).data - new_contact_values["override"] = str(factories.ContactFactory().id) - - response = client.put( - f"/api/v1.0/contacts/{contact.id!s}/", - new_contact_values, - format="json", - ) - - assert response.status_code == 200 - contact.refresh_from_db() - contact_values = serializers.ContactSerializer(instance=contact).data - for key, value in contact_values.items(): - if key in ["override", "owner", "id"]: - assert value == old_contact_values[key] - else: - assert value == new_contact_values[key] - - -def test_api_contacts_update_authenticated_other(): - """ - Authenticated users should not be allowed to update contacts owned by other users. - """ - user = factories.UserFactory() - - client = APIClient() - client.force_login(user) - - contact = factories.ContactFactory() # owned by another user - old_contact_values = serializers.ContactSerializer(instance=contact).data - - new_contact_values = serializers.ContactSerializer( - instance=factories.ContactFactory() - ).data - new_contact_values["override"] = str(factories.ContactFactory().id) - - response = client.put( - f"/api/v1.0/contacts/{contact.id!s}/", - new_contact_values, - format="json", - ) - - assert response.status_code == 403 - - contact.refresh_from_db() - contact_values = serializers.ContactSerializer(instance=contact).data - assert contact_values == old_contact_values - - def test_api_contacts_delete_list_anonymous(): """Anonymous users should not be allowed to delete a list of contacts.""" factories.ContactFactory.create_batch(2) diff --git a/src/backend/core/tests/contacts/test_core_api_contacts_list.py b/src/backend/core/tests/contacts/test_core_api_contacts_list.py index 1168a38..d3e3505 100644 --- a/src/backend/core/tests/contacts/test_core_api_contacts_list.py +++ b/src/backend/core/tests/contacts/test_core_api_contacts_list.py @@ -237,470 +237,3 @@ def test_api_contacts_list_authenticated_accented_query(): assert response.status_code == 200 contact_ids = [contact["id"] for contact in response.json()] assert contact_ids == [str(dave.id)] - - -def test_api_contacts_retrieve_anonymous(): - """Anonymous users should not be allowed to retrieve a user.""" - client = APIClient() - contact = factories.ContactFactory() - response = client.get(f"/api/v1.0/contacts/{contact.id!s}/") - - assert response.status_code == 401 - assert response.json() == { - "detail": "Authentication credentials were not provided." - } - - -def test_api_contacts_retrieve_authenticated_owned(): - """ - Authenticated users should be allowed to retrieve a contact they own. - """ - user = factories.UserFactory() - contact = factories.ContactFactory(owner=user) - - client = APIClient() - client.force_login(user) - - response = client.get(f"/api/v1.0/contacts/{contact.id!s}/") - - assert response.status_code == 200 - assert response.json() == { - "id": str(contact.id), - "override": None, - "owner": str(contact.owner.id), - "data": contact.data, - "full_name": contact.full_name, - "notes": "", - "short_name": contact.short_name, - } - - -def test_api_contacts_retrieve_authenticated_public(): - """ - Authenticated users should be able to retrieve public contacts. - """ - user = factories.UserFactory() - contact = factories.BaseContactFactory() - - client = APIClient() - client.force_login(user) - - response = client.get(f"/api/v1.0/contacts/{contact.id!s}/") - assert response.status_code == 200 - assert response.json() == { - "id": str(contact.id), - "override": None, - "owner": None, - "data": contact.data, - "full_name": contact.full_name, - "notes": "", - "short_name": contact.short_name, - } - - -def test_api_contacts_retrieve_authenticated_other(): - """ - Authenticated users should not be allowed to retrieve another user's contacts. - """ - user = factories.UserFactory() - contact = factories.ContactFactory() - - client = APIClient() - client.force_login(user) - - response = client.get(f"/api/v1.0/contacts/{contact.id!s}/") - assert response.status_code == 403 - assert response.json() == { - "detail": "You do not have permission to perform this action." - } - - -def test_api_contacts_create_anonymous_forbidden(): - """Anonymous users should not be able to create contacts via the API.""" - response = APIClient().post( - "/api/v1.0/contacts/", - { - "full_name": "David", - "short_name": "Bowman", - }, - ) - assert response.status_code == 401 - assert not models.Contact.objects.exists() - - -def test_api_contacts_create_authenticated_missing_base(): - """Authenticated user should be able to create contact without override.""" - user = factories.UserFactory() - - client = APIClient() - client.force_login(user) - - response = client.post( - "/api/v1.0/contacts/", - { - "full_name": "David Bowman", - "short_name": "Dave", - "data": {}, - }, - format="json", - ) - assert response.status_code == 201 - - new_contact = models.Contact.objects.get(owner=user) - - assert response.json() == { - "override": None, - "data": {}, - "full_name": "David Bowman", - "id": str(new_contact.pk), - "notes": "", - "owner": str(user.pk), - "short_name": "Dave", - } - - -def test_api_contacts_create_authenticated_successful(): - """Authenticated users should be able to create contacts.""" - user = factories.UserFactory() - base_contact = factories.BaseContactFactory() - - client = APIClient() - client.force_login(user) - - # Existing override for another user should not interfere - factories.ContactFactory(override=base_contact) - - response = client.post( - "/api/v1.0/contacts/", - { - "override": str(base_contact.id), - "full_name": "David Bowman", - "short_name": "Dave", - "data": CONTACT_DATA, - }, - format="json", - ) - - assert response.status_code == 201 - assert models.Contact.objects.count() == 3 - - contact = models.Contact.objects.get(owner=user) - assert response.json() == { - "id": str(contact.id), - "override": str(base_contact.id), - "data": CONTACT_DATA, - "full_name": "David Bowman", - "notes": "", - "owner": str(user.id), - "short_name": "Dave", - } - - assert contact.full_name == "David Bowman" - assert contact.short_name == "Dave" - assert contact.data == CONTACT_DATA - assert contact.override == base_contact - assert contact.owner == user - - -@override_settings(ALLOW_API_USER_CREATE=True) -def test_api_contacts_create_authenticated_existing_override(): - """ - Trying to create a contact overriding a contact that is already overridden by the user - should receive a 400 error. - """ - user = factories.UserFactory() - base_contact = factories.BaseContactFactory() - factories.ContactFactory(override=base_contact, owner=user) - - client = APIClient() - client.force_login(user) - - response = client.post( - "/api/v1.0/contacts/", - { - "override": str(base_contact.id), - "full_name": "David Bowman", - "notes": "", - "short_name": "Dave", - "data": CONTACT_DATA, - }, - format="json", - ) - - assert response.status_code == 400 - assert models.Contact.objects.count() == 2 - - assert response.json() == { - "__all__": ["Contact with this Owner and Override already exists."] - } - - -def test_api_contacts_create_authenticated_successful_with_notes(): - """Authenticated users should be able to create contacts with notes.""" - user = factories.UserFactory() - - client = APIClient() - client.force_login(user) - - response = client.post( - "/api/v1.0/contacts/", - { - "full_name": "David Bowman", - "short_name": "Dave", - "data": CONTACT_DATA, - "notes": "This is a note", - }, - format="json", - ) - - assert response.status_code == 201 - assert models.Contact.objects.count() == 1 - - contact = models.Contact.objects.get(owner=user) - assert response.json() == { - "id": str(contact.id), - "override": None, - "data": CONTACT_DATA, - "full_name": "David Bowman", - "notes": "This is a note", - "owner": str(user.id), - "short_name": "Dave", - } - - assert contact.full_name == "David Bowman" - assert contact.short_name == "Dave" - assert contact.data == CONTACT_DATA - assert contact.owner == user - assert contact.notes == "This is a note" - - -def test_api_contacts_update_anonymous(): - """Anonymous users should not be allowed to update a contact.""" - contact = factories.ContactFactory() - old_contact_values = serializers.ContactSerializer(instance=contact).data - - new_contact_values = serializers.ContactSerializer( - instance=factories.ContactFactory() - ).data - new_contact_values["override"] = str(factories.ContactFactory().id) - response = APIClient().put( - f"/api/v1.0/contacts/{contact.id!s}/", - new_contact_values, - format="json", - ) - assert response.status_code == 401 - assert response.json() == { - "detail": "Authentication credentials were not provided." - } - - contact.refresh_from_db() - contact_values = serializers.ContactSerializer(instance=contact).data - assert contact_values == old_contact_values - - -def test_api_contacts_update_authenticated_owned(): - """ - Authenticated users should be allowed to update their own contacts. - """ - user = factories.UserFactory() - - client = APIClient() - client.force_login(user) - - contact = factories.ContactFactory(owner=user) # Owned by the logged-in user - old_contact_values = serializers.ContactSerializer(instance=contact).data - - new_contact_values = serializers.ContactSerializer( - instance=factories.ContactFactory() - ).data - new_contact_values["override"] = str(factories.ContactFactory().id) - - response = client.put( - f"/api/v1.0/contacts/{contact.id!s}/", - new_contact_values, - format="json", - ) - - assert response.status_code == 200 - - contact.refresh_from_db() - contact_values = serializers.ContactSerializer(instance=contact).data - for key, value in contact_values.items(): - if key in ["override", "owner", "id"]: - assert value == old_contact_values[key] - else: - assert value == new_contact_values[key] - - -def test_api_contacts_update_authenticated_profile(): - """ - Authenticated users should be allowed to update their profile contact. - """ - user = factories.UserFactory() - - client = APIClient() - client.force_login(user) - - contact = factories.ContactFactory(owner=user, user=user) - - old_contact_values = serializers.ContactSerializer(instance=contact).data - new_contact_values = serializers.ContactSerializer( - instance=factories.ContactFactory() - ).data - new_contact_values["override"] = str(factories.ContactFactory().id) - - response = client.put( - f"/api/v1.0/contacts/{contact.id!s}/", - new_contact_values, - format="json", - ) - - assert response.status_code == 200 - contact.refresh_from_db() - contact_values = serializers.ContactSerializer(instance=contact).data - for key, value in contact_values.items(): - if key in ["override", "owner", "id"]: - assert value == old_contact_values[key] - else: - assert value == new_contact_values[key] - - -def test_api_contacts_update_authenticated_other(): - """ - Authenticated users should not be allowed to update contacts owned by other users. - """ - user = factories.UserFactory() - - client = APIClient() - client.force_login(user) - - contact = factories.ContactFactory() # owned by another user - old_contact_values = serializers.ContactSerializer(instance=contact).data - - new_contact_values = serializers.ContactSerializer( - instance=factories.ContactFactory() - ).data - new_contact_values["override"] = str(factories.ContactFactory().id) - - response = client.put( - f"/api/v1.0/contacts/{contact.id!s}/", - new_contact_values, - format="json", - ) - - assert response.status_code == 403 - - contact.refresh_from_db() - contact_values = serializers.ContactSerializer(instance=contact).data - assert contact_values == old_contact_values - - -def test_api_contacts_delete_list_anonymous(): - """Anonymous users should not be allowed to delete a list of contacts.""" - factories.ContactFactory.create_batch(2) - - response = APIClient().delete("/api/v1.0/contacts/") - - assert response.status_code == 401 - assert models.Contact.objects.count() == 2 - - -def test_api_contacts_delete_list_authenticated(): - """Authenticated users should not be allowed to delete a list of contacts.""" - user = factories.UserFactory() - - client = APIClient() - client.force_login(user) - - factories.ContactFactory.create_batch(2) - - response = client.delete("/api/v1.0/contacts/") - - assert response.status_code == 405 - assert models.Contact.objects.count() == 2 - - -def test_api_contacts_delete_anonymous(): - """Anonymous users should not be allowed to delete a contact.""" - contact = factories.ContactFactory() - - client = APIClient() - response = client.delete(f"/api/v1.0/contacts/{contact.id!s}/") - - assert response.status_code == 401 - assert models.Contact.objects.count() == 1 - - -def test_api_contacts_delete_authenticated_public(): - """ - Authenticated users should not be allowed to delete a public contact. - """ - user = factories.UserFactory() - - client = APIClient() - client.force_login(user) - - contact = factories.BaseContactFactory() - - response = client.delete( - f"/api/v1.0/contacts/{contact.id!s}/", - ) - - assert response.status_code == 403 - assert models.Contact.objects.count() == 1 - - -def test_api_contacts_delete_authenticated_owner(): - """ - Authenticated users should be allowed to delete a contact they own. - """ - user = factories.UserFactory() - contact = factories.ContactFactory(owner=user) - - client = APIClient() - client.force_login(user) - - response = client.delete( - f"/api/v1.0/contacts/{contact.id!s}/", - ) - - assert response.status_code == 204 - assert models.Contact.objects.count() == 0 - assert models.Contact.objects.filter(id=contact.id).exists() is False - - -def test_api_contacts_delete_authenticated_profile(): - """ - Authenticated users should be allowed to delete their profile contact. - """ - user = factories.UserFactory() - contact = factories.ContactFactory(owner=user, user=user) - - client = APIClient() - client.force_login(user) - - response = client.delete( - f"/api/v1.0/contacts/{contact.id!s}/", - ) - - assert response.status_code == 204 - assert models.Contact.objects.exists() is False - - -def test_api_contacts_delete_authenticated_other(): - """ - Authenticated users should not be allowed to delete a contact they don't own. - """ - user = factories.UserFactory() - contact = factories.ContactFactory() - - client = APIClient() - client.force_login(user) - - response = client.delete( - f"/api/v1.0/contacts/{contact.id!s}/", - ) - - assert response.status_code == 403 - assert models.Contact.objects.count() == 1 - diff --git a/src/backend/core/tests/contacts/test_core_api_contacts_retrieve.py b/src/backend/core/tests/contacts/test_core_api_contacts_retrieve.py index 1168a38..8ee5703 100644 --- a/src/backend/core/tests/contacts/test_core_api_contacts_retrieve.py +++ b/src/backend/core/tests/contacts/test_core_api_contacts_retrieve.py @@ -13,232 +13,6 @@ from core.api.client import serializers pytestmark = pytest.mark.django_db -CONTACT_DATA = { - "emails": [ - {"type": "Work", "value": "john.doe@work.com"}, - {"type": "Home", "value": "john.doe@home.com"}, - ], - "phones": [ - {"type": "Work", "value": "(123) 456-7890"}, - {"type": "Other", "value": "(987) 654-3210"}, - ], - "addresses": [ - { - "type": "Home", - "street": "123 Main St", - "city": "Cityville", - "state": "CA", - "zip": "12345", - "country": "USA", - } - ], - "links": [ - {"type": "Blog", "value": "http://personalwebsite.com"}, - {"type": "Website", "value": "http://workwebsite.com"}, - ], - "customFields": {"custom_field_1": "value1", "custom_field_2": "value2"}, - "organizations": [ - { - "name": "ACME Corporation", - "department": "IT", - "jobTitle": "Software Engineer", - }, - { - "name": "XYZ Ltd", - "department": "Marketing", - "jobTitle": "Marketing Specialist", - }, - ], -} - - -def test_api_contacts_list_anonymous(): - """Anonymous users should not be allowed to list contacts.""" - factories.ContactFactory.create_batch(2) - - response = APIClient().get("/api/v1.0/contacts/") - - assert response.status_code == 401 - assert response.json() == { - "detail": "Authentication credentials were not provided." - } - - -def test_api_contacts_list_authenticated_no_query(): - """ - Authenticated users should be able to list contacts without applying a query. - Profile and overridden contacts should be excluded. - """ - user = factories.UserFactory() - factories.ContactFactory(owner=user, user=user) - - # Let's have 5 contacts in database: - assert user.profile_contact is not None # Excluded because profile contact - base_contact = factories.BaseContactFactory() # Excluded because overridden - factories.ContactFactory( - override=base_contact - ) # Excluded because belongs to other user - contact2 = factories.ContactFactory( - override=base_contact, owner=user, full_name="Bernard" - ) # Included - - client = APIClient() - client.force_login(user) - - response = client.get("/api/v1.0/contacts/") - - assert response.status_code == 200 - assert response.json() == [ - { - "id": str(contact2.id), - "override": str(base_contact.id), - "owner": str(contact2.owner.id), - "data": contact2.data, - "full_name": contact2.full_name, - "notes": "", - "short_name": contact2.short_name, - }, - ] - - -def test_api_contacts_list_authenticated_by_full_name(): - """ - Authenticated users should be able to search users with a case insensitive and - partial query on the full name. - """ - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="David Bowman") - nicole = factories.BaseContactFactory(full_name="Nicole Foole") - frank = factories.BaseContactFactory(full_name="Frank Poole") - factories.BaseContactFactory(full_name="Heywood Floyd") - - # Full query should work - client = APIClient() - client.force_login(user) - - response = client.get("/api/v1.0/contacts/?q=David%20Bowman") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Partial query should work - response = client.get("/api/v1.0/contacts/?q=ank") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(frank.id)] - - response = client.get("/api/v1.0/contacts/?q=ole") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(frank.id), str(nicole.id)] - - response = client.get("/api/v1.0/contacts/?q=ool") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(frank.id), str(nicole.id)] - - -def test_api_contacts_list_authenticated_uppercase_content(): - """Upper case content should be found by lower case query.""" - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="EEE", short_name="AAA") - - # Unaccented full name - client = APIClient() - client.force_login(user) - - response = client.get("/api/v1.0/contacts/?q=eee") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Unaccented short name - response = client.get("/api/v1.0/contacts/?q=aaa") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - -def test_api_contacts_list_authenticated_capital_query(): - """Upper case query should find lower case content.""" - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="eee", short_name="aaa") - - client = APIClient() - client.force_login(user) - - # Unaccented full name - response = client.get("/api/v1.0/contacts/?q=EEE") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Unaccented short name - response = client.get("/api/v1.0/contacts/?q=AAA") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - -def test_api_contacts_list_authenticated_accented_content(): - """Accented content should be found by unaccented query.""" - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="ééé", short_name="ààà") - - client = APIClient() - client.force_login(user) - - # Unaccented full name - response = client.get("/api/v1.0/contacts/?q=eee") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Unaccented short name - response = client.get("/api/v1.0/contacts/?q=aaa") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - -def test_api_contacts_list_authenticated_accented_query(): - """Accented query should find unaccented content.""" - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="eee", short_name="aaa") - - client = APIClient() - client.force_login(user) - - # Unaccented full name - response = client.get("/api/v1.0/contacts/?q=ééé") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Unaccented short name - response = client.get("/api/v1.0/contacts/?q=ààà") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - def test_api_contacts_retrieve_anonymous(): """Anonymous users should not be allowed to retrieve a user.""" client = APIClient() diff --git a/src/backend/core/tests/contacts/test_core_api_contacts_update.py b/src/backend/core/tests/contacts/test_core_api_contacts_update.py index 1168a38..f23b398 100644 --- a/src/backend/core/tests/contacts/test_core_api_contacts_update.py +++ b/src/backend/core/tests/contacts/test_core_api_contacts_update.py @@ -2,8 +2,6 @@ Test contacts API endpoints in People's core app. """ -from django.test.utils import override_settings - import pytest from rest_framework.test import APIClient @@ -13,467 +11,6 @@ from core.api.client import serializers pytestmark = pytest.mark.django_db -CONTACT_DATA = { - "emails": [ - {"type": "Work", "value": "john.doe@work.com"}, - {"type": "Home", "value": "john.doe@home.com"}, - ], - "phones": [ - {"type": "Work", "value": "(123) 456-7890"}, - {"type": "Other", "value": "(987) 654-3210"}, - ], - "addresses": [ - { - "type": "Home", - "street": "123 Main St", - "city": "Cityville", - "state": "CA", - "zip": "12345", - "country": "USA", - } - ], - "links": [ - {"type": "Blog", "value": "http://personalwebsite.com"}, - {"type": "Website", "value": "http://workwebsite.com"}, - ], - "customFields": {"custom_field_1": "value1", "custom_field_2": "value2"}, - "organizations": [ - { - "name": "ACME Corporation", - "department": "IT", - "jobTitle": "Software Engineer", - }, - { - "name": "XYZ Ltd", - "department": "Marketing", - "jobTitle": "Marketing Specialist", - }, - ], -} - - -def test_api_contacts_list_anonymous(): - """Anonymous users should not be allowed to list contacts.""" - factories.ContactFactory.create_batch(2) - - response = APIClient().get("/api/v1.0/contacts/") - - assert response.status_code == 401 - assert response.json() == { - "detail": "Authentication credentials were not provided." - } - - -def test_api_contacts_list_authenticated_no_query(): - """ - Authenticated users should be able to list contacts without applying a query. - Profile and overridden contacts should be excluded. - """ - user = factories.UserFactory() - factories.ContactFactory(owner=user, user=user) - - # Let's have 5 contacts in database: - assert user.profile_contact is not None # Excluded because profile contact - base_contact = factories.BaseContactFactory() # Excluded because overridden - factories.ContactFactory( - override=base_contact - ) # Excluded because belongs to other user - contact2 = factories.ContactFactory( - override=base_contact, owner=user, full_name="Bernard" - ) # Included - - client = APIClient() - client.force_login(user) - - response = client.get("/api/v1.0/contacts/") - - assert response.status_code == 200 - assert response.json() == [ - { - "id": str(contact2.id), - "override": str(base_contact.id), - "owner": str(contact2.owner.id), - "data": contact2.data, - "full_name": contact2.full_name, - "notes": "", - "short_name": contact2.short_name, - }, - ] - - -def test_api_contacts_list_authenticated_by_full_name(): - """ - Authenticated users should be able to search users with a case insensitive and - partial query on the full name. - """ - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="David Bowman") - nicole = factories.BaseContactFactory(full_name="Nicole Foole") - frank = factories.BaseContactFactory(full_name="Frank Poole") - factories.BaseContactFactory(full_name="Heywood Floyd") - - # Full query should work - client = APIClient() - client.force_login(user) - - response = client.get("/api/v1.0/contacts/?q=David%20Bowman") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Partial query should work - response = client.get("/api/v1.0/contacts/?q=ank") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(frank.id)] - - response = client.get("/api/v1.0/contacts/?q=ole") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(frank.id), str(nicole.id)] - - response = client.get("/api/v1.0/contacts/?q=ool") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(frank.id), str(nicole.id)] - - -def test_api_contacts_list_authenticated_uppercase_content(): - """Upper case content should be found by lower case query.""" - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="EEE", short_name="AAA") - - # Unaccented full name - client = APIClient() - client.force_login(user) - - response = client.get("/api/v1.0/contacts/?q=eee") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Unaccented short name - response = client.get("/api/v1.0/contacts/?q=aaa") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - -def test_api_contacts_list_authenticated_capital_query(): - """Upper case query should find lower case content.""" - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="eee", short_name="aaa") - - client = APIClient() - client.force_login(user) - - # Unaccented full name - response = client.get("/api/v1.0/contacts/?q=EEE") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Unaccented short name - response = client.get("/api/v1.0/contacts/?q=AAA") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - -def test_api_contacts_list_authenticated_accented_content(): - """Accented content should be found by unaccented query.""" - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="ééé", short_name="ààà") - - client = APIClient() - client.force_login(user) - - # Unaccented full name - response = client.get("/api/v1.0/contacts/?q=eee") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Unaccented short name - response = client.get("/api/v1.0/contacts/?q=aaa") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - -def test_api_contacts_list_authenticated_accented_query(): - """Accented query should find unaccented content.""" - user = factories.UserFactory() - - dave = factories.BaseContactFactory(full_name="eee", short_name="aaa") - - client = APIClient() - client.force_login(user) - - # Unaccented full name - response = client.get("/api/v1.0/contacts/?q=ééé") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - # Unaccented short name - response = client.get("/api/v1.0/contacts/?q=ààà") - - assert response.status_code == 200 - contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(dave.id)] - - -def test_api_contacts_retrieve_anonymous(): - """Anonymous users should not be allowed to retrieve a user.""" - client = APIClient() - contact = factories.ContactFactory() - response = client.get(f"/api/v1.0/contacts/{contact.id!s}/") - - assert response.status_code == 401 - assert response.json() == { - "detail": "Authentication credentials were not provided." - } - - -def test_api_contacts_retrieve_authenticated_owned(): - """ - Authenticated users should be allowed to retrieve a contact they own. - """ - user = factories.UserFactory() - contact = factories.ContactFactory(owner=user) - - client = APIClient() - client.force_login(user) - - response = client.get(f"/api/v1.0/contacts/{contact.id!s}/") - - assert response.status_code == 200 - assert response.json() == { - "id": str(contact.id), - "override": None, - "owner": str(contact.owner.id), - "data": contact.data, - "full_name": contact.full_name, - "notes": "", - "short_name": contact.short_name, - } - - -def test_api_contacts_retrieve_authenticated_public(): - """ - Authenticated users should be able to retrieve public contacts. - """ - user = factories.UserFactory() - contact = factories.BaseContactFactory() - - client = APIClient() - client.force_login(user) - - response = client.get(f"/api/v1.0/contacts/{contact.id!s}/") - assert response.status_code == 200 - assert response.json() == { - "id": str(contact.id), - "override": None, - "owner": None, - "data": contact.data, - "full_name": contact.full_name, - "notes": "", - "short_name": contact.short_name, - } - - -def test_api_contacts_retrieve_authenticated_other(): - """ - Authenticated users should not be allowed to retrieve another user's contacts. - """ - user = factories.UserFactory() - contact = factories.ContactFactory() - - client = APIClient() - client.force_login(user) - - response = client.get(f"/api/v1.0/contacts/{contact.id!s}/") - assert response.status_code == 403 - assert response.json() == { - "detail": "You do not have permission to perform this action." - } - - -def test_api_contacts_create_anonymous_forbidden(): - """Anonymous users should not be able to create contacts via the API.""" - response = APIClient().post( - "/api/v1.0/contacts/", - { - "full_name": "David", - "short_name": "Bowman", - }, - ) - assert response.status_code == 401 - assert not models.Contact.objects.exists() - - -def test_api_contacts_create_authenticated_missing_base(): - """Authenticated user should be able to create contact without override.""" - user = factories.UserFactory() - - client = APIClient() - client.force_login(user) - - response = client.post( - "/api/v1.0/contacts/", - { - "full_name": "David Bowman", - "short_name": "Dave", - "data": {}, - }, - format="json", - ) - assert response.status_code == 201 - - new_contact = models.Contact.objects.get(owner=user) - - assert response.json() == { - "override": None, - "data": {}, - "full_name": "David Bowman", - "id": str(new_contact.pk), - "notes": "", - "owner": str(user.pk), - "short_name": "Dave", - } - - -def test_api_contacts_create_authenticated_successful(): - """Authenticated users should be able to create contacts.""" - user = factories.UserFactory() - base_contact = factories.BaseContactFactory() - - client = APIClient() - client.force_login(user) - - # Existing override for another user should not interfere - factories.ContactFactory(override=base_contact) - - response = client.post( - "/api/v1.0/contacts/", - { - "override": str(base_contact.id), - "full_name": "David Bowman", - "short_name": "Dave", - "data": CONTACT_DATA, - }, - format="json", - ) - - assert response.status_code == 201 - assert models.Contact.objects.count() == 3 - - contact = models.Contact.objects.get(owner=user) - assert response.json() == { - "id": str(contact.id), - "override": str(base_contact.id), - "data": CONTACT_DATA, - "full_name": "David Bowman", - "notes": "", - "owner": str(user.id), - "short_name": "Dave", - } - - assert contact.full_name == "David Bowman" - assert contact.short_name == "Dave" - assert contact.data == CONTACT_DATA - assert contact.override == base_contact - assert contact.owner == user - - -@override_settings(ALLOW_API_USER_CREATE=True) -def test_api_contacts_create_authenticated_existing_override(): - """ - Trying to create a contact overriding a contact that is already overridden by the user - should receive a 400 error. - """ - user = factories.UserFactory() - base_contact = factories.BaseContactFactory() - factories.ContactFactory(override=base_contact, owner=user) - - client = APIClient() - client.force_login(user) - - response = client.post( - "/api/v1.0/contacts/", - { - "override": str(base_contact.id), - "full_name": "David Bowman", - "notes": "", - "short_name": "Dave", - "data": CONTACT_DATA, - }, - format="json", - ) - - assert response.status_code == 400 - assert models.Contact.objects.count() == 2 - - assert response.json() == { - "__all__": ["Contact with this Owner and Override already exists."] - } - - -def test_api_contacts_create_authenticated_successful_with_notes(): - """Authenticated users should be able to create contacts with notes.""" - user = factories.UserFactory() - - client = APIClient() - client.force_login(user) - - response = client.post( - "/api/v1.0/contacts/", - { - "full_name": "David Bowman", - "short_name": "Dave", - "data": CONTACT_DATA, - "notes": "This is a note", - }, - format="json", - ) - - assert response.status_code == 201 - assert models.Contact.objects.count() == 1 - - contact = models.Contact.objects.get(owner=user) - assert response.json() == { - "id": str(contact.id), - "override": None, - "data": CONTACT_DATA, - "full_name": "David Bowman", - "notes": "This is a note", - "owner": str(user.id), - "short_name": "Dave", - } - - assert contact.full_name == "David Bowman" - assert contact.short_name == "Dave" - assert contact.data == CONTACT_DATA - assert contact.owner == user - assert contact.notes == "This is a note" - - def test_api_contacts_update_anonymous(): """Anonymous users should not be allowed to update a contact.""" contact = factories.ContactFactory()