wcs/tests/admin_pages/test_i18n.py

362 lines
12 KiB
Python

import io
import zipfile
import pytest
from webtest import Upload
from wcs.blocks import BlockDef
from wcs.carddef import CardDef
from wcs.categories import Category
from wcs.fields import ItemField, StringField
from wcs.formdef import FormDef
from wcs.i18n import TranslatableMessage
from wcs.mail_templates import MailTemplate
from wcs.qommon import ods
from wcs.qommon.http_request import HTTPRequest
from wcs.sql import Equal
from wcs.workflows import Workflow
from ..utilities import clean_temporary_pub, create_temporary_pub, get_app, login
from .test_all import create_superuser
@pytest.fixture
def pub():
pub = create_temporary_pub()
req = HTTPRequest(None, {'SCRIPT_NAME': '/', 'SERVER_NAME': 'example.net'})
pub.set_app_dir(req)
pub.cfg['identification'] = {'methods': ['password']}
pub.cfg['language'] = {'language': 'en', 'multilinguism': True, 'languages': ['en', 'fr']}
pub.write_cfg()
TranslatableMessage.do_table()
return pub
def teardown_module(module):
clean_temporary_pub()
def test_i18n_link_on_studio_page(pub):
create_superuser(pub)
app = login(get_app(pub))
resp = app.get('/backoffice/studio/')
assert '../i18n/' in resp.text
pub.cfg['language']['multilinguism'] = False
pub.write_cfg()
resp = app.get('/backoffice/studio/')
assert '../i18n/' not in resp.text
app.get('/backoffice/i18n/', status=404)
def test_i18n_page(pub):
workflow = Workflow(name='workflow')
st = workflow.add_status('First Status')
sendmail = st.add_action('sendmail')
sendmail.to = ['_submitter']
sendmail.subject = 'Email Subject'
sendmail.body = 'Email body'
workflow.store()
formdef = FormDef()
formdef.name = 'test title'
formdef.fields = [
StringField(id='1', label='text field', type='string'),
StringField(id='2', label='text field', type='string'),
ItemField(id='3', label='list field', type='item', items=['first', 'second', 'third']),
]
formdef.workflow = workflow
formdef.store()
block = BlockDef(name='test')
# check strings will be stripped
block.fields = [StringField(id='1', label='text field ', type='string')]
block.store()
carddef = CardDef()
carddef.name = 'card test'
carddef.store()
category = Category(name='Category Name')
category.store()
mail_template = MailTemplate(name='test mail template')
mail_template.subject = 'test subject'
mail_template.body = 'test body'
mail_template.store()
app = login(get_app(pub))
# first time goes to scanning
resp = app.get('/backoffice/i18n/', status=302)
resp = resp.follow()
resp = resp.click('Go to multilinguism page')
# second time, the page stays on
resp = app.get('/backoffice/i18n/', status=200)
# relaunch scan
resp = resp.click('Rescan')
resp = resp.follow()
resp = resp.click('Go to multilinguism page')
# check 'text field' only appears one
assert TranslatableMessage.count([Equal('string', 'text field')]) == 1
# check table
assert resp.pyquery('tr').length == TranslatableMessage.count()
# check form filter
assert resp.form['lang'].value == 'fr'
resp.form['q'] = 'Email'
resp = resp.form.submit()
assert resp.pyquery('tr').length == 2 # (email subject, email body)
# translate a message
resp = resp.click('edit', index=0)
resp = resp.form.submit('cancel').follow()
resp = resp.click('edit', index=0)
assert resp.pyquery('.i18n-orig-string').text() == 'Email body'
resp.form['translation'] = 'Texte du courriel'
resp = resp.form.submit('submit').follow()
msg = TranslatableMessage.select([Equal('string', 'Email body')])[0]
assert msg.string_fr == 'Texte du courriel'
# go back
resp = resp.click('edit', index=0)
assert resp.form['translation'].value == 'Texte du courriel'
resp = resp.form.submit('submit').follow()
# 404 pages
resp = app.get('/backoffice/i18n/fr/%s/' % msg.id, status=200)
resp = app.get('/backoffice/i18n/de/%s/' % msg.id, status=404)
resp = app.get('/backoffice/i18n/fr/%s000/' % msg.id, status=404)
def test_i18n_export(pub):
create_superuser(pub)
Workflow.wipe()
BlockDef.wipe()
TranslatableMessage.wipe()
formdef = FormDef()
formdef.name = 'test title'
formdef.fields = [
StringField(id='1', label='text field', type='string'),
ItemField(id='2', label='list field', type='item', items=['first', 'second', 'third']),
]
formdef.store()
# go and scan
app = login(get_app(pub))
resp = app.get('/backoffice/i18n/', status=302).follow()
resp = resp.click('Go to multilinguism page')
resp = resp.click('Export')
resp = resp.form.submit('cancel').follow()
resp = resp.click('Export')
resp.form['format'] = 'ods'
resp = resp.form.submit('submit').follow()
resp = resp.click('Download Export')
assert resp.content_type == 'application/vnd.oasis.opendocument.spreadsheet'
with zipfile.ZipFile(io.BytesIO(resp.body)) as zipf:
content = zipf.read('content.xml')
assert b'>text field<' in content
assert b'>list field<' in content
resp = app.get('/backoffice/i18n/')
resp = resp.click('Export')
resp.form['format'] = 'xliff'
resp = resp.form.submit('submit').follow()
resp = resp.click('Download Export')
assert resp.content_type == 'text/xml'
assert b'>text field<' in resp.body
assert b'>list field<' in resp.body
# check filtered strings
resp = app.get('/backoffice/i18n/')
resp.form['q'] = 'list'
resp = resp.form.submit('submit')
resp = resp.click('Export')
resp.form['format'] = 'xliff'
resp = resp.form.submit('submit').follow()
resp = resp.click('Download Export')
assert resp.content_type == 'text/xml'
assert b'>text field<' not in resp.body
assert b'>list field<' in resp.body
def test_i18n_import(pub):
create_superuser(pub)
Workflow.wipe()
BlockDef.wipe()
TranslatableMessage.wipe()
formdef = FormDef()
formdef.name = 'test title'
formdef.fields = [
StringField(id='1', label='text field', type='string'),
ItemField(id='2', label='list field', type='item', items=['first', 'second', 'third']),
]
formdef.store()
# go and scan
app = login(get_app(pub))
resp = app.get('/backoffice/i18n/', status=302).follow()
resp = resp.click('Go to multilinguism page')
resp = resp.click('Import')
resp = resp.form.submit('cancel').follow()
resp = resp.click('Import')
resp.forms[0]['file'] = Upload(
'test.xliff',
b'''
<xliff:xliff xmlns:xliff="urn:oasis:names:tc:xliff:document:2.0" version="2.0" srcLang="en" trgLang="fr">
<xliff:file id="f1">
<xliff:file id="1">
<xliff:segment>
<xliff:source>text field</xliff:source>
<xliff:target />
</xliff:segment>
<xliff:segment>
<xliff:source>list field</xliff:source>
<xliff:target>champ liste</xliff:target>
</xliff:segment>
<xliff:segment>
<xliff:source>other text</xliff:source>
<xliff:target>autre texte</xliff:target>
</xliff:segment>
</xliff:file>
</xliff:file>
</xliff:xliff>
''',
'text/xml',
)
resp = resp.form.submit('submit').follow()
assert TranslatableMessage.count([Equal('string', 'text field')]) == 1
assert TranslatableMessage.count([Equal('string', 'list field')]) == 1
assert TranslatableMessage.count([Equal('string', 'other text')]) == 1
assert TranslatableMessage.select([Equal('string', 'list field')])[0].string_fr == 'champ liste'
assert TranslatableMessage.select([Equal('string', 'other text')])[0].string_fr == 'autre texte'
TranslatableMessage.wipe()
workbook = ods.Workbook(encoding='utf-8')
ws = workbook.add_sheet('')
ws.write(0, 0, 'list field')
ws.write(0, 1, 'champ liste')
ws.write(1, 0, 'other text')
ws.write(1, 1, 'autre texte')
output = io.BytesIO()
workbook.save(output)
resp = app.get('/backoffice/i18n/', status=302).follow()
resp = resp.click('Go to multilinguism page')
resp = resp.click('Import')
resp.forms[0]['file'] = Upload(
'test.ods', output.getvalue(), 'application/vnd.oasis.opendocument.spreadsheet'
)
resp = resp.form.submit('submit').follow()
assert TranslatableMessage.count([Equal('string', 'text field')]) == 1
assert TranslatableMessage.count([Equal('string', 'list field')]) == 1
assert TranslatableMessage.count([Equal('string', 'other text')]) == 1
assert TranslatableMessage.select([Equal('string', 'list field')])[0].string_fr == 'champ liste'
assert TranslatableMessage.select([Equal('string', 'other text')])[0].string_fr == 'autre texte'
# check query string is kept along
resp = app.get('/backoffice/i18n/')
resp.form['q'] = 'list'
resp = resp.form.submit('submit')
resp = resp.click('Import')
resp.forms[0]['file'] = Upload(
'test.ods', output.getvalue(), 'application/vnd.oasis.opendocument.spreadsheet'
)
resp = resp.form.submit('submit').follow()
resp = resp.click('Go to multilinguism')
assert resp.request.url == 'http://example.net/backoffice/i18n/?q=list&lang=fr'
# invalid file
resp = app.get('/backoffice/i18n/')
resp = resp.click('Import')
resp.forms[0]['file'] = Upload('test.txt', b'blah')
resp = resp.form.submit('submit').follow()
resp = app.get('/afterjobs/' + resp.pyquery('.afterjob').attr('id'))
assert resp.text == 'failed|Unknown file format'
def test_i18n_pagination(pub):
create_superuser(pub)
Workflow.wipe()
BlockDef.wipe()
TranslatableMessage.wipe()
formdef = FormDef()
formdef.name = 'test title'
formdef.fields = []
for i in range(90):
formdef.fields.append(StringField(id=str(i + 1), label='text field %s' % i, type='string'))
formdef.store()
# go and scan
app = login(get_app(pub))
resp = app.get('/backoffice/i18n/', status=302).follow()
resp = resp.click('Go to multilinguism page')
# check page limit
assert resp.pyquery('#page-links a').text() == '1 2 3 4 5 10 50 100'
resp = resp.click('50')
assert resp.pyquery('#page-links a').text() == '1 2 10 20 100'
resp = resp.click('20')
resp = resp.click('3')
assert 'offset=40' in resp.request.url
def test_i18n_mark_as_non_translatabe(pub):
TranslatableMessage.wipe()
Workflow.wipe()
FormDef.wipe()
BlockDef.wipe()
Category.wipe()
CardDef.wipe()
MailTemplate.wipe()
create_superuser(pub)
workflow = Workflow(name='workflow')
workflow.add_status('First Status')
workflow.add_status('Second Status')
workflow.store()
app = login(get_app(pub))
# first time goes to scanning
resp = app.get('/backoffice/i18n/', status=302)
resp = resp.follow()
resp = resp.click('Go to multilinguism page')
# second time, the page stays on
resp = app.get('/backoffice/i18n/', status=200)
assert TranslatableMessage.count() == 2 # First Status / Second Status
assert resp.pyquery('tr').length == 2
# check form filter
assert resp.form['lang'].value == 'fr'
resp.form['q'] = 'First'
resp = resp.form.submit()
assert resp.pyquery('tr').length == 1
# mark a message as non translatable
resp = resp.click('edit', index=0)
resp.form['non_translatable'].checked = True
resp = resp.form.submit('submit').follow()
msg = TranslatableMessage.select([Equal('string', 'First Status')])[0]
assert msg.translatable is False
resp = app.get('/backoffice/i18n/', status=200)
assert resp.pyquery('tr').length == 1
assert resp.pyquery('tr td:first-child').text() == 'Second Status'
resp.form['non_translatable'].checked = True
resp = resp.form.submit('submit')
assert resp.pyquery('tr').length == 1
assert resp.pyquery('tr td:first-child').text() == 'First Status'