From 3c7904bdd517eb7f1f9015877225afa997473855 Mon Sep 17 00:00:00 2001
From: Anna Makarudze
Date: Thu, 8 Feb 2024 14:26:26 +0200
Subject: [PATCH 1/5] Update email templates for global partners
---
.../globalpartners/prospective_sponsor.html | 2 +-
.../emails/globalpartners/renewal_email.html | 27 +++++++++++--------
2 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/templates/emails/globalpartners/prospective_sponsor.html b/templates/emails/globalpartners/prospective_sponsor.html
index 6234c84cd..3e6463aeb 100644
--- a/templates/emails/globalpartners/prospective_sponsor.html
+++ b/templates/emails/globalpartners/prospective_sponsor.html
@@ -7,7 +7,7 @@
We are currently looking for new corporate sponsors who will sponsor us through either monthly donations
or with a once off annual donation. I would like to check with you if your company would consider sponsoring Django Girls.
-Please see attached our sponsors deck for 2023 https://drive.google.com/file/d/1T2jL9tnu5ZkNvkQRAxd7jlt_BnX7VCLE/view
+
Please see attached our sponsors deck for 2024 https://drive.google.com/file/d/1fAmyAiEyLGiE0s6_z3PzgLByHNKzEVHB/view
for our sponsor packages.
If your organisation is interested, kindly get back to me and we can discuss next steps or set up a meeting
diff --git a/templates/emails/globalpartners/renewal_email.html b/templates/emails/globalpartners/renewal_email.html
index 276a57c59..ff4f81052 100644
--- a/templates/emails/globalpartners/renewal_email.html
+++ b/templates/emails/globalpartners/renewal_email.html
@@ -4,20 +4,25 @@
We would like to thank you for your past support, we are so grateful that you chose
to help Django Girls on our mission to inspire women to fall in love with programming.
-In 2021, we introduced an advisory board that has been helping us with diversity and inclussion matters,
- worked with diversity consultants to update our resources to be more inclusive and we continued with
- that mission in 2022. In 2022, we resumed support for in-person workshops. However, we have noticed that
- the number of workshops being organized has greatly reduced following the pandemic and we hope to address
- this by increasing visibility for our work.
+ Since resuming the in-person workshops in 2022, we noticed that the number of workshops being organized was
+ greatly reduced following the pandemic and we hoped to address this in 2023 by increasing visibility for our work.
+ Our plan was to introduce a new role of Communications Officer to help us with our branding and visibility.
+
-We need your support to enable us to continue our work so we thought we should check to see
- if you, our amazing sponsors are willing to renew your sponsorship with us in our 2023 fundraising
+
We are so excited to inform you our global partner that we managed to achieve our focus and mission for 2023
+ to increase our visibility by introducing a part-time paid Communications Officer role to help promote our work.
+ We also promoted our former Awesomeness Ambassador, Claire Wicher to the new role of Chief Emoji Officer
+ (Managing Director) and hired a new Awesomeness Ambassador, growing the number of our paid staff to four.
+
+
+ We need your support to enable us to continue our work so we thought we should check to see
+ if you, our amazing sponsors are willing to renew your sponsorship with us in our 2024 fundraising
period. Should you be interested in supporting us, please find attached our sponsorsβ deck
- here https://drive.google.com/file/d/1T2jL9tnu5ZkNvkQRAxd7jlt_BnX7VCLE/view for the 2023
- fundraising period. Our focus and mission for the upcoming year is in increasing visibility
- by introducing a part-time paid Communications Officer role to help promote our work.
+ here https://drive.google.com/file/d/1fAmyAiEyLGiE0s6_z3PzgLByHNKzEVHB/view for the 2024
+ fundraising period.
+
-Thank you once again for supporting our work. We look forward to working with you again in 2023.
+Thank you once again for supporting our work. We look forward to working with you again in 2024.
Date: Thu, 8 Feb 2024 17:18:06 +0200
Subject: [PATCH 2/5] Add slack invite link for new user email
---
core/emails.py | 1 +
djangogirls/settings.py | 1 +
templates/emails/new_user.html | 7 ++++++-
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/core/emails.py b/core/emails.py
index d9dc7bf11..6e203c344 100644
--- a/core/emails.py
+++ b/core/emails.py
@@ -22,6 +22,7 @@ def notify_new_user(user, event, password, errors=None):
"user": user,
"event": event,
"password": password,
+ "slack_invite_link": settings.SLACK_INVITE_LINK,
"errors": errors,
},
)
diff --git a/djangogirls/settings.py b/djangogirls/settings.py
index 39264ea67..215f65ec1 100644
--- a/djangogirls/settings.py
+++ b/djangogirls/settings.py
@@ -188,6 +188,7 @@ def gettext(s):
SLACK_BOT_TOKEN = os.environ.get("SLACK_BOT_TOKEN")
SLACK_TEAM_ID = os.environ.get("SLACK_TEAM_ID")
SLACK_INVITE_CHANNEL_IDS = os.environ.get("SLACK_INVITE_CHANNEL_IDS", "").split(",")
+SLACK_INVITE_LINK = os.environ.get("SLACK_INVITE_LINK", "")
RECAPTCHA_PUBLIC_KEY = os.environ.get("RECAPTCHA_PUBLIC_KEY", "")
RECAPTCHA_PRIVATE_KEY = os.environ.get("RECAPTCHA_PRIVATE_KEY", "")
diff --git a/templates/emails/new_user.html b/templates/emails/new_user.html
index cab733754..d46cfae18 100644
--- a/templates/emails/new_user.html
+++ b/templates/emails/new_user.html
@@ -29,7 +29,12 @@
{% endblocktrans %}
-{% trans "We also invited you to Django Girls Slack, where we chat, communicate and meet each other!" %}
+
+ {% blocktrans trimmed %}
+ Click this link to join Django Girls Slack,
+ where we chat, communicate and meet each other!
+ {% endblocktrans %}
+
{% blocktrans trimmed %}
From 4d65378739a385508e3746d57d1c3774232627b9 Mon Sep 17 00:00:00 2001
From: Anna Makarudze
Date: Mon, 19 Feb 2024 13:53:49 +0200
Subject: [PATCH 3/5] Add management commands for sponsors emails
---
globalpartners/management/__init__.py | 0
.../management/commands/__init__.py | 0
.../send_prospective_sponsor_email.py | 19 +++++++++++++
...send_sponsor_promotional_material_email.py | 28 +++++++++++++++++++
.../commands/send_sponsor_renewal_email.py | 25 +++++++++++++++++
.../commands/send_sponsor_thank_you_email.py | 26 +++++++++++++++++
globalpartners/models.py | 1 +
7 files changed, 99 insertions(+)
create mode 100644 globalpartners/management/__init__.py
create mode 100644 globalpartners/management/commands/__init__.py
create mode 100644 globalpartners/management/commands/send_prospective_sponsor_email.py
create mode 100644 globalpartners/management/commands/send_sponsor_promotional_material_email.py
create mode 100644 globalpartners/management/commands/send_sponsor_renewal_email.py
create mode 100644 globalpartners/management/commands/send_sponsor_thank_you_email.py
diff --git a/globalpartners/management/__init__.py b/globalpartners/management/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/globalpartners/management/commands/__init__.py b/globalpartners/management/commands/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/globalpartners/management/commands/send_prospective_sponsor_email.py b/globalpartners/management/commands/send_prospective_sponsor_email.py
new file mode 100644
index 000000000..cc92dc5c0
--- /dev/null
+++ b/globalpartners/management/commands/send_prospective_sponsor_email.py
@@ -0,0 +1,19 @@
+from django.core.management.base import BaseCommand
+
+from globalpartners.emails import send_prospective_sponsor_email
+from globalpartners.models import GlobalPartner
+
+
+class Command(BaseCommand):
+ help = "Sends emails to prospective sponsors"
+
+ def add_arguments(self, parser):
+ pass
+
+ def handle(self, *args, **kwargs):
+ try:
+ prospective_sponsors = GlobalPartner.exclude(prospective_sponsor=False).filter(contacted=False)
+ for sponsor in prospective_sponsors:
+ send_prospective_sponsor_email(sponsor.contact_person, sponsor.contact_email)
+ except GlobalPartner.DoesNotExist:
+ self.stdout.write(self.style.error("No prospective sponsors to email at this point."))
diff --git a/globalpartners/management/commands/send_sponsor_promotional_material_email.py b/globalpartners/management/commands/send_sponsor_promotional_material_email.py
new file mode 100644
index 000000000..986fb5cc3
--- /dev/null
+++ b/globalpartners/management/commands/send_sponsor_promotional_material_email.py
@@ -0,0 +1,28 @@
+from django.core.management.base import BaseCommand
+
+from globalpartners.emails import send_promotional_material_email
+from globalpartners.models import GlobalPartner
+
+
+class Command(BaseCommand):
+ help = "Sends emails to sponsors asking them for promotional materials"
+
+ def add_arguments(self, parser):
+ pass
+
+ def handle(self, *args, **kwargs):
+ try:
+ sponsors = GlobalPartner.objects.exclude(sponsor_level_annual="").filter(
+ promotional_materials_requested=False
+ )
+ for sponsor in sponsors:
+ send_promotional_material_email(
+ sponsor.contact_person,
+ sponsor.contact_email,
+ sponsor.prospective_sponsor,
+ sponsor.sponsor_level_annual,
+ )
+ sponsor.promotional_materials_requested = True
+ sponsor.save(update_fields=["promotional_materials_requested"])
+ except GlobalPartner.DoesNotExist:
+ self.stdout.write(self.style.error("No emails requesting promotional materials to send at this point."))
diff --git a/globalpartners/management/commands/send_sponsor_renewal_email.py b/globalpartners/management/commands/send_sponsor_renewal_email.py
new file mode 100644
index 000000000..9b005a546
--- /dev/null
+++ b/globalpartners/management/commands/send_sponsor_renewal_email.py
@@ -0,0 +1,25 @@
+from django.core.management.base import BaseCommand
+
+from globalpartners.emails import send_renewal_email
+from globalpartners.models import GlobalPartner
+
+
+class Command(BaseCommand):
+ help = "Sends renewal emails to sponsors"
+
+ def add_arguments(self, parser):
+ pass
+
+ def handle(self, *args, **kwargs):
+ try:
+ sponsors = (
+ GlobalPartner.objects.exclude(prospective_sponsor=True)
+ .filter(patreon_sponsor=False)
+ .filter(contacted=False)
+ )
+ for sponsor in sponsors:
+ send_renewal_email(sponsor.contact_email, sponsor.contact_email)
+ sponsor.contacted = True
+ sponsor.save(update_fields="contacted")
+ except GlobalPartner.DoesNotExist:
+ self.stdout.write(self.style.error("No sponsor renewal emails to email at this point."))
diff --git a/globalpartners/management/commands/send_sponsor_thank_you_email.py b/globalpartners/management/commands/send_sponsor_thank_you_email.py
new file mode 100644
index 000000000..363c8a859
--- /dev/null
+++ b/globalpartners/management/commands/send_sponsor_thank_you_email.py
@@ -0,0 +1,26 @@
+from datetime import date
+
+from django.core.management.base import BaseCommand
+
+from globalpartners.emails import send_thank_you_email
+from globalpartners.models import GlobalPartner
+
+
+class Command(BaseCommand):
+ help = "Sends thank you emails to sponsors at the end of the year"
+
+ def add_arguments(self, parser):
+ pass
+
+ def handle(self, *args, **kwargs):
+ today = date.today()
+ year = date.year()
+ if today == f"12/12/{year}":
+ try:
+ sponsors = GlobalPartner.objects.exclude(sponsor_level_annual="").filter(is_displayed=True)
+ for sponsor in sponsors:
+ send_thank_you_email(sponsor.contact_person, sponsor.contact_email)
+ sponsor.contacted = False
+ sponsor.save(update_fields=["contacted"])
+ except GlobalPartner.DoesNotExist:
+ self.stdout.write(self.style.error("No sponsor renewal emails to email at this point."))
diff --git a/globalpartners/models.py b/globalpartners/models.py
index 13f8bee28..c1b7ecae6 100644
--- a/globalpartners/models.py
+++ b/globalpartners/models.py
@@ -36,6 +36,7 @@ class GlobalPartner(models.Model):
contacted = models.BooleanField(default=False)
date_contacted = models.DateField(blank=True, null=True)
next_renewal_date = models.DateField(blank=True, null=True)
+ promotional_materials_requested = models.BooleanField(default=False)
logo = models.ImageField(upload_to="uploads", blank=True, null=True)
description = models.TextField(max_length=1000, blank=True, null=True)
is_displayed = models.BooleanField(default=False)
From ff1878454e1e1ddf72f49cc6cd4dea75d65d469a Mon Sep 17 00:00:00 2001
From: Anna Makarudze
Date: Thu, 22 Feb 2024 20:51:50 +0200
Subject: [PATCH 4/5] Make the year dynamic
---
templates/emails/globalpartners/prospective_sponsor.html | 2 +-
templates/emails/globalpartners/renewal_email.html | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/templates/emails/globalpartners/prospective_sponsor.html b/templates/emails/globalpartners/prospective_sponsor.html
index 3e6463aeb..982e40ed9 100644
--- a/templates/emails/globalpartners/prospective_sponsor.html
+++ b/templates/emails/globalpartners/prospective_sponsor.html
@@ -7,7 +7,7 @@
We are currently looking for new corporate sponsors who will sponsor us through either monthly donations
or with a once off annual donation. I would like to check with you if your company would consider sponsoring Django Girls.
-Please see attached our sponsors deck for 2024 https://drive.google.com/file/d/1fAmyAiEyLGiE0s6_z3PzgLByHNKzEVHB/view
+
Please see attached our sponsors deck for {% now "Y" %} https://drive.google.com/file/d/1fAmyAiEyLGiE0s6_z3PzgLByHNKzEVHB/view
for our sponsor packages.
If your organisation is interested, kindly get back to me and we can discuss next steps or set up a meeting
diff --git a/templates/emails/globalpartners/renewal_email.html b/templates/emails/globalpartners/renewal_email.html
index ff4f81052..aa17af0a1 100644
--- a/templates/emails/globalpartners/renewal_email.html
+++ b/templates/emails/globalpartners/renewal_email.html
@@ -16,13 +16,13 @@
We need your support to enable us to continue our work so we thought we should check to see
- if you, our amazing sponsors are willing to renew your sponsorship with us in our 2024 fundraising
+ if you, our amazing sponsors are willing to renew your sponsorship with us in our {% now "Y" %} fundraising
period. Should you be interested in supporting us, please find attached our sponsorsβ deck
- here https://drive.google.com/file/d/1fAmyAiEyLGiE0s6_z3PzgLByHNKzEVHB/view for the 2024
+ here https://drive.google.com/file/d/1fAmyAiEyLGiE0s6_z3PzgLByHNKzEVHB/view for the {% now "Y" %}
fundraising period.
-Thank you once again for supporting our work. We look forward to working with you again in 2024.
+Thank you once again for supporting our work. We look forward to working with you again in {% now "Y" %}.
Sparkles, cupcakes and high-fives, πππβ¨π°π
From b556dab02302f4b0c4a6c47613f352826268e187 Mon Sep 17 00:00:00 2001
From: Anna Makarudze
Date: Mon, 26 Feb 2024 23:44:54 +0200
Subject: [PATCH 5/5] Add management commands for sponsors emails
---
globalpartners/emails.py | 8 +-
.../send_prospective_sponsor_email.py | 7 +-
...send_sponsor_promotional_material_email.py | 6 +-
.../commands/send_sponsor_renewal_email.py | 6 +-
.../commands/send_sponsor_thank_you_email.py | 8 +-
.../migrations/0004_auto_20240226_2119.py | 23 ++++
globalpartners/models.py | 6 +-
tests/globalpartners/conftest.py | 114 ++++++++++++++++++
.../test_management_commands.py | 49 ++++++++
9 files changed, 216 insertions(+), 11 deletions(-)
create mode 100644 globalpartners/migrations/0004_auto_20240226_2119.py
create mode 100644 tests/globalpartners/test_management_commands.py
diff --git a/globalpartners/emails.py b/globalpartners/emails.py
index 2e64d0837..520bc366f 100644
--- a/globalpartners/emails.py
+++ b/globalpartners/emails.py
@@ -25,13 +25,17 @@ def send_renewal_email(contact_person, contact_email):
"""Sends annual sponsors email asking if they are interested in supporting
our work in the new year.
"""
- subject = "Will you be supporting us again in 2023?"
+ subject = f"Will you be supporting us again in {year}?"
template = "emails/globalpartners/renewal_email.html"
send_sponsor_email(contact_person, contact_email, template, subject)
def send_promotional_material_email(
- contact_person, contact_email, prospective_sponsor, sponsor_level_annual, errors=None
+ contact_person,
+ contact_email,
+ prospective_sponsor,
+ sponsor_level_annual,
+ errors=None,
):
"""Sends new sponsors/patreon sponsors asking them for materials to use in
announcing/promoting the sponsor."""
diff --git a/globalpartners/management/commands/send_prospective_sponsor_email.py b/globalpartners/management/commands/send_prospective_sponsor_email.py
index cc92dc5c0..65b220ae5 100644
--- a/globalpartners/management/commands/send_prospective_sponsor_email.py
+++ b/globalpartners/management/commands/send_prospective_sponsor_email.py
@@ -1,3 +1,5 @@
+from datetime import date
+
from django.core.management.base import BaseCommand
from globalpartners.emails import send_prospective_sponsor_email
@@ -12,8 +14,11 @@ def add_arguments(self, parser):
def handle(self, *args, **kwargs):
try:
- prospective_sponsors = GlobalPartner.exclude(prospective_sponsor=False).filter(contacted=False)
+ prospective_sponsors = GlobalPartner.objects.exclude(prospective_sponsor=False).filter(contacted=False)
for sponsor in prospective_sponsors:
send_prospective_sponsor_email(sponsor.contact_person, sponsor.contact_email)
+ sponsor.contacted = True
+ sponsor.date_contacted = date.today()
+ sponsor.save(update_fields=["contacted", "date_contacted"])
except GlobalPartner.DoesNotExist:
self.stdout.write(self.style.error("No prospective sponsors to email at this point."))
diff --git a/globalpartners/management/commands/send_sponsor_promotional_material_email.py b/globalpartners/management/commands/send_sponsor_promotional_material_email.py
index 986fb5cc3..59430b145 100644
--- a/globalpartners/management/commands/send_sponsor_promotional_material_email.py
+++ b/globalpartners/management/commands/send_sponsor_promotional_material_email.py
@@ -12,8 +12,10 @@ def add_arguments(self, parser):
def handle(self, *args, **kwargs):
try:
- sponsors = GlobalPartner.objects.exclude(sponsor_level_annual="").filter(
- promotional_materials_requested=False
+ sponsors = (
+ GlobalPartner.objects.exclude(prospective_sponsor=True)
+ .filter(promotional_materials_requested=False)
+ .filter(is_active=True)
)
for sponsor in sponsors:
send_promotional_material_email(
diff --git a/globalpartners/management/commands/send_sponsor_renewal_email.py b/globalpartners/management/commands/send_sponsor_renewal_email.py
index 9b005a546..fa44ee6b8 100644
--- a/globalpartners/management/commands/send_sponsor_renewal_email.py
+++ b/globalpartners/management/commands/send_sponsor_renewal_email.py
@@ -1,3 +1,5 @@
+from datetime import date
+
from django.core.management.base import BaseCommand
from globalpartners.emails import send_renewal_email
@@ -16,10 +18,12 @@ def handle(self, *args, **kwargs):
GlobalPartner.objects.exclude(prospective_sponsor=True)
.filter(patreon_sponsor=False)
.filter(contacted=False)
+ .filter(next_renewal_date__lte=date.today())
)
for sponsor in sponsors:
send_renewal_email(sponsor.contact_email, sponsor.contact_email)
sponsor.contacted = True
- sponsor.save(update_fields="contacted")
+ sponsor.date_contacted = date.today()
+ sponsor.save(update_fields=["contacted", "date_contacted"])
except GlobalPartner.DoesNotExist:
self.stdout.write(self.style.error("No sponsor renewal emails to email at this point."))
diff --git a/globalpartners/management/commands/send_sponsor_thank_you_email.py b/globalpartners/management/commands/send_sponsor_thank_you_email.py
index 363c8a859..d664978c8 100644
--- a/globalpartners/management/commands/send_sponsor_thank_you_email.py
+++ b/globalpartners/management/commands/send_sponsor_thank_you_email.py
@@ -14,13 +14,13 @@ def add_arguments(self, parser):
def handle(self, *args, **kwargs):
today = date.today()
- year = date.year()
- if today == f"12/12/{year}":
+ year = today.year
+ if today == date(year, 12, 12):
try:
- sponsors = GlobalPartner.objects.exclude(sponsor_level_annual="").filter(is_displayed=True)
+ sponsors = GlobalPartner.objects.exclude(is_active=False).filter(is_displayed=True)
for sponsor in sponsors:
send_thank_you_email(sponsor.contact_person, sponsor.contact_email)
sponsor.contacted = False
sponsor.save(update_fields=["contacted"])
except GlobalPartner.DoesNotExist:
- self.stdout.write(self.style.error("No sponsor renewal emails to email at this point."))
+ self.stdout.write(self.style.error("No thank you emails to send at this point."))
diff --git a/globalpartners/migrations/0004_auto_20240226_2119.py b/globalpartners/migrations/0004_auto_20240226_2119.py
new file mode 100644
index 000000000..12d37ce5c
--- /dev/null
+++ b/globalpartners/migrations/0004_auto_20240226_2119.py
@@ -0,0 +1,23 @@
+# Generated by Django 3.2.20 on 2024-02-26 21:19
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("globalpartners", "0003_globalpartner_description"),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name="globalpartner",
+ name="is_active",
+ field=models.BooleanField(default=False),
+ ),
+ migrations.AddField(
+ model_name="globalpartner",
+ name="promotional_materials_requested",
+ field=models.BooleanField(default=False),
+ ),
+ ]
diff --git a/globalpartners/models.py b/globalpartners/models.py
index c1b7ecae6..d1d88b7ec 100644
--- a/globalpartners/models.py
+++ b/globalpartners/models.py
@@ -39,6 +39,7 @@ class GlobalPartner(models.Model):
promotional_materials_requested = models.BooleanField(default=False)
logo = models.ImageField(upload_to="uploads", blank=True, null=True)
description = models.TextField(max_length=1000, blank=True, null=True)
+ is_active = models.BooleanField(default=False)
is_displayed = models.BooleanField(default=False)
website_url = models.URLField(blank=True, null=True)
style = models.CharField(max_length=50, blank=True, null=True)
@@ -61,7 +62,10 @@ def send_renewal_email(self):
def send_promotional_material_email(self):
send_promotional_material_email(
- self.contact_person, self.contact_email, self.prospective_sponsor, self.sponsor_level_annual
+ self.contact_person,
+ self.contact_email,
+ self.prospective_sponsor,
+ self.sponsor_level_annual,
)
self.update_details()
diff --git a/tests/globalpartners/conftest.py b/tests/globalpartners/conftest.py
index 05bdd0f4d..dabe3f4e7 100644
--- a/tests/globalpartners/conftest.py
+++ b/tests/globalpartners/conftest.py
@@ -1,5 +1,15 @@
+from io import StringIO
+
import pytest
+from globalpartners.models import GlobalPartner
+
+
+@pytest.fixture
+def out():
+ out = StringIO()
+ return out
+
@pytest.fixture
def global_partner_data():
@@ -17,3 +27,107 @@ def global_partner_data():
"website_url": "https://www.djangoproject.com",
}
return data
+
+
+@pytest.fixture
+def partners():
+ return GlobalPartner.objects.bulk_create(
+ [
+ GlobalPartner(
+ company_name="Sherpany",
+ contact_person="Jane Doe",
+ contact_email="jane.doe@test.com",
+ prospective_sponsor=True,
+ contacted=False,
+ ),
+ GlobalPartner(
+ company_name="DigitalOcean",
+ contact_person="John Doe",
+ contact_email="john@test.com",
+ prospective_sponsor=True,
+ contacted=True,
+ ),
+ GlobalPartner(
+ company_name="PythonAnywhere",
+ contact_person="Jane Doe",
+ contact_email="jane@test.com",
+ prospective_sponsor=False,
+ patreon_sponsor=True,
+ patreon_level_per_month=500,
+ sponsor_level_annual=5000,
+ contacted=False,
+ promotional_materials_requested=False,
+ is_active=True,
+ ),
+ GlobalPartner(
+ company_name="3YourMind",
+ contact_person="John Doe",
+ contact_email="john@test.com",
+ prospective_sponsor=False,
+ patreon_sponsor=True,
+ patreon_level_per_month=500,
+ sponsor_level_annual=5000,
+ contacted=True,
+ promotional_materials_requested=True,
+ is_active=True,
+ ),
+ GlobalPartner(
+ company_name="Zapier",
+ contact_person="John Doe",
+ contact_email="john@test.com",
+ prospective_sponsor=False,
+ patreon_sponsor=True,
+ patreon_level_per_month=500,
+ sponsor_level_annual=5000,
+ contacted=True,
+ promotional_materials_requested=False,
+ is_active=True,
+ ),
+ GlobalPartner(
+ company_name="PostHog",
+ contact_person="Jane Tes",
+ contact_email="jane@test.com",
+ prospective_sponsor=False,
+ patreon_sponsor=False,
+ sponsor_level_annual=1000,
+ contacted=False,
+ promotional_materials_requested=False,
+ is_active=False,
+ next_renewal_date="2024-02-15",
+ ),
+ GlobalPartner(
+ company_name="Torchbox",
+ contact_person="John Test",
+ contact_email="test@test.com",
+ prospective_sponsor=False,
+ patreon_sponsor=False,
+ sponsor_level_annual=500,
+ contacted=True,
+ promotional_materials_requested=False,
+ is_active=True,
+ next_renewal_date="2024-02-15",
+ ),
+ GlobalPartner(
+ company_name="Mirumee",
+ contact_person="Test Contact",
+ contact_email="test@test.com",
+ prospective_sponsor=False,
+ sponsor_level_annual=2500,
+ contacted=True,
+ promotional_materials_requested=True,
+ is_active=True,
+ next_renewal_date="2024-02-15",
+ ),
+ GlobalPartner(
+ company_name="Mirumee",
+ contact_person="Test Contact",
+ contact_email="test@test.com",
+ prospective_sponsor=False,
+ sponsor_level_annual=2500,
+ contacted=True,
+ promotional_materials_requested=False,
+ is_active=False,
+ next_renewal_date="2024-02-15",
+ ),
+ ]
+ )
diff --git a/tests/globalpartners/test_management_commands.py b/tests/globalpartners/test_management_commands.py
new file mode 100644
index 000000000..7c78fa5cc
--- /dev/null
+++ b/tests/globalpartners/test_management_commands.py
@@ -0,0 +1,49 @@
+from datetime import date
+from io import StringIO
+
+from django.core.management import call_command
+
+from globalpartners.models import GlobalPartner
+
+today = date.today()
+
+
+def test_send_prospective_sponsor_email_command(partners, out):
+ out = call_command(
+ "send_prospective_sponsor_email",
+ stdout=out,
+ stderr=StringIO(),
+ )
+ sponsors = GlobalPartner.objects.filter(prospective_sponsor=True, contacted=True)
+ assert len(sponsors) == 2
+
+
+def test_send_sponsor_promotional_material_email_command(partners, out):
+ out = call_command("send_sponsor_promotional_material_email", stdout=out, stderr=StringIO())
+ sponsors = (
+ GlobalPartner.objects.exclude(prospective_sponsor=True)
+ .filter(is_active=True)
+ .filter(promotional_materials_requested=True)
+ )
+ assert len(sponsors) == 5
+ assert sponsors[0].promotional_materials_requested
+
+
+def test_send_sponsor_renewal_email_command(partners, out):
+ out = call_command("send_sponsor_renewal_email", stdout=out, stderr=StringIO())
+ sponsors = (
+ GlobalPartner.objects.exclude(prospective_sponsor=True)
+ .filter(next_renewal_date__lte=today)
+ .filter(patreon_sponsor=False)
+ .filter(date_contacted=today)
+ )
+ assert len(sponsors) == 1
+ assert sponsors[0].contacted
+ assert sponsors[0].date_contacted == today
+
+
+def test_send_sponsor_thank_you_email_command(partners, out):
+ out = call_command("send_sponsor_thank_you_email", stdout=out, stderr=StringIO())
+ sponsors = GlobalPartner.objects.exclude(prospective_sponsor=True).filter(is_active=True)
+ assert len(sponsors) == 5
+ assert not sponsors[0].contacted