wcs/tests/test_mail_templates.py

369 lines
12 KiB
Python

# -*- coding: utf-8 -*-
import base64
import io
import os
import xml.etree.ElementTree as ET
import pytest
from django.utils.encoding import force_bytes
from quixote import cleanup
from webtest import Upload
from wcs.fields import FileField
from wcs.formdef import FormDef
from wcs.mail_templates import MailTemplate
from wcs.qommon.http_request import HTTPRequest
from wcs.qommon.ident.password_accounts import PasswordAccount
from wcs.qommon.upload_storage import PicklableUpload
from wcs.workflows import SendmailWorkflowStatusItem, Workflow
from .utilities import clean_temporary_pub, create_temporary_pub, get_app, login
def setup_module(module):
cleanup()
def teardown_module(module):
clean_temporary_pub()
@pytest.fixture
def pub(request):
pub = create_temporary_pub()
req = HTTPRequest(None, {'SCRIPT_NAME': '/', 'SERVER_NAME': 'example.net'})
pub.set_app_dir(req)
pub._set_request(req)
pub.cfg['identification'] = {'methods': ['password']}
pub.write_cfg()
return pub
@pytest.fixture
def superuser(pub):
if pub.user_class.select(lambda x: x.name == 'admin'):
user1 = pub.user_class.select(lambda x: x.name == 'admin')[0]
user1.is_admin = True
user1.store()
return user1
user1 = pub.user_class(name='admin')
user1.is_admin = True
user1.store()
account1 = PasswordAccount(id='admin')
account1.set_password('admin')
account1.user_id = user1.id
account1.store()
return user1
@pytest.fixture
def mail_templates_option(pub):
if not pub.site_options.has_section('options'):
pub.site_options.add_section('options')
pub.site_options.set('options', 'mail-templates', 'true')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
return pub
@pytest.fixture
def mail_template():
MailTemplate.wipe()
mail_template = MailTemplate(name='test MT')
mail_template.subject = 'test subject'
mail_template.body = 'test body'
mail_template.store()
return mail_template
def test_mail_templates_disabled(pub, superuser):
if not pub.site_options.has_section('options'):
pub.site_options.add_section('options')
pub.site_options.set('options', 'mail-templates', 'false')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/')
assert 'Mail Templates' not in resp
def test_mail_templates_basics(pub, superuser, mail_templates_option):
MailTemplate.wipe()
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/')
assert 'Mail Templates' in resp
resp = resp.click('Mail Templates')
assert 'There are no mail templates defined.' in resp
resp = resp.click('New')
resp.form['name'] = 'first mail template'
resp = resp.form.submit('cancel').follow()
assert 'There are no mail templates defined.' in resp
resp = resp.click('New')
resp.form['name'] = 'first mail template'
resp = resp.form.submit('submit').follow()
resp.form['subject'] = 'mail subject'
resp.form['body'] = 'mail body'
resp = resp.form.submit('submit').follow()
resp = resp.click('Edit')
resp.form['subject'] = 'edited mail subject'
resp.form['body'] = 'edited mail body'
resp.form['attachments$element0'] = 'plop'
resp = resp.form.submit('submit').follow()
resp = resp.click('Edit')
assert resp.form['subject'].value == 'edited mail subject'
assert resp.form['body'].value == 'edited mail body'
assert resp.form['attachments$element0'].value == 'plop'
resp = resp.form.submit('submit').follow()
resp = resp.click('Delete')
resp = resp.form.submit('cancel').follow()
assert 'first mail template' in resp
resp = resp.click('Delete')
resp = resp.form.submit('submit').follow()
assert 'first mail template' not in resp
assert 'There are no mail templates defined.' in resp
resp = resp.click('New')
resp.form['name'] = 'first mail template'
resp = resp.form.submit('submit').follow()
resp.form['subject'] = 'mail subject'
resp.form['body'] = 'mail body'
resp = resp.form.submit('submit').follow()
resp = app.get('/backoffice/workflows/')
resp = resp.click('Mail Templates')
assert 'first mail template' in resp
def test_mail_template_in_use(pub, superuser, mail_templates_option):
Workflow.wipe()
MailTemplate.wipe()
workflow = Workflow(name='test workflow')
st1 = workflow.add_status('Status1')
item = SendmailWorkflowStatusItem()
item.to = ['_receiver']
item.subject = 'Foobar'
item.body = 'Hello'
st1.items.append(item)
item.parent = st1
workflow.store()
mail_template = MailTemplate(name='test mail template')
mail_template.subject = 'test subject'
mail_template.body = 'test body'
mail_template.store()
assert mail_template.is_in_use() is False
item.mail_template = mail_template.slug
workflow.store()
assert mail_template.is_in_use() is True
# check workflow usage is displayed
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/mail-templates/%s/' % mail_template.id)
assert 'Usage in workflows' in resp.text
assert 'test workflow' in resp.text
resp.click('test workflow') # make sure the link is ok
resp = resp.click('Delete')
assert 'still used' in resp.text
def test_admin_workflow_edit(pub, superuser, mail_templates_option):
Workflow.wipe()
MailTemplate.wipe()
mail_template = MailTemplate(name='test mail template')
mail_template.subject = 'test subject'
mail_template.body = 'test body'
mail_template.store()
workflow = Workflow(name='test mail template')
st1 = workflow.add_status('Status1')
item = SendmailWorkflowStatusItem()
item.to = ['_receiver']
item.subject = 'Foobar'
item.body = 'Hello'
st1.items.append(item)
item.parent = st1
workflow.store()
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/%s/' % workflow.id)
resp = resp.click('Status1')
resp = resp.click('Email')
resp.form['mail_template'] = 'test-mail-template'
resp = resp.form.submit('submit')
workflow = Workflow.get(workflow.id)
assert workflow.possible_status[0].items[0].mail_template == 'test-mail-template'
def test_workflow_send_mail_template_with_sql(superuser, mail_templates_option, emails):
pub = create_temporary_pub(sql_mode=True)
req = HTTPRequest(None, {'SCRIPT_NAME': '/', 'SERVER_NAME': 'example.net'})
pub.set_app_dir(req)
pub._set_request(req)
Workflow.wipe()
MailTemplate.wipe()
mail_template = MailTemplate(name='test mail template')
mail_template.subject = 'test subject'
mail_template.body = 'test body'
mail_template.store()
workflow = Workflow(name='test mail template')
st1 = workflow.add_status('Status1')
item = SendmailWorkflowStatusItem()
item.to = 'xyz@localhost'
item.subject = 'Foobar'
item.body = 'Hello'
item.mail_template = mail_template.slug
st1.items.append(item)
item.parent = st1
workflow.store()
formdef = FormDef()
formdef.name = 'baz'
formdef.fields = []
formdef.store()
formdata = formdef.data_class()()
formdata.just_created()
formdata.store()
item.perform(formdata)
pub.get_request().response.process_after_jobs()
assert emails.count() == 1
assert emails.get('test subject')['email_rcpt'] == ['xyz@localhost']
assert b'test body' in base64.decodebytes(
force_bytes(emails.get('test subject')['msg'].get_payload(0).get_payload())
)
# check nothing is sent and an error is logged if the mail template is
# missing
emails.empty()
pub.loggederror_class.wipe()
MailTemplate.wipe()
item.perform(formdata)
pub.get_request().response.process_after_jobs()
assert emails.count() == 0
assert pub.loggederror_class.count() == 1
logged_error = pub.loggederror_class.select()[0]
assert logged_error.summary == 'reference to invalid mail template test-mail-template in status Status1'
def test_workflow_send_mail_template_attachments(pub, superuser, mail_templates_option, emails):
Workflow.wipe()
MailTemplate.wipe()
mail_template = MailTemplate(name='test mail template')
mail_template.subject = 'test subject'
mail_template.body = 'test body'
mail_template.attachments = ['form_var_file1_raw']
mail_template.store()
workflow = Workflow(name='test mail template')
st1 = workflow.add_status('Status1')
item = SendmailWorkflowStatusItem()
item.to = 'xyz@localhost'
item.subject = 'Foobar'
item.body = 'Hello'
item.mail_template = mail_template.slug
st1.items.append(item)
item.parent = st1
workflow.store()
formdef = FormDef()
formdef.name = 'baz'
formdef.fields = [
FileField(id='1', label='File', type='file', varname='file1'),
]
formdef.store()
upload = PicklableUpload('test.jpeg', 'image/jpeg')
with open(os.path.join(os.path.dirname(__file__), 'image-with-gps-data.jpeg'), 'rb') as fd:
upload.receive([fd.read()])
formdata = formdef.data_class()()
formdata.data = {'1': upload}
formdata.just_created()
formdata.store()
pub.substitutions.feed(formdata)
item.perform(formdata)
pub.get_request().response.process_after_jobs()
assert emails.count() == 1
payloads = emails.get('test subject')['msg'].get_payload()
assert len(payloads) == 2
assert payloads[1].get_content_type() == 'image/jpeg'
# check two files are sent if mail attachments are also defined on the
# action itself.
emails.empty()
item.attachments = ['form_var_file1_raw']
item.perform(formdata)
pub.get_request().response.process_after_jobs()
payloads = emails.get('test subject')['msg'].get_payload()
assert len(payloads) == 3
assert payloads[1].get_content_type() == 'image/jpeg'
assert payloads[2].get_content_type() == 'image/jpeg'
def test_mail_templates_export(pub, superuser, mail_template):
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/mail-templates/1/')
resp = resp.click(href='export')
xml_export = resp.text
ds = io.StringIO(xml_export)
mail_template2 = MailTemplate.import_from_xml(ds)
assert mail_template2.name == 'test MT'
def test_mail_templates_import(pub, superuser, mail_template):
mail_template.slug = 'foobar'
mail_template.store()
mail_template_xml = ET.tostring(mail_template.export_to_xml(include_id=True))
MailTemplate.wipe()
assert MailTemplate.count() == 0
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/mail-templates/')
resp = resp.click(href='import')
resp.forms[0]['file'] = Upload('mail_template.wcs', mail_template_xml)
resp = resp.forms[0].submit()
assert MailTemplate.count() == 1
assert set([wc.slug for wc in MailTemplate.select()]) == set(['foobar'])
# check slug
resp = app.get('/backoffice/workflows/mail-templates/')
resp = resp.click(href='import')
resp.forms[0]['file'] = Upload('mail_template.wcs', mail_template_xml)
resp = resp.forms[0].submit()
assert MailTemplate.count() == 2
assert set([wc.slug for wc in MailTemplate.select()]) == set(['foobar', 'test-mt'])
resp = app.get('/backoffice/workflows/mail-templates/')
resp = resp.click(href='import')
resp.forms[0]['file'] = Upload('mail_template.wcs', mail_template_xml)
resp = resp.forms[0].submit()
assert MailTemplate.count() == 3
assert set([wc.slug for wc in MailTemplate.select()]) == set(['foobar', 'test-mt', 'test-mt-1'])
# import an invalid file
resp = app.get('/backoffice/workflows/mail-templates/')
resp = resp.click(href='import')
resp.form['file'] = Upload('mail_template.wcs', b'garbage')
resp = resp.form.submit()
assert 'Invalid File' in resp.text