Beispiel #1
0
    def get( self ):
        """Simple endpoint to retrieve all rows from table."""

        agents = get_agents()
        schema = AgentSchema( many=True )
        result = schema.dump( agents ).data
        return result, 200
    def test_agent_model(self):
        """A test to ensure that gifts are saved correctly to the database."""

        with self.app.app_context():

            agent_dict = get_agent_jsons()[AGENT_INDEX]

            agent_model = from_json(AgentSchema(), agent_dict, create=True)
            database.session.add(agent_model.data)
            database.session.commit()

            agent_query = AgentModel.query\
                .filter_by( user_id=agent_dict[ 'user_id' ] ).one()
            agent_session = database.session.query( AgentModel )\
                .filter_by( user_id=agent_dict[ 'user_id' ] ).one()

            kwargs = {
                'self': self,
                'model_dict': agent_dict,
                'model': AgentModel,
                'model_data': agent_model.data,
                'model_query': agent_query,
                'model_session': agent_session
            }
            ensure_query_session_aligned(kwargs)
Beispiel #3
0
    def test_donation_new_donor(self, ultsys_user_function,
                                create_ultsys_user_function,
                                update_ultsys_user_function,
                                mock_caging_function):  # pylint: disable=unused-argument
        """Test Braintree sale for a new donor.

        :param ultsys_user_function: Argument for mocked function.
        :param ultsys_user_update_function: Argument for mocked function.
        :param ultsys_user_create_function: Argument for mocked function.
        :return:
        """
        with self.app.app_context():
            # Create agent ( Braintree ) for the online donation.

            agent_dict = get_agent_dict()
            agent_model = from_json(AgentSchema(), agent_dict, create=True)
            database.session.add(agent_model.data)

            # Flush to get the ID and set the database.
            database.session.flush()
            database.session.commit()
            agent_id = agent_model.data.id

            # Call the function to be tested.
            payload = get_donate_dict({
                'user': get_new_donor_dict(),
                'recurring_subscription': False
            })
            result = post_donation(payload)

            self.assertEqual(result['job_id'], 'redis-queue-job-id')

            # The function should create one transaction, a gift, and a user.
            transaction = TransactionModel.query.filter_by(id=1).one_or_none()
            gift = GiftModel.query.filter_by(id=1).one_or_none()

            self.assertEqual(transaction.gift_id, gift.id)
            self.assertEqual(transaction.enacted_by_agent_id, agent_id)
            self.assertEqual(transaction.type,
                             self.parameters['transaction_type'])
            self.assertEqual(transaction.status,
                             self.parameters['transaction_status'])
            self.assertEqual(transaction.reference_number,
                             self.parameters['reference_number'])
            self.assertEqual(transaction.gross_gift_amount,
                             self.parameters['gross_gift_amount'])
            self.assertEqual(transaction.fee, self.parameters['fee'])

            self.assertEqual(str(gift.user_id), self.parameters['user_new_id'])
            self.assertEqual(gift.method_used_id, self.method_used_id)
            self.assertEqual(gift.given_to, self.parameters['given_to'])
    def test_put_gift_update_note(self):
        """Gifts endpoint to add a note to a gift with searchable_id ( methods = [ PUT ] )."""

        with self.app.app_context():
            # Parameter in URL is for a searchable_id_prefix.
            url = '/donation/gift/{}/notes'

            agent_dict = get_agent_dict({
                'name': 'Aaron Peters',
                'user_id': 3255162,
                'type': 'Staff Member'
            })
            agent_model = from_json(AgentSchema(), agent_dict, create=True)
            database.session.add(agent_model.data)

            gift_transactions = TransactionModel.query.all()
            # Ensure no transactions in the database.
            self.assertEqual(len(gift_transactions), 0)

            gift_json = get_gift_dict()
            del gift_json['id']
            gift_json['searchable_id'] = uuid.uuid4()
            gift_model = GiftSchema().load(gift_json).data
            database.session.add(gift_model)
            database.session.commit()

            transaction_note = {
                'enacted_by_agent_id': '5',
                'note': 'Add this to the Gift please.'
            }

            response = self.test_client.put(url.format(
                gift_model.searchable_id.hex),
                                            data=json.dumps(transaction_note),
                                            content_type='application/json',
                                            headers=self.headers)

            self.assertEqual(response.status_code, status.HTTP_200_OK)

            # Make sure a transaction was added.
            gift_transactions = TransactionModel.query.all()

            self.assertEqual(len(gift_transactions), 1)
            self.assertEqual(gift_transactions[0].notes,
                             transaction_note['note'])
