Example #1
0
    def test_done_random_checks(
        self,
        client: Client,
        settings: SettingsWrapper,
        probability: float,
        gamma: int,
        message: bool,
        tor_url: [str, None],
        trans_url: [str, None],
    ) -> None:
        """Test whether the random checks for the done process are invoked correctly."""
        # Mock both the gamma property and the random.random function.
        with patch("authentication.models.BlossomUser.gamma",
                   new_callable=PropertyMock) as mock, patch(
                       "api.views.submission._is_returning_transcriber",
                       return_value=False), patch("random.random",
                                                  lambda: probability):
            mock.return_value = gamma
            # Mock the Slack client to catch the sent messages by the function under test.
            slack_client.chat_postMessage = MagicMock()

            client, headers, user = setup_user_client(client)
            submission = create_submission(tor_url=tor_url, claimed_by=user)
            create_transcription(submission, user, url=trans_url)

            result = client.patch(
                reverse("submission-done", args=[submission.id]),
                json.dumps({"username": user.username}),
                content_type="application/json",
                **headers,
            )
            slack_message = (
                f"Please check the following transcription of u/{user.username}: "
                f"{trans_url if trans_url else tor_url}.")
            assert result.status_code == status.HTTP_201_CREATED
            if message:
                assert (call(
                    channel=settings.SLACK_TRANSCRIPTION_CHECK_CHANNEL,
                    text=slack_message,
                ) in slack_client.chat_postMessage.call_args_list)
            else:
                assert slack_client.chat_postMessage.call_count == 0
    def test_list_with_filters(self, client: Client) -> None:
        """Verify that listing all submissions works correctly."""
        client, headers, _ = setup_user_client(client)

        aaa, _ = Source.objects.get_or_create(name="AAA")
        bbb, _ = Source.objects.get_or_create(name="BBB")

        create_submission(source=aaa)
        create_submission(source=aaa)
        create_submission(source=bbb)
        create_submission(source=bbb)

        result = client.get(
            reverse("submission-list"), content_type="application/json", **headers
        )

        assert result.status_code == status.HTTP_200_OK
        assert len(result.json()["results"]) == 4

        result = client.get(
            reverse("submission-list") + "?source=AAA",
            content_type="application/json",
            **headers,
        )

        assert result.status_code == status.HTTP_200_OK
        assert len(result.json()["results"]) == 2
        assert "AAA" in result.json()["results"][0]["source"]  # it will be a full link

        result = client.get(
            reverse("submission-list") + "?source=AAA&id=1",
            content_type="application/json",
            **headers,
        )

        assert result.status_code == status.HTTP_200_OK
        assert len(result.json()["results"]) == 1
        assert "AAA" in result.json()["results"][0]["source"]  # it will be a full link
        assert result.json()["results"][0]["id"] == 1
Example #3
0
    def test_nsfw_no_change(self, client: Client) -> None:
        """Verify that setting a submission NSFW twice doesn't change anything."""
        client, headers, user = setup_user_client(client)

        submission = create_submission(id=3, nsfw=True)
        assert submission.nsfw

        data = {}

        result = client.patch(
            reverse("submission-nsfw", args=[submission.id]),
            json.dumps(data),
            content_type="application/json",
            **headers
        )

        submission.refresh_from_db()

        assert result.status_code == status.HTTP_200_OK
        assert submission.nsfw
Example #4
0
    def test_reported_post_is_removed(self, client: Client) -> None:
        """Verify that a reported post is not brought back to the page."""
        client, _, user = setup_user_client(client)
        add_social_auth_to_user(user)

        submission = create_submission(
            original_id=int(random.random() * 1000),
            title="a",
            content_url="http://imgur.com",
        )

        response = client.get(reverse("choose_transcription"))

        assert submission in response.context["options"]

        # Now we'll report it and verify that it's not rolled anymore
        client.get(
            reverse("app_report", kwargs={"submission_id": submission.id}))
        response = client.get(reverse("choose_transcription"))
        assert submission not in response.context["options"]
Example #5
0
    def test_remove_param_true(self, client: Client) -> None:
        """Verify that marking a submission as NSFW works with parameters."""
        client, headers, user = setup_user_client(client)

        submission = create_submission(id=3)
        assert not submission.nsfw

        data = {"nsfw": True}

        result = client.patch(
            reverse("submission-nsfw", args=[submission.id]),
            json.dumps(data),
            content_type="application/json",
            **headers
        )

        submission.refresh_from_db()

        assert result.status_code == status.HTTP_200_OK
        assert submission.nsfw
    def test_unarchived_old_unarchived(self, client: Client) -> None:
        """Test whether an unarchived old post is returned correctly."""
        client, headers, user = setup_user_client(client)
        reddit, _ = Source.objects.get_or_create(name="reddit")

        submission = create_submission(
            completed_by=user,
            complete_time=timezone.now() - timezone.timedelta(hours=1),
            archived=False,
            source=reddit,
        )

        result = client.get(
            reverse("submission-unarchived") + "?source=reddit",
            content_type="application/json",
            **headers,
        )
        assert result.status_code == status.HTTP_200_OK
        assert len(result.json()) == 1
        assert result.json()[0]["id"] == submission.id
