511 lines
18 KiB
Python
511 lines
18 KiB
Python
import io
|
|
import os
|
|
import re
|
|
import xml.etree.ElementTree as ET
|
|
|
|
import pytest
|
|
from quixote import cleanup
|
|
from webtest import Upload
|
|
|
|
from wcs.categories import CommentTemplateCategory
|
|
from wcs.comment_templates import CommentTemplate
|
|
from wcs.fields import FileField
|
|
from wcs.formdef import FormDef
|
|
from wcs.qommon.http_request import HTTPRequest
|
|
from wcs.qommon.ident.password_accounts import PasswordAccount
|
|
from wcs.qommon.misc import indent_xml as indent
|
|
from wcs.qommon.upload_storage import PicklableUpload
|
|
from wcs.workflows import 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 comment_template():
|
|
CommentTemplate.wipe()
|
|
comment_template = CommentTemplate(name='test CT')
|
|
comment_template.comment = 'test comment'
|
|
comment_template.store()
|
|
return comment_template
|
|
|
|
|
|
def test_comment_templates_basics(pub, superuser):
|
|
CommentTemplateCategory.wipe()
|
|
CommentTemplate.wipe()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/workflows/')
|
|
assert 'Comment Templates' in resp
|
|
resp = resp.click('Comment Templates')
|
|
assert 'There are no comment templates defined.' in resp
|
|
|
|
resp = resp.click('New')
|
|
resp.form['name'] = 'first comment template'
|
|
resp = resp.form.submit('cancel').follow()
|
|
assert 'There are no comment templates defined.' in resp
|
|
|
|
resp = resp.click('New')
|
|
resp.form['name'] = 'first comment template'
|
|
resp = resp.form.submit('submit').follow()
|
|
resp.form['comment'] = 'comment body'
|
|
resp = resp.form.submit('submit').follow()
|
|
|
|
resp = resp.click('Edit')
|
|
resp.form['comment'] = 'edited comment body'
|
|
resp.form['attachments$element0'] = 'plop'
|
|
resp = resp.form.submit('submit').follow()
|
|
|
|
resp = resp.click('Edit')
|
|
assert resp.form['comment'].value == 'edited comment 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 comment template' in resp
|
|
|
|
resp = resp.click('Delete')
|
|
resp = resp.form.submit('submit').follow()
|
|
assert 'first comment template' not in resp
|
|
assert 'There are no comment templates defined.' in resp
|
|
|
|
resp = resp.click('New')
|
|
resp.form['name'] = 'first comment template'
|
|
resp = resp.form.submit('submit').follow()
|
|
resp.form['comment'] = 'comment body'
|
|
resp = resp.form.submit('submit').follow()
|
|
|
|
resp = app.get('/backoffice/workflows/')
|
|
resp = resp.click('Comment Templates')
|
|
assert 'first comment template' in resp
|
|
|
|
|
|
def test_comment_template_in_use(pub, superuser):
|
|
Workflow.wipe()
|
|
CommentTemplate.wipe()
|
|
workflow = Workflow(name='test workflow')
|
|
st1 = workflow.add_status('Status1')
|
|
item = st1.add_action('register-comment')
|
|
item.comment = 'Hello'
|
|
workflow.store()
|
|
|
|
comment_template = CommentTemplate(name='test comment template')
|
|
comment_template.comment = 'test comment'
|
|
comment_template.store()
|
|
assert comment_template.is_in_use() is False
|
|
|
|
item.comment_template = comment_template.slug
|
|
workflow.store()
|
|
assert comment_template.is_in_use() is True
|
|
|
|
# check workflow usage is displayed
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/workflows/comment-templates/%s/' % comment_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):
|
|
CommentTemplateCategory.wipe()
|
|
Workflow.wipe()
|
|
CommentTemplate.wipe()
|
|
comment_template = CommentTemplate(name='test comment template')
|
|
comment_template.comment = 'test comment'
|
|
comment_template.store()
|
|
|
|
workflow = Workflow(name='test comment template')
|
|
st1 = workflow.add_status('Status1')
|
|
item = st1.add_action('register-comment')
|
|
item.comment = 'Hello'
|
|
workflow.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/workflows/%s/status/%s/items/1/' % (workflow.id, st1.id))
|
|
assert [o[0] for o in resp.form['comment_template'].options] == ['', 'test-comment-template']
|
|
|
|
cat_b = CommentTemplateCategory(name='Cat B')
|
|
cat_b.store()
|
|
comment_template = CommentTemplate(name='foo bar')
|
|
comment_template.category_id = cat_b.id
|
|
comment_template.store()
|
|
comment_template = CommentTemplate(name='bar foo')
|
|
comment_template.category_id = cat_b.id
|
|
comment_template.store()
|
|
cat_a = CommentTemplateCategory(name='Cat A')
|
|
cat_a.store()
|
|
comment_template = CommentTemplate(name='foo baz')
|
|
comment_template.category_id = cat_a.id
|
|
comment_template.store()
|
|
|
|
resp = app.get('/backoffice/workflows/%s/status/%s/items/1/' % (workflow.id, st1.id))
|
|
assert [o[0] for o in resp.form['comment_template'].options] == [
|
|
'',
|
|
'foo-baz',
|
|
'bar-foo',
|
|
'foo-bar',
|
|
'test-comment-template',
|
|
]
|
|
resp.form['comment_template'] = 'test-comment-template'
|
|
resp = resp.form.submit('submit')
|
|
|
|
workflow = Workflow.get(workflow.id)
|
|
assert workflow.possible_status[0].items[0].comment_template == 'test-comment-template'
|
|
|
|
|
|
def test_comment_templates_category(pub, superuser):
|
|
CommentTemplateCategory.wipe()
|
|
CommentTemplate.wipe()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/workflows/comment-templates/new')
|
|
assert 'category_id' not in resp.form.fields
|
|
|
|
comment_template = CommentTemplate(name='foo')
|
|
comment_template.store()
|
|
|
|
resp = app.get('/backoffice/workflows/comment-templates/categories/')
|
|
resp = resp.click('New Category')
|
|
resp.form['name'] = 'a new category'
|
|
resp.form['description'] = 'description of the category'
|
|
resp = resp.form.submit('submit')
|
|
assert CommentTemplateCategory.count() == 1
|
|
category = CommentTemplateCategory.select()[0]
|
|
assert category.name == 'a new category'
|
|
|
|
resp = app.get('/backoffice/workflows/comment-templates/new')
|
|
resp.form['name'] = 'template 2'
|
|
resp = resp.form.submit('submit').follow()
|
|
assert CommentTemplate.count() == 2
|
|
assert CommentTemplate.get(2).category_id is None
|
|
resp = app.get('/backoffice/workflows/comment-templates/new')
|
|
resp.form['name'] = 'template 3'
|
|
resp.form['category_id'] = str(category.id)
|
|
resp = resp.form.submit('submit').follow()
|
|
assert CommentTemplate.count() == 3
|
|
assert CommentTemplate.get(3).category_id == str(category.id)
|
|
|
|
resp = app.get('/backoffice/workflows/comment-templates/%s/' % comment_template.id)
|
|
resp = resp.click(href=re.compile('^edit$'))
|
|
resp.form['category_id'] = str(category.id)
|
|
resp = resp.form.submit('cancel').follow()
|
|
comment_template.refresh_from_storage()
|
|
assert comment_template.category_id is None
|
|
|
|
resp = app.get('/backoffice/workflows/comment-templates/%s/' % comment_template.id)
|
|
resp = resp.click(href=re.compile('^edit$'))
|
|
resp.form['category_id'] = str(category.id)
|
|
resp.form['comment'] = 'comment body'
|
|
resp = resp.form.submit('submit').follow()
|
|
comment_template.refresh_from_storage()
|
|
assert str(comment_template.category_id) == str(category.id)
|
|
|
|
resp = app.get('/backoffice/workflows/comment-templates/%s/' % comment_template.id)
|
|
resp = resp.click(href=re.compile('^edit$'))
|
|
assert resp.form['category_id'].value == str(category.id)
|
|
|
|
resp = app.get('/backoffice/workflows/comment-templates/categories/')
|
|
resp = resp.click('New Category')
|
|
resp.form['name'] = 'a second category'
|
|
resp.form['description'] = 'description of the category'
|
|
resp = resp.form.submit('submit')
|
|
assert CommentTemplateCategory.count() == 2
|
|
category2 = [x for x in CommentTemplateCategory.select() if x.id != category.id][0]
|
|
assert category2.name == 'a second category'
|
|
|
|
app.get(
|
|
'/backoffice/workflows/comment-templates/categories/update_order?order=%s;%s;'
|
|
% (category2.id, category.id)
|
|
)
|
|
categories = CommentTemplateCategory.select()
|
|
CommentTemplateCategory.sort_by_position(categories)
|
|
assert [x.id for x in categories] == [str(category2.id), str(category.id)]
|
|
|
|
app.get(
|
|
'/backoffice/workflows/comment-templates/categories/update_order?order=%s;%s;0'
|
|
% (category.id, category2.id)
|
|
)
|
|
categories = CommentTemplateCategory.select()
|
|
CommentTemplateCategory.sort_by_position(categories)
|
|
assert [x.id for x in categories] == [str(category.id), str(category2.id)]
|
|
|
|
resp = app.get('/backoffice/workflows/comment-templates/categories/')
|
|
resp = resp.click('a new category')
|
|
resp = resp.click('Delete')
|
|
resp = resp.form.submit()
|
|
comment_template.refresh_from_storage()
|
|
assert not comment_template.category_id
|
|
|
|
|
|
def test_workflow_register_comment_template(pub):
|
|
Workflow.wipe()
|
|
CommentTemplate.wipe()
|
|
|
|
comment_template = CommentTemplate(name='test comment template')
|
|
comment_template.comment = 'test comment'
|
|
comment_template.store()
|
|
|
|
workflow = Workflow(name='test comment template')
|
|
st1 = workflow.add_status('Status1')
|
|
item = st1.add_action('register-comment')
|
|
item.comment = 'Hello'
|
|
item.comment_template = comment_template.slug
|
|
workflow.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'baz'
|
|
formdef.fields = []
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.store()
|
|
|
|
item.perform(formdata)
|
|
assert len(formdata.evolution) == 1
|
|
assert len(formdata.evolution[0].parts) == 2
|
|
assert formdata.evolution[-1].parts[1].content == 'test comment'
|
|
|
|
# check nothing is registered and an error is logged if the comment template is missing
|
|
CommentTemplate.wipe()
|
|
item.perform(formdata)
|
|
assert len(formdata.evolution) == 1
|
|
assert len(formdata.evolution[0].parts) == 2
|
|
assert pub.loggederror_class.count() == 1
|
|
logged_error = pub.loggederror_class.select()[0]
|
|
assert (
|
|
logged_error.summary
|
|
== 'reference to invalid comment template test-comment-template in status Status1'
|
|
)
|
|
|
|
|
|
def test_workflow_register_comment_template_attachments(pub):
|
|
Workflow.wipe()
|
|
CommentTemplate.wipe()
|
|
|
|
comment_template = CommentTemplate(name='test comment template')
|
|
comment_template.comment = 'test comment'
|
|
comment_template.attachments = ['form_var_file1_raw']
|
|
comment_template.store()
|
|
|
|
workflow = Workflow(name='test comment template')
|
|
st1 = workflow.add_status('Status1')
|
|
item = st1.add_action('register-comment')
|
|
item.comment = 'Hello'
|
|
item.comment_template = comment_template.slug
|
|
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)
|
|
assert len(formdata.evolution) == 1
|
|
assert len(formdata.evolution[0].parts) == 3
|
|
assert formdata.evolution[-1].parts[2].content == 'test comment'
|
|
assert formdata.evolution[-1].parts[1].base_filename == 'test.jpeg'
|
|
|
|
# check two files are sent if attachments are also defined on the action itself.
|
|
item.attachments = ['form_var_file1_raw']
|
|
item.perform(formdata)
|
|
assert len(formdata.evolution) == 1
|
|
assert len(formdata.evolution[0].parts) == 6
|
|
assert formdata.evolution[-1].parts[5].content == 'test comment'
|
|
assert formdata.evolution[-1].parts[4].base_filename == 'test.jpeg'
|
|
assert formdata.evolution[-1].parts[3].base_filename == 'test.jpeg'
|
|
|
|
|
|
def test_workflow_register_comment_template_empty(pub):
|
|
Workflow.wipe()
|
|
CommentTemplate.wipe()
|
|
|
|
comment_template = CommentTemplate(name='test comment template')
|
|
comment_template.comment = None
|
|
comment_template.store()
|
|
|
|
workflow = Workflow(name='test comment template')
|
|
st1 = workflow.add_status('Status1')
|
|
item = st1.add_action('register-comment')
|
|
item.comment = 'Hello'
|
|
item.comment_template = comment_template.slug
|
|
workflow.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'baz'
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {}
|
|
formdata.just_created()
|
|
formdata.store()
|
|
pub.substitutions.feed(formdata)
|
|
|
|
item.perform(formdata)
|
|
assert len(formdata.evolution) == 1
|
|
assert len(formdata.evolution[0].parts) == 1
|
|
|
|
|
|
def test_comment_templates_export(pub, superuser, comment_template):
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/workflows/comment-templates/1/')
|
|
|
|
resp = resp.click(href='export')
|
|
xml_export = resp.text
|
|
|
|
ds = io.StringIO(xml_export)
|
|
comment_template2 = CommentTemplate.import_from_xml(ds)
|
|
assert comment_template2.name == 'test CT'
|
|
|
|
|
|
def test_comment_templates_import(pub, superuser, comment_template):
|
|
comment_template.slug = 'foobar'
|
|
comment_template.store()
|
|
comment_template_xml = ET.tostring(comment_template.export_to_xml(include_id=True))
|
|
CommentTemplate.wipe()
|
|
assert CommentTemplate.count() == 0
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/workflows/comment-templates/')
|
|
resp = resp.click(href='import')
|
|
resp.forms[0]['file'] = Upload('comment_template.wcs', comment_template_xml)
|
|
resp = resp.forms[0].submit()
|
|
assert CommentTemplate.count() == 1
|
|
assert {wc.slug for wc in CommentTemplate.select()} == {'foobar'}
|
|
|
|
# check slug
|
|
resp = app.get('/backoffice/workflows/comment-templates/')
|
|
resp = resp.click(href='import')
|
|
resp.forms[0]['file'] = Upload('comment_template.wcs', comment_template_xml)
|
|
resp = resp.forms[0].submit()
|
|
assert CommentTemplate.count() == 2
|
|
assert {wc.slug for wc in CommentTemplate.select()} == {'foobar', 'test-ct'}
|
|
resp = app.get('/backoffice/workflows/comment-templates/')
|
|
resp = resp.click(href='import')
|
|
resp.forms[0]['file'] = Upload('comment_template.wcs', comment_template_xml)
|
|
resp = resp.forms[0].submit()
|
|
assert CommentTemplate.count() == 3
|
|
assert {wc.slug for wc in CommentTemplate.select()} == {'foobar', 'test-ct', 'test-ct-1'}
|
|
|
|
# import an invalid file
|
|
resp = app.get('/backoffice/workflows/comment-templates/')
|
|
resp = resp.click(href='import')
|
|
resp.form['file'] = Upload('comment_template.wcs', b'garbage')
|
|
resp = resp.form.submit()
|
|
assert 'Invalid File' in resp.text
|
|
|
|
|
|
def test_comment_templates_duplicate(pub, superuser, comment_template):
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/workflows/comment-templates/1/')
|
|
|
|
resp = resp.click(href='duplicate')
|
|
assert resp.form['name'].value == 'test CT (copy)'
|
|
resp = resp.form.submit('cancel').follow()
|
|
assert CommentTemplate.count() == 1
|
|
|
|
resp = resp.click(href='duplicate')
|
|
assert resp.form['name'].value == 'test CT (copy)'
|
|
resp = resp.form.submit('submit').follow()
|
|
assert CommentTemplate.count() == 2
|
|
|
|
resp = app.get('/backoffice/workflows/comment-templates/1/')
|
|
resp = resp.click(href='duplicate')
|
|
assert resp.form['name'].value == 'test CT (copy 2)'
|
|
resp.form['name'].value = 'other copy'
|
|
resp = resp.form.submit('submit').follow()
|
|
assert CommentTemplate.count() == 3
|
|
assert {x.name for x in CommentTemplate.select()} == {'test CT', 'test CT (copy)', 'other copy'}
|
|
assert {x.slug for x in CommentTemplate.select()} == {'test-ct', 'test-ct-copy', 'other-copy'}
|
|
|
|
|
|
def export_to_indented_xml(comment_template, include_id=False):
|
|
comment_template_xml = comment_template.export_to_xml(include_id=include_id)
|
|
indent(comment_template_xml)
|
|
return comment_template_xml
|
|
|
|
|
|
def assert_import_export_works(comment_template, include_id=False):
|
|
comment_template2 = CommentTemplate.import_from_xml_tree(
|
|
ET.fromstring(ET.tostring(comment_template.export_to_xml(include_id))), include_id
|
|
)
|
|
assert ET.tostring(export_to_indented_xml(comment_template)) == ET.tostring(
|
|
export_to_indented_xml(comment_template2)
|
|
)
|
|
return comment_template2
|
|
|
|
|
|
def test_comment_template(pub):
|
|
comment_template = CommentTemplate(name='test')
|
|
assert_import_export_works(comment_template, include_id=True)
|
|
|
|
|
|
def test_comment_template_with_category(pub):
|
|
category = CommentTemplateCategory(name='test category')
|
|
category.store()
|
|
|
|
comment_template = CommentTemplate(name='test category')
|
|
comment_template.category_id = category.id
|
|
comment_template.store()
|
|
comment_template2 = assert_import_export_works(comment_template, include_id=True)
|
|
assert comment_template2.category_id == comment_template.category_id
|
|
|
|
# import with non existing category
|
|
CommentTemplateCategory.wipe()
|
|
export = ET.tostring(comment_template.export_to_xml(include_id=True))
|
|
comment_template3 = CommentTemplate.import_from_xml_tree(ET.fromstring(export), include_id=True)
|
|
assert comment_template3.category_id is None
|