Beispiel #5
0
    def test_donation_donor_update(self, ultsys_user_function,
                                   create_ultsys_user_function,
                                   update_ultsys_user_function,
                                   mock_caging_function):  # pylint: disable=unused-argument
        """Test Braintree sale where there is an update to Braintree customer address.

        :param ultsys_user_function: Argument for mocked function.
        :param ultsys_user_update_function: Argument for mocked function.
        :param ultsys_user_create_function: Argument for mocked function.
        :return:
        """
        with self.app.app_context():
            # Create agent ( Braintree ) for the online donation.
            agent_dict = get_agent_dict()
            agent_model = from_json(AgentSchema(), agent_dict, create=True)
            database.session.add(agent_model.data)
            database.session.commit()

            # Call function to be tested with new billing information.
            # See customer_details in TRANSACTION_SUCCESSFUL.
            new_info = {
                'user': {
                    'id': 5,
                    'user_address': {
                        'user_address': '126 Jackson Street',
                        'user_zipcode': '48336'
                    }
                }
            }

            payload = get_donate_dict(new_info)
            result = post_donation(payload)

            self.assertEqual(result['job_id'], 'redis-queue-job-id')

            # The function should NOT update the user.
            user = UltsysUserModel.query.filter_by(ID=5).one_or_none()
            self.assertNotEqual(
                user.email, new_info['user']['user_address']['user_address'])
            self.assertNotEqual(
                user.zip,
                int(new_info['user']['user_address']['user_zipcode']))
Beispiel #6
0
    def test_build_transaction( self ):
        """Transactions endpoint to add a transaction to a gift with searchable_id ( methods = [ POST ] )."""

        with self.app.app_context():
            # Parameter in URL is for a searchable_id_prefix.
            url = '/donation/gift/transaction'

            agent_dict = get_agent_dict( { 'name': 'Aaron Peters', 'user_id': 3255162, 'type': 'Staff Member' } )
            agent_model = from_json( AgentSchema(), agent_dict, create=True )
            database.session.add( agent_model.data )

            # Create a gift to attach a transaction to.
            gift_json = get_gift_dict()
            del gift_json[ 'id' ]
            gift_json[ 'searchable_id' ] = uuid.uuid4()
            gift_model = GiftSchema().load( gift_json ).data
            database.session.add( gift_model )
            database.session.commit()

            gift = GiftModel.query.all()[ 0 ]

            # Ensure no transactions currently on gift.
            self.assertEqual( len( gift.transactions ), 0 )

            new_transaction = get_transaction_dict(
                {
                    'gift_searchable_id': gift_json[ 'searchable_id' ].hex,
                    'enacted_by_agent_id': None
                }
            )

            self.test_client.post(
                url,
                data=json.dumps( new_transaction ),
                content_type='application/json',
                headers=self.headers
            )

            # Ensure the new transactions is now on the gift.
            self.assertEqual( len( gift.transactions ), 1 )
            self.assertEqual( gift.transactions[ 0 ].gift_searchable_id.hex, gift_json[ 'searchable_id' ].hex )
    def test_large_donation_emails(self, ultsys_user_function,
                                   create_ultsys_user_function,
                                   update_ultsys_user_function,
                                   mock_caging_function):  # pylint: disable=unused-argument
        """Test large donation adds entry to GiftThankYouLetter table.

        :param ultsys_user_function: Argument for mocked function.
        :param ultsys_user_update_function: Argument for mocked function.
        :param ultsys_user_create_function: Argument for mocked function.
        :return:
        """
        with self.app.app_context():
            # Create agent ( Braintree ) for the online donation.

            agent_dict = get_agent_dict()
            agent_model = from_json(AgentSchema(), agent_dict, create=True)
            database.session.add(agent_model.data)

            # Flush to get the ID and set the database.
            database.session.flush()
            database.session.commit()

            # Call the function to be tested.
            payload = get_donate_dict({
                'user': get_new_donor_dict(),
                'recurring_subscription': False,
                'transaction': {
                    'gross_gift_amount': '110.00'
                }
            })
            post_donation(payload)

            gift_thank_you_letter = GiftThankYouLetterModel.query.filter_by(
                gift_id=1).one_or_none()
            self.assertEqual(gift_thank_you_letter.gift_id, 1)

            transaction = TransactionModel.query.filter_by(
                gift_id=1).one_or_none()
            self.assertIsNotNone(transaction)
            self.assertIsInstance(transaction.receipt_sent_in_utc, datetime)
Beispiel #8
0
    def test_get_agents(self):
        """Agents API endpoint ( methods = [ GET ] )."""

        with self.app.app_context():
            url = '/donation/agents'

            # Ensure a GET with no saved agents returns 0.
            response = self.test_client.get(url, headers=self.headers)
            self.assertEqual(len(json.loads(response.data.decode('utf-8'))), 0)

            # Create some agents to retrieve.
            agent_models = []
            agent_jsons = get_agent_jsons()
            for agent_json in agent_jsons:
                agent_model = AgentSchema().load(agent_json).data
                agent_models.append(agent_model)
            database.session.bulk_save_objects(agent_models)
            database.session.commit()

            # Ensure GET returns all agents.
            response = self.test_client.get(url, headers=self.headers)
            self.assertEqual(len(json.loads(response.data.decode('utf-8'))),
                             len(agent_jsons))
