示例#1
0
    def setUp(self):
        # Balanced Customer without funding instruments
        self.david = self.make_participant('david', is_suspicious=False,
                                           claimed_time='now',
                                           balanced_customer_href=self.david_href)

        # Balanced Customer with CC attached
        self.janet = self.make_participant('janet', is_suspicious=False,
                                           claimed_time='now',
                                           balanced_customer_href=self.janet_href)
        self.janet_route = ExchangeRoute.insert(self.janet, 'balanced-cc', self.card_href)

        # Balanced Customer with BA attached
        self.homer = self.make_participant('homer', is_suspicious=False,
                                           claimed_time='now',
                                           balanced_customer_href=self.homer_href)
        self.homer_route = ExchangeRoute.insert(self.homer, 'balanced-ba', self.bank_account_href)

        # Braintree Customer without funding instruments
        self.roman = self.make_participant('roman', is_suspicious=False,
                                         claimed_time='now',
                                         braintree_customer_id=self.roman_bt_id)
        # Braintree Customer with CC attached
        self.obama = self.make_participant('obama', is_suspicious=False,
                                          claimed_time='now',
                                          braintree_customer_id=self.obama_bt_id)
        self.obama_route = ExchangeRoute.insert(self.obama, 'braintree-cc', self.obama_cc_token)
 def test_credit_callback(self, rer):
     alice = self.make_participant('alice')
     ExchangeRoute.insert(alice, 'balanced-ba', '/bank/foo', '')
     ba = ExchangeRoute.from_network(alice, 'balanced-ba')
     for status in ('succeeded', 'failed'):
         error = 'FOO' if status == 'failed' else None
         e_id = record_exchange(self.db, ba, 10, 0, alice, 'pre')
         body = json.dumps({
             "events": [{
                 "type": "credit." + status,
                 "entity": {
                     "credits": [{
                         "failure_reason": error,
                         "meta": {
                             "participant_id": alice.id,
                             "exchange_id": e_id,
                         },
                         "status": status,
                     }]
                 }
             }]
         })
         r = self.callback(body=body, csrf_token=False)
         assert r.code == 200, r.body
         assert rer.call_count == 1
         assert rer.call_args[0][:-1] == (self.db, e_id, status, error)
         assert rer.call_args[0][-1].id == alice.id
         assert rer.call_args[1] == {}
         rer.reset_mock()
 def test_credit_callback(self, rer):
     alice = self.make_participant('alice')
     ExchangeRoute.insert(alice, 'balanced-ba', '/bank/foo', '')
     ba = ExchangeRoute.from_network(alice, 'balanced-ba')
     for status in ('succeeded', 'failed'):
         error = 'FOO' if status == 'failed' else None
         e_id = record_exchange(self.db, ba, 10, 0, alice, 'pre')
         body = json.dumps({
             "events": [
                 {
                     "type": "credit."+status,
                     "entity": {
                         "credits": [
                             {
                                 "failure_reason": error,
                                 "meta": {
                                     "participant_id": alice.id,
                                     "exchange_id": e_id,
                                 },
                                 "status": status,
                             }
                         ]
                     }
                 }
             ]
         })
         r = self.callback(body=body, csrf_token=False)
         assert r.code == 200, r.body
         assert rer.call_count == 1
         assert rer.call_args[0][:-1] == (self.db, e_id, status, error)
         assert rer.call_args[0][-1].id == alice.id
         assert rer.call_args[1] == {}
         rer.reset_mock()
 def test_grprbn_includes_1_0_payouts(self):
     alice = self.make_participant('alice',
                                   balance=24,
                                   status_of_1_0_payout='pending-payout',
                                   claimed_time='now')
     ExchangeRoute.insert(alice, 'paypal', '*****@*****.**')
     routes = get_ready_payout_routes_by_network(self.db, 'paypal')
     assert [r.participant.username for r in routes] == ['alice']
 def test_grprbn_includes_1_0_payouts(self):
     alice = self.make_participant( 'alice'
                                  , balance=24
                                  , status_of_1_0_payout='pending-payout'
                                  , claimed_time='now'
                                   )
     ExchangeRoute.insert(alice, 'paypal', '*****@*****.**')
     routes = get_ready_payout_routes_by_network(self.db, 'paypal')
     assert [r.participant.username for r in routes] == ['alice']
