def test_notification_raises_a_retry_exception_if_mlwr_state_is_not_complete(sample_email_template, mocker):
    mocker.patch("app.aws_ses_client.send_email", return_value="reference")
    mocker.patch("app.delivery.send_to_providers.check_mlwr", return_value={"state": "foo"})
    personalisation = {"file": document_download_response()}

    db_notification = create_notification(template=sample_email_template, personalisation=personalisation)

    with pytest.raises(MalwarePendingException):
        send_to_providers.send_email_to_provider(
            db_notification,
        )
def test_notification_can_have_document_attachment_if_mlwr_sid_is_false(sample_email_template, mocker):
    send_mock = mocker.patch("app.aws_ses_client.send_email", return_value="reference")
    mlwr_mock = mocker.patch("app.delivery.send_to_providers.check_mlwr")
    personalisation = {"file": document_download_response({"mlwr_sid": "false"})}

    db_notification = create_notification(template=sample_email_template, personalisation=personalisation)

    send_to_providers.send_email_to_provider(
        db_notification,
    )

    send_mock.assert_called()
    mlwr_mock.assert_not_called()
def test_notification_can_have_document_attachment_without_mlwr_sid(sample_email_template, mocker):
    send_mock = mocker.patch("app.aws_ses_client.send_email", return_value="reference")
    mlwr_mock = mocker.patch("app.delivery.send_to_providers.check_mlwr")
    response = document_download_response()
    del response["document"]["mlwr_sid"]
    personalisation = {"file": response}

    db_notification = create_notification(template=sample_email_template, personalisation=personalisation)

    send_to_providers.send_email_to_provider(
        db_notification,
    )

    send_mock.assert_called()
    mlwr_mock.assert_not_called()
def test_notification_raises_sets_notification_to_virus_found_if_mlwr_score_above_500(sample_email_template, mocker):
    send_mock = mocker.patch("app.aws_ses_client.send_email", return_value="reference")
    mocker.patch(
        "app.delivery.send_to_providers.check_mlwr",
        return_value={"state": "completed", "submission": {"max_score": 501}},
    )
    personalisation = {"file": document_download_response()}

    db_notification = create_notification(template=sample_email_template, personalisation=personalisation)

    with pytest.raises(NotificationTechnicalFailureException) as e:
        send_to_providers.send_email_to_provider(db_notification)
        assert db_notification.id in e.value
    send_mock.assert_not_called()

    assert Notification.query.get(db_notification.id).status == "virus-scan-failed"
def test_notification_document_with_pdf_attachment(
    mocker,
    notify_db,
    notify_db_session,
    filename_attribute_present,
    filename,
    expected_filename,
):
    template = sample_email_template(notify_db, notify_db_session, content="Here is your ((file))")
    personalisation = {
        "file": document_download_response(
            {
                "direct_file_url": "http://foo.bar/direct_file_url",
                "url": "http://foo.bar/url",
                "mime_type": "application/pdf",
                "mlwr_sid": "false",
            }
        )
    }
    if filename_attribute_present:
        personalisation["file"]["document"]["filename"] = filename
        personalisation["file"]["document"]["sending_method"] = "attach"
    else:
        personalisation["file"]["document"]["sending_method"] = "link"

    db_notification = create_notification(template=template, personalisation=personalisation)

    statsd_mock = mocker.patch("app.delivery.send_to_providers.statsd_client")
    send_mock = mocker.patch("app.aws_ses_client.send_email", return_value="reference")
    request_mock = mocker.patch(
        "app.delivery.send_to_providers.urllib.request.Request",
        return_value="request_mock",
    )
    # See https://stackoverflow.com/a/34929900
    cm = MagicMock()
    cm.read.return_value = "request_content"
    cm.__enter__.return_value = cm
    urlopen_mock = mocker.patch("app.delivery.send_to_providers.urllib.request.urlopen")
    urlopen_mock.return_value = cm

    send_to_providers.send_email_to_provider(db_notification)

    attachments = []
    if filename_attribute_present:
        request_mock.assert_called_once_with("http://foo.bar/direct_file_url")
        urlopen_mock.assert_called_once_with("request_mock")
        attachments = [
            {
                "data": "request_content",
                "name": expected_filename,
                "mime_type": "application/pdf",
            }
        ]
    send_mock.assert_called_once_with(
        ANY,
        ANY,
        ANY,
        body=ANY,
        html_body=ANY,
        reply_to_address=ANY,
        attachments=attachments,
    )
    if not filename_attribute_present:
        assert "http://foo.bar/url" in send_mock.call_args[1]["html_body"]

    notification = Notification.query.get(db_notification.id)
    assert notification.status == "sending"

    if attachments:
        statsd_calls = statsd_mock.timing_with_dates.call_args_list
        statsd_key = "email.with-attachments.process_type-normal"
        assert call(statsd_key, notification.sent_at, notification.created_at) in statsd_calls
        assert call(statsd_key) in statsd_mock.incr.call_args_list