Compare commits
5 Commits
d238bc07db
...
fda1bf7cad
Author | SHA1 | Date |
---|---|---|
Emmanuel Cazenave | fda1bf7cad | |
Frédéric Péters | ab38410f34 | |
Frédéric Péters | 2eb29089a1 | |
Valentin Deniaud | f418c515f5 | |
Valentin Deniaud | d784acba07 |
|
@ -2,6 +2,7 @@ import os
|
|||
|
||||
import pytest
|
||||
|
||||
from wcs.formdef import FormDef
|
||||
from wcs.qommon.http_request import HTTPRequest
|
||||
from wcs.qommon.ident.password_accounts import PasswordAccount
|
||||
|
||||
|
@ -86,6 +87,10 @@ def test_admin_for_all(pub):
|
|||
user = create_superuser(pub)
|
||||
role = create_role(pub)
|
||||
|
||||
formdef = FormDef()
|
||||
formdef.name = 'test'
|
||||
formdef.store()
|
||||
|
||||
try:
|
||||
with open(os.path.join(pub.app_dir, 'ADMIN_FOR_ALL'), 'w'):
|
||||
pass # create empty file
|
||||
|
|
|
@ -4712,7 +4712,7 @@ def test_admin_form_inspect_drafts(pub):
|
|||
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/forms/%s/inspect' % formdef.id)
|
||||
assert resp.pyquery('#inspect-drafts p').text() == 'No drafts found for this form'
|
||||
assert resp.pyquery('#inspect-drafts p').text() == 'There are currently no drafts for this form.'
|
||||
|
||||
data_class = formdef.data_class()
|
||||
formdata = data_class()
|
||||
|
@ -4739,28 +4739,28 @@ def test_admin_form_inspect_drafts(pub):
|
|||
resp = app.get('/backoffice/forms/%s/inspect' % formdef.id)
|
||||
assert resp.pyquery('div#inspect-drafts tr#0').length == 1
|
||||
assert resp.pyquery('div#inspect-drafts tr#0 td.label').text() == '1st page'
|
||||
assert resp.pyquery('div#inspect-drafts tr#0 td.percent').text() == '20.0\xa0%'
|
||||
assert resp.pyquery('div#inspect-drafts tr#0 td.percent').text() == '20.0%'
|
||||
assert resp.pyquery('div#inspect-drafts tr#0 td.total').text() == '(1/5)'
|
||||
|
||||
assert resp.pyquery('div#inspect-drafts tr#2').length == 1
|
||||
assert resp.pyquery('div#inspect-drafts tr#2 td.label').text() == '2nd page'
|
||||
assert resp.pyquery('div#inspect-drafts tr#2 td.percent').text() == '20.0\xa0%'
|
||||
assert resp.pyquery('div#inspect-drafts tr#2 td.percent').text() == '20.0%'
|
||||
assert resp.pyquery('div#inspect-drafts tr#2 td.total').text() == '(1/5)'
|
||||
|
||||
assert resp.pyquery('div#inspect-drafts tr#4').length == 1
|
||||
assert resp.pyquery('div#inspect-drafts tr#4 td.label').text() == '3rd page'
|
||||
assert resp.pyquery('div#inspect-drafts tr#4 td.percent').text() == '20.0\xa0%'
|
||||
assert resp.pyquery('div#inspect-drafts tr#4 td.percent').text() == '20.0%'
|
||||
assert resp.pyquery('div#inspect-drafts tr#4 td.total').text() == '(1/5)'
|
||||
|
||||
assert resp.pyquery('div#inspect-drafts tr#_confirmation_page').length == 1
|
||||
assert resp.pyquery('div#inspect-drafts tr#_confirmation_page td.label').text() == 'Confirmation page'
|
||||
assert resp.pyquery('div#inspect-drafts tr#_confirmation_page td.percent').text() == '20.0\xa0%'
|
||||
assert resp.pyquery('div#inspect-drafts tr#_confirmation_page td.percent').text() == '20.0%'
|
||||
assert resp.pyquery('div#inspect-drafts tr#_confirmation_page td.total').text() == '(1/5)'
|
||||
|
||||
assert resp.pyquery('div#inspect-drafts tr#_unkown').length == 1
|
||||
assert resp.pyquery('div#inspect-drafts tr#_unkown td.label').text() == 'Unkown'
|
||||
assert resp.pyquery('div#inspect-drafts tr#_unkown td.percent').text() == '20.0\xa0%'
|
||||
assert resp.pyquery('div#inspect-drafts tr#_unkown td.total').text() == '(1/5)'
|
||||
assert resp.pyquery('div#inspect-drafts tr#_unknown').length == 1
|
||||
assert resp.pyquery('div#inspect-drafts tr#_unknown td.label').text() == 'Unknown'
|
||||
assert resp.pyquery('div#inspect-drafts tr#_unknown td.percent').text() == '20.0%'
|
||||
assert resp.pyquery('div#inspect-drafts tr#_unknown td.total').text() == '(1/5)'
|
||||
|
||||
|
||||
def test_form_import_fields(pub):
|
||||
|
|
|
@ -1369,6 +1369,7 @@ def test_tests_webservice_response(pub):
|
|||
resp = resp.click('Test response')
|
||||
resp.form['url'] = 'http://example.com/'
|
||||
resp.form['payload'] = '{"a": "b"}'
|
||||
resp.form['status_code'] = '400'
|
||||
resp.form['qs_data$element0key'] = 'foo'
|
||||
resp.form['method'] = 'POST (JSON)'
|
||||
resp.form['post_data$element0key'] = 'bar'
|
||||
|
@ -1381,6 +1382,7 @@ def test_tests_webservice_response(pub):
|
|||
assert response.name == 'Test response'
|
||||
assert response.url == 'http://example.com/'
|
||||
assert response.payload == '{"a": "b"}'
|
||||
assert response.status_code == 400
|
||||
assert response.qs_data == {'foo': ''}
|
||||
assert response.method == 'POST'
|
||||
assert response.post_data == {'bar': ''}
|
||||
|
|
|
@ -543,3 +543,53 @@ def test_workflow_tests_webservice(pub):
|
|||
with pytest.raises(WorkflowTestError) as excinfo:
|
||||
testdef.run(formdef)
|
||||
assert str(excinfo.value) == 'Webservice response Fake response was used 0 times (instead of 1).'
|
||||
|
||||
|
||||
def test_workflow_tests_webservice_status_jump(pub):
|
||||
user = pub.user_class(name='test user')
|
||||
user.store()
|
||||
|
||||
workflow = Workflow(name='Workflow One')
|
||||
new_status = workflow.add_status(name='New status')
|
||||
end_status = workflow.add_status(name='Error status')
|
||||
|
||||
wscall = new_status.add_action('webservice_call')
|
||||
wscall.url = 'http://example.com/json'
|
||||
wscall.varname = 'test_webservice'
|
||||
wscall.action_on_4xx = end_status.id
|
||||
|
||||
workflow.store()
|
||||
|
||||
formdef = FormDef()
|
||||
formdef.name = 'test title'
|
||||
formdef.workflow_id = workflow.id
|
||||
formdef.store()
|
||||
|
||||
formdata = formdef.data_class()()
|
||||
formdata.just_created()
|
||||
|
||||
testdef = TestDef.create_from_formdata(formdef, formdata)
|
||||
testdef.agent_id = user.id
|
||||
testdef.store()
|
||||
|
||||
response = WebserviceResponse()
|
||||
response.testdef_id = testdef.id
|
||||
response.name = 'Fake response'
|
||||
response.url = 'http://example.com/json'
|
||||
response.payload = '{"foo": "foo"}'
|
||||
response.store()
|
||||
|
||||
testdef.workflow_tests.actions = [
|
||||
workflow_tests.AssertStatus(status_name='New status'),
|
||||
workflow_tests.AssertWebserviceCall(webservice_response_id=response.id, call_count=1),
|
||||
]
|
||||
|
||||
testdef.run(formdef)
|
||||
|
||||
response.status_code = 400
|
||||
response.store()
|
||||
|
||||
testdef.workflow_tests.actions = [
|
||||
workflow_tests.AssertStatus(status_name='End status'),
|
||||
workflow_tests.AssertWebserviceCall(webservice_response_id=response.id, call_count=1),
|
||||
]
|
||||
|
|
|
@ -1777,33 +1777,48 @@ class FormDefPage(Directory, TempfileDirectoryMixin):
|
|||
)
|
||||
context['deprecation_titles'] = deprecations.titles
|
||||
|
||||
temp_drafts = defaultdict(int)
|
||||
temp_drafts = {}
|
||||
total_drafts = 0
|
||||
drafts = {}
|
||||
for formdata in self.formdef.data_class().select(clause=[Equal('status', 'draft')]):
|
||||
page_id = formdata.page_id if formdata.page_id is not None else '_unkown'
|
||||
temp_drafts[page_id] += 1
|
||||
for formdata in self.formdef.data_class().select_iterator(
|
||||
clause=[Equal('status', 'draft')], itersize=200
|
||||
):
|
||||
page_id = formdata.page_id if formdata.page_id is not None else '_unknown'
|
||||
if page_id not in temp_drafts:
|
||||
temp_drafts[page_id] = {'total': 0, 'page_no': int(formdata.page_no)}
|
||||
temp_drafts[page_id]['total'] += 1
|
||||
total_drafts += 1
|
||||
if total_drafts:
|
||||
for key in ('_unkown', '_confirmation_page', '_first_page'):
|
||||
special_page_page_no_mapping = {
|
||||
'_first_page': -100, # first
|
||||
'_unknown': 1000, # last
|
||||
'_confirmation_page': 999, # second to last
|
||||
}
|
||||
for page_id, page_no in special_page_page_no_mapping.items():
|
||||
try:
|
||||
num_drafts = temp_drafts.pop(key)
|
||||
draft_info = temp_drafts.pop(page_id)
|
||||
except KeyError:
|
||||
num_drafts = 0
|
||||
drafts[key] = {'total': num_drafts, 'field': None}
|
||||
for page_id, num_drafts in temp_drafts.items():
|
||||
draft_info = {'total': 0}
|
||||
drafts[page_id] = {'total': draft_info['total'], 'field': None, 'page_no': page_no}
|
||||
for page_id, draft_info in temp_drafts.items():
|
||||
for field in self.formdef.iter_fields(with_backoffice_fields=False):
|
||||
if page_id == field.id and isinstance(field, PageField):
|
||||
drafts[page_id] = {'total': num_drafts, 'field': field}
|
||||
drafts[page_id] = {
|
||||
'total': draft_info['total'],
|
||||
'field': field,
|
||||
'page_no': draft_info['page_no'],
|
||||
}
|
||||
break
|
||||
else:
|
||||
drafts['_unkown']['total'] += num_drafts
|
||||
drafts['_unknown']['total'] += draft_info['total']
|
||||
for draft_data in drafts.values():
|
||||
draft_percent = 100 * draft_data['total'] / total_drafts
|
||||
draft_data['percent'] = draft_percent
|
||||
draft_data['percent_rounded'] = '%d' % draft_percent
|
||||
context['drafts'] = sorted(drafts.items(), reverse=True, key=lambda x: x[1]['total'])
|
||||
|
||||
context['drafts'] = sorted(drafts.items(), key=lambda x: x[1]['page_no'])
|
||||
context['drafts_total'] = total_drafts
|
||||
context['is_carddef'] = isinstance(self.formdef, CardDef)
|
||||
|
||||
return template.QommonTemplateResponse(
|
||||
templates=[self.inspect_template_name],
|
||||
|
|
|
@ -754,6 +754,16 @@ class WebserviceResponsePage(Directory):
|
|||
validation_function=validate_json,
|
||||
)
|
||||
|
||||
form.add(
|
||||
RadiobuttonsWidget,
|
||||
'status_code',
|
||||
title=_('Response status code'),
|
||||
required=True,
|
||||
options=[200, 204, 400, 401, 403, 404, 500, 502, 503],
|
||||
value=self.webservice_response.status_code,
|
||||
extra_css_class='widget-inline-radio',
|
||||
)
|
||||
|
||||
form.add(
|
||||
WidgetDict,
|
||||
'qs_data',
|
||||
|
@ -820,6 +830,7 @@ class WebserviceResponsePage(Directory):
|
|||
self.webservice_response.name = form.get_widget('name').parse()
|
||||
self.webservice_response.payload = form.get_widget('payload').parse()
|
||||
self.webservice_response.url = form.get_widget('url').parse()
|
||||
self.webservice_response.status_code = form.get_widget('status_code').parse()
|
||||
self.webservice_response.qs_data = form.get_widget('qs_data').parse()
|
||||
self.webservice_response.method = form.get_widget('method').parse()
|
||||
self.webservice_response.post_data = form.get_widget('post_data').parse()
|
||||
|
|
|
@ -4,8 +4,8 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: wcs 0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-03-04 13:46+0100\n"
|
||||
"PO-Revision-Date: 2024-03-04 13:47+0100\n"
|
||||
"POT-Creation-Date: 2024-03-04 17:49+0100\n"
|
||||
"PO-Revision-Date: 2024-03-04 17:49+0100\n"
|
||||
"Last-Translator: Thomas Noël <tnoel@entrouvert.com>\n"
|
||||
"Language-Team: french\n"
|
||||
"Language: fr\n"
|
||||
|
@ -2628,6 +2628,10 @@ msgstr "JSON invalide : %s"
|
|||
msgid "Response payload (JSON)"
|
||||
msgstr "Contenu de la réponse (JSON)"
|
||||
|
||||
#: admin/tests.py
|
||||
msgid "Response status code"
|
||||
msgstr "Code de statut de la réponse"
|
||||
|
||||
#: admin/tests.py
|
||||
msgid "Restrict to query string data"
|
||||
msgstr "Limiter aux paramètres de l’URL"
|
||||
|
@ -11948,11 +11952,14 @@ msgstr "Les traces des erreurs seront envoyées à %s."
|
|||
msgid ""
|
||||
"Record errors in the central error screen, for management by administrators"
|
||||
msgstr ""
|
||||
" Enregistrer les erreurs dans l’écran de centralisation des erreurs, pour traitement par l’équipe d’administration"
|
||||
" Enregistrer les erreurs dans l’écran de centralisation des erreurs, pour "
|
||||
"traitement par l’équipe d’administration"
|
||||
|
||||
#: wf/wscall.py
|
||||
msgid "Record errors in card/form history log, for agents"
|
||||
msgstr "Enregistrer les erreurs dans l’historique de la demande ou fiche, pour visualisation par les agents"
|
||||
msgstr ""
|
||||
"Enregistrer les erreurs dans l’historique de la demande ou fiche, pour "
|
||||
"visualisation par les agents"
|
||||
|
||||
#: wf/wscall.py
|
||||
msgctxt "wscall-parameter"
|
||||
|
@ -12044,10 +12051,25 @@ msgstr "Nom du statut"
|
|||
msgid "Assert email is sent"
|
||||
msgstr "Vérifier l’envoi d’un courriel"
|
||||
|
||||
#: workflow_tests.py
|
||||
#, python-format
|
||||
msgid "Email to \"%s\""
|
||||
msgstr "Courriel vers « %s »"
|
||||
|
||||
#: workflow_tests.py
|
||||
msgid "No email was sent."
|
||||
msgstr "Aucun courriel envoyé."
|
||||
|
||||
#: workflow_tests.py
|
||||
#, python-format
|
||||
msgid "Email addresses: %s"
|
||||
msgstr "Adresses de courriel : %s"
|
||||
|
||||
#: workflow_tests.py
|
||||
#, python-format
|
||||
msgid "Email was not sent to address \"%s\"."
|
||||
msgstr "Le courriel n’a pas été envoyé vers l’adresse « %s »."
|
||||
|
||||
#: workflow_tests.py
|
||||
#, python-format
|
||||
msgid "Email subject: %s"
|
||||
|
@ -12068,6 +12090,14 @@ msgstr "Corps du courriel : %s"
|
|||
msgid "Email body does not contain \"%s\"."
|
||||
msgstr "Le corps du courriel ne contient pas « %s »."
|
||||
|
||||
#: workflow_tests.py
|
||||
msgid "Email addresses"
|
||||
msgstr "Adresses de courriel"
|
||||
|
||||
#: workflow_tests.py
|
||||
msgid "Add address"
|
||||
msgstr "Ajouter une adresse"
|
||||
|
||||
#: workflow_tests.py
|
||||
msgid "Subject must contain"
|
||||
msgstr "Le sujet doit contenir"
|
||||
|
|
|
@ -1281,7 +1281,7 @@ def intcomma(value):
|
|||
|
||||
@register.filter
|
||||
def get_preference(user, pref_name):
|
||||
return user.get_preference(pref_name)
|
||||
return user.get_preference(pref_name) if user else None
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<button role="tab" aria-selected="false" aria-controls="inspect-workflow" id="tab-workflow" tabindex="-1">{% trans "Workflow" %}</button>
|
||||
<button role="tab" aria-selected="false" aria-controls="inspect-options" id="tab-options" tabindex="-1">{% trans "Options" %}</button>
|
||||
<button role="tab" aria-selected="false" aria-controls="inspect-fields" id="tab-fields" tabindex="-1">{% trans "Fields" %}</button>
|
||||
{% if not snapshots_diff %}
|
||||
{% if not snapshots_diff and not is_carddef %}
|
||||
<button role="tab" aria-selected="false" aria-controls="inspect-drafts" id="tab-drafts" tabindex="-1">{% trans "Drafts" %}</button>
|
||||
{% endif %}
|
||||
{% if custom_views %}
|
||||
|
@ -93,16 +93,19 @@
|
|||
|
||||
<div id="inspect-drafts" role="tabpanel" tabindex="0" aria-labelledby="tab-drafts" hidden>
|
||||
{% if drafts %}
|
||||
<div class="infonotice">
|
||||
<p>{% trans "Statistics on drafts by page." %}</p>
|
||||
<p>{% trans "Lifespan of drafts (in days)" %}{% trans ":" %} {{ formdef.drafts_lifespan|default_if_none:_('default value') }}.</p>
|
||||
</div>
|
||||
<table class="stats">
|
||||
<thead><tr><th colspan="4">{% trans "Page" %}</th></tr></thead>
|
||||
<tbody>
|
||||
{% for page_drafts in drafts %}
|
||||
{% with page_id=page_drafts.0 draft_data=page_drafts.1 %}
|
||||
{% if draft_data.total %}
|
||||
<tr id="{{ page_id }}">
|
||||
<td class="label">
|
||||
{% if page_id == "_unkown" %}
|
||||
{% trans "Unkown" %}
|
||||
{% if page_id == "_unknown" %}
|
||||
{% trans "Unknown" %}
|
||||
{% elif page_id == "_first_page" %}
|
||||
{% trans "Only page" %}
|
||||
{% elif page_id == "_confirmation_page" %}
|
||||
|
@ -111,7 +114,7 @@
|
|||
{{ draft_data.field.ellipsized_label }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="percent"> {{draft_data.percent}} %</td>
|
||||
<td class="percent">{% blocktranslate with percent=draft_data.percent %}{{percent}}%{% endblocktranslate %}</td>
|
||||
<td class="total">({{draft_data.total}}/{{drafts_total}})</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -125,7 +128,7 @@
|
|||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p>{% trans "No drafts found for this form" %}</p>
|
||||
<p>{% trans "There are currently no drafts for this form." %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -640,7 +640,7 @@ class MockWebserviceResponseAdapter(requests.adapters.HTTPAdapter):
|
|||
}
|
||||
|
||||
raw_response = HTTPResponse(
|
||||
status=200,
|
||||
status=response.status_code,
|
||||
body=io.BytesIO(response.payload.encode()),
|
||||
headers=headers,
|
||||
original_response=self.make_original_response(headers),
|
||||
|
@ -669,6 +669,7 @@ class WebserviceResponse(XmlStorableObject):
|
|||
name = ''
|
||||
payload = None
|
||||
url = None
|
||||
status_code = 200
|
||||
qs_data = None
|
||||
method = ''
|
||||
post_data = None
|
||||
|
@ -678,6 +679,7 @@ class WebserviceResponse(XmlStorableObject):
|
|||
('name', 'str'),
|
||||
('payload', 'str'),
|
||||
('url', 'str'),
|
||||
('status_code', 'int'),
|
||||
('qs_data', 'kv_data'),
|
||||
('method', 'str'),
|
||||
('post_data', 'kv_data'),
|
||||
|
|
Loading…
Reference in New Issue