示例#6
0
    def make_participant(self, username, **kw):
        """Factory for :py:class:`~gratipay.models.participant.Participant`.
        """
        participant = self.db.one(
            """
            INSERT INTO participants
                        (username, username_lower)
                 VALUES (%s, %s)
              RETURNING participants.*::participants
        """, (username, username.lower()))

        if 'elsewhere' in kw or 'claimed_time' in kw:
            platform = kw.pop('elsewhere', 'github')
            self.db.run(
                """
                INSERT INTO elsewhere
                            (platform, user_id, user_name, participant)
                     VALUES (%s,%s,%s,%s)
            """, (platform, participant.id, username, username))

        # Insert exchange routes
        if 'last_bill_result' in kw:
            route = ExchangeRoute.insert(participant, 'braintree-cc',
                                         '/cards/foo')
            route.update_error(kw.pop('last_bill_result'))
        if 'last_paypal_result' in kw:
            route = ExchangeRoute.insert(participant, 'paypal',
                                         '*****@*****.**')
            route.update_error(kw.pop('last_paypal_result'))

        # Update participant
        verified_in = kw.pop('verified_in', [])
        if kw:
            if kw.get('claimed_time') == 'now':
                kw['claimed_time'] = utcnow()
            cols, vals = zip(*kw.items())
            cols = ', '.join(cols)
            placeholders = ', '.join(['%s'] * len(vals))
            participant = self.db.one(
                """
                UPDATE participants
                   SET ({0}) = ({1})
                 WHERE username=%s
             RETURNING participants.*::participants
            """.format(cols, placeholders), vals + (username, ))

        # Verify identity
        countries = [verified_in
                     ] if type(verified_in) in (str, unicode) else verified_in
        for code in countries:
            country = self.db.one("SELECT id FROM countries WHERE code=%s",
                                  (code, ))
            participant.store_identity_info(country, 'nothing-enforced',
                                            {'name': username})
            participant.set_identity_verification(country, True)

        return participant
示例#7
0
 def setUp(self):
     self.david = self.make_participant('david', is_suspicious=False,
                                        claimed_time='now',
                                        balanced_customer_href=self.david_href)
     self.janet = self.make_participant('janet', is_suspicious=False,
                                        claimed_time='now',
                                        balanced_customer_href=self.janet_href)
     self.janet_route = ExchangeRoute.insert(self.janet, 'balanced-cc', self.card_href)
     self.homer = self.make_participant('homer', is_suspicious=False,
                                        claimed_time='now',
                                        balanced_customer_href=self.homer_href)
     self.homer_route = ExchangeRoute.insert(self.homer, 'balanced-ba', self.bank_account_href)
示例#8
0
    def test_create_card_hold_bad_card(self):
        bob = self.make_participant('bob',
                                    balanced_customer_href='new',
                                    is_suspicious=False)
        card = balanced.Card(number='4444444444444448',
                             expiration_year=2020,
                             expiration_month=12).save()
        card.associate_to_customer(bob.balanced_customer_href)
        ExchangeRoute.insert(bob, 'balanced-cc', card.href)

        hold, error = create_card_hold(self.db, bob, D('10.00'))
        assert error.startswith('402 Payment Required, ')
    def test_create_card_hold_bad_card(self):
        bob = self.make_participant('bob', balanced_customer_href='new',
                                    is_suspicious=False)
        card = balanced.Card(
            number='4444444444444448',
            expiration_year=2020,
            expiration_month=12
        ).save()
        card.associate_to_customer(bob.balanced_customer_href)
        ExchangeRoute.insert(bob, 'balanced-cc', card.href)

        hold, error = create_card_hold(self.db, bob, D('10.00'))
        assert error.startswith('402 Payment Required, ')
示例#10
0
def set_paypal_email(username='',
                     email='',
                     api_key_fragment='',
                     overwrite=False):
    """
    Usage:

    [gratipay] $ env/bin/invoke set_paypal_email --username=username [email protected] [--api-key-fragment=12e4s678] [--overwrite]
    """

    if not username or not email:
        print_help(set_paypal_email)
        sys.exit(1)

    if not os.environ.get('DATABASE_URL'):
        load_prod_envvars()

    if not api_key_fragment:
        first_eight = "unknown!"
    else:
        first_eight = api_key_fragment

    wireup.db(wireup.env())

    participant = Participant.from_username(username)
    if not participant:
        print("No Gratipay participant found with username '" + username + "'")
        sys.exit(2)

    route = ExchangeRoute.from_network(participant, 'paypal')

    # PayPal caps the MassPay fee at $20 for users outside the U.S., and $1 for
    # users inside the U.S. Most Gratipay users using PayPal are outside the U.S.
    # so we set to $20 and I'll manually adjust to $1 when running MassPay and
    # noticing that something is off.
    FEE_CAP = 20

    if route:
        print("PayPal email is already set to: " + route.address)
        if not overwrite:
            print("Not overwriting existing PayPal email.")
            sys.exit(3)

    if participant.api_key == None:
        assert first_eight == "None"
    else:
        assert participant.api_key[0:8] == first_eight

    print("Setting PayPal email for " + username + " to " + email)
    ExchangeRoute.insert(participant, 'paypal', email, fee_cap=FEE_CAP)
    print("All done.")