Beispiel #9
0
def create_agent_table():
    """A function to create the DONATE database AgentModel table."""

    with app.app_context():
        drop_all_and_create()

        # Create the agents.
        agent_jsons = [
            { 'name': 'Donate API', 'user_id': None, 'staff_id': None, 'type': 'Automated' },
            { 'name': 'Braintree', 'user_id': None, 'staff_id': None, 'type': 'Organization' },
            { 'name': 'PayPal', 'user_id': None, 'staff_id': None, 'type': 'Organization' },
            { 'name': 'Credit Card Issuer', 'user_id': None, 'staf_id': None, 'type': 'Organization' },
            { 'name': 'Unspecified NumbersUSA Staff', 'user_id': None, 'staff_id': None, 'type': 'Staff Member' },
            { 'name': 'Dan Marsh', 'user_id': 1234, 'staff_id': 4321, 'type': 'Staff Member' },
            { 'name': 'Joshua Turcotte', 'user_id': 7041, 'staff_id': 1407, 'type': 'Staff Member' },
            { 'name': 'Donate API', 'user_id': None, 'staff_id': None, 'type': 'Automated' }
        ]
        agents = []
        for agent_json in agent_jsons:
            agent_model = AgentSchema().load( agent_json ).data
            agents.append( agent_model )
        database.session.bulk_save_objects( agents )

        database.session.commit()
    def test_admin_new_donor(self, ultsys_user_function,
                             create_ultsys_user_function,
                             update_ultsys_user_function,
                             mock_caging_function):  # pylint: disable=unused-argument
        """Test the administrative donation of a donor who is a new user."""

        with self.app.app_context():

            # Create the sourced by agent.
            agent_dict = get_agent_dict(
                {'name': 'Unspecified NumbersUSA Staff'})
            agent_model = from_json(AgentSchema(), agent_dict, create=True)
            database.session.add(agent_model.data)
            database.session.flush()
            database.session.commit()

            agent_dict = get_agent_dict({'name': 'Fidelity Bank'})
            bank_agent_model = from_json(AgentSchema(),
                                         agent_dict,
                                         create=True)
            database.session.add(bank_agent_model.data)
            database.session.flush()
            database.session.commit()

            # Create the agent who will be referenced in the payload.
            agent_user_id = '3255162'
            agent_dict = get_agent_dict({
                'name': 'Aaron Peters',
                'user_id': agent_user_id,
                'type': 'Staff Member'
            })
            user_agent_model = from_json(AgentSchema(),
                                         agent_dict,
                                         create=True)
            database.session.add(user_agent_model.data)
            database.session.flush()
            database.session.commit()

            # Call the function to be tested.
            # Administrative donations need to provide information not required by an online donation.
            payload = get_donate_dict({
                'gift': {
                    'method_used': self.parameters['method_used'],
                },
                'transaction': {
                    'date_of_method_used':
                    self.parameters['date_of_method_used']
                },
                'user': get_new_donor_dict(),
                'recurring_subscription': False
            })
            payload['sourced_from_agent_user_id'] = agent_user_id

            payload['transaction']['reference_number'] = self.parameters[
                'reference_number']
            payload['transaction']['type'] = self.parameters[
                'transaction_type']

            self.assertEqual(
                post_donation(payload)['job_id'], 'redis-queue-job-id')

            # The function should create one transaction, a gift, and a user.
            transactions = TransactionModel.query.all()
            gift = GiftModel.query.filter_by(id=1).one_or_none()

            self.assertEqual(transactions[0].gift_id, gift.id)
            self.assertEqual(transactions[0].enacted_by_agent_id, 3)
            self.assertEqual(transactions[0].type,
                             self.parameters['transaction_type'])
            self.assertEqual(transactions[0].status,
                             self.parameters['transaction_status'])
            self.assertEqual(transactions[0].reference_number,
                             self.parameters['reference_number'])
            self.assertEqual(transactions[0].gross_gift_amount,
                             self.parameters['gross_gift_amount'])

            self.assertEqual(transactions[1].gift_id, gift.id)
            self.assertEqual(transactions[1].enacted_by_agent_id, 2)
            self.assertEqual(transactions[1].type,
                             self.parameters['second_transaction_type'])
            self.assertEqual(transactions[1].status,
                             self.parameters['transaction_status'])
            self.assertEqual(transactions[1].reference_number,
                             self.parameters['bank_deposit_number'])
            self.assertEqual(transactions[1].gross_gift_amount,
                             self.parameters['gross_gift_amount'])

            # Find the newly created Ultsys ID.
            ultsys_user = UltsysUserModel.query.filter_by(
                email=self.parameters['new_user_email']).one_or_none()

            self.assertEqual(gift.user_id, ultsys_user.ID)
            self.assertEqual(gift.method_used_id, self.method_used_id)
            self.assertEqual(gift.given_to, self.parameters['given_to'])
    def test_admin_caged_donor(self, ultsys_user_function,
                               mock_caging_function):  # pylint: disable=unused-argument
        """Test the administrative donation of a donor who has been previously caged."""

        with self.app.app_context():
            agent_dict = get_agent_dict(
                {'name': 'Unspecified NumbersUSA Staff'})
            agent_model = from_json(AgentSchema(), agent_dict, create=True)
            database.session.add(agent_model.data)
            database.session.flush()
            database.session.commit()

            agent_dict = get_agent_dict({'name': 'Fidelity Bank'})
            bank_agent_model = from_json(AgentSchema(),
                                         agent_dict,
                                         create=True)
            database.session.add(bank_agent_model.data)
            database.session.flush()
            database.session.commit()

            # Create the agent who will be referenced in the payload.
            agent_user_id = '3255162'
            agent_dict = get_agent_dict({
                'name': 'Aaron Peters',
                'user_id': agent_user_id,
                'type': 'Staff Member'
            })
            user_agent_model = from_json(AgentSchema(),
                                         agent_dict,
                                         create=True)
            database.session.add(user_agent_model.data)
            database.session.flush()
            database.session.commit()

            # Create a caged donor, which will be caged again.
            caged_donor_dict = get_caged_donor_dict({
                'gift_searchable_id':
                uuid.uuid4(),
                'customer_id':
                self.parameters['customer_id']
            })
            caged_donor_model = from_json(CagedDonorSchema(),
                                          caged_donor_dict,
                                          create=True)
            database.session.add(caged_donor_model.data)
            database.session.flush()
            database.session.commit()

            # Call function to tests.
            payload = get_donate_dict({
                'gift': {
                    'method_used': self.parameters['method_used'],
                    'date_of_method_used':
                    self.parameters['date_of_method_used']
                },
                'user': {
                    'user_address': {
                        'user_first_name':
                        caged_donor_model.data.user_first_name,
                        'user_last_name':
                        caged_donor_model.data.user_last_name,
                        'user_address': caged_donor_model.data.user_address
                    }
                }
            })
            payload['sourced_from_agent_user_id'] = agent_user_id
            payload['transaction']['reference_number'] = self.parameters[
                'reference_number']
            payload['transaction']['type'] = self.parameters[
                'transaction_type']

            self.assertEqual(
                post_donation(payload)['job_id'], 'redis-queue-job-id')

            # The function should create one transaction, a gift, and a user.
            transactions = TransactionModel.query.all()
            gift = GiftModel.query.filter_by(id=1).one_or_none()

            self.assertEqual(transactions[0].gift_id, gift.id)
            self.assertEqual(transactions[0].enacted_by_agent_id, 3)
            self.assertEqual(transactions[0].type,
                             self.parameters['transaction_type'])
            self.assertEqual(transactions[0].status,
                             self.parameters['transaction_status'])
            self.assertEqual(transactions[0].reference_number,
                             self.parameters['reference_number'])
            self.assertEqual(transactions[0].gross_gift_amount,
                             self.parameters['gross_gift_amount'])

            self.assertEqual(transactions[1].gift_id, gift.id)
            self.assertEqual(transactions[1].enacted_by_agent_id, 2)
            self.assertEqual(transactions[1].type,
                             self.parameters['second_transaction_type'])
            self.assertEqual(transactions[1].status,
                             self.parameters['transaction_status'])
            self.assertEqual(transactions[1].reference_number,
                             self.parameters['bank_deposit_number'])
            self.assertEqual(transactions[1].gross_gift_amount,
                             self.parameters['gross_gift_amount'])

            caged_donor = CagedDonorModel.query.filter_by(id=2).one()

            self.assertEqual(caged_donor.gift_searchable_id,
                             gift.searchable_id)
            self.assertEqual(caged_donor.user_first_name,
                             caged_donor_dict['user_first_name'])
            self.assertEqual(caged_donor.user_last_name,
                             caged_donor_dict['user_last_name'])
    def test_braintree_webhooks(self, mock_init_gateway_function,
                                mock_subscription_function,
                                get_ultsys_user_function):  # pylint: disable=unused-argument
        """Make sure the webhook endpoint receives a payload and makes updates as expected."""

        with self.app.app_context():
            url = '/donation/webhook/braintree/subscription'

            # Create the sourced by agent for the subscription webhook.
            agent_model = from_json(AgentSchema(),
                                    get_agent_jsons()[0],
                                    create=True)
            database.session.add(agent_model.data)
            database.session.commit()

            # Here is the first gift as check.
            gift_dict = get_gift_dict({
                'user_id':
                1,
                'method_used':
                METHOD_USED,
                'sourced_from_agent_id':
                1,
                'recurring_subscription_id':
                'recurring_subscription_id'
            })
            gift_model = from_json(GiftSchema(), gift_dict, create=True)
            database.session.add(gift_model.data)
            database.session.flush()

            # Create a transaction on the gift.
            transaction_dict = get_transaction_dict({
                'gift_id':
                gift_model.data.id,
                'enacted_by_agent_id':
                agent_model.data.id,
                'type':
                'Gift',
                'gross_gift_amount':
                Decimal('1.00')
            })
            transaction_model = from_json(TransactionSchema(),
                                          transaction_dict,
                                          create=True)
            database.session.add(transaction_model.data)

            database.session.commit()

            # Here is the fake POST from Braintree when the subscription webhook is triggered.
            response = self.test_client.post(
                url,
                data={
                    'bt_signature': 'bt_signature',
                    'bt_payload': 'subscription_charged_successfully'
                })

            self.assertEqual(response.status_code, status.HTTP_200_OK)

            method_used_id = MethodUsedModel.get_method_used(
                'name', METHOD_USED).id
            gift = GiftModel.query.filter_by(id=1).one_or_none()
            self.assertEqual(gift.method_used_id, method_used_id)
            self.assertEqual(gift.sourced_from_agent_id, SOURCED_FROM_AGENT)
            self.assertEqual(gift.recurring_subscription_id,
                             RECURRING_SUBSCRIPTION_ID)

            transaction = TransactionModel.query.filter_by(id=1).one_or_none()
            self.assertEqual(transaction.gift_id, 1)
            self.assertEqual(transaction.type, 'Gift')
            self.assertEqual(transaction.status, 'Completed')

            response = self.test_client.post(
                url,
                data={
                    'bt_signature': 'bt_signature',
                    'bt_payload': 'subscription_charged_unsuccessfully'
                })

            self.assertEqual(response.status_code, status.HTTP_200_OK)
            transaction = TransactionModel.query.filter_by(id=3).one_or_none()
            self.assertEqual(transaction.status, 'Declined')

            response = self.test_client.post(url,
                                             data={
                                                 'bt_signature':
                                                 'bt_signature',
                                                 'bt_payload':
                                                 'subscription_went_past_due'
                                             })

            self.assertEqual(response.status_code, status.HTTP_200_OK)

            transaction = TransactionModel.query.filter_by(id=4).one_or_none()
            self.assertEqual(transaction.status, 'Failed')

            response = self.test_client.post(url,
                                             data={
                                                 'bt_signature':
                                                 'bt_signature',
                                                 'bt_payload':
                                                 'subscription_expired'
                                             })

            self.assertEqual(response.status_code, status.HTTP_200_OK)

            transaction = TransactionModel.query.filter_by(id=5).one_or_none()
            self.assertEqual(transaction.status, 'Failed')