Example #7
0
    def test_yeet_also_removes_linked_transcription(self,
                                                    client: Client) -> None:
        """Verify that a linked transcription also gets yeeted."""
        client, headers, user = setup_user_client(client)
        submission = create_submission(original_id=str(uuid4()),
                                       completed_by=user)
        create_transcription(submission, user)

        assert Submission.objects.count() == 1
        assert Transcription.objects.count() == 1

        data = {"username": user.username}

        client.post(reverse("submission-yeet"),
                    json.dumps(data),
                    content_type="application/json",
                    **headers)

        assert Submission.objects.count() == 0
        assert Transcription.objects.count() == 0
Example #8
0
    def test_post_formatting_errors(self, client: Client) -> None:
        """Verify that correctable formatting issues are handled."""
        client, _, user = setup_user_client(client)
        add_social_auth_to_user(user)

        submission = create_submission(
            original_id=int(random.random() * 1000),
            content_url="http://imgur.com",
            title="a",
            claimed_by=user,
        )
        client.post(
            reverse("transcribe_submission",
                    kwargs={"submission_id": submission.id}),
            data={
                "transcription":
                "u/aaa ! Check this out!\n```\nabcde\n```\n\nayy"
            },
        )
        assert "`" not in Transcription.objects.first().text
        assert "\\/" in Transcription.objects.first().text
    def test_report_already_removed(self, client: Client) -> None:
        """Verify that reporting an already removed submission doesn't do anything."""
        slack_client.chat_postMessage = MagicMock()
        client, headers, user = setup_user_client(client)

        submission = create_submission(id=3, removed_from_queue=True)
        assert submission.removed_from_queue

        data = {"reason": "Violation of ALL the rules"}

        result = client.patch(reverse("submission-report",
                                      args=[submission.id]),
                              json.dumps(data),
                              content_type="application/json",
                              **headers)

        submission.refresh_from_db()

        assert result.status_code == status.HTTP_201_CREATED
        assert submission.removed_from_queue
        assert slack_client.chat_postMessage.call_count == 0
    def test_list(self, client: Client) -> None:
        """Test that the primary API page for transcriptions works correctly."""
        client, headers, user = setup_user_client(client)
        submission = create_submission()

        result = client.get(reverse("transcription-list"),
                            content_type="application/json",
                            **headers)

        assert result.status_code == status.HTTP_200_OK
        assert result.json()["count"] == 0

        create_transcription(submission, user)

        result = client.get(reverse("transcription-list"),
                            content_type="application/json",
                            **headers)

        assert result.status_code == status.HTTP_200_OK
        assert result.json()["count"] == 1
        assert result.json()["results"][0]["id"] == 1
Example #11
0
    def test_approve_reverting_removal(self, client: Client) -> None:
        """Verify that approving a submission reverts its removal."""
        client, headers, user = setup_user_client(client)

        submission = create_submission(id=3, removed_from_queue=True)
        assert not submission.approved
        assert submission.removed_from_queue

        data = {}

        result = client.patch(reverse("submission-approve",
                                      args=[submission.id]),
                              json.dumps(data),
                              content_type="application/json",
                              **headers)

        submission.refresh_from_db()

        assert result.status_code == status.HTTP_200_OK
        assert submission.approved
        assert not submission.removed_from_queue
Example #12
0
    def test_completed_ocr_transcriptions(self, client: Client) -> None:
        """Test that a completed transcription removes the submission from the queue."""
        client, headers, _ = setup_user_client(client)
        user_model = get_user_model()
        transcribot = user_model.objects.get(username="******")
        submission = create_submission(source="reddit")

        result = client.get(
            reverse("submission-get-transcribot-queue") + "?source=reddit",
            content_type="application/json",
            **headers,
        ).json()

        assert len(result["data"]) == 0

        transcription = create_transcription(submission,
                                             transcribot,
                                             original_id=None)

        result = client.get(
            reverse("submission-get-transcribot-queue") + "?source=reddit",
            content_type="application/json",
            **headers,
        ).json()

        # now there's a transcription that needs work
        assert len(result["data"]) == 1

        # transcribot works on it
        transcription.original_id = "AAA"
        transcription.save()

        result = client.get(
            reverse("submission-get-transcribot-queue") + "?source=reddit",
            content_type="application/json",
            **headers,
        ).json()

        # Queue goes back to 0.
        assert len(result["data"]) == 0