示例#11
0
 def setUp(self):
     # Braintree Customer without funding instruments
     self.roman = self.make_participant('roman', is_suspicious=False,
                                      claimed_time='now',
                                      braintree_customer_id=self.roman_bt_id)
     # Braintree Customer with CC attached
     self.obama = self.make_participant('obama', is_suspicious=False,
                                       claimed_time='now',
                                       braintree_customer_id=self.obama_bt_id)
     self.obama_route = ExchangeRoute.insert(self.obama, 'braintree-cc', self.obama_cc_token)
     # A customer with Paypal attached.
     self.homer = self.make_participant('homer', is_suspicious=False,
                                        claimed_time='now')
     self.homer_route = ExchangeRoute.insert(self.homer, 'paypal', '*****@*****.**')
    def test_cch_multiple_cards(self):
        bob = self.make_participant('bob', is_suspicious=False)
        customer_id = bob.get_braintree_account().id

        for i in range(2):
            result = braintree.PaymentMethod.create({
                "customer_id": customer_id,
                "payment_method_nonce": Nonces.Transactable
            })
            assert result.is_success
            ExchangeRoute.insert(bob, 'braintree-cc', result.payment_method.token)

        self.hold, error = create_card_hold(self.db, bob, D('100.00'))
        assert error == ''
    def test_cch_multiple_cards(self):
        bob = self.make_participant('bob', is_suspicious=False)
        customer_id = bob.get_braintree_account().id

        for i in range(2):
            result = braintree.PaymentMethod.create({
                "customer_id": customer_id,
                "payment_method_nonce": Nonces.Transactable
            })
            assert result.is_success
            ExchangeRoute.insert(bob, 'braintree-cc', result.payment_method.token)

        self.hold, error = create_card_hold(self.db, bob, D('100.00'))
        assert error == ''
示例#14
0
    def test_giving_is_updated_when_credit_card_is_updated(self, btd):
        alice = self.make_participant('alice', claimed_time='now', last_bill_result='fail')
        team = self.make_team(is_approved=True)

        alice.set_payment_instruction(team, '5.00') # Not funded, failing card

        assert alice.giving == Decimal('0.00')
        assert Team.from_slug(team.slug).receiving == Decimal('0.00')

        # Alice updates her card..
        ExchangeRoute.from_network(alice, 'braintree-cc').invalidate()
        ExchangeRoute.insert(alice, 'braintree-cc', '/cards/bar', '')

        assert alice.giving == Decimal('5.00')
        assert Team.from_slug(team.slug).receiving == Decimal('5.00')
    def test_giving_is_updated_when_credit_card_is_updated(self, btd):
        alice = self.make_participant('alice', claimed_time='now', last_bill_result='fail')
        team = self.make_team(is_approved=True)

        alice.set_payment_instruction(team, '5.00') # Not funded, failing card

        assert alice.giving == Decimal('0.00')
        assert Team.from_slug(team.slug).receiving == Decimal('0.00')

        # Alice updates her card..
        ExchangeRoute.from_network(alice, 'braintree-cc').invalidate()
        ExchangeRoute.insert(alice, 'braintree-cc', '/cards/bar', '')

        assert alice.giving == Decimal('5.00')
        assert Team.from_slug(team.slug).receiving == Decimal('5.00')
    def test_cch_bad_card(self):
        bob = self.make_participant('bob', is_suspicious=False)
        customer_id = bob.get_braintree_account().id
        result = braintree.PaymentMethod.create({
            "customer_id": customer_id,
            "payment_method_nonce": Nonces.Transactable
        })
        assert result.is_success
        ExchangeRoute.insert(bob, 'braintree-cc', result.payment_method.token)

        # https://developers.braintreepayments.com/ios+python/reference/general/testing#test-amounts
        # $2002 is upcharged to $2062, which corresponds to 'Invalid Tax Amount'
        self.hold, error = create_card_hold(self.db, bob, D('2002.00'))
        assert self.hold is None
        assert error.startswith('Invalid Tax Amount')
    def test_cch_bad_card(self):
        bob = self.make_participant('bob', is_suspicious=False)
        customer_id = bob.get_braintree_account().id
        result = braintree.PaymentMethod.create({
            "customer_id": customer_id,
            "payment_method_nonce": Nonces.Transactable
        })
        assert result.is_success
        ExchangeRoute.insert(bob, 'braintree-cc', result.payment_method.token)

        # https://developers.braintreepayments.com/ios+python/reference/general/testing#test-amounts
        # $2002 is upcharged to $2062, which corresponds to 'Invalid Tax Amount'
        self.hold, error = create_card_hold(self.db, bob, D('2002.00'))
        assert self.hold is None
        assert error.startswith('Invalid Tax Amount')