Beispiel #13
0
    def test_braintree_reallocate_gift(self):
        """Test for reallocating a gift mocking Braintree's responses."""

        with self.app.app_context():
            # Create the transaction to partially refund.

            gift_dict = get_gift_dict({
                'user_id':
                '5',
                'customer_id':
                'braintree_customer_id',
                'recurring_subscription_id':
                'subscription_id'
            })
            gift_model = from_json(GiftSchema(), gift_dict, create=True)
            database.session.add(gift_model.data)
            database.session.commit()

            gift_id = gift_model.data.id
            transaction_dict = get_transaction_dict({'gift_id': gift_id})
            transaction_model = from_json(TransactionSchema(),
                                          transaction_dict,
                                          create=True)
            database.session.add(transaction_model.data)

            # Create the agent who does the refund.
            agent_user_id = '3255162'
            agent_dict = get_agent_dict({
                'name': 'Aaron Peters',
                'user_id': agent_user_id,
                'type': 'Staff Member'
            })
            agent_model = from_json(AgentSchema(), agent_dict, create=True)
            database.session.add(agent_model.data)

            database.session.commit()

            # Call the function to tests.
            payload = {
                "gift": {
                    "reallocate_to": "NERF"
                },
                "transaction": {
                    "gift_searchable_id": gift_model.data.searchable_id,
                    "gross_gift_amount":
                    self.parameters['gift_amount_reallocate'],
                    "notes": "An online donation to test receipt sent email."
                },
                "user": {
                    "user_id": None
                },
                "agent_ultsys_id": 322156
            }

            # Calling the function for reallocating a gift directly and bypassing JWT is resource.
            reallocate_result = admin_reallocate_gift(payload)

            gift_reallocate = GiftModel.query.filter_by(
                id=gift_id).one_or_none()
            transaction_reallocate = TransactionModel.query.filter_by(
                id=2).one_or_none()

            self.assertEqual(reallocate_result, True)
            self.assertEqual(gift_reallocate.id, gift_id)
            self.assertEqual(gift_reallocate.given_to,
                             payload['gift']['reallocate_to'])
            self.assertEqual(transaction_reallocate.enacted_by_agent_id, 1)
            self.assertEqual(transaction_reallocate.type,
                             self.parameters['transaction_type_reallocation'])
            self.assertEqual(transaction_reallocate.gross_gift_amount,
                             self.parameters['gift_amount_reallocate'])

            self.assertEqual(transaction_reallocate.enacted_by_agent_id, 1)
            self.assertEqual(transaction_reallocate.type,
                             self.parameters['transaction_type_reallocation'])
            self.assertEqual(transaction_reallocate.gross_gift_amount,
                             self.parameters['gift_amount_reallocate'])
