From 5dacfa58a273ad68f768264bbff5020a7d18ebf7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?=
Date: Tue, 28 Nov 2017 10:28:19 +0100
Subject: [PATCH] api: add possibility to get drafts from /api/user/forms
endpoint (#20230)
---
help/fr/api-user.page | 11 +++------
tests/test_api.py | 25 +++++++++++++++++++
wcs/api.py | 66 +++++++++++++++++++++------------------------------
3 files changed, 55 insertions(+), 47 deletions(-)
diff --git a/help/fr/api-user.page b/help/fr/api-user.page
index 10c6bc4a..c4c0f156 100644
--- a/help/fr/api-user.page
+++ b/help/fr/api-user.page
@@ -128,15 +128,10 @@ l'adresse /user
.
Il est possible de recevoir un ensemble plus complet de données en passant un
-paramètre full=on
à l'adresse.
+paramètre full=on
à l'adresse. Pour inclure également les
+brouillons, un paramètre include-drafts=true
peut être passé.
-
-Note de compatibilité : cette information est également disponible à
-l'adresse /myspace/forms
.
-
-
-
Brouillons
@@ -147,7 +142,7 @@ l'adresse /myspace/forms
.
-$ curl https://www.example.net/myspace/drafts
+$ curl https://www.example.net/api/user/drafts
[
{
"datetime": "2014-07-21 10:15:21",
diff --git a/tests/test_api.py b/tests/test_api.py
index 14a36c7d..cecedd54 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -1096,6 +1096,8 @@ def test_user_forms(pub, local_user):
fields.StringField(id='0', label='foobar', varname='foobar'),
fields.StringField(id='1', label='foobar2'),]
formdef.keywords = 'hello, world'
+ formdef.disabled = False
+ formdef.enable_tracking_codes = True
formdef.store()
formdef.data_class().wipe()
@@ -1130,6 +1132,27 @@ def test_user_forms(pub, local_user):
resp = get_app(pub).get(sign_uri('/api/user/forms', user=local_user))
assert len(resp.json) == 1
+ formdata = formdef.data_class()()
+ formdata.user_id = local_user.id
+ formdata.status = 'draft'
+ formdata.receipt_time = datetime.datetime(2015, 1, 1).timetuple()
+ formdata.store()
+
+ resp = get_app(pub).get(sign_uri('/api/user/forms', user=local_user))
+ assert len(resp.json) == 1
+
+ resp = get_app(pub).get(sign_uri('/api/user/forms?include-drafts=true', user=local_user))
+ assert len(resp.json) == 1
+
+ formdef.disabled = False
+ formdef.store()
+
+ resp = get_app(pub).get(sign_uri('/api/user/forms?include-drafts=true', user=local_user))
+ assert len(resp.json) == 2
+
+ draft_formdata = [x for x in resp.json if x['status'] == 'Draft'][0]
+ assert draft_formdata.get('url')[-1] != '/'
+
def test_user_drafts(pub, local_user):
FormDef.wipe()
formdef = FormDef()
@@ -1143,6 +1166,8 @@ def test_user_drafts(pub, local_user):
formdef.enable_tracking_codes = True
formdef.store()
+ formdef.data_class().wipe()
+
resp = get_app(pub).get(sign_uri('/api/user/drafts', user=local_user))
assert len(resp.json) == 0
diff --git a/wcs/api.py b/wcs/api.py
index ac06fafb..8c82ab53 100644
--- a/wcs/api.py
+++ b/wcs/api.py
@@ -24,6 +24,7 @@ from quixote.directory import Directory
from qommon import _
from qommon import misc
+from qommon.evalutils import make_datetime
from qommon.errors import (AccessForbiddenError, QueryError, TraversalError,
UnknownNameIdAccessForbiddenError)
from qommon.form import ValidationError, ComputedExpressionWidget
@@ -67,7 +68,7 @@ def posted_json_data_to_formdata_data(formdef, data):
def get_formdata_dict(formdata, user, consider_status_visibility=True):
- if consider_status_visibility:
+ if consider_status_visibility and not formdata.is_draft():
status = formdata.get_visible_status(user=user)
if not status:
# skip hidden forms
@@ -75,21 +76,29 @@ def get_formdata_dict(formdata, user, consider_status_visibility=True):
else:
status = formdata.get_status()
- title = _('%(name)s #%(id)s (%(status)s)') % {
- 'name': formdata.formdef.name,
- 'id': formdata.get_display_id(),
- 'status': status.name,
- }
- d = {'title': title,
+ d = {
'name': formdata.formdef.name,
'url': formdata.get_url(),
'datetime': misc.strftime('%Y-%m-%d %H:%M:%S', formdata.receipt_time),
- 'status': status.name,
- 'status_css_class': status.extra_css_class,
+ 'status': status.name if not formdata.is_draft() else _('Draft'),
+ 'status_css_class': status.extra_css_class if status else None,
'keywords': formdata.formdef.keywords_list,
+ 'draft': formdata.is_draft(),
}
if formdata.last_update_time:
d['last_update_time'] = misc.strftime('%Y-%m-%d %H:%M:%S', formdata.last_update_time)
+
+ if formdata.is_draft():
+ d['url'] = d['url'].rstrip('/')
+ d['form_number_raw'] = d['form_number'] = None
+ d['title'] = _('%(name)s (draft)') % {'name': formdata.formdef.name}
+ else:
+ d['title'] = _('%(name)s #%(id)s (%(status)s)') % {
+ 'name': formdata.formdef.name,
+ 'id': formdata.get_display_id(),
+ 'status': status.name,
+ }
+
d.update(formdata.get_substitution_variables(minimal=True))
if get_request().form.get('full') == 'on':
d.update(formdata.get_json_export_dict(include_files=False))
@@ -520,44 +529,23 @@ class ApiUserDirectory(Directory):
return user_forms
def drafts(self):
- get_response().set_content_type('application/json')
- user = self.user or get_user_from_api_query_string() or get_request().user
- if not user:
- raise AccessForbiddenError('no user specified')
- drafts = []
- for form in self.get_user_forms(user):
- if not form.is_draft():
- continue
- if form.formdef.is_disabled() or not form.formdef.enable_tracking_codes:
- continue
- title = _('%(name)s, draft saved on %(datetime)s') % {
- 'name': form.formdef.name,
- 'datetime': misc.localstrftime(form.receipt_time)
- }
- # !!! no trailing slash in the special draft case
- url = form.get_url().rstrip('/')
- d = {'title': title,
- 'name': form.formdef.name,
- 'url': url,
- 'datetime': misc.strftime('%Y-%m-%d %H:%M:%S', form.receipt_time),
- 'keywords': form.formdef.keywords_list,
- }
- if get_request().form.get('full') == 'on':
- d.update(form.get_json_export_dict(include_files=False))
- drafts.append(d)
-
- return json.dumps(drafts,
- cls=misc.JSONEncoder,
- encoding=get_publisher().site_charset)
+ return self.forms(include_drafts=True, include_non_drafts=False)
- def forms(self):
+ def forms(self, include_drafts=False, include_non_drafts=True):
get_response().set_content_type('application/json')
user = self.user or get_user_from_api_query_string() or get_request().user
if not user:
raise AccessForbiddenError('no user specified')
forms = []
+ include_drafts = include_drafts or get_request().form.get('include-drafts') == 'true'
for form in self.get_user_forms(user):
if form.is_draft():
+ if not include_drafts:
+ continue
+ if form.formdef.is_disabled() or not form.formdef.enable_tracking_codes:
+ # the form or its draft support has been disabled
+ continue
+ elif not include_non_drafts:
continue
formdata_dict = get_formdata_dict(form, user)
if not formdata_dict:
--
2.15.1