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

Commit

Permalink
Shelve
Browse files Browse the repository at this point in the history
  • Loading branch information
chadwhitacre committed Sep 9, 2017
1 parent 982f75c commit 3e13478
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 66 deletions.
5 changes: 3 additions & 2 deletions gratipay/homepage.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ def _parse(raw):
"""

errors = []
x = lambda f: raw.get(f, '').strip()
x = lambda f: raw[f].strip() # KeyError -> 400

# amount
amount = x('amount') or '0'
amount = x('amount')
if (not amount.isdigit()) or (int(amount) < 10):
errors.append('amount')
amount = ''.join(x for x in amount.split('.')[0] if x.isdigit())
Expand Down Expand Up @@ -105,6 +105,7 @@ def pay_for_open_source(app, raw):
payment_method_nonce = parsed.pop('payment_method_nonce')
payment_for_open_source = _store(parsed)
if not errors:
import pdb; pdb.set_trace()
result = _charge(parsed['amount'], payment_method_nonce)
payment_for_open_source.process_result(result)
if not payment_for_open_source.succeeded:
Expand Down
2 changes: 1 addition & 1 deletion gratipay/models/payment_for_open_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class PaymentForOpenSource(Model):
typname = "payments_for_open_source"

def __repr__(self):
return '<PaymentForOpenSource: %s>'.format(repr(self.amount))
return '<PaymentForOpenSource: {}>'.format(repr(self.amount))


@property
Expand Down
52 changes: 26 additions & 26 deletions js/gratipay/homepage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,33 @@ Gratipay.homepage = {}
Gratipay.homepage.initForm = function(clientAuthorization) {
$form = $('#homepage #content form');

$submit= $form.find('button[type=submit]');
$submit.click(Gratipay.homepage.submitForm);

$chooseEcosystem = $form.find('.ecosystem-chooser button');
$chooseEcosystem.click(function(e) {
e.preventDefault();
Gratipay.notification('Not implemented.', 'error');
});

$promote = $form.find('.promotion-gate button');
$promote.click(Gratipay.homepage.openPromote);

function callback(createErr, instance) {
$submit = $form.find('button[type=submit]');
$submit.click(function(e) {
e.preventDefault();
instance.requestPaymentMethod(function(requestPaymentMethodErr, payload) {
Gratipay.homepage.submitFormWithNonce(payload.nonce);
});
});
}

braintree.dropin.create({
authorization: clientAuthorization,
container: '#braintree-container'
}, function (createErr, instance) {
$submit.click(function () {
instance.requestPaymentMethod(function (requestPaymentMethodErr, payload) {
// Submit payload.nonce to your server
});
});
});
}
}, callback);
};

Gratipay.homepage.submitForm = function(e) {
e.preventDefault();

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

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

$.ajax({
url: $form.attr('action'),
Expand All @@ -43,21 +38,26 @@ Gratipay.homepage.submitForm = function(e) {
processData: false,
contentType: false,
dataType: 'json',
success: function (d) {
success: function(d) {
$('a.team_url').attr('href', d.team_url).text(d.team_url);
$('a.review_url').attr('href', d.review_url).text(d.review_url);
$('form').slideUp(500, function() {
$('.application-complete').slideDown(250);
});
},
error: [Gratipay.error, function() { $input.prop('disable', false); }]
error: function(e) {
console.log(e);
debugger;
Gratipay.error(e);
$submit.prop('disable', false);
}
});
}
};

Gratipay.homepage.openPromote = function(e) {
e.preventDefault();
$('.promotion-gate').fadeOut();
$('.promotion-fields').slideDown(function() {
$('.promotion-fields input:first').focus();
});
}
};
16 changes: 15 additions & 1 deletion tests/py/test_www_homepage.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,21 @@ def test_flags_failures_with_transaction_id(self):


def test_post_gets_json(self):
response = self.client.POST('/', data=GOOD)
response = self.client.POST('/', data=GOOD, HTTP_ACCEPT=b'application/json')
assert response.code == 200
assert response.headers['Content-Type'] == 'application/json'
assert json.loads(response.body) == {'parsed': {}, 'errors': []}

def test_bad_post_gets_400(self):
response = self.client.PxST('/', data=BAD, HTTP_ACCEPT=b'application/json')
assert response.code == 400
assert response.headers['Content-Type'] == 'application/json'
scrubbed = SCRUBBED.copy()
scrubbed.pop('payment_method_nonce') # consumed
assert json.loads(response.body) == {'parsed': scrubbed, 'errors': ALL}

def test_really_bad_post_gets_plain_400(self):
response = self.client.PxST('/', data={}, HTTP_ACCEPT=b'application/json')
assert response.code == 400
assert response.headers == {}
assert response.body == "Missing key: u'amount'"
37 changes: 37 additions & 0 deletions tests/ttw/test_homepage.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,28 @@

class Tests(BrowserHarness):

def fill_form(self, amount, credit_card_number, expiration, cvv, name, email_address,
follow_up, promotion_name, promotion_url, promotion_twitter, promotion_message):
self.wait_for('.braintree-form-number')
self.fill('amount', amount)
with self.get_iframe('braintree-hosted-field-number') as iframe:
iframe.fill('credit-card-number', credit_card_number)
with self.get_iframe('braintree-hosted-field-expirationDate') as iframe:
iframe.fill('expiration', expiration)
with self.get_iframe('braintree-hosted-field-cvv') as iframe:
iframe.fill('cvv', cvv)
self.fill('name', name)
self.fill('email_address', email_address)
if promotion_name:
self.css('.promotion-gate button').type('\n')
# stackoverflow.com/q/11908249#comment58577676_19763087
self.wait_for('#promotion-message')
self.fill('promotion_name', promotion_name)
self.fill('promotion_url', promotion_url)
self.fill('promotion_twitter', promotion_twitter)
self.fill('promotion_message', promotion_message)


def test_loads_for_anon(self):
assert self.css('#banner h1').html == 'Pay for open source.'
assert self.css('#header .sign-in button').html.strip()[:17] == 'Sign in / Sign up'
Expand All @@ -15,3 +37,18 @@ def test_redirects_for_authed_exclamation_point(self):
self.reload()
assert self.css('#banner h1').html == 'Browse'
assert self.css('.you-are a').html.strip()[:6] == '~alice'

def test_anon_can_post(self):
self.fill_form('537', '4242424242424242', '1020', '123', 'Alice Liddell',
'[email protected]', 'monthly', 'Wonderland', 'http://www.example.com/',
'thebestbutter', 'Love me! Love me! Say that you love me!')
self.css('fieldset.submit button').type('\n')
import pdb; pdb.set_trace()
assert self.db.one('SELECT * FROM payments_for_open_source').promotion_name == 'Wonderland'

def est_validation_works(self):
self.fill_form('537', '4242424242424242', '', '', 'Alice Liddell', '[email protected]',
'monthly', 'Wonderland', 'http://www.example.com/', 'thebestbutter',
'Love me! Love me! Say that you love me!')
self.css('fieldset.submit button').type('\n')
assert self.db.one('select * from moral_license_payments').promotion_name == 'Wonderland'
66 changes: 30 additions & 36 deletions www/index.spt
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
import json
from aspen import Response
from gratipay.homepage import pay_for_open_source
[---]
if not user.ANON:
Expand All @@ -7,6 +9,9 @@ suppress_sidebar = True
page_id = "homepage"
banner = "Pay for Open Source"
result = pay_for_open_source(website.app, request.body) if request.method == 'POST' else {}
if result.get('errors'):
# Hmmm ... bit of an Aspen rough spot ... interaction w/ error.spt, skip it
raise Response(400, json.dumps(result), {'Content-Type': 'application/json'})
[---] application/json via json_dump
result
[---] text/html
Expand Down Expand Up @@ -37,7 +42,7 @@ $(document).ready(function() {
{% endblock %}

{% block content %}
<form action="/companies/create.json" method="POST">
<form action="/" method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">

<fieldset>
Expand All @@ -62,20 +67,21 @@ $(document).ready(function() {
<div id="braintree-container"></div>
</fieldset>

<fieldset>
<legend>{{ _('Step 2 of 3') }}</legend>
<fieldset class="optional">
<legend>{{ _('Optional') }}</legend>

<h2>{{ _('Who are you?') }}</h2>

<div class="field">
<label for="name">{{ _('Your Name') }}</label>
<input name="name" id="name" type="text" required>
<input name="name" id="name" type="text">
</div>

<div class="field email-address">
<label for="email-address">{{ _('Your Email Address') }}</label>
<input name="email-address" id="email-address" type="text" required>
<input name="email_address" id="email-address" type="text">
<p class="fine-print">
{{ _('You will get a verification link before we finalize your payment.') }}
{{ _('You will get a receipt for your payment.') }}
</p>
</div>

Expand All @@ -84,23 +90,23 @@ $(document).ready(function() {
<legend>{{ _('Follow-up') }}</legend>

<div class="fancy-radio">
<input type="radio" name="follow-up" id="follow-up-monthly" value="monthly">
<input type="radio" name="follow_up" id="follow-up-monthly" value="monthly">
<label for="follow-up-monthly">{{ _('Monthly') }}</label>
</div>

<div class="fancy-radio">
<input type="radio" name="follow-up" id="follow-up-quarterly"
<input type="radio" name="follow_up" id="follow-up-quarterly"
value="quarterly" checked>
<label for="follow-up-quarterly">{{ _('Quarterly') }}</label>
</div>

<div class="fancy-radio">
<input type="radio" name="follow-up" id="follow-up-yearly" value="yearly">
<input type="radio" name="follow_up" id="follow-up-yearly" value="yearly">
<label for="follow-up-yearly">{{ _('Yearly') }}</label>
</div>

<div class="fancy-radio">
<input type="radio" name="follow-up" id="follow-up-never" value="never">
<input type="radio" name="follow_up" id="follow-up-never" value="never">
<label for="follow-up-never">{{ _('Never') }}</label>
</div>

Expand All @@ -109,19 +115,6 @@ $(document).ready(function() {
</p>
</fieldset>
</div>
</fieldset>

<fieldset class="optional">
<legend>{{ _('Optional') }}</legend>
<h2>{{ _('Ecosystems') }}</h2>
<p class="fine-print">
{{ _('Which do you value most?{br}(JavaScript, Python, etc.)', br='<br>'|safe) }}
</p>

<div class="important-button ecosystem-chooser">
<button class="large">{{ _('Choose an Ecosystem') }}</button>
</div>
<div class="ecosystems"></div>


<h2>{{ _('Promotion') }}</h2>
Expand All @@ -130,23 +123,24 @@ $(document).ready(function() {
<p class="fine-print">{{ _('Thanks! We are excited to brag about you!') }}</p>

<div class="field">
<label label="company">{{ _("Your Company Name") }}</label>
<input type="text" name="promote-name" id="promote-name">
<label for="promotion-name">{{ _("Your Company Name") }}</label>
<input type="text" name="promotion_name" id="promotion-name">
</div>

<div class="field">
<label label="company">{{ _("Your Landing Page URL") }}</label>
<input type="text" name="promote-url" id="promote-url">
<label for="promotion-url">{{ _("Your Landing Page URL") }}</label>
<input type="text" name="promotion_url" id="promotion-url">
</div>

<div class="field">
<label label="company">{{ _("Your Company Twitter Handle") }}</label>
<input type="text" name="promote-twitter" id="promote-twitter">
<label for="promotion-twitter">{{ _("Your Company Twitter Handle") }}</label>
<input type="text" name="promotion_twitter" id="promotion-twitter">
</div>

<div class="field">
<label label="company">{{ _("Your Message to the Open Source Community") }}</label>
<input type="text" name="promote-message" id="promote-message">
<label for="promotion-message">
{{ _("Your Message to the Open Source Community") }}</label>
<input type="text" name="promotion_message" id="promotion-message">
</div>
</div>

Expand All @@ -157,18 +151,18 @@ $(document).ready(function() {

</fieldset>

<fieldset>
<fieldset class="submit">
<legend>{{ _('Submit Form') }}</legend>

<div class="important-button">
<button type="submit" class="apply selected large">
<button type="submit" class="selected large">
{{ _("Pay for Open Source") }}
</button>
</div>
<p class="fine-print">
{{ _( "By submitting this form you agree to our {0}terms of service{1}."
, '<a href="/about/policies/terms-of-service">'|safe
, '</a>'|safe
{{ _( "By submitting this form you agree to our {a}terms of service{_a}."
, a='<a href="/about/policies/terms-of-service">'|safe
, _a='</a>'|safe
) }}
</p>
</fieldset>
Expand Down

0 comments on commit 3e13478

Please sign in to comment.