misc: use active language to format dates/times (#73484) #124

Merged
fpeters merged 1 commits from wip/73484-datetime-language into main 2023-02-24 07:00:32 +01:00
8 changed files with 89 additions and 60 deletions

View File

@ -1,3 +1,4 @@
import datetime
import json
import os
@ -328,3 +329,30 @@ def test_translated_card_item(pub):
'1_display': 'hello world',
'1_structured': {'id': 1, 'text': 'hello world', 'foo': 'hello world'},
}
def test_translated_datetime(pub, user):
FormDef.wipe()
formdef = FormDef()
formdef.name = 'test form'
formdef.fields = [
StringField(id='1', label='text field', type='string'),
]
formdef.store()
app = login(get_app(pub), username='foo', password='foo')
resp = app.get('/en/test-form/')
resp.form['f1'] = 'foobar'
resp = resp.form.submit('submit') # 1st draft
resp = app.get('/en/test-form/')
resp.form['f1'] = 'foobar'
resp = resp.form.submit('submit') # 2nd draft
resp = app.get('/en/test-form/')
# check date starts with year-
assert (' %s-' % datetime.date.today().year) in resp.pyquery('.drafts-recall li:first-child a').text()
resp = app.get('/fr/test-form/')
# check date end with /year
assert ('/%s ' % datetime.date.today().year) in resp.pyquery('.drafts-recall li:first-child a').text()

View File

@ -118,11 +118,10 @@ def test_date_qualifier(pub):
template.generate(output, {'foo': datetime.date(2019, 1, 2)})
assert output.getvalue() == '<p>2019-01-02</p>'
pub.cfg['language'] = {'language': 'fr'}
pub.write_cfg()
output = io.StringIO()
template.generate(output, {'foo': datetime.date(2019, 1, 2)})
assert output.getvalue() == '<p>02/01/2019</p>'
with pub.with_language('fr'):
output = io.StringIO()
template.generate(output, {'foo': datetime.date(2019, 1, 2)})
assert output.getvalue() == '<p>02/01/2019</p>'
def test_datetime_qualifier(pub):
@ -132,11 +131,10 @@ def test_datetime_qualifier(pub):
template.generate(output, {'foo': datetime.datetime(2019, 1, 2, 14, 4)})
assert output.getvalue() == '<p>2019-01-02 14:04</p>'
pub.cfg['language'] = {'language': 'fr'}
pub.write_cfg()
output = io.StringIO()
template.generate(output, {'foo': datetime.datetime(2019, 1, 2, 14, 4)})
assert output.getvalue() == '<p>02/01/2019 14:04</p>'
with pub.with_language('fr'):
output = io.StringIO()
template.generate(output, {'foo': datetime.datetime(2019, 1, 2, 14, 4)})
assert output.getvalue() == '<p>02/01/2019 14:04</p>'
def test_is_bool():

View File