Beispiel #14
0
    def test_donation_caged_donor(self, ultsys_user_function,
                                  mock_caging_function):  # pylint: disable=unused-argument
        """Test Braintree sale for a donor that has already been caged.

        :param ultsys_user_function: Argument for mocked function.
        :return:
        """
        with self.app.app_context():
            # Create agent ( Braintree ) for the online donation.
            agent_dict = get_agent_dict()
            agent_model = from_json(AgentSchema(), agent_dict, create=True)
            database.session.add(agent_model.data)

            # Flush to get agent ID and set database.
            database.session.flush()
            agent_id = agent_model.data.id

            # Create a caged donor, which will be caged again.
            caged_donor_dict = get_caged_donor_dict({
                'gift_searchable_id':
                uuid.uuid4(),
                'customer_id':
                self.parameters['customer_id']
            })

            caged_donor_model = from_json(CagedDonorSchema(), caged_donor_dict)
            database.session.add(caged_donor_model.data)

            database.session.commit()

            # Call function to tests.
            payload = get_donate_dict({
                'user': {
                    'user_address': {
                        'user_first_name': 'Alice',
                        'user_email_address': '*****@*****.**'
                    },
                    'billing_address': {}
                },
                'recurring_subscription': False
            })

            result = post_donation(payload)

            self.assertEqual(result['job_id'], 'redis-queue-job-id')

            # The function should create one transaction, a gift, and an additional caged donor.
            # Additional caged donor is the same as first, but attached to a separate gift.
            transaction = TransactionModel.query.filter_by(id=1).one_or_none()
            gift = GiftModel.query.filter_by(id=1).one_or_none()
            caged_donor = CagedDonorModel.query.filter_by(id=2).one_or_none()

            self.assertEqual(transaction.gift_id, gift.id)
            self.assertEqual(transaction.enacted_by_agent_id, agent_id)
            self.assertEqual(transaction.type,
                             self.parameters['transaction_type'])
            self.assertEqual(transaction.status,
                             self.parameters['transaction_status'])
            self.assertEqual(transaction.reference_number,
                             self.parameters['reference_number'])
            self.assertEqual(transaction.gross_gift_amount,
                             self.parameters['gross_gift_amount'])
            self.assertEqual(transaction.fee, self.parameters['fee'])

            self.assertEqual(gift.user_id, -1)
            self.assertEqual(gift.method_used_id, self.method_used_id)
            self.assertEqual(gift.given_to, self.parameters['given_to'])

            self.assertEqual(caged_donor.gift_searchable_id,
                             gift.searchable_id)
            self.assertEqual(caged_donor.customer_id,
                             self.parameters['customer_id'])
            self.assertEqual(caged_donor.user_first_name,
                             caged_donor_dict['user_first_name'])
            self.assertEqual(caged_donor.user_last_name,
                             caged_donor_dict['user_last_name'])
