Skip to content
This repository has been archived by the owner on Feb 8, 2018. It is now read-only.

Commit

Permalink
Add error handling to the UI
Browse files Browse the repository at this point in the history
  • Loading branch information
chadwhitacre committed Sep 11, 2017
1 parent 8d246cd commit 0161380
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 35 deletions.
8 changes: 4 additions & 4 deletions gratipay/homepage.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ def _parse(raw):

# name
name = x('name')
if len(name) > 256:
name = name[:256]
if len(name) > 255:
name = name[:255]
errors.append('name')

# email address
Expand All @@ -51,8 +51,8 @@ def _parse(raw):

promotion_url = x('promotion_url')
is_link = lambda x: (x.startswith('http://') or x.startswith('https://')) and '.' in x
if len(promotion_url) > 256 or (promotion_url and not is_link(promotion_url)):
promotion_url = promotion_url[:256]
if len(promotion_url) > 255 or (promotion_url and not is_link(promotion_url)):
promotion_url = promotion_url[:255]
errors.append('promotion_url')

promotion_twitter = x('promotion_twitter')
Expand Down
32 changes: 18 additions & 14 deletions js/gratipay/homepage.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
Gratipay.homepage = {}

Gratipay.homepage.initForm = function(clientAuthorization) {
$form = $('#homepage #content form');
$submit = $form.find('button[type=submit]');
var self = this;
self.$form = $('#homepage #content form');
self.$submit = self.$form.find('button[type=submit]');

if (clientAuthorization === undefined) { // Offline mode

Expand All @@ -14,10 +15,10 @@ Gratipay.homepage.initForm = function(clientAuthorization) {
['p', {'class': 'fine-print'}, "If you're seeing this on gratipay.com, we screwed up."]
]));