示例#18
0
    def test_giving_is_updated_when_credit_card_is_updated(self, btd):
        alice = self.make_participant("alice", claimed_time="now", last_bill_result="fail")
        team = self.make_team(is_approved=True)

        alice.set_payment_instruction(team, "5.00")  # Not funded, failing card

        assert alice.giving == Decimal("0.00")
        assert Team.from_slug(team.slug).receiving == Decimal("0.00")

        # Alice updates her card..
        ExchangeRoute.from_network(alice, "braintree-cc").invalidate()
        ExchangeRoute.insert(alice, "braintree-cc", "/cards/bar", "")

        assert alice.giving == Decimal("5.00")
        assert Team.from_slug(team.slug).receiving == Decimal("5.00")
示例#19
0
def set_paypal_email(username='', email='', api_key_fragment='', overwrite=False):
    """
    Usage:

    [gratipay] $ env/bin/invoke set_paypal_email --username=username [email protected] [--api-key-fragment=12e4s678] [--overwrite]
    """

    if not username or not email:
        print_help(set_paypal_email)
        sys.exit(1)

    if not os.environ.get('DATABASE_URL'):
        load_prod_envvars()

    if not api_key_fragment:
        first_eight = "unknown!"
    else:
        first_eight = api_key_fragment

    wireup.db(wireup.env())

    participant = Participant.from_username(username)
    if not participant:
        print("No Gratipay participant found with username '" + username + "'")
        sys.exit(2)

    route = ExchangeRoute.from_network(participant, 'paypal')

    # PayPal caps the MassPay fee at $20 for users outside the U.S., and $1 for
    # users inside the U.S. Most Gratipay users using PayPal are outside the U.S.
    # so we set to $20 and I'll manually adjust to $1 when running MassPay and
    # noticing that something is off.
    FEE_CAP = 20

    if route:
        print("PayPal email is already set to: " + route.address)
        if not overwrite:
            print("Not overwriting existing PayPal email.")
            sys.exit(3)

    if participant.api_key == None:
        assert first_eight == "None"
    else:
        assert participant.api_key[0:8] == first_eight

    print("Setting PayPal email for " + username + " to " + email)
    ExchangeRoute.insert(participant, 'paypal', email, fee_cap=FEE_CAP)
    print("All done.")
示例#20
0
    def make_participant(self, username, **kw):
        participant = self.db.one(
            """
            INSERT INTO participants
                        (username, username_lower)
                 VALUES (%s, %s)
              RETURNING participants.*::participants
        """,
            (username, username.lower()),
        )

        if "elsewhere" in kw or "claimed_time" in kw:
            platform = kw.pop("elsewhere", "github")
            self.db.run(
                """
                INSERT INTO elsewhere
                            (platform, user_id, user_name, participant)
                     VALUES (%s,%s,%s,%s)
            """,
                (platform, participant.id, username, username),
            )

        # Insert exchange routes
        if "last_bill_result" in kw:
            ExchangeRoute.insert(participant, "braintree-cc", "/cards/foo", kw.pop("last_bill_result"))
        if "last_paypal_result" in kw:
            ExchangeRoute.insert(participant, "paypal", "*****@*****.**", kw.pop("last_paypal_result"))

        # Update participant
        if kw:
            if kw.get("claimed_time") == "now":
                kw["claimed_time"] = utcnow()
            cols, vals = zip(*kw.items())
            cols = ", ".join(cols)
            placeholders = ", ".join(["%s"] * len(vals))
            participant = self.db.one(
                """
                UPDATE participants
                   SET ({0}) = ({1})
                 WHERE username=%s
             RETURNING participants.*::participants
            """.format(
                    cols, placeholders
                ),
                vals + (username,),
            )

        return participant