Example #13
0
    def test_image_proxies(self, client: Client) -> None:
        """Verify that the transcription page loads as expected."""
        client, _, user = setup_user_client(client)
        add_social_auth_to_user(user)

        # Imgur direct link
        submission = create_submission(
            original_id=int(random.random() * 1000),
            content_url="http://imgur.com/aaa.png",
            title="a",
        )

        response = client.get(
            reverse("transcribe_submission",
                    kwargs={"submission_id": submission.id}))

        assert "imgur_content_url" in response.context
        assert response.context["imgur_content_url"] == "aaa.png"

        # Imgur post link
        submission.claimed_by = None
        submission.content_url = "http://imgur.com/aaa"
        submission.save()

        response = client.get(
            reverse("transcribe_submission",
                    kwargs={"submission_id": submission.id}))
        assert "imgur_content_url" in response.context
        assert response.context["imgur_content_url"] == "aaa.jpg"

        # Reddit link
        submission.claimed_by = None
        submission.content_url = "i.redd.it/bbb"
        submission.save()

        response = client.get(
            reverse("transcribe_submission",
                    kwargs={"submission_id": submission.id}))
        assert "ireddit_content_url" in response.context
        assert response.context["ireddit_content_url"] == "bbb"
Example #14
0
def test_unclaim_errors(client: Client, error: int,
                        expected_redirect: str) -> None:
    """Verify that errors redirect as they should."""
    client, _, user = setup_user_client(client)
    add_social_auth_to_user(user)

    submission = create_submission(claimed_by=user)

    class Response:
        ...

    response = Response()
    response.status_code = error

    with patch("api.views.submission.SubmissionViewSet.unclaim",
               lambda a, b, c: response):
        response = client.get(
            reverse("app_unclaim", kwargs={"submission_id": submission.id}))
        assert reverse(expected_redirect) in response.url

    # the unclaim should not have succeeded
    assert submission.claimed_by == user
 def test_pagination(self, client: Client) -> None:
     """Verify that pagination parameters properly change response."""
     client, headers, user = setup_user_client(client, id=123456)
     for day in range(1, 4):
         date = make_aware(datetime(2021, 6, day))
         create_transcription(
             create_submission(completed_by=user, complete_time=date),
             user,
             create_time=date,
         )
     result = client.get(
         reverse("submission-rate") +
         "?page_size=1&page=2&completed_by=123456",
         content_type="application/json",
         **headers,
     )
     assert result.status_code == status.HTTP_200_OK
     response = result.json()
     assert len(response["results"]) == 1
     assert response["results"][0]["date"] == "2021-06-02T00:00:00Z"
     assert response["previous"] is not None
     assert response["next"] is not None
Example #16
0
    def test_done_no_coc(self, client: Client) -> None:
        """# noqa
        Test that a submission isn't marked as done when the CoC hasn't been accepted.
        """
        client, headers, user = setup_user_client(client)
        submission = create_submission(claimed_by=user)
        user.accepted_coc = False
        user.save()

        create_transcription(submission, user)
        data = {"username": user.username}

        result = client.patch(
            reverse("submission-done", args=[submission.id]),
            json.dumps(data),
            content_type="application/json",
            **headers,
        )

        submission.refresh_from_db()
        assert result.status_code == status.HTTP_403_FORBIDDEN
        assert submission.claimed_by == user
        assert submission.completed_by is None
Example #17
0
    def test_post_session(self, client: Client) -> None:
        """Verify that the session gets set appropriately if errors arise."""
        client, _, user = setup_user_client(client)
        add_social_auth_to_user(user)

        submission = create_submission(
            original_id=int(random.random() * 1000),
            content_url="http://imgur.com",
            title="a",
            claimed_by=user,
        )

        response = client.post(
            reverse("transcribe_submission",
                    kwargs={"submission_id": submission.id}),
            data={"transcription": "#aaa"},
        )
        assert (reverse("transcribe_submission",
                        kwargs={"submission_id": submission.id})
                in response.url)
        assert response.wsgi_request.session["transcription"] == "#aaa"
        assert response.wsgi_request.session["submission_id"] == submission.id
        assert response.wsgi_request.session["heading"] is None
Example #18
0
    def test_post(self, client: Client) -> None:
        """Verify that posting a valid transcription completes the process."""
        client, _, user = setup_user_client(client)
        add_social_auth_to_user(user)

        submission = create_submission(
            original_id=int(random.random() * 1000),
            content_url="http://imgur.com/aaa",
            title="a",
            claimed_by=user,
        )
        assert submission.completed_by is None

        response = client.post(
            reverse("transcribe_submission",
                    kwargs={"submission_id": submission.id}),
            data={"transcription": "AAA"},
        )

        submission.refresh_from_db()
        assert reverse("choose_transcription") in response.url
        assert submission.completed_by == user
        assert Transcription.objects.count() == 1
