예제 #1
0
    def test_list_topics_performance(self):
        """
        Make sure even with large numbers of topics and children, we do not make an onslaught
        of requests, and the whole API request does not take too much time to execute.
        """
        user = factories.UserFactory()
        unit = factories.UnitFactory()
        # Use the 'build' method as we have more operations to perform before actually
        # saving our topics.
        root_topics = factories.TopicFactory.build_batch(100, unit=unit)
        child_topics = factories.TopicFactory.build_batch(300, unit=unit)
        # Link 3 child topics to each of our root topics
        i = 0
        for child_topic in child_topics:
            child_topic.parent = root_topics[floor(i / 3)]
            i = i + 1
        # Use a bulk operation to speed up the test
        Topic.objects.bulk_create(root_topics + child_topics)

        with self.assertNumQueries(8):
            pre_response = perf_counter()
            response = self.client.get(
                "/api/topics/?limit=999",
                HTTP_AUTHORIZATION=
                f"Token {Token.objects.get_or_create(user=user)[0]}",
            )
            post_response = perf_counter()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json()["count"], 400)
        self.assertLess(post_response - pre_response, 0.4)
예제 #2
0
    def test_list_topics_by_unit(self):
        """
        Logged-in users can list topics for a given unit.
        """
        user = factories.UserFactory()
        factories.TopicFactory.create_batch(2)

        unit = factories.UnitFactory()
        expected_topics = [
            factories.TopicFactory(name="First topic", unit=unit),
            factories.TopicFactory(name="Second topic", unit=unit),
        ]

        response = self.client.get(
            f"/api/topics/?limit=999&unit={unit.id}",
            HTTP_AUTHORIZATION=
            f"Token {Token.objects.get_or_create(user=user)[0]}",
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json()["count"], 2)
        self.assertEqual(response.json()["results"][0]["id"],
                         str(expected_topics[0].id))
        self.assertEqual(response.json()["results"][1]["id"],
                         str(expected_topics[1].id))
예제 #3
0
    def test_list_units_from_anonymous_user(self):
        """
        Anonymous users cannot list existing units.
        """
        factories.UnitFactory()

        response = self.client.get("/api/units/")

        self.assertEqual(response.status_code, 401)
예제 #4
0
    def test_retrieve_unit_from_anonymous_user(self):
        """
        Anonymous users cannot retrieve an existing unit.
        """
        unit = factories.UnitFactory()

        response = self.client.get(f"/api/units/{unit.id}/")

        self.assertEqual(response.status_code, 401)
예제 #5
0
    def test_retrieve_unit_from_random_logged_in_user(self):
        """
        Random logged-in users cannot retrieve an existing unit.
        """
        user = factories.UserFactory()
        unit = factories.UnitFactory()

        response = self.client.get(
            f"/api/units/{unit.id}/",
            HTTP_AUTHORIZATION=f"Token {Token.objects.get_or_create(user=user)[0]}",
        )

        self.assertEqual(response.status_code, 403)
