Skip to content

Commit

Permalink
Do not confuse media column names with question…
Browse files Browse the repository at this point in the history
types!

This fixes #322 for new schemas, but doesn't yet handle existing schemas
that have a superfluous `None` translation
  • Loading branch information
jnm committed Jun 15, 2024
1 parent 3800323 commit 3e9a06f
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 8 deletions.
8 changes: 8 additions & 0 deletions src/formpack/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@
'hxl': '',
}

# Which columns can contain media filenames? Do not confuse this with question
# types that can collect media! From https://xlsform.org/en/#media:
# You can include questions in your form that display images or that play
# video or audio files
# …
# Media is translatable in the same way as labels and hints…
MEDIA_COLUMN_NAMES = ('audio', 'image', 'video')

# Export Settings
EXPORT_SETTING_FIELDS = 'fields'
EXPORT_SETTING_FIELDS_FROM_ALL_VERSIONS = 'fields_from_all_versions'
Expand Down
15 changes: 9 additions & 6 deletions src/formpack/utils/expand_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@

from .array_to_xpath import EXPANDABLE_FIELD_TYPES
from .iterator import get_first_occurrence
from .replace_aliases import MEDIA_TYPES, META_TYPES, selects
from .replace_aliases import META_TYPES, selects
from ..constants import (
MEDIA_COLUMN_NAMES,
OR_OTHER_COLUMN,
TAG_COLUMNS_AND_SEPARATORS,
UNTRANSLATED,
Expand Down Expand Up @@ -186,7 +187,7 @@ def _get_known_translated_cols(translated_cols: List[str]) -> List[str]:

_translated_cols = []
for col in translated_cols:
if col in MEDIA_TYPES:
if col in MEDIA_COLUMN_NAMES:
col = f'media::{col}'
_translated_cols.append(col)

Expand All @@ -207,7 +208,7 @@ def _get_special_survey_cols(
'hint::English',
For more examples, see tests.
"""
RE_MEDIA_TYPES = '|'.join(MEDIA_TYPES)
RE_MEDIA_COLUMN_NAMES = '|'.join(MEDIA_COLUMN_NAMES)

uniq_cols = OrderedDict()
special = OrderedDict()
Expand Down Expand Up @@ -238,14 +239,14 @@ def _mark_special(**kwargs: str) -> None:
column=column_name,
translation=UNTRANSLATED,
)
if ':' not in column_name and column_name not in MEDIA_TYPES:
if ':' not in column_name and column_name not in MEDIA_COLUMN_NAMES:
continue
if column_name.startswith('bind:'):
continue
if column_name.startswith('body:'):
continue
mtch = re.match(
rf'^(media\s*::?\s*)?({RE_MEDIA_TYPES})\s*::?\s*([^:]+)$',
rf'^(media\s*::?\s*)?({RE_MEDIA_COLUMN_NAMES})\s*::?\s*([^:]+)$',
column_name,
)
if mtch:
Expand All @@ -260,7 +261,9 @@ def _mark_special(**kwargs: str) -> None:
translation=translation,
)
continue
mtch = re.match(rf'^(media\s*::?\s*)?({RE_MEDIA_TYPES})$', column_name)
mtch = re.match(
rf'^(media\s*::?\s*)?({RE_MEDIA_COLUMN_NAMES})$', column_name
)
if mtch:
matched = mtch.groups()
media_type = matched[1]
Expand Down
15 changes: 13 additions & 2 deletions tests/test_exports.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,11 @@ def test_translations_labels_mismatch(self):
FormPack(schemas, title)

def test_translations_with_select_multiple_from_file(self):
"""
Make sure that exports do not crash if `select_multiple_from_file` is
used in a multi-language form. See #322
"""

title, schemas, submissions = restaurant_profile

# Add a `select_multiple_from_file` question to existing `rpV4` schema
Expand All @@ -401,8 +406,14 @@ def test_translations_with_select_multiple_from_file(self):
# Feed this schema with `file` back into formpack again
fp = FormPack([fp.versions['rpV4'].schema], title)

# Fails here with
# `formpack.errors.TranslationError: Mismatched labels and translations: [restaurant name, nom du restaurant] [english, french, None] 2!=3`
# At this point, issue #322 would have already caused
# `TranslationError: Mismatched labels and translations`, but perform a
# simple export anyway, adding a response for `suppliers`
submissions[-1]['suppliers'] = 'SFG Ocsys'
export = fp.export(versions=fp.versions)
actual_dict = export.to_dict(submissions)
assert actual_dict['Restaurant profile']['fields'][-1] == 'suppliers'
assert actual_dict['Restaurant profile']['data'][-1][-1] == 'SFG Ocsys'

def test_simple_nested_grouped_repeatable(self):
title, schemas, submissions = build_fixture(
Expand Down

0 comments on commit 3e9a06f

Please sign in to comment.