[REF] survey: clean survey routes definitions

Purpose of this commit is to ease understanding or routes. In this commit
we make token a parameter where it is optional and force is where it is
not; we remove unnecessary list on routes; we rename some controller methods
to ease understanding;

Code calling those URLs is adapted accordingly. No functional change should
occur with this commit.

Some routes are json-http-mixed as a result of old implementation. Those
will be updated in future tasks when cleaning the templates and routes.

This commit is linked to task ID 1911586 and PR #28986.
This commit is contained in:
Thibault Delavallée
2019-01-14 15:22:18 +00:00
parent 08a9391a84
commit ee2631cd51
5 changed files with 59 additions and 66 deletions
+37 -50
View File
@@ -58,13 +58,11 @@ class Survey(http.Controller):
'survey_id': survey.id,
'test_entry': True
})
return request.redirect('/survey/start/%s/%s' % (survey.id, user_input.token))
return request.redirect('/survey/start/%s?token=%s' % (survey.id, user_input.token))
return werkzeug.utils.redirect('/')
@http.route(['/survey/start/<model("survey.survey"):survey>',
'/survey/start/<model("survey.survey"):survey>/<string:token>'],
type='http', auth='public', website=True)
def survey_start(self, survey, token=None, **post):
@http.route('/survey/start/<model("survey.survey"):survey>', type='http', auth='public', website=True)
def survey_start(self, survey, token=None):
""" Start a survey by providing a token linked to an answer or generate
a new token if access is allowed """
UserInput = request.env['survey.user_input']
@@ -97,12 +95,8 @@ class Survey(http.Controller):
else:
return request.redirect('/survey/fill/%s/%s' % (survey.id, user_input.token))
# Survey displaying
@http.route(['/survey/fill/<model("survey.survey"):survey>/<string:token>',
'/survey/fill/<model("survey.survey"):survey>/<string:token>/<string:prev>'],
type='http', auth='public', website=True)
def fill_survey(self, survey, token, prev=None, **post):
'''Display and validates a survey'''
@http.route('/survey/fill/<model("survey.survey"):survey>/<string:token>', type='http', auth='public', website=True)
def survey_display_page(self, survey, token, prev=None):
Survey = request.env['survey.survey']
UserInput = request.env['survey.user_input']
@@ -131,8 +125,8 @@ class Survey(http.Controller):
return request.render('survey.survey', data)
elif user_input.state == 'done': # Display success message
return request.render('survey.sfinished', {'survey': survey,
'token': token,
'user_input': user_input})
'token': token,
'user_input': user_input})
elif user_input.state == 'skip':
flag = (True if prev and prev == 'prev' else False)
page, page_nr, last = Survey.next_page(user_input, user_input.last_displayed_page_id.id, go_back=flag)
@@ -148,17 +142,15 @@ class Survey(http.Controller):
else:
return request.render("survey.403", {'survey': survey})
# AJAX prefilling of a survey
@http.route(['/survey/prefill/<model("survey.survey"):survey>/<string:token>',
'/survey/prefill/<model("survey.survey"):survey>/<string:token>/<model("survey.page"):page>'],
type='http', auth='public', website=True)
def prefill(self, survey, token, page=None, **post):
@http.route('/survey/prefill/<model("survey.survey"):survey>/<string:token>', type='http', auth='public', website=True)
def survey_get_answers(self, survey, token, page_id=None):
""" TDE NOTE: original comment: # AJAX prefilling of a survey -> AJAX / http ?? """
UserInputLine = request.env['survey.user_input_line']
ret = {}
# Fetch previous answers
if page:
previous_answers = UserInputLine.sudo().search([('user_input_id.token', '=', token), ('page_id', '=', page.id)])
if page_id:
previous_answers = UserInputLine.sudo().search([('user_input_id.token', '=', token), ('page_id', '=', page_id)])
else:
previous_answers = UserInputLine.sudo().search([('user_input_id.token', '=', token)])
@@ -190,10 +182,9 @@ class Survey(http.Controller):
_logger.warning("[survey] No answer has been found for question %s marked as non skipped" % answer_tag)
return json.dumps(ret, default=str)
# AJAX scores loading for quiz correction mode
@http.route(['/survey/scores/<model("survey.survey"):survey>/<string:token>'],
type='http', auth='public', website=True)
def get_scores(self, survey, token, page=None, **post):
@http.route('/survey/scores/<model("survey.survey"):survey>/<string:token>', type='http', auth='public', website=True)
def survey_get_scores(self, survey, token, page_id=None):
""" TDE NOTE: original comment: # AJAX scores loading for quiz correction mode -> AJAX / http ?? """
ret = {}
# Fetch answers
@@ -205,9 +196,9 @@ class Survey(http.Controller):
ret.update({answer.question_id.id: tmp_score + answer.quizz_mark})
return json.dumps(ret)
# AJAX submission of a page
@http.route(['/survey/submit/<model("survey.survey"):survey>'], type='http', methods=['POST'], auth='public', website=True)
def submit(self, survey, **post):
@http.route('/survey/submit/<model("survey.survey"):survey>/<string:token>', type='http', methods=['POST'], auth='public', website=True)
def survey_submit(self, survey, token, **post):
""" TDE NOTE: original comment: # AJAX submission of a page -> AJAX / http ?? """
_logger.debug('Incoming data: %s', post)
page_id = int(post['page_id'])
questions = request.env['survey.question'].search([('page_id', '=', page_id)])
@@ -225,7 +216,7 @@ class Survey(http.Controller):
else:
# Store answers into database
try:
user_input = request.env['survey.user_input'].sudo().search([('token', '=', post['token'])], limit=1)
user_input = request.env['survey.user_input'].sudo().search([('token', '=', token)], limit=1)
except KeyError: # Invalid token
return request.render("survey.403", {'survey': survey})
user_id = request.env.user.id if user_input.input_type != 'link' else SUPERUSER_ID
@@ -242,27 +233,23 @@ class Survey(http.Controller):
else:
vals.update({'state': 'skip'})
user_input.sudo(user=user_id).write(vals)
ret['redirect'] = '/survey/fill/%s/%s' % (survey.id, post['token'])
ret['redirect'] = '/survey/fill/%s/%s' % (survey.id, token)
if go_back:
ret['redirect'] += '/prev'
ret['redirect'] += '?prev=prev'
return json.dumps(ret)
# Printing routes
@http.route(['/survey/print/<model("survey.survey"):survey>',
'/survey/print/<model("survey.survey"):survey>/<string:token>'],
type='http', auth='public', website=True)
def print_survey(self, survey, token=None, **post):
@http.route('/survey/print/<model("survey.survey"):survey>', type='http', auth='public', website=True)
def survey_print(self, survey, token=None, **post):
'''Display an survey in printable view; if <token> is set, it will
grab the answers of the user_input_id that has <token>.'''
return request.render('survey.survey_print',
{'survey': survey,
'token': token,
'page_nr': 0,
'quizz_correction': True if survey.quizz_mode and token else False})
return request.render('survey.survey_print', {
'survey': survey,
'token': token,
'page_nr': 0,
'quizz_correction': True if survey.quizz_mode and token else False})
@http.route(['/survey/results/<model("survey.survey"):survey>'],
type='http', auth='user', website=True)
def survey_reporting(self, survey, token=None, **post):
@http.route('/survey/results/<model("survey.survey"):survey>', type='http', auth='user', website=True)
def survey_report(self, survey, token=None, **post):
'''Display survey Results & Statistics for given survey.'''
result_template = 'survey.result'
current_filters = []
@@ -275,12 +262,12 @@ class Survey(http.Controller):
post.pop('finished')
filter_finish = True
if post or filter_finish:
filter_data = self.get_filter_data(post)
filter_data = self._get_filter_data(post)
current_filters = survey.filter_input_ids(filter_data, filter_finish)
filter_display_data = survey.get_filter_display_data(filter_data)
return request.render(result_template,
{'survey': survey,
'survey_dict': self.prepare_result_dict(survey, current_filters),
'survey_dict': self._prepare_result_dict(survey, current_filters),
'page_range': self.page_range,
'current_filters': current_filters,
'filter_display_data': filter_display_data,
@@ -324,7 +311,7 @@ class Survey(http.Controller):
# filter_finish: boolean => only finished surveys or not
#
def prepare_result_dict(self, survey, current_filters=None):
def _prepare_result_dict(self, survey, current_filters=None):
"""Returns dictionary having values for rendering template"""
current_filters = current_filters if current_filters else []
Survey = request.env['survey.survey']
@@ -336,14 +323,14 @@ class Survey(http.Controller):
'question': question,
'input_summary': Survey.get_input_summary(question, current_filters),
'prepare_result': Survey.prepare_result(question, current_filters),
'graph_data': self.get_graph_data(question, current_filters),
'graph_data': self._get_graph_data(question, current_filters),
}
page_dict['question_ids'].append(question_dict)
result['page_ids'].append(page_dict)
return result
def get_filter_data(self, post):
def _get_filter_data(self, post):
"""Returns data used for filtering the result"""
filters = []
for ids in post:
@@ -360,9 +347,9 @@ class Survey(http.Controller):
total = ceil(total_record / float(limit))
return range(1, int(total + 1))
def get_graph_data(self, question, current_filters=None):
def _get_graph_data(self, question, current_filters=None):
'''Returns formatted data required by graph library on basis of filter'''
# TODO refactor this terrible method and merge it with prepare_result_dict
# TODO refactor this terrible method and merge it with _prepare_result_dict
current_filters = current_filters if current_filters else []
Survey = request.env['survey.survey']
result = []
+2 -2
View File
@@ -268,7 +268,7 @@ class Survey(models.Model):
""" Open the website page with the survey form """
self.ensure_one()
token = self.env.context.get('survey_token')
trail = "/%s" % token if token else ""
trail = "?token=%s" % token if token else ""
return {
'type': 'ir.actions.act_url',
'name': "Start Survey",
@@ -312,7 +312,7 @@ class Survey(models.Model):
""" Open the website page with the survey printable view """
self.ensure_one()
token = self.env.context.get('survey_token')
trail = "/" + token if token else ""
trail = "?token=%s" % token if token else ""
return {
'type': 'ir.actions.act_url',
'name': "Print Survey",
+1 -1
View File
@@ -92,7 +92,7 @@ class SurveyUserInput(models.Model):
'type': 'ir.actions.act_url',
'name': "View Answers",
'target': 'self',
'url': '%s/%s' % (self.print_url, self.token)
'url': '%s?token=%s' % (self.print_url, self.token)
}
@api.multi
+4 -4
View File
@@ -17,8 +17,8 @@ class TestSurveyFlow(common.SurveyCase, HttpCase):
def _access_page(self, survey, token):
return self.url_open('/survey/fill/%s/%s' % (survey.id, token))
def _access_submit(self, survey, post_data):
return self.url_open('/survey/submit/%s' % survey.id, data=post_data)
def _access_submit(self, survey, token, post_data):
return self.url_open('/survey/submit/%s/%s' % (survey.id, token), data=post_data)
def _find_csrf_token(self, text):
csrf_token_re = re.compile("(input.+csrf_token.+value=\")([_a-zA-Z0-9]{51})", re.MULTILINE)
@@ -108,7 +108,7 @@ class TestSurveyFlow(common.SurveyCase, HttpCase):
page0_q1.id: {'value': [44.0]},
}
post_data = self._format_submission_data(page_0, answer_data, {'csrf_token': csrf_token, 'token': answer_token, 'button_submit': 'next'})
r = self._access_submit(survey, post_data)
r = self._access_submit(survey, answer_token, post_data)
self.assertResponse(r, 200)
answers.invalidate_cache() # TDE note: necessary as lots of sudo in controllers messing with cache
@@ -127,7 +127,7 @@ class TestSurveyFlow(common.SurveyCase, HttpCase):
page1_q0.id: {'value': [page1_q0.labels_ids.ids[0], page1_q0.labels_ids.ids[1]]},
}
post_data = self._format_submission_data(page_1, answer_data, {'csrf_token': csrf_token, 'token': answer_token, 'button_submit': 'next'})
r = self._access_submit(survey, post_data)
r = self._access_submit(survey, answer_token, post_data)
self.assertResponse(r, 200)
answers.invalidate_cache() # TDE note: necessary as lots of sudo in controllers messing with cache
+15 -9
View File
@@ -26,7 +26,7 @@
<h1>Thank you!</h1>
<div t-field="survey.thank_you_message" class="oe_no_empty" />
<div t-if='survey.quizz_mode'>You scored <t t-esc="user_input.quizz_score" /> points.</div>
<div>If you wish, you can <a t-att-href="'/survey/print/%s/%s' % (slug(survey), token)">review your answers</a>.</div>
<div>If you wish, you can <a t-att-href="'/survey/print/%s?token=%s' % (slug(survey), token)">review your answers</a>.</div>
</div>
</div>
</div>
@@ -54,7 +54,9 @@
<div class="container">
<div class="jumbotron mt32">
<h1>Login required</h1>
<p>This survey is open only to registered people. Please <a t-attf-href="/web/login?redirect=%2Fsurvey%2Fstart%2F#{ slug(survey) }%2F#{token}">log in</a>.</p>
<p>This survey is open only to registered people. Please
<a t-att-href="'/web/login?redirect=%s' % ('/survey/start/%s?token=%s' % (survey, token))">log in</a>.
</p>
</div>
</div>
</div>
@@ -167,7 +169,11 @@
<div t-field='page.description' class="oe_no_empty"/>
</div>
<form role="form" method="post" class="js_surveyform" t-att-name="'%s_%s' % (survey.id, page.id)" t-att-action="'/survey/fill/%s/%s' % (slug(survey), token)" t-att-data-prefill="'/survey/prefill/%s/%s/%s' % (slug(survey), token, slug(page))" t-att-data-validate="'/survey/validate/%s' % (slug(survey))" t-att-data-submit="'/survey/submit/%s' % (slug(survey))">
<form role="form" method="post" class="js_surveyform" t-att-name="'%s_%s' % (survey.id, page.id)"
t-att-action="'/survey/fill/%s/%s' % (slug(survey), token)"
t-att-data-prefill="'/survey/prefill/%s/%s?page_id=%s' % (slug(survey), token, page.id)"
t-att-data-validate="'/survey/validate/%s/%s' % (slug(survey), token)"
t-att-data-submit="'/survey/submit/%s/%s' % (slug(survey), token)">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<input type="hidden" name="page_id" t-att-value="page.id" />
<input type="hidden" name="token" t-att-value="token" />
@@ -455,20 +461,20 @@
<tbody>
<t t-set="text_result" t-value="prepare_result"/>
<tr t-foreach="text_result" t-as="user_input">
<td><a t-att-href="'%s/%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)"><t t-esc="user_input_index + 1"></t></a></td>
<td><a t-att-href="'%s?token=%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)"><t t-esc="user_input_index + 1"></t></a></td>
<t t-if="question.question_type == 'free_text'">
<td>
<a t-att-href="'%s/%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)" t-field="user_input.value_free_text"></a><br/>
<a t-att-href="'%s?token=%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)" t-field="user_input.value_free_text"></a><br/>
</td>
</t>
<t t-if="question.question_type == 'textbox'">
<td>
<a t-att-href="'%s/%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)" t-field="user_input.value_text"></a><br/>
<a t-att-href="'%s?token=%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)" t-field="user_input.value_text"></a><br/>
</td>
</t>
<t t-if="question.question_type == 'date'">
<td>
<a t-att-href="'%s/%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)" t-field="user_input.value_date"></a><br/>
<a t-att-href="'%s?token=%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)" t-field="user_input.value_date"></a><br/>
</td>
</t>
</tr>
@@ -489,7 +495,7 @@
</thead>
<tbody>
<tr t-foreach="comments" t-as="user_input">
<td><a t-att-href="'%s/%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)"><t t-esc="user_input_index + 1"></t></a></td>
<td><a t-att-href="'%s?token=%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)"><t t-esc="user_input_index + 1"></t></a></td>
<td>
<span t-field="user_input.value_text"></span><br/>
</td>
@@ -673,7 +679,7 @@
</thead>
<tbody>
<tr class="d-none" t-foreach="number_result['input_lines']" t-as="user_input">
<td><a t-att-href="'%s/%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)"><t t-esc="user_input_index + 1"></t></a></td>
<td><a t-att-href="'%s?token=%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)"><t t-esc="user_input_index + 1"></t></a></td>
<td><span t-field="user_input.value_number"></span><br/></td>
</tr>
</tbody>