示例#21
0
 def test_bitcoin_payout(self, cb):
     # https://developers.coinbase.com/api#send-money
     cb.return_value.status_code = 200
     cb.return_value.json = lambda: {
         'success': True,
         'transfer': {
             'fees': {
                 'coinbase': {'currency_iso': 'USD', 'cents': 10},
                 'bank': {'currency_iso': 'USD', 'cents': 15}
             },
             'subtotal': {'currency': 'USD', 'amount': 20},
             'btc': {'currency': 'BTC', 'amount': 1}
         }
     }
     alice = self.make_participant('alice', api_key='abcdefgh', balance=100)
     route = ExchangeRoute.insert(alice, 'bitcoin', '17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j')
     bitcoin_payout(username='******', amount=20, api_key_fragment=alice.api_key[0:8])
     alice = Participant.from_username('alice')
     assert alice.balance == 79.75
     exchange = self.db.one("""
         SELECT *
           FROM exchanges
          WHERE participant='alice'
     """)
     assert exchange.amount == -20
     assert exchange.fee == 0.25
     assert exchange.route == route.id
 def test_scopes_to_cursor(self):
     alice = self.make_participant('alice', claimed_time='now')
     with self.db.get_cursor() as cursor:
         route = ExchangeRoute.insert(alice, 'paypal', '*****@*****.**', cursor=cursor)
         assert alice.get_payout_routes() == []
         assert alice.get_payout_routes(cursor=cursor) == [route]
     assert alice.get_payout_routes() == [route]
示例#23
0
    def record_an_exchange(self, data, make_participants=True):
        if make_participants:
            self.make_participants()

        data.setdefault('status', 'succeeded')
        data.setdefault('note', 'noted')

        if 'route_id' not in data:
            try:
                data['route_id'] = ExchangeRoute.insert(
                    self.bob, 'paypal', '*****@*****.**').id
            except IntegrityError:
                data['route_id'] = ExchangeRoute.from_network(
                    self.bob, 'paypal').id

        if data['status'] is None:
            del (data['status'])
        if data['route_id'] is None:
            del (data['route_id'])

        if 'ref' not in data:
            data['ref'] = 'N/A'

        return self.client.PxST('/~bob/history/record-an-exchange',
                                data,
                                auth_as='alice')
    def test_cch_deleted_card(self):
        bob = self.make_participant('bob', is_suspicious=False)
        route = ExchangeRoute.insert(bob, 'braintree-cc', 'foo')
        self.db.run("UPDATE exchange_routes SET is_deleted=true WHERE id=%s", (route.id,))

        self.hold, error = create_card_hold(self.db, bob, D('10.00'))
        assert error == 'No credit card'
示例#25
0
    def make_participant(self, username, **kw):
        """Factory for :py:class:`~gratipay.models.participant.Participant`.
        """
        participant = self.db.one("""
            INSERT INTO participants
                        (username, username_lower)
                 VALUES (%s, %s)
              RETURNING participants.*::participants
        """, (username, username.lower()))

        if 'elsewhere' in kw or 'claimed_time' in kw:
            platform = kw.pop('elsewhere', 'github')
            self.db.run("""
                INSERT INTO elsewhere
                            (platform, user_id, user_name, participant)
                     VALUES (%s,%s,%s,%s)
            """, (platform, participant.id, username, username))

        # Insert exchange routes
        if 'last_bill_result' in kw:
            ExchangeRoute.insert(participant, 'braintree-cc', '/cards/foo', kw.pop('last_bill_result'))
        if 'last_paypal_result' in kw:
            ExchangeRoute.insert(participant, 'paypal', '*****@*****.**', kw.pop('last_paypal_result'))

        # Update participant
        verified_in = kw.pop('verified_in', [])
        if kw:
            if kw.get('claimed_time') == 'now':
                kw['claimed_time'] = utcnow()
            cols, vals = zip(*kw.items())
            cols = ', '.join(cols)
            placeholders = ', '.join(['%s']*len(vals))
            participant = self.db.one("""
                UPDATE participants
                   SET ({0}) = ({1})
                 WHERE username=%s
             RETURNING participants.*::participants
            """.format(cols, placeholders), vals+(username,))

        # Verify identity
        countries = [verified_in] if type(verified_in) in (str, unicode) else verified_in
        for code in countries:
            country = self.db.one("SELECT id FROM countries WHERE code=%s", (code,))
            participant.store_identity_info(country, 'nothing-enforced', {'name': username})
            participant.set_identity_verification(country, True)

        return participant