$submit.click(function(e) {
self.$submit.click(function(e) {
e.preventDefault();
nonce = $('#braintree-container input').val();
Gratipay.homepage.submitFormWithNonce(nonce);
self.submitFormWithNonce(nonce);
});

} else { // Online mode (sandbox or production)
Expand All @@ -26,10 +27,10 @@ Gratipay.homepage.initForm = function(clientAuthorization) {
if (createErr) {
$('#braintree-container').addClass('failed').text('Failed to load Braintree.');
} else {
$submit.click(function(e) {
self.$submit.click(function(e) {
e.preventDefault();
instance.requestPaymentMethod(function(requestPaymentMethodErr, payload) {
Gratipay.homepage.submitFormWithNonce(payload.nonce);
self.submitFormWithNonce(payload.nonce);
});
});
}
Expand All @@ -44,15 +45,14 @@ Gratipay.homepage.initForm = function(clientAuthorization) {


Gratipay.homepage.submitFormWithNonce = function(nonce) {
$submit = $form.find('button[type=submit]');
$form = $('#homepage #content form');
var data = new FormData($form[0]);
var self = this;
var data = new FormData(self.$form[0]);
data.set('payment_method_nonce', nonce);

$submit.prop('disable', true);
self.$submit.prop('disable', true);

$.ajax({
url: $form.attr('action'),
url: self.$form.attr('action'),
type: 'POST',
data: data,
processData: false,
Expand All @@ -61,12 +61,16 @@ Gratipay.homepage.submitFormWithNonce = function(nonce) {
success: function(data) {
// Due to Aspen limitations we use 200 for both success and failure. :/
if (data.errors.length > 0) {
$submit.prop('disable', false);
self.$submit.prop('disable', false);
Gratipay.notification(data.msg, 'error');
for (var i=0, fieldName; fieldName=data.errors[i]; i++) {
$('.'+fieldName, self.$form).addClass('error');
}
} else {
$('.payment-complete a.receipt').attr('href', data.receipt_url);
$('.payment-complete').slideDown(200);
$('form').slideUp(500);
$('form').slideUp(500, function() {
$('.payment-complete').fadeIn(500);
});
}
}
});
Expand Down
21 changes: 19 additions & 2 deletions scss/pages/homepage.scss
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,16 @@
width: 50%;
text-align: center;
}
.help {
text-align: center;
}
}
&.email-address, &.follow-up {
&.email_address, &.follow_up {
.fine-print {
text-align: left;
}
}
&.follow-up {
&.follow_up {
.fancy-radio {
position: relative;
display: inline-block;
Expand Down Expand Up @@ -191,6 +194,20 @@
}
}
}
.help {
display: none;
color: red;
text-align: left;
}
&.error {
.help {
display: block;
}
input {
border-color: red;
background: pink;
}
}
}
&.optional {
button {
Expand Down
4 changes: 2 additions & 2 deletions tests/py/test_www_homepage.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@
}
SCRUBBED = { 'amount': '1000'
, 'payment_method_nonce': ''
, 'name': 'Alice Liddell' * 19 + 'Alice Lid'
, 'name': 'Alice Liddell' * 19 + 'Alice Li'
, 'email_address': 'alice' * 51
, 'follow_up': 'monthly'
, 'promotion_name': 'WonderlandWonderlandWonderlandWo'
, 'promotion_url': 'http://www.example.com/' + 'cheese' * 38 + 'chees'
, 'promotion_url': 'http://www.example.com/' + 'cheese' * 38 + 'chee'
, 'promotion_twitter': 'thebestbutterthebestbutterthebes'
, 'promotion_message': 'Love me!' * 16
}
Expand Down
13 changes: 12 additions & 1 deletion tests/ttw/test_homepage.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@ def test_anon_can_post(self):
'thebestbutter', 'Love me! Love me! Say that you love me!')
assert self.submit_succeeds()

def test_optional_are_optional(self):
def test_options_are_optional(self):
self.fill_form('537', '4242424242424242', '1020', '123')
assert self.submit_succeeds()

def test_errors_are_handled(self):
self.fill_form('1,000', '4242424242424242', '1020', '123', 'Alice Liddell',
'alice@example', 'Wonderland',
'htp://www.example.com/', 'thebestbutter', 'Love me!')
self.css('fieldset.submit button').click()
assert self.wait_for_error() == 'Eep! Mind looking over your info for us?'
assert self.css('.field.email_address').has_class('error')
assert self.css('.field.promotion_url').has_class('error')
assert not self.css('.field.email_address').has_class('amount')
assert self.fetch() is None
55 changes: 43 additions & 12 deletions www/index.spt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ result = pay_for_open_source(website.app, request.body) if request.method == 'PO
if result and result['errors']:
# Hmmm ... bit of an Aspen rough spot ... interaction w/ error.spt, skip it
# by overriding 200 for both success and failure. :(
result['msg'] = _("Sorry, we could not process your payment.")
result['msg'] = _("Eep! Mind looking over your info for us?")
[---] application/json via json_dump
result
[---] text/html
Expand Down Expand Up @@ -53,7 +53,7 @@ $(document).ready(function() {
{{ _("Payment complete!") }} 💃
</div>
<p class="instructions">
{{ _("Thank you for your payment!") }}
{{ _("Thank you for paying for open source!") }}
</p>
<div class="important-button" class="important-button">
<a class="button large selected receipt" href="">{{ _("View Receipt") }}</a>
Expand Down Expand Up @@ -95,6 +95,10 @@ $(document).ready(function() {
placeholder="{{ _("2,000 / person") }}"
required autofocus>

<p class="fine-print help">
{{ _("Please enter a whole dollar amount (minimum $10, no punctuation).") }}
</p>

<p class="fine-print">
{{ _( 'We {a}recommend{_a} $2,000 per year{br}per technical employee{br}at your company.'
, br='<br>'|safe
Expand All @@ -105,7 +109,12 @@ $(document).ready(function() {

</div>

<div id="braintree-container"></div>
<div class="field charging">
<div id="braintree-container"></div>
<p class="fine-print help">
{{ _("We weren't able to process your card.") }}
</p>
</div>
</fieldset>

<fieldset class="optional">
Expand All @@ -114,20 +123,26 @@ $(document).ready(function() {
<h2>{{ _('Who are you?') }}</h2>
<p class="fine-print">{{ _('And do you wish to subscribe to our newsletter?') }}</p>

<div class="field">
<div class="field name">
<label for="name">{{ _('Your Name') }}</label>
<input name="name" id="name" type="text">
<p class="fine-print help">
{{ _("Please enter a value shorter than 256 characters.") }}
</p>
</div>

<div class="field email-address">
<div class="field email_address">
<label for="email-address">{{ _('Your Email Address') }}</label>
<input name="email_address" id="email-address" type="text">
<p class="fine-print help">
{{ _("Please enter a valid email address shorter than 255 characters.") }}
</p>
<p class="fine-print">
{{ _('You will get a receipt for your payment.') }}
{{ _('You will get a link to a receipt for your payment.') }}
</p>
</div>

<div class="field follow-up">
<div class="field follow_up">
<fieldset>
<legend>{{ _('Follow-up') }}</legend>

Expand All @@ -152,6 +167,10 @@ $(document).ready(function() {
<label for="follow-up-never">{{ _('Never') }}</label>
</div>

<p class="fine-print help">
{{ _("I am surprised that you are seeing this message.") }}
</p>

<p class="fine-print">
{{ _('You will get a progress report, with a reminder to pay again.') }}
</p>
Expand All @@ -160,28 +179,40 @@ $(document).ready(function() {


<h2>{{ _('Promotion') }}</h2>
<p class="fine-print">{{ _('We want to brag about you! May we?') }}</p>
<p class="fine-print">{{ _('We (probably) want to brag about you! May we?') }}</p>

<div class="promotion-fields">
<div class="field">
<div class="field promotion_name">
<label for="promotion-name">{{ _("Your Company Name") }}</label>
<input type="text" name="promotion_name" id="promotion-name">
<p class="fine-print help">
{{ _("Please enter a value 32 characters or shorter.") }}
</p>
</div>

<div class="field">
<div class="field promotion_url">
<label for="promotion-url">{{ _("Your Landing Page URL") }}</label>
<input type="text" name="promotion_url" id="promotion-url">
<p class="fine-print help">
{{ _("Please enter a valid URL shorter than 256 characters.") }}
</p>
</div>

<div class="field">
<div class="field promotion_twitter">
<label for="promotion-twitter">{{ _("Your Company Twitter Handle") }}</label>
<input type="text" name="promotion_twitter" id="promotion-twitter">
<p class="fine-print help">
{{ _("Please enter a valid Twitter handle.") }}
</p>
</div>

<div class="field">
<div class="field promotion_message">
<label for="promotion-message">
{{ _("Your Message to the Open Source Community") }}</label>
<input type="text" name="promotion_message" id="promotion-message">
<p class="fine-print help">
{{ _("Please limit your message to 128 characters.") }}
</p>
</div>
</div>
</fieldset>
Expand Down

0 comments on commit 0161380

Please sign in to comment.