Beispiel #15
0
    def test_admin_record_bounced_check(self):
        """Test for recording a bounced check."""

        with self.app.app_context():
            # Create 2 gifts: one for the transaction that needs to record bounced check, the other to query against.

            # Create the bank and sourced by agents for recording a check.
            agent_dict = get_agent_dict({
                'name': 'Fidelity Bank',
                'type': 'Organization'
            })
            bank_agent_model = from_json(AgentSchema(),
                                         agent_dict,
                                         create=True)
            database.session.add(bank_agent_model.data)
            database.session.flush()

            agent_user_id = 3255162
            agent_dict = get_agent_dict({
                'name': 'Aaron Peters',
                'user_id': agent_user_id,
                'type': 'Staff Member'
            })
            user_agent_model = from_json(AgentSchema(),
                                         agent_dict,
                                         create=True)
            database.session.add(user_agent_model.data)
            database.session.flush()

            # Here is the first gift as check.
            gift_dict = get_gift_dict({
                'method_used_id': 3,
                'sourced_from_agent_id': 1,
                'reference_number': '1201',
                'customer_id': ''
            })
            gift_model = from_json(GiftSchema(), gift_dict, create=True)
            database.session.add(gift_model.data)
            database.session.flush()
            gift_searchable_id = gift_model.data.searchable_id

            # Create the 2nd gift as check.
            gift_dict = get_gift_dict({
                'method_used_id': 3,
                'sourced_from_agent_id': 1
            })
            gift_model = from_json(GiftSchema(), gift_dict, create=True)
            database.session.add(gift_model.data)
            database.session.flush()

            # Create 2 transactions on the first gift for the check.
            transaction_dict = get_transaction_dict({
                'gift_id':
                1,
                'enacted_by_agent_id':
                1,
                'type':
                'Gift',
                'gross_gift_amount':
                Decimal('25.00'),
                'reference_number':
                '1201'
            })
            transaction_model = from_json(TransactionSchema(),
                                          transaction_dict,
                                          create=True)
            database.session.add(transaction_model.data)

            transaction_dict = get_transaction_dict({
                'gift_id':
                1,
                'enacted_by_agent_id':
                2,
                'type':
                'Deposit to Bank',
                'gross_gift_amount':
                Decimal('25.00'),
                'reference_number':
                '<bank-deposit-number>'
            })
            transaction_model = from_json(TransactionSchema(),
                                          transaction_dict,
                                          create=True)
            database.session.add(transaction_model.data)

            # Put a transaction on the second gift.
            transaction_dict = get_transaction_dict({
                'gift_id':
                2,
                'enacted_by_agent_id':
                1,
                'type':
                'Refund',
                'gross_gift_amount':
                Decimal('25.00')
            })
            transaction_model = from_json(TransactionSchema(),
                                          transaction_dict,
                                          create=True)
            database.session.add(transaction_model.data)

            database.session.flush()
            database.session.commit()

            # Call the function to test.
            # Needs the JWT Ultsys agent user ID because calling function directly ( not through resource ).
            payload = {
                'gift_searchable_id': gift_searchable_id,
                'reference_number': '1201',
                'transaction_notes': '',
                'gross_gift_amount': '0.00',
                'user_id': 3255162
            }

            # Calling the function for recording the bounced check directly and bypassing JWT is resource.
            record_bounced_check = admin_record_bounced_check(payload)

            transaction_bounced_check = TransactionModel.query\
                .filter_by( type=self.parameters[ 'transaction_type_bounced' ] ).one_or_none()

            self.assertEqual(record_bounced_check, True)
            self.assertEqual(transaction_bounced_check.enacted_by_agent_id, 2)
            self.assertEqual(transaction_bounced_check.type,
                             self.parameters['transaction_type_bounced'])
            self.assertEqual(transaction_bounced_check.gross_gift_amount,
                             self.parameters['gift_amount_bounced'])