示例#26
0
def get_route_id(cur, transaction, counts, usernames, exchange_id):

    # First strategy: match on exchange id.
    route_id = cur.one("SELECT route FROM exchanges WHERE id=%s", (exchange_id,))
    if route_id:
        counts.route_in_exchange += 1
        log("exchange has a route", 22)
        return route_id

    # Second strategy: match on known cards.
    if not route_id:
        routes = cur.all( "SELECT * FROM exchange_routes "
                          "WHERE network='balanced-cc' AND address='/cards/'||%s"
                        , (transaction['links']['source'],)
                         )
        route_id = resolve_route(cur, transaction, counts, routes, usernames)
    if route_id:
        counts.route_matched_via_card += 1
        log("card matches {}".format(route_id), 22)
        return route_id

    # Third strategy: match on usernames.
    if not route_id:
        routes = cur.all("""\
            SELECT *
              FROM exchange_routes
             WHERE network='balanced-cc' and participant in (
                    SELECT id
                      FROM participants
                     WHERE username=ANY(%s)
                   )
        """, (usernames,))
        route_id = resolve_route(cur, transaction, counts, routes, usernames)
    if route_id:
        counts.route_matched_via_customer += 1
        log("customer matches {}".format(route_id), 22)
        return route_id

    # Fourth strategy: make a route!
    if not route_id:
        if len(usernames) > 1:
            counts.route_ambiguous_customer += 1
            raise AmbiguousCustomer()
        username = usernames[0]
        participant = cur.one("SELECT participants.*::participants FROM participants "
                              "WHERE username=%s", (username,))
        route = ExchangeRoute.insert( participant
                                    , 'balanced-cc'
                                    , '/cards/'+transaction['links']['source']
                                    , cursor=cur
                                     )
        route_id = route.id
    if route_id:
        counts.route_created += 1
        log("created a route", 22)
        return route_id

    counts.route_unknown += 1
    raise UnknownRoute()
    def test_cch_deleted_card(self):
        bob = self.make_participant('bob', is_suspicious=False)
        route = ExchangeRoute.insert(bob, 'braintree-cc', 'foo')
        self.db.run("UPDATE exchange_routes SET is_deleted=true WHERE id=%s",
                    (route.id, ))

        self.hold, error = create_card_hold(self.db, bob, D('10.00'))
        assert error == 'No credit card'
示例#28
0
    def setUp(self):
        if not BillingHarness._fixture_installed:
            install_fixture()

        # Braintree Customer without funding instruments
        self.roman = self.make_participant('roman', is_suspicious=False,
                                         claimed_time='now',
                                         braintree_customer_id=self.roman_bt_id)
        # Braintree Customer with CC attached
        self.obama = self.make_participant('obama', is_suspicious=False,
                                          claimed_time='now',
                                          braintree_customer_id=self.obama_bt_id)
        self.obama_route = ExchangeRoute.insert(self.obama, 'braintree-cc', self.obama_cc_token)
        # A customer with Paypal attached.
        self.homer = self.make_participant('homer', is_suspicious=False, verified_in='US',
                                           claimed_time='now', email_address='*****@*****.**')
        self.homer_route = ExchangeRoute.insert(self.homer, 'paypal', '*****@*****.**')
    def test_route_should_belong_to_user_else_400(self):
        alice = self.make_participant('alice', claimed_time='now', is_admin=True)
        self.make_participant('bob', claimed_time='now')
        route = ExchangeRoute.insert(alice, 'paypal', '*****@*****.**')

        response = self.record_an_exchange({'amount': '10', 'fee': '0', 'route_id': route.id}, False)
        assert response.code == 400
        assert response.body == "Route doesn't exist"
示例#30
0
    def test_create_card_hold_multiple_cards(self):
        bob = self.make_participant('bob',
                                    balanced_customer_href='new',
                                    is_suspicious=False)
        card = balanced.Card(number='4242424242424242',
                             expiration_year=2020,
                             expiration_month=12).save()
        card.associate_to_customer(bob.balanced_customer_href)
        ExchangeRoute.insert(bob, 'balanced-cc', card.href)

        card = balanced.Card(number='4242424242424242',
                             expiration_year=2030,
                             expiration_month=12).save()
        card.associate_to_customer(bob.balanced_customer_href)
        ExchangeRoute.insert(bob, 'balanced-cc', card.href)

        hold, error = create_card_hold(self.db, bob, D('10.00'))
        assert error == ''
示例#31
0
 def make_exchange(self, route, amount, fee, participant, status='succeeded', error=''):
     if not isinstance(route, ExchangeRoute):
         network = route
         route = ExchangeRoute.from_network(participant, network)
         if not route:
             route = ExchangeRoute.insert(participant, network, 'dummy-address')
             assert route
     e_id = record_exchange(self.db, route, amount, fee, participant, 'pre')
     record_exchange_result(self.db, e_id, status, error, participant)
     return e_id
 def test_scopes_to_cursor(self):
     alice = self.make_participant('alice', claimed_time='now')
     with self.db.get_cursor() as cursor:
         route = ExchangeRoute.insert(alice,
                                      'paypal',
                                      '*****@*****.**',
                                      cursor=cursor)
         assert alice.get_payout_routes() == []
         assert alice.get_payout_routes(cursor=cursor) == [route]
     assert alice.get_payout_routes() == [route]