예제 #6
0
    def test_list_units_with_autocomplete_query(self):
        """
        Lists of units can be filtered down, autocomplete-style, with a query parameter.
        """
        user = factories.UserFactory()
        unit_1 = factories.UnitFactory(name="First unit")
        factories.UnitFactory(name="Second unit")
        unit_3 = factories.UnitFactory(name="Fifth unit")

        response = self.client.get(
            "/api/units/?query=fi",
            HTTP_AUTHORIZATION=f"Token {Token.objects.get_or_create(user=user)[0]}",
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(
            response.json(),
            {
                "count": 2,
                "next": None,
                "previous": None,
                "results": [
                    {
                        "id": str(unit_3.id),
                        "members": [],
                        "created_at": unit_3.created_at.isoformat()[:-6]
                        + "Z",  # NB: DRF literally does this
                        "name": "Fifth unit",
                    },
                    {
                        "id": str(unit_1.id),
                        "members": [],
                        "created_at": unit_1.created_at.isoformat()[:-6]
                        + "Z",  # NB: DRF literally does this
                        "name": "First unit",
                    },
                ],
            },
        )
예제 #7
0
    def test_list_units_from_random_logged_in_user(self):
        """
        Any logged-in user can query the list of units and get a complete list.
        """
        user = factories.UserFactory()
        unit_1 = factories.UnitFactory(name="First unit")
        unit_2 = factories.UnitFactory(name="Second unit")

        response = self.client.get(
            "/api/units/",
            HTTP_AUTHORIZATION=f"Token {Token.objects.get_or_create(user=user)[0]}",
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(
            response.json(),
            {
                "count": 2,
                "next": None,
                "previous": None,
                "results": [
                    {
                        "id": str(unit_1.id),
                        "members": [],
                        "created_at": unit_1.created_at.isoformat()[:-6]
                        + "Z",  # NB: DRF literally does this
                        "name": "First unit",
                    },
                    {
                        "id": str(unit_2.id),
                        "members": [],
                        "created_at": unit_2.created_at.isoformat()[:-6]
                        + "Z",  # NB: DRF literally does this
                        "name": "Second unit",
                    },
                ],
            },
        )
예제 #8
0
    def test_retrieve_unit_from_unit_member(self):
        """
        Members of a given unit can retrieve it.
        """
        user = factories.UserFactory()
        unit = factories.UnitFactory()
        unit.members.add(user)

        response = self.client.get(
            f"/api/units/{unit.id}/",
            HTTP_AUTHORIZATION=f"Token {Token.objects.get_or_create(user=user)[0]}",
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json()["id"], str(unit.id))
예제 #9
0
    def test_create_topic(self):
        """
        The topic API does not support topic creation.
        """
        user = factories.UserFactory(is_staff=True)
        unit = factories.UnitFactory()

        response = self.client.post(
            "/api/topics/",
            {"name": "Example topic", "unit": unit.id},
            HTTP_AUTHORIZATION=f"Token {Token.objects.get_or_create(user=user)[0]}",
        )

        self.assertEqual(response.status_code, 403)
        self.assertEqual(Topic.objects.count(), 0)
예제 #10
0
    def test_create_referralmessage_by_referral_linked_user(self, mock_mailer_send):
        """
        A referral's linked user can create messages for their referral.
        """
        # Create a unit with an owner, and admin and a member
        unit1 = factories.UnitFactory()
        unit1_owner_membership = factories.UnitMembershipFactory(
            unit=unit1, role=models.UnitMembershipRole.OWNER
        )
        factories.UnitMembershipFactory(
            unit=unit1, role=models.UnitMembershipRole.ADMIN
        )
        factories.UnitMembershipFactory(
            unit=unit1, role=models.UnitMembershipRole.MEMBER
        )
        # Create another unit with two owners and a member
        unit2 = factories.UnitFactory()
        unit2_owner1_membership = factories.UnitMembershipFactory(
            unit=unit2, role=models.UnitMembershipRole.OWNER
        )
        unit2_owner2_membership = factories.UnitMembershipFactory(
            unit=unit2, role=models.UnitMembershipRole.OWNER
        )
        factories.UnitMembershipFactory(
            unit=unit2, role=models.UnitMembershipRole.MEMBER
        )

        referral = factories.ReferralFactory()
        referral.units.set([unit1, unit2])

        file1 = BytesIO(b"firstfile")
        file1.name = "the first file name"
        file2 = BytesIO(b"secondfile")
        file2.name = "the second file name"
        form_data = {
            "content": "some message",
            "files": (file1, file2),
            "referral": str(referral.id),
        }

        self.assertEqual(models.ReferralMessage.objects.count(), 0)
        self.assertEqual(models.ReferralMessageAttachment.objects.count(), 0)
        token = Token.objects.get_or_create(user=referral.users.first())[0]
        response = self.client.post(
            "/api/referralmessages/",
            form_data,
            HTTP_AUTHORIZATION=f"Token {token}",
        )
        self.assertEqual(response.status_code, 201)
        # The referral message instance was created with our values
        self.assertEqual(models.ReferralMessage.objects.count(), 1)
        self.assertEqual(response.json()["content"], "some message")
        self.assertEqual(response.json()["user"]["id"], str(referral.users.first().id))
        self.assertEqual(response.json()["referral"], referral.id)
        # The related attachment instances were created along with the message
        self.assertEqual(models.ReferralMessageAttachment.objects.count(), 2)
        self.assertEqual(
            response.json()["attachments"][0]["name"], "the first file name"
        )
        self.assertEqual(
            response.json()["attachments"][1]["name"], "the second file name"
        )

        # The relevant email should be sent to all owners of units linked to the referral
        # but not to the referral user (they sent the message) or regular members
        self.assertEqual(mock_mailer_send.call_count, 3)
        for index, owner_membership in enumerate(
            [
                unit1_owner_membership,
                unit2_owner1_membership,
                unit2_owner2_membership,
            ]
        ):
            self.assertEqual(
                tuple(mock_mailer_send.call_args_list[index]),
                (
                    (
                        {
                            "params": {
                                "case_number": referral.id,
                                "link_to_referral": (
                                    f"https://partaj/app/unit/{owner_membership.unit.id}"
                                    f"/referrals-list/referral-detail/{referral.id}/messages"
                                ),
                                "message_author": referral.users.first().get_full_name(),
                                "referral_author": referral.users.first().get_full_name(),
                                "title": referral.object,
                                "topic": referral.topic.name,
                            },
                            "replyTo": {
                                "email": "*****@*****.**",
                                "name": "Partaj",
                            },
                            "templateId": settings.SENDINBLUE[
                                "REFERRAL_NEW_MESSAGE_FOR_UNIT_MEMBER_TEMPLATE_ID"
                            ],
                            "to": [{"email": owner_membership.user.email}],
                        },
                    ),
                    {},
                ),
            )