Beispiel #16
0
    def test_braintree_void_transaction(self):
        """Test for voiding a transaction mocking Braintree's response."""

        with self.app.app_context():
            # Create the transaction to void.
            gift_dict = get_gift_dict({
                'user_id':
                '5',
                'customer_id':
                'braintree_customer_id',
                'recurring_subscription_id':
                'subscription_id'
            })
            gift_model = from_json(GiftSchema(), gift_dict, create=True)
            database.session.add(gift_model.data)
            database.session.commit()

            gift_id = gift_model.data.id
            transaction_dict = get_transaction_dict({'gift_id': gift_id})
            transaction_model = from_json(TransactionSchema(),
                                          transaction_dict,
                                          create=True)
            database.session.add(transaction_model.data)

            # Create the sourced by agent who voids the transaction.
            agent_dict = get_agent_dict({})
            agent_model = from_json(AgentSchema(), agent_dict, create=True)
            database.session.add(agent_model.data)

            # Create the enacted by agent who voids the transaction.
            agent_user_id = '3255162'
            agent_dict = get_agent_dict({
                'name': 'Aaron Peters',
                'user_id': agent_user_id,
                'type': 'Staff Member'
            })
            agent_model = from_json(AgentSchema(), agent_dict, create=True)
            database.session.add(agent_model.data)

            # Set the database.
            database.session.commit()

            # Call function to tests.
            payload = {
                'transaction_id': 1,
                'user_id': agent_user_id,
                'transaction_notes': 'Transaction notes.'
            }

            # Calling the function to void a transaction directly and bypassing JWT is resource.
            void_result = admin_void_transaction(payload)

            # The transaction to void was separately created and has ID equal to 1.
            # The voided is its own transaction and will have ID equal to 2 attached to gift 1.
            transaction_void = TransactionModel.query.filter_by(
                id=2).one_or_none()

            self.assertEqual(void_result, True)
            self.assertEqual(transaction_void.id, 2)
            self.assertEqual(transaction_void.gift_id, gift_id)
            self.assertEqual(transaction_void.enacted_by_agent_id, 2)
            self.assertEqual(transaction_void.type,
                             self.parameters['transaction_type_void'])