示例#33
0
 def make_exchange(self, route, amount, fee, participant, status='succeeded', error=''):
     if not isinstance(route, ExchangeRoute):
         network = route
         route = ExchangeRoute.from_network(participant, network)
         if not route:
             route = ExchangeRoute.insert(participant, network, 'dummy-address')
             assert route
     e_id = record_exchange(self.db, route, amount, fee, participant, 'pre')
     record_exchange_result(self.db, e_id, status, error, participant)
     return e_id
示例#34
0
    def make_participant(self, username, **kw):
        participant = self.db.one(
            """
            INSERT INTO participants
                        (username, username_lower)
                 VALUES (%s, %s)
              RETURNING participants.*::participants
        """, (username, username.lower()))

        if 'elsewhere' in kw or 'claimed_time' in kw:
            platform = kw.pop('elsewhere', 'github')
            self.db.run(
                """
                INSERT INTO elsewhere
                            (platform, user_id, user_name, participant)
                     VALUES (%s,%s,%s,%s)
            """, (platform, participant.id, username, username))

        # Insert exchange routes
        if 'last_bill_result' in kw:
            ExchangeRoute.insert(participant, 'braintree-cc', '/cards/foo',
                                 kw.pop('last_bill_result'))
        if 'last_paypal_result' in kw:
            ExchangeRoute.insert(participant, 'paypal', '*****@*****.**',
                                 kw.pop('last_paypal_result'))

        # Update participant
        if kw:
            if kw.get('claimed_time') == 'now':
                kw['claimed_time'] = utcnow()
            cols, vals = zip(*kw.items())
            cols = ', '.join(cols)
            placeholders = ', '.join(['%s'] * len(vals))
            participant = self.db.one(
                """
                UPDATE participants
                   SET ({0}) = ({1})
                 WHERE username=%s
             RETURNING participants.*::participants
            """.format(cols, placeholders), vals + (username, ))

        return participant
示例#35
0
 def make_exchange(self, route, amount, fee, participant, status='succeeded', error=''):
     if not isinstance(route, ExchangeRoute):
         network = route
         route = ExchangeRoute.from_network(participant, network)
         if not route:
             from .balanced import BalancedHarness
             route = ExchangeRoute.insert(participant, network, BalancedHarness.card_href)
             assert route
     e_id = record_exchange(self.db, route, amount, fee, participant, 'pre')
     record_exchange_result(self.db, e_id, status, error, participant)
     return e_id
示例#36
0
 def setUp(self):
     self.david = self.make_participant(
         'david',
         is_suspicious=False,
         claimed_time='now',
         balanced_customer_href=self.david_href)
     self.janet = self.make_participant(
         'janet',
         is_suspicious=False,
         claimed_time='now',
         balanced_customer_href=self.janet_href)
     self.janet_route = ExchangeRoute.insert(self.janet, 'balanced-cc',
                                             self.card_href)
     self.homer = self.make_participant(
         'homer',
         is_suspicious=False,
         claimed_time='now',
         balanced_customer_href=self.homer_href)
     self.homer_route = ExchangeRoute.insert(self.homer, 'balanced-ba',
                                             self.bank_account_href)
    def test_create_card_hold_multiple_cards(self):
        bob = self.make_participant('bob', balanced_customer_href='new',
                                    is_suspicious=False)
        card = balanced.Card(
            number='4242424242424242',
            expiration_year=2020,
            expiration_month=12
        ).save()
        card.associate_to_customer(bob.balanced_customer_href)
        ExchangeRoute.insert(bob, 'balanced-cc', card.href)

        card = balanced.Card(
            number='4242424242424242',
            expiration_year=2030,
            expiration_month=12
        ).save()
        card.associate_to_customer(bob.balanced_customer_href)
        ExchangeRoute.insert(bob, 'balanced-cc', card.href)

        hold, error = create_card_hold(self.db, bob, D('10.00'))
        assert error == ''
示例#38
0
 def make_exchange(self, route, amount, fee, participant, status='succeeded', error='',
                                                ref='dummy-trans-id', address='dummy-address'):
     """Factory for exchanges.
     """
     if not isinstance(route, ExchangeRoute):
         network = route
         route = ExchangeRoute.from_network(participant, network)
         if not route:
             route = ExchangeRoute.insert(participant, network, address)
             assert route
     e_id = record_exchange(self.db, route, amount, fee, participant, 'pre', ref)
     record_exchange_result(self.db, e_id, status, error, participant)
     return e_id