Example #19
0
    def test_get_errors(self, client: Client, error: int,
                        expected_redirect: str) -> None:
        """Verify that errors from the API translate correctly to responses."""
        client, _, user = setup_user_client(client)
        add_social_auth_to_user(user)

        submission = create_submission(
            original_id=int(random.random() * 1000),
            content_url="http://imgur.com",
            title="a",
        )

        class Response:
            ...

        response = Response()
        response.status_code = error

        with patch("api.views.submission.SubmissionViewSet.claim",
                   lambda a, b, c: response):
            response = client.get(
                reverse("transcribe_submission",
                        kwargs={"submission_id": submission.id}))
            assert reverse(expected_redirect) in response.url
Example #20
0
    def test_normal_transcriptions_dont_affect_ocr_queue(
            self, client: Client) -> None:
        """Verify that a human-completed transcription doesn't affect the OCR queue."""
        client, headers, user = setup_user_client(client)
        submission = create_submission(source="reddit")

        result = client.get(
            reverse("submission-get-transcribot-queue") + "?source=reddit",
            content_type="application/json",
            **headers,
        ).json()

        assert len(result["data"]) == 0

        create_transcription(submission, user)

        result = client.get(
            reverse("submission-get-transcribot-queue") + "?source=reddit",
            content_type="application/json",
            **headers,
        ).json()

        # there should be no change to the OCR queue
        assert len(result["data"]) == 0
    def test_list_with_contains_filters(
        self, client: Client, filter_str: str, result_count: int
    ) -> None:
        """Verify that the title can be searched."""
        client, headers, user = setup_user_client(client, id=123)

        create_submission(
            id=1, title="This is a title",
        )
        create_submission(
            id=2, title="Another title",
        )
        create_submission(
            id=3, title="TITLE IS GOOD",
        )

        result = client.get(
            reverse("submission-list") + f"?{filter_str}",
            content_type="application/json",
            **headers,
        )
        assert result.status_code == status.HTTP_200_OK
        assert len(result.json()["results"]) == result_count
Example #22
0
    def test_send_transcription_to_slack(self, client: Client,
                                         settings: SettingsWrapper) -> None:
        """Verify that a new user gets a different welcome message."""
        # Mock both the gamma property and the random.random function.
        with patch("authentication.models.BlossomUser.gamma",
                   new_callable=PropertyMock) as mock:
            mock.return_value = 0
            # Mock the Slack client to catch the sent messages by the function under test.
            slack_client.chat_postMessage = MagicMock()

            client, headers, user = setup_user_client(client)
            submission = create_submission(tor_url="asdf", claimed_by=user)
            create_transcription(submission, user, url=None)

            result = client.patch(
                reverse("submission-done", args=[submission.id]),
                json.dumps({"username": user.username}),
                content_type="application/json",
                **headers,
            )

            first_slack_message = (
                f":rotating_light: First transcription! :rotating_light:"
                f" Please check the following transcription of u/{user.username}:"
                f" asdf.")
            second_slack_message = (
                f"Please check the following transcription of u/{user.username}:"
                f" asdf.")
            check_slack_message = (
                f"Please check the following transcription of u/{user.username}:"
                f" asdf.\n\nThis user is being watched with a chance of 100%.\n"
                f"Undo this using the `unwatch {user.username}` command.")

            assert result.status_code == status.HTTP_201_CREATED
            assert (call(
                channel=settings.SLACK_TRANSCRIPTION_CHECK_CHANNEL,
                text=first_slack_message,
            ) == slack_client.chat_postMessage.call_args_list[0])
            submission.refresh_from_db()
            submission.completed_by = None
            submission.save()

            mock.return_value = 1

            result = client.patch(
                reverse("submission-done", args=[submission.id]),
                json.dumps({"username": user.username}),
                content_type="application/json",
                **headers,
            )
            assert result.status_code == status.HTTP_201_CREATED
            assert (call(
                channel=settings.SLACK_TRANSCRIPTION_CHECK_CHANNEL,
                text=second_slack_message,
            ) == slack_client.chat_postMessage.call_args_list[-1])
            submission.refresh_from_db()
            submission.completed_by = None
            submission.save()

            user.overwrite_check_percentage = 1
            user.save()
            result = client.patch(
                reverse("submission-done", args=[submission.id]),
                json.dumps({"username": user.username}),
                content_type="application/json",
                **headers,
            )
            assert result.status_code == status.HTTP_201_CREATED
            assert (call(
                channel=settings.SLACK_TRANSCRIPTION_CHECK_CHANNEL,
                text=check_slack_message,
            ) == slack_client.chat_postMessage.call_args_list[-1])