wcs/tests/workflow/test_notification.py

316 lines
10 KiB
Python

import datetime
import json
import pytest
from quixote import cleanup
from wcs import sessions
from wcs.formdef import FormDef
from wcs.qommon.http_request import HTTPRequest
from wcs.wf.notification import SendNotificationWorkflowStatusItem
from ..utilities import clean_temporary_pub, create_temporary_pub
def setup_module(module):
cleanup()
def teardown_module(module):
clean_temporary_pub()
@pytest.fixture
def pub():
pub = create_temporary_pub()
pub.cfg['language'] = {'language': 'en'}
pub.write_cfg()
req = HTTPRequest(None, {'SERVER_NAME': 'example.net', 'SCRIPT_NAME': ''})
req.response.filter = {}
req._user = None
pub._set_request(req)
req.session = sessions.BasicSession(id=1)
pub.set_config(req)
return pub
def test_notifications(pub, http_requests):
pub.user_class.wipe()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'baz'
formdef.fields = []
formdef.store()
formdef.data_class().wipe()
formdata = formdef.data_class()()
formdata.just_created()
formdata.store()
assert not SendNotificationWorkflowStatusItem.is_available()
if not pub.site_options.has_section('variables'):
pub.site_options.add_section('variables')
pub.site_options.set('variables', 'portal_url', 'https://portal/')
assert SendNotificationWorkflowStatusItem.is_available()
item = SendNotificationWorkflowStatusItem()
assert item.to == ['_submitter']
item.title = 'xxx'
item.body = 'XXX'
# no user
http_requests.empty()
item.perform(formdata)
assert http_requests.count() == 0
# user
http_requests.empty()
user = pub.user_class()
user.name_identifiers = ['xxx']
user.store()
formdata.user_id = user.id
formdata.store()
item.perform(formdata)
assert http_requests.count() == 1
assert http_requests.get_last('url') == 'https://portal/api/notification/add/'
assert json.loads(http_requests.get_last('body')) == {
'body': 'XXX',
'url': formdata.get_url(),
'id': 'formdata:%s' % formdata.get_display_id(),
'origin': '',
'summary': 'xxx',
'name_ids': ['xxx'],
}
# deleted user
http_requests.empty()
user.deleted_timestamp = datetime.datetime.now()
user.store()
item.perform(formdata)
assert http_requests.count() == 0
# roles (not exposed in current UI)
http_requests.empty()
user.deleted_timestamp = datetime.datetime.now()
user.store()
role = pub.role_class(name='blah')
role.store()
user1 = pub.user_class()
user1.roles = [role.id]
user1.name_identifiers = ['xxy1']
user1.store()
user2 = pub.user_class()
user2.roles = [role.id]
user2.name_identifiers = ['xxy2']
user2.store()
formdef.workflow_roles = {'_receiver': role.id}
item.to = ['_receiver']
item.perform(formdata)
assert http_requests.count() == 1
assert http_requests.get_last('url') == 'https://portal/api/notification/add/'
assert set(json.loads(http_requests.get_last('body'))['name_ids']) == {'xxy1', 'xxy2'}
# test inactive users are ignored
user2.is_active = False
user2.store()
http_requests.empty()
item.perform(formdata)
assert http_requests.count() == 1
assert http_requests.get_last('url') == 'https://portal/api/notification/add/'
assert set(json.loads(http_requests.get_last('body'))['name_ids']) == {'xxy1'}
user1.is_active = False
user1.store()
http_requests.empty()
item.perform(formdata)
assert http_requests.count() == 0
# check notifications are sent to interco portal if it exists
user1.is_active = True
user1.store()
pub.site_options.set('variables', '_interco_portal_url', 'https://interco-portal/')
http_requests.empty()
item.perform(formdata)
assert http_requests.count() == 1
assert http_requests.get_last('url') == 'https://interco-portal/api/notification/add/'
assert set(json.loads(http_requests.get_last('body'))['name_ids']) == {'xxy1'}
def test_notifications_to_users_template(pub, http_requests):
pub.user_class.wipe()
FormDef.wipe()
user1 = pub.user_class(name='userA')
user1.name_identifiers = ['xxy1']
user1.email = 'user1@example.com'
user1.store()
user2 = pub.user_class(name='userB')
user2.name_identifiers = ['xxy2']
user2.email = 'user2@example.com'
user2.store()
formdef = FormDef()
formdef.name = 'foo'
formdef.fields = []
formdef.store()
formdef.data_class().wipe()
formdatas = []
for i in range(2):
formdatas.append(formdef.data_class()())
formdatas[0].user_id = user1.id
formdatas[1].user_id = user2.id
for formdata in formdatas:
formdata.just_created()
formdata.store()
formdef = FormDef()
formdef.name = 'baz'
formdef.fields = []
formdef.store()
formdef.data_class().wipe()
formdata = formdef.data_class()()
formdata.just_created()
formdata.store()
assert not SendNotificationWorkflowStatusItem.is_available()
if not pub.site_options.has_section('variables'):
pub.site_options.add_section('variables')
pub.site_options.set('variables', 'portal_url', 'https://portal/')
assert SendNotificationWorkflowStatusItem.is_available()
item = SendNotificationWorkflowStatusItem()
item.to = []
item.title = 'xxx'
item.body = 'XXX'
# no user template defined
http_requests.empty()
item.perform(formdata)
assert http_requests.count() == 0
for users_template in [
'xxy1, , xxy2',
'user1@example.com,user2@example.com',
'{% for obj in forms|objects:"foo" %}{{ obj|get:"form_user_nameid" }},{% endfor %}',
'{% for obj in forms|objects:"foo" %}{{ obj|get:"form_user_email" }},{% endfor %}',
'{{ forms|objects:"foo"|getlist:"form_user_nameid" }}',
'{{ forms|objects:"foo"|getlist:"form_user_nameid"|list }}',
'{{ forms|objects:"foo"|getlist:"form_user_email" }}',
'{{ forms|objects:"foo"|getlist:"form_user_email"|list }}',
'{{ forms|objects:"foo"|getlist:"form_user" }}',
'{{ forms|objects:"foo"|getlist:"form_user"|list }}',
]:
item.users_template = users_template
http_requests.empty()
item.perform(formdata)
assert http_requests.count() == 1
assert http_requests.get_last('url') == 'https://portal/api/notification/add/'
assert set(json.loads(http_requests.get_last('body'))['name_ids']) == {'xxy1', 'xxy2'}
formdatas[1].user_id = user1.id
formdatas[1].store()
for users_template in [
'xxy1,',
'user1@example.com',
'{% for obj in forms|objects:"foo" %}{{ obj|get:"form_user_nameid" }},{% endfor %}',
'{% for obj in forms|objects:"foo" %}{{ obj|get:"form_user_email" }},{% endfor %}',
'{{ forms|objects:"foo"|getlist:"form_user_nameid" }}',
'{{ forms|objects:"foo"|getlist:"form_user_nameid"|list }}',
'{{ forms|objects:"foo"|getlist:"form_user_email" }}',
'{{ forms|objects:"foo"|getlist:"form_user_email"|list }}',
'{{ forms|objects:"foo"|getlist:"form_user" }}',
'{{ forms|objects:"foo"|getlist:"form_user"|list }}',
]:
item.users_template = users_template
http_requests.empty()
item.perform(formdata)
assert http_requests.count() == 1
assert http_requests.get_last('url') == 'https://portal/api/notification/add/'
assert set(json.loads(http_requests.get_last('body'))['name_ids']) == {'xxy1'}
# unknown user
item.users_template = 'xxy1, foobar'
http_requests.empty()
item.perform(formdata)
assert http_requests.count() == 1
assert set(json.loads(http_requests.get_last('body'))['name_ids']) == {'xxy1'}
assert pub.loggederror_class.count() == 1
logged_error = pub.loggederror_class.select()[0]
assert logged_error.summary == 'Failed to notify user (not found: "foobar")'
assert logged_error.formdata_id == str(formdata.id)
# result bad format
item.users_template = '{{ forms|objects:"foo"|get:"foobarbaz" }}' # None
http_requests.empty()
item.perform(formdata)
assert http_requests.count() == 0
assert pub.loggederror_class.count() == 2
logged_error = pub.loggederror_class.select()[1]
assert logged_error.summary == 'Failed to notify users, bad template result (None)'
assert logged_error.formdata_id == str(formdata.id)
# template error
item.users_template = '{% for obj in forms|objects:"foo" %}{{ obj|get:"form_user_nameid" }},'
http_requests.empty()
item.perform(formdata)
assert http_requests.count() == 0
assert pub.loggederror_class.count() == 3
logged_error = pub.loggederror_class.select()[2]
assert logged_error.summary == 'Failed to compute template'
assert logged_error.formdata_id == str(formdata.id)
def test_notifications_target_url(pub, http_requests):
pub.substitutions.feed(pub)
pub.user_class.wipe()
user = pub.user_class()
user.name_identifiers = ['xxx']
user.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'baz'
formdef.fields = []
formdef.store()
formdef.data_class().wipe()
formdata = formdef.data_class()()
formdata.user_id = user.id
formdata.just_created()
formdata.store()
pub.load_site_options()
if not pub.site_options.has_section('variables'):
pub.site_options.add_section('variables')
pub.site_options.set('variables', 'portal_url', 'https://portal/')
item = SendNotificationWorkflowStatusItem()
item.title = 'xxx'
item.body = 'XXX'
item.target_url = '{{ portal_url }}plop'
http_requests.empty()
item.perform(formdata)
assert http_requests.count() == 1
assert http_requests.get_last('url') == 'https://portal/api/notification/add/'
assert json.loads(http_requests.get_last('body')) == {
'body': 'XXX',
'url': 'https://portal/plop',
'id': 'formdata:%s' % formdata.get_display_id(),
'origin': '',
'summary': 'xxx',
'name_ids': ['xxx'],
}