generated from westfarn/web_django_template
Initial commit
This commit is contained in:
@@ -0,0 +1,281 @@
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.test import Client, TestCase, override_settings
|
||||
from django.urls import reverse
|
||||
from unittest.mock import patch
|
||||
|
||||
from contacts.models import Channel, ConsentRecord, Contact, Suppression
|
||||
from directmail.models import Campaign, Message, MessageTemplate, ProviderEvent
|
||||
from contacts.consent import channel_preferences
|
||||
from directmail.services import (
|
||||
contact_may_receive,
|
||||
create_campaign_draft,
|
||||
opted_in_contacts,
|
||||
set_channel_consent,
|
||||
)
|
||||
|
||||
|
||||
class PcmPostcardWebhookTests(TestCase):
|
||||
def setUp(self):
|
||||
self.client = Client()
|
||||
self.contact = Contact.objects.create(
|
||||
email="mail@example.com",
|
||||
first_name="Pat",
|
||||
last_name="Lee",
|
||||
postal_address=Contact.make_postal_address(
|
||||
line1="123 Main St",
|
||||
city="Naperville",
|
||||
state="IL",
|
||||
zip_code="60540",
|
||||
),
|
||||
)
|
||||
set_channel_consent(
|
||||
self.contact, Channel.POSTCARD, opted_in=True, reason="test"
|
||||
)
|
||||
template = MessageTemplate.objects.create(
|
||||
name="PCM test design",
|
||||
channel=Channel.POSTCARD,
|
||||
body="Postcard",
|
||||
postcard_front={"design_id": 99, "size": "46", "provider": "pcm"},
|
||||
)
|
||||
self.campaign = create_campaign_draft(
|
||||
name="March mailer",
|
||||
audience=Campaign.Audience.POSTCARD_OPT_IN,
|
||||
body="Postcard mailing",
|
||||
template=template,
|
||||
)
|
||||
self.message = self.campaign.messages.get()
|
||||
self.message.status = Message.Status.SENT
|
||||
self.message.provider = "pcm"
|
||||
self.message.provider_message_id = "order-555"
|
||||
self.message.save()
|
||||
|
||||
def test_delivered_by_ext_ref(self):
|
||||
import json
|
||||
|
||||
url = reverse("directmail:postcard_webhook")
|
||||
response = self.client.post(
|
||||
url,
|
||||
data=json.dumps(
|
||||
{
|
||||
"status": "Delivered",
|
||||
"extRefNbr": str(self.message.pk),
|
||||
"orderID": 555,
|
||||
}
|
||||
),
|
||||
content_type="application/json",
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.message.refresh_from_db()
|
||||
self.assertEqual(self.message.status, Message.Status.DELIVERED)
|
||||
self.assertTrue(
|
||||
ProviderEvent.objects.filter(
|
||||
message=self.message, provider="pcm", event_type="Delivered"
|
||||
).exists()
|
||||
)
|
||||
|
||||
def test_requires_bearer_when_secret_set(self):
|
||||
import json
|
||||
|
||||
url = reverse("directmail:postcard_webhook")
|
||||
with self.settings(PCM_WEBHOOK_SECRET="pcm-secret", PCM_WEBHOOK_SECRETS=""):
|
||||
denied = self.client.post(
|
||||
url,
|
||||
data=json.dumps({"status": "Delivered", "orderID": 555}),
|
||||
content_type="application/json",
|
||||
)
|
||||
self.assertEqual(denied.status_code, 403)
|
||||
ok = self.client.post(
|
||||
url,
|
||||
data=json.dumps(
|
||||
{
|
||||
"status": "Delivered",
|
||||
"orderID": "order-555",
|
||||
}
|
||||
),
|
||||
content_type="application/json",
|
||||
HTTP_AUTHORIZATION="Bearer pcm-secret",
|
||||
)
|
||||
self.assertEqual(ok.status_code, 200)
|
||||
|
||||
def test_accepts_any_secret_from_list(self):
|
||||
import json
|
||||
|
||||
url = reverse("directmail:postcard_webhook")
|
||||
with self.settings(
|
||||
PCM_WEBHOOK_SECRET="",
|
||||
PCM_WEBHOOK_SECRETS="sec-a,sec-b",
|
||||
):
|
||||
denied = self.client.post(
|
||||
url,
|
||||
data=json.dumps({"status": "Delivered", "orderID": "order-555"}),
|
||||
content_type="application/json",
|
||||
HTTP_AUTHORIZATION="Bearer wrong",
|
||||
)
|
||||
self.assertEqual(denied.status_code, 403)
|
||||
ok = self.client.post(
|
||||
url,
|
||||
data=json.dumps({"status": "Delivered", "orderID": "order-555"}),
|
||||
content_type="application/json",
|
||||
HTTP_AUTHORIZATION="Bearer sec-b",
|
||||
)
|
||||
self.assertEqual(ok.status_code, 200)
|
||||
|
||||
|
||||
class PcmAuthTests(TestCase):
|
||||
def setUp(self):
|
||||
from directmail.providers.postcard import pcm as pcm_mod
|
||||
|
||||
pcm_mod.clear_token_cache()
|
||||
|
||||
def tearDown(self):
|
||||
from directmail.providers.postcard import pcm as pcm_mod
|
||||
|
||||
pcm_mod.clear_token_cache()
|
||||
|
||||
def test_login_required_before_design_list(self):
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from directmail.providers.postcard import pcm as pcm_mod
|
||||
|
||||
login_resp = MagicMock()
|
||||
login_resp.status_code = 200
|
||||
login_resp.content = b'{"token":"session-tok","expires":"2099-01-01T00:00:00.000Z"}'
|
||||
login_resp.json.return_value = {
|
||||
"token": "session-tok",
|
||||
"expires": "2099-01-01T00:00:00.000Z",
|
||||
}
|
||||
|
||||
design_resp = MagicMock()
|
||||
design_resp.status_code = 200
|
||||
design_resp.content = b'{"results":[]}'
|
||||
design_resp.json.return_value = {"results": []}
|
||||
|
||||
with self.settings(PCM_API_KEY="key", PCM_API_SECRET="secret"):
|
||||
with patch("directmail.providers.postcard.pcm.requests.post") as post:
|
||||
with patch(
|
||||
"directmail.providers.postcard.pcm.requests.request"
|
||||
) as request:
|
||||
post.return_value = login_resp
|
||||
request.return_value = design_resp
|
||||
designs = pcm_mod.list_designs()
|
||||
|
||||
self.assertEqual(designs, [])
|
||||
post.assert_called_once()
|
||||
self.assertIn("/auth/login", post.call_args.args[0])
|
||||
self.assertEqual(
|
||||
post.call_args.kwargs["json"],
|
||||
{"apiKey": "key", "apiSecret": "secret"},
|
||||
)
|
||||
auth = request.call_args.kwargs["headers"]["Authorization"]
|
||||
self.assertEqual(auth, "Bearer session-tok")
|
||||
|
||||
def test_missing_secret_raises(self):
|
||||
from directmail.providers.postcard import pcm as pcm_mod
|
||||
|
||||
with self.settings(PCM_API_KEY="key", PCM_API_SECRET=""):
|
||||
with self.assertRaises(pcm_mod.PcmApiError) as ctx:
|
||||
pcm_mod.login(force=True)
|
||||
self.assertIn("PCM_API_SECRET", str(ctx.exception))
|
||||
|
||||
def test_return_address_requires_street_fields(self):
|
||||
from directmail.providers.postcard import pcm as pcm_mod
|
||||
|
||||
with self.settings(
|
||||
SITE_NAME="Monica Dhillon",
|
||||
PCM_RETURN_ADDRESS="",
|
||||
PCM_RETURN_LINE1="",
|
||||
PCM_RETURN_CITY="",
|
||||
PCM_RETURN_STATE="",
|
||||
PCM_RETURN_ZIP="",
|
||||
):
|
||||
with self.assertRaises(pcm_mod.PcmApiError) as ctx:
|
||||
pcm_mod.return_address_from_settings()
|
||||
self.assertIn("PCM return address incomplete", str(ctx.exception))
|
||||
|
||||
def test_return_address_from_json(self):
|
||||
from directmail.providers.postcard import pcm as pcm_mod
|
||||
|
||||
with self.settings(
|
||||
PCM_RETURN_ADDRESS=(
|
||||
'{"firstName":"Mo","lastName":"D","address":"1 Main",'
|
||||
'"city":"Naperville","state":"IL","zipCode":"60540"}'
|
||||
),
|
||||
):
|
||||
addr = pcm_mod.return_address_from_settings()
|
||||
self.assertEqual(addr["address"], "1 Main")
|
||||
self.assertEqual(addr["zipCode"], "60540")
|
||||
|
||||
|
||||
class PostcardAddressDefaultConsentTests(TestCase):
|
||||
def test_address_without_consent_is_postcard_eligible(self):
|
||||
contact = Contact.objects.create(
|
||||
email="addr@example.com",
|
||||
first_name="Ann",
|
||||
postal_address=Contact.make_postal_address(
|
||||
line1="1 Oak St",
|
||||
city="Naperville",
|
||||
state="IL",
|
||||
zip_code="60540",
|
||||
),
|
||||
)
|
||||
self.assertTrue(contact_may_receive(contact, Channel.POSTCARD))
|
||||
prefs = channel_preferences(contact)
|
||||
self.assertTrue(prefs[Channel.POSTCARD])
|
||||
self.assertEqual(opted_in_contacts(Channel.POSTCARD).count(), 1)
|
||||
|
||||
def test_explicit_postcard_opt_out_respected(self):
|
||||
contact = Contact.objects.create(
|
||||
email="out@example.com",
|
||||
postal_address=Contact.make_postal_address(line1="2 Oak St"),
|
||||
)
|
||||
set_channel_consent(
|
||||
contact, Channel.POSTCARD, opted_in=False, reason="opt_out"
|
||||
)
|
||||
self.assertFalse(contact_may_receive(contact, Channel.POSTCARD))
|
||||
self.assertEqual(opted_in_contacts(Channel.POSTCARD).count(), 0)
|
||||
|
||||
|
||||
class PostcardDesignPickTests(TestCase):
|
||||
def setUp(self):
|
||||
User = get_user_model()
|
||||
self.user = User.objects.create_user(
|
||||
username="pcm-pick", password="test-pass-123"
|
||||
)
|
||||
self.client = Client()
|
||||
self.client.login(username="pcm-pick", password="test-pass-123")
|
||||
self.contact = Contact.objects.create(
|
||||
email="mail@example.com",
|
||||
postal_address=Contact.make_postal_address(line1="9 Main"),
|
||||
)
|
||||
|
||||
def test_compose_can_pick_pcm_design_id(self):
|
||||
from unittest.mock import patch
|
||||
|
||||
with patch(
|
||||
"directmail.views._fetch_pcm_designs",
|
||||
return_value=(
|
||||
[{"design_id": "42", "name": "Spring card", "size": "46"}],
|
||||
"",
|
||||
),
|
||||
):
|
||||
url = reverse("directmail:campaign_list")
|
||||
response = self.client.post(
|
||||
url,
|
||||
{
|
||||
"name": "Mailer",
|
||||
"subject": "",
|
||||
"body": "",
|
||||
"audience": Campaign.Audience.POSTCARD_OPT_IN,
|
||||
"template_id": "d:42",
|
||||
},
|
||||
)
|
||||
campaign = Campaign.objects.get(name="Mailer")
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(campaign.channel, Channel.POSTCARD)
|
||||
self.assertIsNotNone(campaign.template_id)
|
||||
self.assertEqual(
|
||||
campaign.template.postcard_front.get("design_id"), 42
|
||||
)
|
||||
self.assertEqual(campaign.messages.count(), 1)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user