Skip to content
This repository has been archived by the owner on Nov 12, 2022. It is now read-only.

Commit

Permalink
[carpentries#2065] Add/remove automated email for instructor signup
Browse files Browse the repository at this point in the history
  • Loading branch information
pbanaszkiewicz committed Apr 3, 2022
1 parent a339165 commit 4d5f17b
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 10 deletions.
64 changes: 58 additions & 6 deletions amy/recruitment/tests/test_instructor_recruitment_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@
from django.test.client import RequestFactory
from django.urls import reverse

from autoemails.actions import NewInstructorAction
from autoemails.models import EmailTemplate, RQJob, Trigger
from autoemails.tests.base import FakeRedisTestCaseMixin
from recruitment.filters import InstructorRecruitmentFilter
from recruitment.forms import (
InstructorRecruitmentCreateForm,
InstructorRecruitmentSignupChangeStateForm,
)
from recruitment.models import InstructorRecruitment, InstructorRecruitmentSignup
import recruitment.views
from recruitment.views import (
InstructorRecruitmentCreate,
InstructorRecruitmentDetails,
Expand All @@ -23,6 +27,7 @@
Organization,
Person,
Role,
Tag,
Task,
WorkshopRequest,
)
Expand Down Expand Up @@ -387,7 +392,38 @@ def test_integration(self) -> None:
self.assertEqual(response.context["object"], recruitment)


class TestInstructorRecruitmentSignupChangeState(TestBase):
class TestInstructorRecruitmentSignupChangeState(FakeRedisTestCaseMixin, TestBase):
def setUp(self):
super().setUp()

# save scheduler and connection data
self._saved_scheduler = recruitment.views.scheduler
self._saved_redis_connection = recruitment.views.redis_connection
# overwrite them
recruitment.views.scheduler = self.scheduler
recruitment.views.redis_connection = self.connection

def tearDown(self):
super().tearDown()
recruitment.views.scheduler = self._saved_scheduler
recruitment.views.redis_connection = self._saved_redis_connection

def _prepare_email_automation_data(self) -> None:
self.automated_email_tag = Tag.objects.create(
name="automated-email", priority=0
)
template = EmailTemplate.objects.create(
slug="sample-template",
subject="Welcome!",
to_header="",
from_header="[email protected]",
cc_header="[email protected]",
bcc_header="[email protected]",
reply_to_header="",
body_template="# Welcome",
)
Trigger.objects.create(action="new-instructor", template=template)

def test_class_fields(self) -> None:
# Arrange
view = InstructorRecruitmentSignupChangeState()
Expand Down Expand Up @@ -486,25 +522,41 @@ def test_form_valid(self) -> None:
def test_add_instructor_task(self) -> None:
# Arrange
super()._setUpRoles()
view = InstructorRecruitmentSignupChangeState()
self._prepare_email_automation_data()
request = RequestFactory().post("/")
view = InstructorRecruitmentSignupChangeState(request=request)
person = Person.objects.create(
personal="Test", family="User", username="test_user"
)
organization = Organization.objects.first()
organization = self.org_alpha
event = Event.objects.create(
slug="test-event",
host=organization,
administrator=organization,
)
event.tags.add(self.automated_email_tag)
# Act
result = view.add_instructor_task(person, event)
task = view.add_instructor_task(person, event)
# Assert
self.assertTrue(result.pk)
self.assertTrue(task.pk)
self.assertTrue(NewInstructorAction.check(task))
self.assertTrue(task.rq_jobs.all())

# 1 new jobs
self.assertEqual(self.scheduler.count(), 1)
job = next(self.scheduler.get_jobs())
# 1 new rqjobs
self.assertEqual(RQJob.objects.count(), 1)
rqjob = RQJob.objects.first()
# ensure it's the same job
self.assertEqual(job.get_id(), rqjob.job_id)

def test_remove_instructor_task(self) -> None:
# Arrange
super()._setUpRoles()
view = InstructorRecruitmentSignupChangeState()
self._prepare_email_automation_data()
request = RequestFactory().post("/")
view = InstructorRecruitmentSignupChangeState(request=request)
person = Person.objects.create(
personal="Test", family="User", username="test_user"
)
Expand Down
49 changes: 45 additions & 4 deletions amy/recruitment/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
from typing import Optional

from django.conf import settings
Expand All @@ -9,7 +10,12 @@
from django.urls import reverse
from django.views.generic import View
from django.views.generic.edit import FormMixin
import django_rq

from autoemails.actions import NewInstructorAction
from autoemails.base_views import ActionManageMixin
from autoemails.job import Job
from autoemails.models import RQJob, Trigger
from autoemails.utils import safe_next_or_default_url
from recruitment.filters import InstructorRecruitmentFilter
from recruitment.forms import (
Expand All @@ -28,6 +34,11 @@

from .models import InstructorRecruitment, InstructorRecruitmentSignup

logger = logging.getLogger("amy.signals")
scheduler = django_rq.get_scheduler("default")
redis_connection = django_rq.get_connection("default")


# ------------------------------------------------------------
# InstructorRecruitment related views

Expand Down Expand Up @@ -274,16 +285,46 @@ def form_valid(self, form) -> HttpResponse:

def add_instructor_task(self, person: Person, event: Event) -> Task:
role = Role.objects.get(name="instructor")
return Task.objects.create(
task = Task.objects.create(
event=event,
person=person,
role=role,
)
self.add_automated_email(task)
return task

def remove_instructor_task(self, person: Person, event: Event) -> None:
Task.objects.filter(
role__name="instructor", person=person, event=event
).delete()
task = Task.objects.get(role__name="instructor", person=person, event=event)
self.remove_automated_email(task)
task.delete()

def add_automated_email(self, task: Task) -> tuple[list[Job], list[RQJob]]:
trigger_name = "new-instructor"
triggers = Trigger.objects.filter(active=True, action=trigger_name)
return ActionManageMixin.add(
action_class=NewInstructorAction,
logger=logger,
scheduler=scheduler,
triggers=triggers,
context_objects=dict(task=task, event=task.event),
object_=task,
request=self.request,
)

def remove_automated_email(self, task: Task) -> None:
trigger_name = "new-instructor"
jobs = task.rq_jobs.filter(trigger__action=trigger_name).values_list(
"job_id", flat=True
)
return ActionManageMixin.remove(
action_class=NewInstructorAction,
logger=logger,
scheduler=scheduler,
connection=redis_connection,
jobs=jobs,
object_=task,
request=self.request,
)

def post(self, request, *args, **kwargs):
self.request = request
Expand Down

0 comments on commit 4d5f17b

Please sign in to comment.