Beispiel #17
0
def create_database_tables():
    """Function to create the DONATE database tables, specifically the CagedDonorModel and QueuedDonorModel with UUID.

    All that is said here for the CagedDonorModel also holds for the QueuedDonorModel. The CagedDonorModel is built
    using Marshmallow schema CagedDonorSchema, which deserializes a dictionary to the model. The searchable_id in the
    donor_json is:
        donor_json[ 'searchable_id' ] = uuid.uuid4()
    This gets passed to the CagedDonorSchema where:
        searchable_id = fields.UUID()
    And so the validation step is passed.
    MySql does not have a UUID type though and there we have ( CagedDonorModel ):
        searchable_id = database.Column( database.BINARY( 16 ), nullable=False, default=uuid.uuid4().bytes )
    The helper model class BinaryUUID in binary_uuid.py handles the serialization in and out.
    """

    with app.app_context():
        drop_all_and_create()

        caged_donors = []
        queued_donors = []
        # Create 100 caged donors.
        for i in range(0, 100):
            donor_json = get_caged_donor_dict(
                {'gift_searchable_id': uuid.uuid4()})
            donor_json['gift_id'] = i + 1
            donor_json['customer_id'] = str((i + 1) + 1000)
            del donor_json['id']

            caged_donor = CagedDonorSchema().load(donor_json).data
            queued_donor = QueuedDonorSchema().load(donor_json).data

            caged_donors.append(caged_donor)
            queued_donors.append(queued_donor)

        # Create the agents.
        agent_jsons = [{
            'name': 'Donate API',
            'user_id': None,
            'staff_id': None,
            'type': 'Automated'
        }, {
            'name': 'Braintree',
            'user_id': None,
            'staff_id': None,
            'type': 'Organization'
        }, {
            'name': 'PayPal',
            'user_id': None,
            'staff_id': None,
            'type': 'Organization'
        }, {
            'name': 'Credit Card Issuer',
            'user_id': None,
            'staf_id': None,
            'type': 'Organization'
        }, {
            'name': 'Unspecified NumbersUSA Staff',
            'user_id': None,
            'staff_id': None,
            'type': 'Staff Member'
        }, {
            'name': 'Dan Marsh',
            'user_id': 1234,
            'staff_id': 4321,
            'type': 'Staff Member'
        }, {
            'name': 'Joshua Turcotte',
            'user_id': 7041,
            'staff_id': 1407,
            'type': 'Staff Member'
        }, {
            'name': 'Donate API',
            'user_id': None,
            'staff_id': None,
            'type': 'Automated'
        }]
        agents = []
        for agent_json in agent_jsons:
            agent_model = AgentSchema().load(agent_json).data
            agents.append(agent_model)

        database.session.bulk_save_objects(caged_donors)
        database.session.bulk_save_objects(queued_donors)
        database.session.bulk_save_objects(agents)

        database.session.commit()
Beispiel #18
0
    def test_admin_refund_transaction(self, get_ultsys_user_function):  # pylint: disable=unused-argument
        """Test for creating a refund mocking Braintree's responses."""

        with self.app.app_context():
            # Create the transaction to partially refund.

            gift_dict = get_gift_dict({
                'user_id':
                '5',
                'customer_id':
                'braintree_customer_id',
                'recurring_subscription_id':
                'subscription_id'
            })
            gift_model = from_json(GiftSchema(), gift_dict, create=True)
            database.session.add(gift_model.data)
            database.session.commit()

            gift_id = gift_model.data.id
            transaction_dict = get_transaction_dict({'gift_id': gift_id})
            transaction_model = from_json(TransactionSchema(),
                                          transaction_dict,
                                          create=True)
            database.session.add(transaction_model.data)

            # Create the sourced by agent who refunds the transaction.
            agent_dict = get_agent_dict({})
            agent_model = from_json(AgentSchema(), agent_dict, create=True)
            database.session.add(agent_model.data)

            # Create the enacted by agent who does the refund.
            agent_user_id = '3255162'
            agent_dict = get_agent_dict({
                'name': 'Aaron Peters',
                'user_id': agent_user_id,
                'type': 'Staff Member'
            })
            agent_model = from_json(AgentSchema(), agent_dict, create=True)
            database.session.add(agent_model.data)

            # Set the database.
            database.session.commit()

            # Call function to tests.
            # The function requires the JWT claim from the ontroller and that is included here in the payload.
            payload = {
                'transaction_id': 1,
                'amount': self.parameters['gift_amount_refund'],
                'user_id': agent_user_id,
                'transaction_notes': 'Transaction notes.'
            }

            # Calling the function for a refund directly and bypassing JWT is resource.
            refund_result = admin_refund_transaction(payload)

            # The transaction to refund was separately created and has ID equalt 1.
            # The refund is its own transaction and will have ID equal to 2.
            transaction_refund = TransactionModel.query.filter_by(
                id=2).one_or_none()
            self.assertEqual(refund_result, True)
            self.assertEqual(transaction_refund.id, 2)
            self.assertEqual(transaction_refund.gift_id, gift_id)
            self.assertEqual(transaction_refund.enacted_by_agent_id, 2)
            self.assertEqual(transaction_refund.type,
                             self.parameters['transaction_type_refund'])

            current_gross_gift_amount = \
                Decimal( transaction_dict[ 'gross_gift_amount' ] ) - self.parameters[ 'gift_amount_refund' ]
            self.assertEqual(transaction_refund.gross_gift_amount,
                             current_gross_gift_amount)