示例#39
0
    def make_participant(self, username, **kw):
        participant = self.db.one("""
            INSERT INTO participants
                        (username, username_lower)
                 VALUES (%s, %s)
              RETURNING participants.*::participants
        """, (username, username.lower()))

        if 'elsewhere' in kw or 'claimed_time' in kw:
            platform = kw.pop('elsewhere', 'github')
            self.db.run("""
                INSERT INTO elsewhere
                            (platform, user_id, user_name, participant)
                     VALUES (%s,%s,%s,%s)
            """, (platform, participant.id, username, username))

        # Insert exchange routes
        if 'last_bill_result' in kw:
            ExchangeRoute.insert(participant, 'balanced-cc', '/cards/foo', kw.pop('last_bill_result'))
        if 'last_ach_result' in kw:
            ExchangeRoute.insert(participant, 'balanced-ba', '/bank_accounts/bar', kw.pop('last_ach_result'))

        # Update participant
        if kw:
            if kw.get('claimed_time') == 'now':
                kw['claimed_time'] = utcnow()
            if kw.get('balanced_customer_href') == 'new':
                kw['balanced_customer_href'] = self.make_balanced_customer()
            cols, vals = zip(*kw.items())
            cols = ', '.join(cols)
            placeholders = ', '.join(['%s']*len(vals))
            participant = self.db.one("""
                UPDATE participants
                   SET ({0}) = ({1})
                 WHERE username=%s
             RETURNING participants.*::participants
            """.format(cols, placeholders), vals+(username,))

        return participant
示例#40
0
 def make_exchange(self, route, amount, fee, participant, status='succeeded', error='',
                                                ref='dummy-trans-id', address='dummy-address'):
     """Factory for exchanges.
     """
     if not isinstance(route, ExchangeRoute):
         network = route
         route = ExchangeRoute.from_network(participant, network)
         if not route:
             route = ExchangeRoute.insert(participant, network, address)
             assert route
     e_id = record_exchange(self.db, route, amount, fee, participant, 'pre', ref)
     record_exchange_result(self.db, e_id, status, error, participant)
     return e_id
示例#41
0
    def test_route_should_belong_to_user_else_400(self):
        alice = self.make_participant('alice',
                                      claimed_time='now',
                                      is_admin=True)
        self.make_participant('bob', claimed_time='now')
        route = ExchangeRoute.insert(alice, 'paypal', '*****@*****.**')

        response = self.record_an_exchange(
            {
                'amount': '10',
                'fee': '0',
                'route_id': route.id
            }, False)
        assert response.code == 400
        assert response.body == "Route doesn't exist"
    def record_an_exchange(self, data, make_participants=True):
        if make_participants:
            self.make_participants()

        data.setdefault('status', 'succeeded')
        data.setdefault('note', 'noted')

        if 'route_id' not in data:
            try:
                data['route_id'] = ExchangeRoute.insert(self.bob, 'paypal', '*****@*****.**').id
            except IntegrityError:
                data['route_id'] = ExchangeRoute.from_network(self.bob, 'paypal').id

        if data['status'] is None:
            del(data['status'])
        if data['route_id'] is None:
            del(data['route_id'])

        return self.client.PxST('/~bob/history/record-an-exchange', data, auth_as='alice')
 def test_gets_only_good_routes(self):
     alice = self.make_participant('alice', claimed_time='now')
     route = ExchangeRoute.insert(alice, 'paypal', '*****@*****.**')
     route.update_error('so erroneous')
     assert alice.get_payout_routes(good_only=True) == []
 def test_gets_payout_routes(self):
     alice = self.make_participant('alice', claimed_time='now')
     route = ExchangeRoute.insert(alice, 'paypal', '*****@*****.**')
     assert alice.get_payout_routes() == [route]
 def test_gets_only_good_routes(self):
     alice = self.make_participant('alice', claimed_time='now')
     route = ExchangeRoute.insert(alice, 'paypal', '*****@*****.**')
     route.update_error('so erroneous')
     assert alice.get_payout_routes(good_only=True) == []
 def test_cch_invalidated_card(self):
     bob = self.make_participant('bob', is_suspicious=False)
     ExchangeRoute.insert(bob, 'braintree-cc', 'foo', error='invalidated')
     self.hold, error = create_card_hold(self.db, bob, D('10.00'))
     assert error == 'No credit card'
 def test_cch_invalidated_card(self):
     bob = self.make_participant('bob', is_suspicious=False)
     ExchangeRoute.insert(bob, 'braintree-cc', 'foo', error='invalidated')
     self.hold, error = create_card_hold(self.db, bob, D('10.00'))
     assert error == 'No credit card'
 def test_gets_payout_routes(self):
     alice = self.make_participant('alice', claimed_time='now')
     route = ExchangeRoute.insert(alice, 'paypal', '*****@*****.**')
     assert alice.get_payout_routes() == [route]