wcs/tests/api/test_export_import.py

1179 lines
41 KiB
Python

import io
import json
import os
import tarfile
import xml.etree.ElementTree as ET
import pytest
from wcs.applications import Application, ApplicationElement
from wcs.blocks import BlockDef
from wcs.carddef import CardDef
from wcs.categories import (
BlockCategory,
CardDefCategory,
Category,
CommentTemplateCategory,
DataSourceCategory,
MailTemplateCategory,
WorkflowCategory,
)
from wcs.comment_templates import CommentTemplate
from wcs.data_sources import NamedDataSource
from wcs.fields import BlockField, CommentField, ComputedField, PageField, StringField
from wcs.formdef import FormDef
from wcs.mail_templates import MailTemplate
from wcs.sql import Equal
from wcs.wf.form import WorkflowFormFieldsFormDef
from wcs.workflows import Workflow, WorkflowBackofficeFieldsFormDef, WorkflowVariablesFieldsFormDef
from wcs.wscalls import NamedWsCall
from ..utilities import clean_temporary_pub, create_temporary_pub, get_app
from .utils import sign_uri
@pytest.fixture
def pub():
pub = create_temporary_pub()
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
fd.write(
'''\
[api-secrets]
coucou = 1234
'''
)
Application.wipe()
ApplicationElement.wipe()
Category.wipe()
FormDef.wipe()
CardDefCategory.wipe()
CardDef.wipe()
BlockCategory.wipe()
BlockDef.wipe()
WorkflowCategory.wipe()
Workflow.wipe()
MailTemplateCategory.wipe()
MailTemplate.wipe()
CommentTemplateCategory.wipe()
CommentTemplate.wipe()
DataSourceCategory.wipe()
NamedDataSource.wipe()
NamedWsCall.wipe()
pub.custom_view_class.wipe()
return pub
def teardown_module(module):
clean_temporary_pub()
def test_export_import_index(pub):
get_app(pub).get('/api/export-import/', status=403)
resp = get_app(pub).get(sign_uri('/api/export-import/'))
assert resp.json['data'][0]['id'] == 'forms'
assert resp.json['data'][0]['text'] == 'Forms'
assert resp.json['data'][0]['urls']['list'] == 'http://example.net/api/export-import/forms/'
def test_export_import_list_forms(pub):
resp = get_app(pub).get(sign_uri('/api/export-import/forms/'))
assert not resp.json['data']
formdef = FormDef()
formdef.name = 'Test'
formdef.store()
resp = get_app(pub).get(sign_uri('/api/export-import/forms/'))
assert resp.json['data'][0]['id'] == 'test'
assert resp.json['data'][0]['text'] == 'Test'
assert resp.json['data'][0]['category'] is None
category = Category(name='Test')
category.store()
formdef.category = category
formdef.store()
resp = get_app(pub).get(sign_uri('/api/export-import/forms/'))
assert resp.json['data'][0]['id'] == 'test'
assert resp.json['data'][0]['text'] == 'Test'
assert resp.json['data'][0]['category'] == 'Test'
def test_export_import_list_404(pub):
get_app(pub).get(sign_uri('/api/export-import/xxx/'), status=404)
def test_export_import_form(pub):
formdef = FormDef()
formdef.name = 'Test'
formdef.store()
resp = get_app(pub).get(sign_uri('/api/export-import/forms/'))
resp = get_app(pub).get(sign_uri(resp.json['data'][0]['urls']['export']))
assert resp.text.startswith('<formdef ')
def test_export_import_form_404(pub):
get_app(pub).get(sign_uri('/api/export-import/xxx/plop/'), status=404)
get_app(pub).get(sign_uri('/api/export-import/forms/plop/'), status=404)
def test_export_import_form_dependencies_404(pub):
get_app(pub).get(sign_uri('/api/export-import/forms/plop/dependencies/'), status=404)
def test_export_import_dependencies(pub):
role = pub.role_class(name='Test role')
role.store()
role2 = pub.role_class(name='Second role')
role2.store()
role3 = pub.role_class(name='Third role')
role3.store()
wscall = NamedWsCall(name='Test')
wscall.store()
wscall = NamedWsCall(name='Test bis')
wscall.store()
wscall = NamedWsCall(name='Test ter')
wscall.store()
wscall = NamedWsCall(name='Test quater')
wscall.store()
wscall = NamedWsCall(name='Test quinquies')
wscall.store()
wscall = NamedWsCall(name='Test sexies')
wscall.store()
wscall = NamedWsCall(name='Test in computed field')
wscall.store()
carddef = CardDef()
carddef.name = 'Test'
carddef.store()
carddef = CardDef()
carddef.name = 'Test bis'
carddef.store()
carddef = CardDef()
carddef.name = 'Test ter'
carddef.store()
carddef = CardDef()
carddef.name = 'Test quater'
carddef.store()
formdef = FormDef()
formdef.name = 'Test bis'
formdef.store()
formdef = FormDef()
formdef.name = 'Test ter'
formdef.store()
formdef = FormDef()
formdef.name = 'Test quater'
formdef.store()
formdef = FormDef()
formdef.name = 'Test quinquies'
formdef.store()
formdef = FormDef()
formdef.name = 'Test'
formdef.store()
resp = get_app(pub).get(sign_uri('/api/export-import/forms/'))
resp = get_app(pub).get(sign_uri(resp.json['data'][0]['urls']['dependencies']))
assert not resp.json['data']
formdef.roles = ['logged-users']
formdef.backoffice_submission_roles = [role2.id]
formdef.workflow_roles = {'_receiver': role3.id}
formdef.store()
block = BlockDef(name='test')
block.store()
workflow = Workflow(name='test')
workflow.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(workflow)
workflow.backoffice_fields_formdef.fields = [
BlockField(id='bo1', label='test', block_slug='test'),
]
workflow.variables_formdef = WorkflowVariablesFieldsFormDef(workflow=workflow)
workflow.variables_formdef.fields = [StringField(label='Test', id='1')]
status = workflow.add_status('New')
action = status.add_action('form')
action.by = [role.id]
data_source = NamedDataSource(name='foobar')
data_source.store()
display_form = status.add_action('form', id='_x')
display_form.formdef = WorkflowFormFieldsFormDef(item=display_form)
display_form.formdef.fields.append(
StringField(
label='Test',
data_source={'type': 'foobar'},
prefill={'type': 'string', 'value': '{{ webservice.test_bis.plop }}'},
)
)
display_form.formdef.fields.append(
StringField(
label='Test',
data_source={'type': 'foobar'},
prefill={'type': 'string', 'value': '{{ webservice.unknown }}'},
)
)
display_form.formdef.fields.append(
StringField(
label='Test',
data_source={'type': 'foobar'},
prefill={'type': 'string', 'value': '{{ cards|objects:"unknown" }}'},
)
)
display_form.formdef.fields.append(
StringField(
label='Test',
data_source={'type': 'foobar'},
prefill={'type': 'string', 'value': '{{ cards|objects:"test-bis" }}'},
)
)
display_form.formdef.fields.append(
StringField(
label='Test',
data_source={'type': 'foobar'},
prefill={'type': 'string', 'value': '{{ forms|objects:"test-bis" }}'},
)
)
display_form.formdef.fields.append(
StringField(
label='Test',
data_source={'type': 'foobar'},
prefill={'type': 'string', 'value': '{{ forms|objects:"unknown" }}'},
)
)
send_mail = status.add_action('sendmail')
send_mail.to = [role.id]
send_mail.subject = '{{ webservice.test }}'
send_mail.body = '{{ cards|objects:"test" }} {{ forms|objects:"test-ter" }}'
send_mail.condition = {
'type': 'django',
'value': '{{ cards|objects:"test-ter" }} {{ webservice.test_ter }}',
}
register_comment = status.add_action('register-comment')
register_comment.to = [role.id]
register_comment.comment = (
'{{ cards|objects:"test-quater" }} {{ forms|objects:"test-quinquies" }} {{ webservice.test_sexies }}'
)
dispatch_auto = status.add_action('dispatch')
dispatch_auto.rules = [{'role_id': role.id, 'value': 'xxx'}]
status.add_action('dispatch') # unconfigured/manual dispatch
workflow.store()
formdef.fields = [
PageField(
id='0',
label='Page',
post_conditions=[
{
'condition': {
'type': 'django',
'value': '{{ cards|objects:"test-bis" }} {{ forms|objects:"test-quater" }} {{ webservice.test_quater }}',
},
'error_message': 'You shall not pass.',
}
],
),
BlockField(
id='1',
label='test',
block_slug='test',
condition={
'type': 'django',
'value': '{{ forms|objects:"test-bis" }} {{ webservice.test_quinquies }}',
},
),
CommentField(
id='2',
label='X {{ webservice.test }} X {{ cards|objects:"test" }} X {{ forms|objects:"test-ter" }} X',
),
ComputedField(
id='3',
label='computed field',
varname='computed_field',
value_template='{{ webservice.test_in_computed_field.xxx }}',
),
]
formdef.workflow = workflow
formdef.store()
resp = get_app(pub).get(sign_uri('/api/export-import/forms/'))
form_data = [d for d in resp.json['data'] if d['id'] == 'test']
resp = get_app(pub).get(sign_uri(form_data[0]['urls']['dependencies']))
assert {(x['id'], x['type']) for x in resp.json['data']} == {
('test', 'workflows'),
('test', 'blocks'),
('test', 'wscalls'),
('test_quater', 'wscalls'),
('test_quinquies', 'wscalls'),
('test_in_computed_field', 'wscalls'),
('test', 'cards'),
('test-bis', 'cards'),
('test-bis', 'forms'),
('test-ter', 'forms'),
('test-quater', 'forms'),
('second-role', 'roles'),
('third-role', 'roles'),
}
for dependency in resp.json['data']:
get_app(pub).get(sign_uri(dependency['urls']['export']))
resp = get_app(pub).get(sign_uri('/api/export-import/workflows/'))
resp = get_app(pub).get(sign_uri(resp.json['data'][0]['urls']['dependencies']))
assert {(x['id'], x['type']) for x in resp.json['data']} == {
('foobar', 'data-sources'),
('test', 'wscalls'),
('test_bis', 'wscalls'),
('test_ter', 'wscalls'),
('test_sexies', 'wscalls'),
('test', 'cards'),
('test-bis', 'cards'),
('test-ter', 'cards'),
('test-quater', 'cards'),
('test-ter', 'forms'),
('test-bis', 'forms'),
('test-quinquies', 'forms'),
('test', 'blocks'),
('test-role', 'roles'),
}
for dependency in resp.json['data']:
resp = get_app(pub).get(sign_uri(dependency['urls']['export']))
if 'test-role' in dependency['urls']['export']:
assert resp.json == {'name': 'Test role', 'slug': 'test-role', 'uuid': None}
assert resp.content_type == 'application/json'
else:
assert resp.content_type == 'text/xml'
mail_template = MailTemplate(name='test mail template')
mail_template.store()
send_mail.mail_template = mail_template.slug
comment_template = CommentTemplate(name='test comment template')
comment_template.store()
register_comment.comment_template = comment_template.slug
workflow.store()
resp = get_app(pub).get(sign_uri('/api/export-import/workflows/'))
resp = get_app(pub).get(sign_uri(resp.json['data'][0]['urls']['dependencies']))
assert {(x['id'], x['type']) for x in resp.json['data']} == {
('foobar', 'data-sources'),
('test_bis', 'wscalls'),
('test_ter', 'wscalls'),
('test-bis', 'cards'),
('test-ter', 'cards'),
('test-bis', 'forms'),
('test', 'blocks'),
('test-mail-template', 'mail-templates'),
('test-comment-template', 'comment-templates'),
('test-role', 'roles'),
}
for dependency in resp.json['data']:
get_app(pub).get(sign_uri(dependency['urls']['export']))
resp = get_app(pub).get(sign_uri(resp.json['data'][-1]['urls']['dependencies']))
assert resp.json['data'] == []
cat = MailTemplateCategory(name='Cat')
cat.store()
mail_template.category_id = cat.id
mail_template.subject = '{{ webservice.test }}'
mail_template.body = '{{ cards|objects:"test" }} {{ forms|objects:"test-ter" }}'
mail_template.store()
resp = get_app(pub).get(sign_uri('/api/export-import/workflows/'))
resp = get_app(pub).get(sign_uri(resp.json['data'][0]['urls']['dependencies']))
mail_template_entry = [x for x in resp.json['data'] if x['type'] == 'mail-templates'][0]
resp = get_app(pub).get(sign_uri(mail_template_entry['urls']['dependencies']))
assert {(x['id'], x['type']) for x in resp.json['data']} == {
('cat', 'mail-templates-categories'),
('test', 'cards'),
('test', 'wscalls'),
('test-ter', 'forms'),
}
for dependency in resp.json['data']:
get_app(pub).get(sign_uri(dependency['urls']['export']))
cat = CommentTemplateCategory(name='Cat')
cat.store()
comment_template.category_id = cat.id
comment_template.comment = (
'{{ cards|objects:"test-quater" }} {{ forms|objects:"test-quinquies" }} {{ webservice.test_sexies }}'
)
comment_template.store()
resp = get_app(pub).get(sign_uri('/api/export-import/workflows/'))
resp = get_app(pub).get(sign_uri(resp.json['data'][0]['urls']['dependencies']))
comment_template_entry = [x for x in resp.json['data'] if x['type'] == 'comment-templates'][0]
resp = get_app(pub).get(sign_uri(comment_template_entry['urls']['dependencies']))
assert {(x['id'], x['type']) for x in resp.json['data']} == {
('cat', 'comment-templates-categories'),
('test-quater', 'cards'),
('test-quinquies', 'forms'),
('test_sexies', 'wscalls'),
}
for dependency in resp.json['data']:
get_app(pub).get(sign_uri(dependency['urls']['export']))
resp = get_app(pub).get(sign_uri('/api/export-import/workflows/'))
resp = get_app(pub).get(sign_uri(resp.json['data'][0]['urls']['dependencies']))
resp = get_app(pub).get(sign_uri(resp.json['data'][1]['urls']['dependencies']))
assert resp.json['data'] == []
cat = DataSourceCategory(name='Cat')
cat.store()
data_source.category_id = cat.id
data_source.store()
resp = get_app(pub).get(sign_uri('/api/export-import/workflows/'))
resp = get_app(pub).get(sign_uri(resp.json['data'][0]['urls']['dependencies']))
data_sources_entry = [x for x in resp.json['data'] if x['type'] == 'data-sources'][0]
resp = get_app(pub).get(sign_uri(data_sources_entry['urls']['dependencies']))
assert {(x['id'], x['type']) for x in resp.json['data']} == {('cat', 'data-sources-categories')}
def test_export_import_dependencies_default_workflow(pub):
formdef = FormDef()
formdef.name = 'Test'
formdef.workflow_id = '_default'
formdef.store()
carddef = CardDef()
carddef.name = 'Test'
carddef.workflow_id = '_carddef_default'
carddef.store()
resp = get_app(pub).get(sign_uri('/api/export-import/forms/'))
resp = get_app(pub).get(sign_uri(resp.json['data'][0]['urls']['dependencies']))
assert resp.json['data'] == []
resp = get_app(pub).get(sign_uri('/api/export-import/cards/'))
resp = get_app(pub).get(sign_uri(resp.json['data'][0]['urls']['dependencies']))
assert resp.json['data'] == []
def test_export_import_redirect_url(pub):
workflow = Workflow(name='test')
workflow.store()
block = BlockDef(name='test')
block.store()
formdef = FormDef()
formdef.name = 'Test'
formdef.store()
carddef = CardDef()
carddef.name = 'Test'
carddef.store()
category = Category(name='Test')
category.store()
data_source = NamedDataSource(name='Test')
data_source.store()
ds_category = DataSourceCategory(name='Test')
ds_category.store()
mail_template = MailTemplate(name='Test')
mail_template.store()
mail_template_category = MailTemplateCategory(name='Test')
mail_template_category.store()
comment_template = CommentTemplate(name='Test')
comment_template.store()
comment_template_category = CommentTemplateCategory(name='Test')
comment_template_category.store()
elements = [
('forms', '/backoffice/forms/%s/' % formdef.id),
('cards', '/backoffice/cards/%s/' % carddef.id),
('blocks', '/backoffice/forms/blocks/%s/' % block.id),
('workflows', '/backoffice/workflows/%s/' % workflow.id),
('forms-categories', '/backoffice/forms/categories/%s/' % category.id),
('data-sources', '/backoffice/settings/data-sources/%s/' % data_source.id),
(
'data-sources-categories',
'/backoffice/forms/data-sources/categories/%s/' % ds_category.id,
),
('mail-templates', '/backoffice/workflows/mail-templates/%s/' % mail_template.id),
(
'mail-templates-categories',
'/backoffice/workflows/mail-templates/categories/%s/' % mail_template_category.id,
),
('comment-templates', '/backoffice/workflows/comment-templates/%s/' % comment_template.id),
(
'comment-templates-categories',
'/backoffice/workflows/comment-templates/categories/%s/' % comment_template_category.id,
),
]
for object_type, obj_url in elements:
resp = get_app(pub).get(sign_uri('/api/export-import/%s/' % object_type))
assert (
resp.json['data'][0]['urls']['redirect']
== 'http://example.net/api/export-import/%s/test/redirect/' % object_type
)
resp = get_app(pub).get(resp.json['data'][0]['urls']['redirect'], status=302)
assert resp.location == 'http://example.net%s' % obj_url
get_app(pub).get('/api/export-import/%s/unknown/redirect/' % object_type, status=404)
role = pub.role_class(name='test')
role.store()
resp = get_app(pub).get(sign_uri('/api/export-import/roles/'))
assert resp.json['data'][0]['urls'].get('redirect') is None
get_app(pub).get('/api/export-import/roles/test/redirect/', status=404)
def create_bundle(elements, *args, **kwargs):
visible = kwargs.get('visible', True)
tar_io = io.BytesIO()
with tarfile.open(mode='w', fileobj=tar_io) as tar:
manifest_json = {
'application': 'Test',
'slug': 'test',
'icon': 'foo.png',
'description': 'Foo Bar',
'documentation_url': 'http://foo.bar',
'visible': visible,
'version_number': '42.0',
'version_notes': 'foo bar blah',
'elements': elements,
}
manifest_fd = io.BytesIO(json.dumps(manifest_json, indent=2).encode())
tarinfo = tarfile.TarInfo('manifest.json')
tarinfo.size = len(manifest_fd.getvalue())
tar.addfile(tarinfo, fileobj=manifest_fd)
icon_fd = io.BytesIO(
b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='
)
tarinfo = tarfile.TarInfo('foo.png')
tarinfo.size = len(icon_fd.getvalue())
tar.addfile(tarinfo, fileobj=icon_fd)
for path, obj in args:
tarinfo = tarfile.TarInfo(path)
if hasattr(obj, 'export_for_application'):
export, _ = obj.export_for_application()
export = export.encode()
else:
export = ET.tostring(obj.export_to_xml(include_id=True))
tarinfo.size = len(export)
tar.addfile(tarinfo, fileobj=io.BytesIO(export))
return tar_io.getvalue()
def test_export_import_bundle_import(pub):
workflow_category = WorkflowCategory(name='test')
workflow_category.store()
workflow = Workflow(name='test')
workflow.roles = {'_receiver': 'Receiver'}
workflow.category = workflow_category
workflow.store()
block_category = BlockCategory(name='test')
block_category.store()
block = BlockDef(name='test')
block.category = block_category
block.store()
role = pub.role_class(name='test')
role.store()
category = Category(name='Test')
category.store()
formdef = FormDef()
formdef.name = 'Test'
formdef.fields = [
BlockField(id='1', label='test', block_slug='test'),
]
formdef.workflow = workflow
formdef.workflow_roles = {'_receiver': role.id}
formdef.disabled = False
formdef.category = category
formdef.store()
custom_view = pub.custom_view_class()
custom_view.title = 'shared formdef custom view'
custom_view.formdef = formdef
custom_view.columns = {'list': [{'id': '1'}]}
custom_view.filters = {}
custom_view.visibility = 'any'
custom_view.store()
card_category = CardDefCategory(name='Test')
card_category.store()
carddef = CardDef()
carddef.name = 'Test'
carddef.category = card_category
carddef.store()
ds_category = DataSourceCategory(name='Test')
ds_category.store()
data_source = NamedDataSource(name='Test')
data_source.category = ds_category
data_source.store()
mail_template_category = MailTemplateCategory(name='Test')
mail_template_category.store()
mail_template = MailTemplate(name='Test')
mail_template.category = mail_template_category
mail_template.store()
comment_template_category = CommentTemplateCategory(name='Test')
comment_template_category.store()
comment_template = CommentTemplate(name='Test')
comment_template.category = comment_template_category
comment_template.store()
wscall = NamedWsCall(name='Test')
wscall.store()
bundle = create_bundle(
[
{'type': 'forms-categories', 'slug': 'test', 'name': 'test'},
{'type': 'forms', 'slug': 'test', 'name': 'test'},
{'type': 'cards-categories', 'slug': 'test', 'name': 'test'},
{'type': 'cards', 'slug': 'test', 'name': 'test'},
{'type': 'blocks-categories', 'slug': 'test', 'name': 'test'},
{'type': 'blocks', 'slug': 'test', 'name': 'test'},
{'type': 'roles', 'slug': 'test', 'name': 'test'},
{'type': 'workflows-categories', 'slug': 'test', 'name': 'test'},
{'type': 'workflows', 'slug': 'test', 'name': 'test'},
{'type': 'mail-templates-categories', 'slug': 'test', 'name': 'test'},
{'type': 'mail-templates', 'slug': 'test', 'name': 'test'},
{'type': 'comment-templates-categories', 'slug': 'test', 'name': 'test'},
{'type': 'comment-templates', 'slug': 'test', 'name': 'test'},
{'type': 'data-sources-categories', 'slug': 'test', 'name': 'test'},
{'type': 'data-sources', 'slug': 'test', 'name': 'test'},
{'type': 'wscalls', 'slug': 'test', 'name': 'test'},
],
('forms-categories/test', category),
('forms/test', formdef),
('cards-categories/test', card_category),
('cards/test', carddef),
('blocks-categories/test', block_category),
('blocks/test', block),
('workflows-categories/test', workflow_category),
('workflows/test', workflow),
('data-sources-categories/test', ds_category),
('data-sources/test', data_source),
('mail-templates-categories/test', mail_template_category),
('mail-templates/test', mail_template),
('comment-templates-categories/test', comment_template_category),
('comment-templates/test', comment_template),
('roles/test', role),
('wscalls/test', wscall),
)
Category.wipe()
FormDef.wipe()
CardDefCategory.wipe()
CardDef.wipe()
BlockCategory.wipe()
BlockDef.wipe()
WorkflowCategory.wipe()
Workflow.wipe()
MailTemplateCategory.wipe()
MailTemplate.wipe()
CommentTemplateCategory.wipe()
CommentTemplate.wipe()
DataSourceCategory.wipe()
NamedDataSource.wipe()
pub.role_class.wipe()
pub.custom_view_class.wipe()
NamedWsCall.wipe()
# roles will be created beforehand with authentic provisionning
extra_role = pub.role_class(name='not this one')
extra_role.store()
role = pub.role_class(name='test')
role.store()
resp = get_app(pub).put(sign_uri('/api/export-import/bundle-import/'), bundle)
afterjob_url = resp.json['url']
resp = get_app(pub).put(sign_uri(afterjob_url))
assert resp.json['data']['status'] == 'completed'
assert resp.json['data']['completion_status'] == '19/19 (100%)'
assert Category.count() == 1
assert FormDef.count() == 1
assert FormDef.select()[0].fields[0].key == 'block'
assert FormDef.select()[0].fields[0].block_slug == 'test'
assert FormDef.select()[0].workflow_roles == {'_receiver': role.id}
assert FormDef.select()[0].category_id == Category.select()[0].id
assert CardDefCategory.count() == 1
assert CardDef.count() == 1
assert CardDef.select()[0].category_id == CardDefCategory.select()[0].id
assert BlockCategory.count() == 1
assert BlockDef.count() == 1
assert BlockDef.select()[0].category_id == BlockCategory.select()[0].id
assert WorkflowCategory.count() == 1
assert Workflow.count() == 1
assert Workflow.select()[0].category_id == WorkflowCategory.select()[0].id
assert MailTemplateCategory.count() == 1
assert MailTemplate.count() == 1
assert MailTemplate.select()[0].category_id == MailTemplateCategory.select()[0].id
assert CommentTemplateCategory.count() == 1
assert CommentTemplate.count() == 1
assert CommentTemplate.select()[0].category_id == CommentTemplateCategory.select()[0].id
assert DataSourceCategory.count() == 1
assert NamedDataSource.count() == 1
assert NamedDataSource.select()[0].category_id == DataSourceCategory.select()[0].id
assert NamedWsCall.count() == 1
assert pub.custom_view_class().count() == 1
assert Application.count() == 1
application = Application.select()[0]
assert application.slug == 'test'
assert application.name == 'Test'
assert application.description == 'Foo Bar'
assert application.documentation_url == 'http://foo.bar'
assert application.version_number == '42.0'
assert application.version_notes == 'foo bar blah'
assert application.icon.base_filename == 'foo.png'
assert application.editable is False
assert application.visible is True
assert ApplicationElement.count() == 15
# check editable flag is kept on install
application.editable = False
application.store()
# create some links to elements not present in manifest: they should be unlinked
element1 = ApplicationElement()
element1.application_id = application.id
element1.object_type = 'foobar'
element1.object_id = '42'
element1.store()
element2 = ApplicationElement()
element2.application_id = application.id
element2.object_type = 'foobarblah'
element2.object_id = '35'
element2.store()
# run new import to check it doesn't duplicate objects
resp = get_app(pub).put(sign_uri('/api/export-import/bundle-import/'), bundle)
afterjob_url = resp.json['url']
resp = get_app(pub).put(sign_uri(afterjob_url))
assert resp.json['data']['status'] == 'completed'
assert Category.count() == 1
assert FormDef.count() == 1
assert CardDefCategory.count() == 1
assert CardDef.count() == 1
assert BlockCategory.count() == 1
assert BlockDef.count() == 1
assert WorkflowCategory.count() == 1
assert Workflow.count() == 1
assert MailTemplateCategory.count() == 1
assert MailTemplate.count() == 1
assert CommentTemplateCategory.count() == 1
assert CommentTemplate.count() == 1
assert DataSourceCategory.count() == 1
assert NamedDataSource.count() == 1
assert pub.custom_view_class().count() == 1
assert NamedWsCall.count() == 1
assert Application.count() == 1
assert ApplicationElement.count() == 15
assert (
ApplicationElement.select(
[
Equal('application_id', application.id),
Equal('object_type', element1.object_type),
Equal('object_id', element1.object_id),
]
)
== []
)
assert (
ApplicationElement.select(
[
Equal('application_id', application.id),
Equal('object_type', element2.object_type),
Equal('object_id', element2.object_id),
]
)
== []
)
application = Application.select()[0]
assert application.editable is False
# change immutable attributes and check they are not reset
formdef = FormDef.select()[0]
formdef.workflow_roles = {'_receiver': extra_role.id}
formdef.disabled = True
formdef.store()
resp = get_app(pub).put(sign_uri('/api/export-import/bundle-import/'), bundle)
afterjob_url = resp.json['url']
resp = get_app(pub).put(sign_uri(afterjob_url))
assert resp.json['data']['status'] == 'completed'
formdef = FormDef.select()[0]
assert formdef.disabled is True
assert formdef.workflow_roles == {'_receiver': extra_role.id}
def test_export_import_formdef_do_not_overwrite_table_name(pub):
formdef = FormDef()
formdef.name = 'Test2'
formdef.fields = []
formdef.disabled = False
formdef.store()
assert formdef.table_name == 'formdata_%s_test2' % formdef.id
formdata = formdef.data_class()()
formdata.just_created()
formdata.store()
# change formdef url name, internal table name won't be changed
formdef.url_name = 'test'
formdef.store()
assert formdef.table_name == 'formdata_%s_test2' % formdef.id
assert formdef.data_class().count() == 1
bundle = create_bundle([{'type': 'forms', 'slug': 'test', 'name': 'test'}], ('forms/test', formdef))
resp = get_app(pub).put(sign_uri('/api/export-import/bundle-import/'), bundle)
afterjob_url = resp.json['url']
resp = get_app(pub).put(sign_uri(afterjob_url))
assert resp.json['data']['status'] == 'completed'
# check table name is not overwritten
formdef = FormDef.select()[0]
assert formdef.table_name == 'formdata_%s_test2' % formdef.id
assert formdef.data_class().count() == 1
def test_export_import_bundle_declare(pub):
workflow_category = WorkflowCategory(name='test')
workflow_category.store()
workflow = Workflow(name='test')
workflow.store()
block_category = BlockCategory(name='test')
block_category.store()
block = BlockDef(name='test')
block.store()
role = pub.role_class(name='test')
role.store()
category = Category(name='Test')
category.store()
formdef = FormDef()
formdef.name = 'Test'
formdef.store()
card_category = CardDefCategory(name='Test')
card_category.store()
carddef = CardDef()
carddef.name = 'Test'
carddef.store()
ds_category = DataSourceCategory(name='Test')
ds_category.store()
data_source = NamedDataSource(name='Test')
data_source.store()
mail_template_category = MailTemplateCategory(name='Test')
mail_template_category.store()
mail_template = MailTemplate(name='Test')
mail_template.store()
comment_template_category = CommentTemplateCategory(name='Test')
comment_template_category.store()
comment_template = CommentTemplate(name='Test')
comment_template.store()
wscall = NamedWsCall(name='Test')
wscall.store()
bundle = create_bundle(
[
{'type': 'forms-categories', 'slug': 'test', 'name': 'test'},
{'type': 'forms', 'slug': 'test', 'name': 'test'},
{'type': 'cards-categories', 'slug': 'test', 'name': 'test'},
{'type': 'cards', 'slug': 'test', 'name': 'test'},
{'type': 'blocks-categories', 'slug': 'test', 'name': 'test'},
{'type': 'blocks', 'slug': 'test', 'name': 'test'},
{'type': 'roles', 'slug': 'test', 'name': 'test'},
{'type': 'workflows-categories', 'slug': 'test', 'name': 'test'},
{'type': 'workflows', 'slug': 'test', 'name': 'test'},
{'type': 'mail-templates-categories', 'slug': 'test', 'name': 'test'},
{'type': 'mail-templates', 'slug': 'test', 'name': 'test'},
{'type': 'comment-templates-categories', 'slug': 'test', 'name': 'test'},
{'type': 'comment-templates', 'slug': 'test', 'name': 'test'},
{'type': 'data-sources-categories', 'slug': 'test', 'name': 'test'},
{'type': 'data-sources', 'slug': 'test', 'name': 'test'},
{'type': 'data-sources', 'slug': 'unknown', 'name': 'unknown'},
{'type': 'wscalls', 'slug': 'test', 'name': 'test'},
],
('forms-categories/test', category),
('forms/test', formdef),
('cards-categories/test', card_category),
('cards/test', carddef),
('blocks-categories/test', block_category),
('blocks/test', block),
('workflows-categories/test', workflow_category),
('workflows/test', workflow),
('data-sources-categories/test', ds_category),
('data-sources/test', data_source),
('data-sources/unknown', data_source),
('mail-templates-categories/test', mail_template_category),
('mail-templates/test', mail_template),
('comment-templates-categories/test', comment_template_category),
('comment-templates/test', comment_template),
('roles/test', role),
('wscalls/test', wscall),
visible=False,
)
resp = get_app(pub).put(sign_uri('/api/export-import/bundle-declare/'), bundle)
afterjob_url = resp.json['url']
resp = get_app(pub).put(sign_uri(afterjob_url))
assert resp.json['data']['status'] == 'completed'
assert resp.json['data']['completion_status'] == '16/16 (100%)'
assert Application.count() == 1
application = Application.select()[0]
assert application.slug == 'test'
assert application.name == 'Test'
assert application.description == 'Foo Bar'
assert application.documentation_url == 'http://foo.bar'
assert application.version_number == '42.0'
assert application.version_notes == 'foo bar blah'
assert application.icon.base_filename == 'foo.png'
assert application.editable is True
assert application.visible is False
assert ApplicationElement.count() == 15
# create some links to elements not present in manifest: they should be unlinked
element1 = ApplicationElement()
element1.application_id = application.id
element1.object_type = 'foobar'
element1.object_id = '42'
element1.store()
element2 = ApplicationElement()
element2.application_id = application.id
element2.object_type = 'foobarblah'
element2.object_id = '35'
element2.store()
# and remove an object to have an unkown reference in manifest
MailTemplate.wipe()
resp = get_app(pub).put(sign_uri('/api/export-import/bundle-declare/'), bundle)
afterjob_url = resp.json['url']
resp = get_app(pub).put(sign_uri(afterjob_url))
assert resp.json['data']['status'] == 'completed'
assert Application.count() == 1
assert ApplicationElement.count() == 14
assert (
ApplicationElement.select(
[
Equal('application_id', application.id),
Equal('object_type', element1.object_type),
Equal('object_id', element1.object_id),
]
)
== []
)
assert (
ApplicationElement.select(
[
Equal('application_id', application.id),
Equal('object_type', element2.object_type),
Equal('object_id', element2.object_id),
]
)
== []
)
assert (
ApplicationElement.select(
[
Equal('application_id', application.id),
Equal('object_type', MailTemplate.xml_root_node),
]
)
== []
)
def test_export_import_bundle_unlink(pub):
application = Application()
application.slug = 'test'
application.name = 'Test'
application.version_number = 'foo'
application.store()
other_application = Application()
other_application.slug = 'other-test'
other_application.name = 'Other Test'
other_application.version_number = 'foo'
other_application.store()
workflow_category = WorkflowCategory(name='test')
workflow_category.store()
ApplicationElement.update_or_create_for_object(application, workflow_category)
workflow = Workflow(name='test')
workflow.store()
ApplicationElement.update_or_create_for_object(application, workflow)
block_category = BlockCategory(name='test')
block_category.store()
ApplicationElement.update_or_create_for_object(application, block_category)
block = BlockDef(name='test')
block.store()
ApplicationElement.update_or_create_for_object(application, block)
category = Category(name='Test')
category.store()
ApplicationElement.update_or_create_for_object(application, category)
formdef = FormDef()
formdef.name = 'Test'
formdef.store()
ApplicationElement.update_or_create_for_object(application, formdef)
card_category = CardDefCategory(name='Test')
card_category.store()
ApplicationElement.update_or_create_for_object(application, card_category)
carddef = CardDef()
carddef.name = 'Test'
carddef.store()
ApplicationElement.update_or_create_for_object(application, carddef)
ds_category = DataSourceCategory(name='Test')
ds_category.store()
ApplicationElement.update_or_create_for_object(application, ds_category)
data_source = NamedDataSource(name='Test')
data_source.store()
ApplicationElement.update_or_create_for_object(application, data_source)
mail_template_category = MailTemplateCategory(name='Test')
mail_template_category.store()
ApplicationElement.update_or_create_for_object(application, mail_template_category)
mail_template = MailTemplate(name='Test')
mail_template.store()
ApplicationElement.update_or_create_for_object(application, mail_template)
comment_template_category = CommentTemplateCategory(name='Test')
comment_template_category.store()
ApplicationElement.update_or_create_for_object(application, comment_template_category)
comment_template = CommentTemplate(name='Test')
comment_template.store()
ApplicationElement.update_or_create_for_object(application, comment_template)
wscall = NamedWsCall(name='Test')
wscall.store()
ApplicationElement.update_or_create_for_object(application, wscall)
element = ApplicationElement()
element.application_id = application.id
element.object_type = 'foobar'
element.object_id = '42'
element.store()
other_element = ApplicationElement()
other_element.application_id = other_application.id
other_element.object_type = 'foobar'
other_element.object_id = '42'
other_element.store()
assert Application.count() == 2
assert ApplicationElement.count() == 17
get_app(pub).post(sign_uri('/api/export-import/unlink/'), {'application': 'test'})
assert Application.count() == 1
assert ApplicationElement.count() == 1
assert (
Application.count(
[
Equal('id', other_application.id),
]
)
== 1
)
assert (
ApplicationElement.count(
[
Equal('application_id', other_application.id),
]
)
== 1
)
# again
get_app(pub).post(sign_uri('/api/export-import/unlink/'), {'application': 'test'})
assert Application.count() == 1
assert ApplicationElement.count() == 1
def test_export_import_workflow_options(pub):
FormDef.wipe()
Workflow.wipe()
workflow = Workflow(name='variables')
workflow.variables_formdef = WorkflowVariablesFieldsFormDef(workflow=workflow)
workflow.variables_formdef.fields = [
StringField(id='1', label='Test', varname='foo'),
]
workflow.store()
formdef = FormDef()
formdef.name = 'foo'
formdef.workflow = workflow
formdef.workflow_options = {'foo': 'bar'}
formdef.store()
bundle = create_bundle(
[
{'type': 'forms', 'slug': 'foo', 'name': 'foo'},
{'type': 'workflows', 'slug': 'variables', 'name': 'variables'},
],
('forms/foo', formdef),
('workflows/variables', workflow),
)
FormDef.wipe()
Workflow.wipe()
resp = get_app(pub).put(sign_uri('/api/export-import/bundle-import/'), bundle)
afterjob_url = resp.json['url']
resp = get_app(pub).put(sign_uri(afterjob_url))
assert resp.json['data']['status'] == 'completed'
assert resp.json['data']['completion_status'] == '4/4 (100%)'
# check workflow options are set on first install
formdef = FormDef.get_by_slug('foo')
assert formdef.workflow_options == {'foo': 'bar'}
# check workflow options are not reset on further installs
formdef.workflow_options = {'foo': 'bar2'}
formdef.store()
resp = get_app(pub).put(sign_uri('/api/export-import/bundle-import/'), bundle)
afterjob_url = resp.json['url']
resp = get_app(pub).put(sign_uri(afterjob_url))
assert resp.json['data']['status'] == 'completed'
formdef = FormDef.get_by_slug('foo')
assert formdef.workflow_options == {'foo': 'bar2'}