diff --git a/tests/unit/test_form.py b/tests/unit/test_form.py index 68223f7a5..3e454f96e 100644 --- a/tests/unit/test_form.py +++ b/tests/unit/test_form.py @@ -100,22 +100,22 @@ def test_metadata_wrapping(self): def test_radio_button_label(self): """Check that appropriate radio button label is returned.""" - test_labels_list = [ - ('detection_bug', 'Desktop site instead of mobile site'), - ('unknown_bug', 'Something else') + tests_labels_lists = [ + [('detection_bug', 'i.svg', 'Desktop site instead of mobile site'), + ('unknown_bug', 'b.svg', 'Something else')], + [('detection_bug', 'Desktop site instead of mobile site'), + ('unknown_bug', 'Something else')], ] - r = form.get_radio_button_label('unknown_bug', test_labels_list) - self.assertEqual(r, 'Something else') - - r = form.get_radio_button_label('detection_bug', test_labels_list) - self.assertEqual(r, 'Desktop site instead of mobile site') - - r = form.get_radio_button_label(None, test_labels_list) - self.assertEqual(r, 'Unknown') - - r = form.get_radio_button_label('failme', test_labels_list) - self.assertEqual(r, 'Unknown') + for test_labels_list in tests_labels_lists: + r = form.get_radio_button_label('unknown_bug', test_labels_list) + self.assertEqual(r, 'Something else') + r = form.get_radio_button_label('detection_bug', test_labels_list) + self.assertEqual(r, 'Desktop site instead of mobile site') + r = form.get_radio_button_label(None, test_labels_list) + self.assertEqual(r, 'Unknown') + r = form.get_radio_button_label('failme', test_labels_list) + self.assertEqual(r, 'Unknown') def test_get_form(self): """Check we return the right form with the appropriate data.""" @@ -126,7 +126,7 @@ def test_get_form(self): actual = form.get_form(form_data) expected_browser = 'Firefox 48.0' expected_os = 'Mac OS X 10.11' - self.assertIsInstance(actual, form.IssueForm) + self.assertIsInstance(actual, form.FormWizard) self.assertEqual(actual.browser.data, expected_browser) self.assertEqual(actual.os.data, expected_os) self.assertEqual(actual.reported_with.data, 'desktop-reporter') diff --git a/webcompat/form.py b/webcompat/form.py index 17d0f04c6..0c9b0bf5c 100644 --- a/webcompat/form.py +++ b/webcompat/form.py @@ -22,7 +22,6 @@ from flask_wtf.file import FileField from markupsafe import Markup from wtforms import HiddenField -from wtforms import Label from wtforms import RadioField from wtforms import StringField from wtforms import TextAreaField @@ -38,8 +37,6 @@ from webcompat.helpers import get_details_list from webcompat.helpers import is_json_object -AUTH_REPORT = 'github-auth-report' -PROXY_REPORT = 'github-proxy-report' SCHEMES = ('http://', 'https://') BAD_SCHEMES = ('http:/', 'https:/', 'http:', 'https:') GITHUB_HELP = '_From [webcompat.com](https://webcompat.com/) with ❤️_' @@ -88,14 +85,6 @@ } ] -problem_choices = [ - ('detection_bug', 'Desktop site instead of mobile site'), - ('site_bug', 'Site is not usable'), - ('layout_bug', 'Design is broken'), - ('video_bug', 'Video or audio doesn\'t play'), - ('unknown_bug', 'Something else') -] - problem_choices_wizard = [ ('detection_bug', 'svg-problem-mobile-vs-desktop.svg', 'Desktop site instead of mobile site'), @@ -176,77 +165,69 @@ class PrefixedRadioField(RadioField): - """Prefix radio field label with an image.""" + """Prefix radio field label with an image. + + This renders the radio elements with a specific html markup. + """ def __init__(self, *args, **kwargs): prefixed_choices = kwargs.pop('choices') - template = '
{text}' choices = [] - - css_class = 'icon-container' for slug, img, text in prefixed_choices: - filename = 'img/svg/icons/{img}'.format(img=img) + filename = f'img/svg/icons/{img}' src = url_for('static', filename=filename) - label = Markup(template.format( - src=src, css_class=css_class, text=text) - ) + t = f' {text}' + label = Markup(t) choice = (slug, label) choices.append(choice) - kwargs['choices'] = choices super().__init__(*args, **kwargs) -class IssueForm(FlaskForm): - """Define form fields and validation for our bug reporting form.""" - - url = StringField(url_label, - [InputRequired(message=url_message)]) - browser = StringField('Is this information correct?', [Optional()]) - os = StringField('Operating System', [Optional()]) - # A dummy field to trap common bots. Users do not see that. - username = StringField('Username', - [Length(max=0, message=username_message)]) - # Field for people who want to be contacted, but do not want to login - # regex for GitHub usernames - username_pattern = r"^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}$" - # Field definition +class FormWizard(FlaskForm): + """IssueForm to a multi step wizard form. + + Attributes notes: + * contact: + Field for people who want to be contacted, + but do not want to login + github_username_pattern defines regex for GitHub usernames + * image: + We filter allowed type in uploads.py + We don't use the label programatically for this input[type=file], + any changes here need to be updated in form.html. + * username: + A dummy field to trap common bots. Users do not see that. + """ + steps = NEW_ISSUE_STEPS + github_username_pattern = r"^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}$" + # Hidden Form Fields + console_logs_url = HiddenField() + description = HiddenField() + details = HiddenField() + extra_labels = HiddenField() + reported_with = HiddenField() + submit_type = HiddenField() + ua_header = HiddenField() + # Visible Form Fields + browser = StringField( + u'Browser', + [Optional()] + ) + browser_test = RadioField(browser_test_label, [Optional()], + choices=tested_elsewhere) contact = StringField( contact_label, - [Regexp(username_pattern, + [Regexp(github_username_pattern, flags=re.IGNORECASE, message=contact_message)]) - description = StringField(desc_label, - [InputRequired(message=desc_message)]) - - steps_reproduce = TextAreaField(textarea_label, [Optional()]) - problem_category = RadioField([InputRequired(message=radio_message)], - choices=problem_choices) - browser_test = RadioField(browser_test_label, [Optional()], - choices=tested_elsewhere) - # we filter allowed type in uploads.py - # Note, we don't use the label programtically for this input[type=file], - # any changes here need to be updated in form.html. image = FileField('Attach a screenshot image', [Optional(), FileAllowed(ImageUpload.ALLOWED_FORMATS, image_message)]) - details = HiddenField() - reported_with = HiddenField() - ua_header = HiddenField() - submit_type = HiddenField() - extra_labels = HiddenField() - console_logs_url = HiddenField() - - -class FormWizard(IssueForm): - """Re-designed version of IssueForm to a multi step wizard form.""" - - steps = NEW_ISSUE_STEPS - - browser = StringField(u'Browser', [Optional()]) os = StringField('Operating System', [Optional()]) - description = HiddenField() - + steps_reproduce = TextAreaField(textarea_label, [Optional()]) + url = StringField(url_label, [InputRequired(message=url_message)]) + # Steps Form Fields problem_category = PrefixedRadioField( [InputRequired(message=radio_message)], choices=problem_choices_wizard @@ -275,9 +256,12 @@ class FormWizard(IssueForm): [InputRequired(message=radio_message)], choices=browser_choices ) + # Bots Trap + username = StringField('Username', + [Length(max=0, message=username_message)]) -def get_form(form_data, form=IssueForm): +def get_form(form_data, form=FormWizard): """Return an instance of flask_wtf.FlaskForm. It receives a dictionary of everything which needs to be fed to the form. @@ -334,6 +318,8 @@ def build_details(details): def get_radio_button_label(field_value, label_list): """Return human-readable label for problem choices form value.""" + if len(label_list[0]) == 3: + label_list = [(value, text) for value, icon, text in label_list] for value, text in label_list: if value == field_value: return text @@ -349,7 +335,7 @@ def get_problem_summary(category): else: # Return the usual message in lowercase # because it is not at the start of the summary. - return get_radio_button_label(category, problem_choices).lower() + return get_radio_button_label(category, problem_choices_wizard).lower() def wrap_metadata(metadata): @@ -524,7 +510,7 @@ def build_formdata(form_object): 'browser': normalize_metadata(form_object.get('browser')), 'os': normalize_metadata(form_object.get('os')), 'problem_type': get_radio_button_label( - form_object.get('problem_category'), problem_choices), + form_object.get('problem_category'), problem_choices_wizard), 'browser_test_type': get_radio_button_label(form_object.get( 'browser_test'), tested_elsewhere), 'description': form_object.get('description'), diff --git a/webcompat/helpers.py b/webcompat/helpers.py index 5c29007dc..3dddcd7c1 100644 --- a/webcompat/helpers.py +++ b/webcompat/helpers.py @@ -28,7 +28,6 @@ import requests from ua_parser import user_agent_parser -from webcompat import api from webcompat import app from webcompat import github diff --git a/webcompat/views.py b/webcompat/views.py index 988465e48..d2bcbae7f 100644 --- a/webcompat/views.py +++ b/webcompat/views.py @@ -24,10 +24,8 @@ from webcompat.api.endpoints import proxy_issue from webcompat.db import session_db from webcompat.db import User -from webcompat.form import AUTH_REPORT from webcompat.form import get_form from webcompat.form import FormWizard -from webcompat.form import PROXY_REPORT from webcompat.form import normalize_url from webcompat.helpers import ab_active from webcompat.helpers import ab_current_experiments @@ -305,7 +303,7 @@ def create_issue(): msg = app.config['IS_DARKNET_DOMAIN'].format(form['url']) flash(msg, 'notimeout') return redirect(url_for('index')) - if form.get('submit_type') == PROXY_REPORT: + if form.get('submit_type') == 'github-proxy-report': if not app.config['ANONYMOUS_REPORTING_ENABLED']: abort(400) # Checking blocked domains @@ -319,7 +317,7 @@ def create_issue(): return redirect( url_for('show_issue', number=json_response.get('number'))) # Authenticated reporting - if form.get('submit_type') == AUTH_REPORT: + if form.get('submit_type') == 'github-auth-report': if g.user: # If you're already authed, submit the bug. json_response = report_issue(form) session['show_thanks'] = True