wcs/tests/api/test_export_import.py

319 lines
11 KiB
Python

import io
import json
import os
import tarfile
import xml.etree.ElementTree as ET
import pytest
from wcs.blocks import BlockDef
from wcs.categories import Category, DataSourceCategory, MailTemplateCategory
from wcs.data_sources import NamedDataSource
from wcs.fields import BlockField, StringField
from wcs.formdef import FormDef
from wcs.mail_templates import MailTemplate
from wcs.wf.form import WorkflowFormFieldsFormDef
from wcs.workflows import Workflow, WorkflowBackofficeFieldsFormDef, WorkflowVariablesFieldsFormDef
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
'''
)
Category.wipe()
FormDef.wipe()
BlockDef.wipe()
Workflow.wipe()
MailTemplate.wipe()
MailTemplateCategory.wipe()
NamedDataSource.wipe()
DataSourceCategory.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'
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):
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']
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', type='block:test'),
]
workflow.variables_formdef = WorkflowVariablesFieldsFormDef(workflow=workflow)
workflow.variables_formdef.fields = [StringField(label='Test', id='1')]
status = workflow.add_status('New')
status.add_action('form')
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'}))
send_mail = status.add_action('sendmail')
workflow.store()
formdef.fields = [
BlockField(id='1', label='test', type='block:test'),
]
formdef.workflow = workflow
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 resp.json['data']
assert {(x['id'], x['type']) for x in resp.json['data']} == {('test', 'workflows'), ('test', 'blocks')}
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 resp.json['data']
assert {(x['id'], x['type']) for x in resp.json['data']} == {
('foobar', 'data-sources'),
('test', 'blocks'),
}
mail_template = MailTemplate(name='test mail template')
mail_template.store()
send_mail.mail_template = mail_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 resp.json['data']
assert {(x['id'], x['type']) for x in resp.json['data']} == {
('foobar', 'data-sources'),
('test', 'blocks'),
('test-mail-template', 'mail-templates'),
}
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.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']))
resp = get_app(pub).get(sign_uri(resp.json['data'][-1]['urls']['dependencies']))
assert resp.json['data']
assert {(x['id'], x['type']) for x in resp.json['data']} == {('cat', 'mail-templates-categories')}
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']))
resp = get_app(pub).get(sign_uri(resp.json['data'][1]['urls']['dependencies']))
assert {(x['id'], x['type']) for x in resp.json['data']} == {('cat', 'data-sources-categories')}
def create_bundle(*args):
tar_io = io.BytesIO()
with tarfile.open(mode='w', fileobj=tar_io) as tar:
manifest_json = {
'application': 'Test',
'slug': 'test',
'description': '',
'elements': [
{'type': 'forms', 'slug': 'test', 'name': 'test'},
{'type': 'blocks', 'slug': 'test', 'name': 'test'},
{'type': 'workflows', 'slug': 'test', 'name': 'test'},
{'type': 'forms-categories', 'slug': 'test', 'name': 'test'},
{'type': 'mail-templates-categories', 'slug': 'test', 'name': 'test'},
{'type': 'mail-templates', 'slug': 'test', 'name': 'test'},
{'type': 'data-sources', 'slug': 'test', 'name': 'test'},
{'type': 'data-sources-categories', 'slug': 'test', 'name': 'test'},
],
}
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)
for (path, obj) in args:
tarinfo = tarfile.TarInfo(path)
xml_export = ET.tostring(obj.export_to_xml(include_id=True))
tarinfo.size = len(xml_export)
tar.addfile(tarinfo, fileobj=io.BytesIO(xml_export))
return tar_io.getvalue()
def test_export_import_bundle_import(pub):
workflow = Workflow(name='test')
workflow.store()
block = BlockDef(name='test')
block.store()
formdef = FormDef()
formdef.name = 'Test'
formdef.fields = [
BlockField(id='1', label='test', type='block:test'),
]
formdef.workflow = workflow
formdef.disabled = False
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()
category = Category(name='Test')
category.store()
data_source = NamedDataSource(name='Test')
data_source.store()
category = DataSourceCategory(name='Test')
category.store()
mail_template = MailTemplate(name='Test')
mail_template.store()
mail_template_category = MailTemplateCategory(name='Test')
mail_template_category.store()
bundle = create_bundle(
('forms/test', formdef),
('blocks/test', block),
('workflows/test', workflow),
('forms-categories/test', category),
('data-sources/test', data_source),
('data-sources-categories/test', category),
('mail-templates/test', mail_template),
('mail-templates-categories/test', mail_template_category),
)
Category.wipe()
FormDef.wipe()
BlockDef.wipe()
Workflow.wipe()
MailTemplate.wipe()
MailTemplateCategory.wipe()
NamedDataSource.wipe()
DataSourceCategory.wipe()
pub.custom_view_class.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 Category.count() == 1
assert FormDef.count() == 1
assert BlockDef.count() == 1
assert Workflow.count() == 1
assert MailTemplate.count() == 1
assert MailTemplateCategory.count() == 1
assert NamedDataSource.count() == 1
assert DataSourceCategory.count() == 1
assert FormDef.select()[0].fields[0].type == 'block:test'
assert pub.custom_view_class().count() == 1
# 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 BlockDef.count() == 1
assert Workflow.count() == 1
assert MailTemplate.count() == 1
assert MailTemplateCategory.count() == 1
assert NamedDataSource.count() == 1
assert DataSourceCategory.count() == 1
assert pub.custom_view_class().count() == 1
# change immutable attribute and check it's not reset
formdef = FormDef.select()[0]
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