def dispatchInvitation(invitation: Invitation) -> bool: """ Sends an email to an invitee """ try: assert not invitation.mailed and not invitation.fulfilled except AssertionError: logger.warning(f"Invitation for {invitation.email} was not sent: " "Already fulfilled!") return False if invitation.refkey is None: invitation.refkey = referralKeygen(invitation.email) invitation.save() if invitation.customemail and invitation.customsig: et = EmailTemplate( subject=settings.DEFAULT_EMAIL_TITLE, headline="Conflict Cartographer", message=invitation.customemail, signature=invitation.customsig, ) else: try: et = EmailTemplate.objects.get(active=True, email_type="inv") except EmailTemplate.DoesNotExist: et = EmailTemplate.objects.create( active=True, subject=settings.DEFAULT_EMAIL_TITLE, email_type="inv") html = renderEmailTemplate(et, {"link": invitation.invitationLink()}) plaintext = re.sub("\[[^\)]+", invitation.invitationLink(), et.message) call = { "subject": et.subject, "message": plaintext, "html_message": html, "from_email": settings.EMAIL_FROM_ADDRESS, "recipient_list": [invitation.email] } try: mail.send_mail(**call) except ConnectionRefusedError: logger.error("Failed to send email to %s, connection refused!", invitation.email) return False else: logger.info("Sent email to %s", invitation.email) invitation.mailed = True invitation.save() return True
def test_dispatch_and_register(self): """ Long-form test that tests creating and sending an invite, and then registering a user by following the referral link in the invitation email. """ countries = [ Country(gwno=i, name=str(i), shape={}, simpleshape={}) for i in range(5) ] for c in countries: c.save() i = Invitation(email="*****@*****.**") i.save() i.countries.set(countries) dispatchInvitation(i) m = mail.outbox[0] # Mailed flag self.assertTrue(i.mailed) # Email has proper title self.assertEqual(m.subject, settings.DEFAULT_EMAIL_TITLE) # Email contains ref. key self.assertIsNotNone(re.search(i.refkey, m.body)) r = self.client.get(i.invitationLink(), follow=True) location, *_ = r.redirect_chain[-1] soup = BeautifulSoup(r.content, features="html.parser") regform = soup.find("form") usernameInput = regform.find("input", attrs={"name": "username"}) # Email is in the username form self.assertEqual(usernameInput["value"], i.email) url = regform.action if regform.action else location method = regform.method if regform.method else "POST" getattr(self.client, method.lower())(url, { "username": usernameInput["value"], "password1": hashlib.md5(b"1234").hexdigest(), "password2": hashlib.md5(b"1234").hexdigest() }) # User was created try: u = User.objects.get(email=i.email) except User.DoesNotExist: self.fail("User was not created") # Make sure all countries were added self.assertEqual({c.pk for c in countries}, {c.pk for c in u.profile.countries.all()})