@ -8,6 +8,7 @@ import uuid
from unittest import mock
import pytest
from django.utils import formats
from quixote import get_publisher, get_request
from quixote.http_request import Upload
@ -339,9 +340,8 @@ def test_date_field(pub, formdef):
assert formdata2.data == {'0': value}
assert formdata2.get_substitution_variables()['form_field_date'] == '2015-05-12'
pub.cfg['language'] = {'language': 'fr'}
assert formdata2.get_substitution_variables()['form_field_date'] == '12/05/2015'
pub.cfg['language'] = {'language': 'en'}
with pub.with_language('fr'):
assert formdata2.get_substitution_variables()['form_field_date'] == '12/05/2015'
def test_clean_drafts(pub):
@ -743,7 +743,7 @@ def test_lazy_formdata(pub, variable_test_data):
formdata = FormDef.select()[0].data_class().select()[0]
lazy_formdata = LazyFormData(formdata)
assert lazy_formdata.receipt_date == time.strftime('%Y-%m-%d', formdata.receipt_time)
assert lazy_formdata.receipt_time == time.strftime('%H:%M', formdata.receipt_time)
assert lazy_formdata.receipt_time == formats.time_format(datetime.datetime(*formdata.receipt_time[:6]))
assert lazy_formdata.last_update_datetime.timetuple()[:6] == formdata.last_update_time[:6]
assert lazy_formdata.internal_id == formdata.id
assert lazy_formdata.name == 'foobarlazy'
@ -760,7 +760,7 @@ def test_lazy_formdata(pub, variable_test_data):
for attribute in (
'name',
'receipt_date',
'receipt_time',
# 'receipt_time', # lazy value is localized
'previous_status',
'uri',
'status_changed',
@ -2788,12 +2788,11 @@ def test_form_digest_date(pub):
formdata.store()
assert formdef.data_class().get(formdata.id).digests['default'] == 'plop 2015-05-12 plop'
pub.cfg['language'] = {'language': 'fr'}
pub.write_cfg()
formdata = formdef.data_class()()
formdata.data = {'0': time.strptime('2015-05-12', '%Y-%m-%d')}
formdata.store()
assert formdef.data_class().get(formdata.id).digests['default'] == 'plop 12/05/2015 plop'
with pub.with_language('fr'):
formdata = formdef.data_class()()
formdata.data = {'0': time.strptime('2015-05-12', '%Y-%m-%d')}
formdata.store()
assert formdef.data_class().get(formdata.id).digests['default'] == 'plop 12/05/2015 plop'
formdef.digest_templates = {'default': 'plop {{ form_var_date|date:"Y" }} plop'}
formdef.store()

View File

@ -289,8 +289,8 @@ def test_date_format():
assert date_format() == '%d/%m/%Y'
os.environ['LC_TIME'] = 'nl_BE.UTF-8'
assert date_format() == '%Y-%m-%d'
pub.cfg['language'] = {'language': 'fr'}
assert date_format() == '%d/%m/%Y'
with pub.with_language('fr'):
assert date_format() == '%d/%m/%Y'
finally:
os.environ = orig_environ

View File

@ -373,29 +373,30 @@ def test_date_widget():
mock_form_submission(req, widget, {'test': '2014-1-20'})
assert widget.has_error()
pub.cfg['language'] = {'language': 'fr'}
widget = DateWidget('test')
mock_form_submission(req, widget, {'test': '20/1/2014'})
assert not widget.has_error()
assert widget.parse() == '20/01/2014'
with pub.with_language('fr'):
pub.cfg['language'] = {'language': 'fr'}
widget = DateWidget('test')
mock_form_submission(req, widget, {'test': '20/1/2014'})
assert not widget.has_error()
assert widget.parse() == '20/01/2014'
mock_form_submission(req, widget, {'test': '2014-1-20'})
assert not widget.has_error()
assert widget.parse() == '20/01/2014'
mock_form_submission(req, widget, {'test': '2014-1-20'})
assert not widget.has_error()
assert widget.parse() == '20/01/2014'
# prevent typo in years (too far in the past of future)
widget = DateWidget('test')
mock_form_submission(req, widget, {'test': '20/1/2123'})
assert widget.has_error()
# prevent typo in years (too far in the past of future)
widget = DateWidget('test')
mock_form_submission(req, widget, {'test': '20/1/2123'})
assert widget.has_error()
widget = DateWidget('test')
mock_form_submission(req, widget, {'test': '20/1/1123'})
assert widget.has_error()
widget = DateWidget('test')
mock_form_submission(req, widget, {'test': '20/1/1123'})
assert widget.has_error()
widget = DateWidget('test')
mock_form_submission(req, widget, {'test': '20/1/1789'})
assert not widget.has_error()
assert widget.parse() == '20/01/1789'
widget = DateWidget('test')
mock_form_submission(req, widget, {'test': '20/1/1789'})
assert not widget.has_error()
assert widget.parse() == '20/01/1789'
widget = DateWidget('test', minimum_date='1/1/2014')
mock_form_submission(req, widget, {'test': '20/1/2014'})

View File

@ -2896,23 +2896,21 @@ def test_display_form(pub):
assert formdata.get_substitution_variables()['xxx_var_date'] == '2015-05-12'
pub.cfg['language'] = {'language': 'fr'}
formdata = formdef.data_class()()
formdata.just_created()
formdata.store()
with pub.with_language('fr'):
formdata = formdef.data_class()()
formdata.just_created()
formdata.store()
form = Form(action='#', use_tokens=False)
display_form.fill_form(form, formdata, None)
pub.get_request().environ['REQUEST_METHOD'] = 'POST'
pub.get_request().form = {'fxxx_1': 'Foobar', 'fxxx_2': '12/05/2015', 'submit': 'submit'}
display_form.submit_form(form, formdata, None, None)
assert formdata.get_substitution_variables()['xxx_var_date'] == '12/05/2015'
form = Form(action='#', use_tokens=False)
display_form.fill_form(form, formdata, None)
pub.get_request().environ['REQUEST_METHOD'] = 'POST'
pub.get_request().form = {'fxxx_1': 'Foobar', 'fxxx_2': '12/05/2015', 'submit': 'submit'}
display_form.submit_form(form, formdata, None, None)
assert formdata.get_substitution_variables()['xxx_var_date'] == '12/05/2015'
assert formdata.get_substitution_variables()['xxx_var_date_raw'] == time.strptime(
'2015-05-12', '%Y-%m-%d'
)
pub.cfg['language'] = {'language': 'en'}
assert formdata.get_substitution_variables()['xxx_var_date_raw'] == time.strptime(
'2015-05-12', '%Y-%m-%d'
)
def test_display_form_and_comment(pub):

View File

@ -184,7 +184,7 @@ def simplify(s, space='-'):
def get_datetime_language():
lang = get_cfg('language', {}).get('language', None)
lang = get_publisher().current_language
if lang is None:
if os.environ.get('LC_TIME'):
lang = os.environ.get('LC_TIME')[:2]

View File

@ -16,6 +16,7 @@
import warnings
from django.utils import formats
from django.utils.encoding import force_text
from django.utils.functional import SimpleLazyObject
from quixote import get_publisher, get_request
@ -570,11 +571,15 @@ class LazyFormData(LazyFormDef):
@property
def receipt_date(self):
return misc.strftime(misc.date_format(), self._formdata.receipt_time)
if not self._formdata.receipt_time:
return ''
return formats.date_format(make_datetime(self._formdata.receipt_time))
@property
def receipt_time(self):
return misc.strftime('%H:%M', self._formdata.receipt_time)
if not self._formdata.receipt_time:
return ''
return formats.time_format(make_datetime(self._formdata.receipt_time))
@property
def number(self):