コード例 #1
0
ファイル: helper.py プロジェクト: winstonhoseadriggins/billy
class ModelTestCase(unittest.TestCase):
    def setUp(self):

        self.session = create_session()
        self._old_now_func = tables.set_now_func(utc_now)

        self.dummy_processor = DummyProcessor()

        self.model_factory = ModelFactory(
            session=self.session,
            processor_factory=lambda: self.dummy_processor,
            settings={},
        )
        self.company_model = self.model_factory.create_company_model()
        self.customer_model = self.model_factory.create_customer_model()
        self.plan_model = self.model_factory.create_plan_model()
        self.subscription_model = self.model_factory.create_subscription_model(
        )
        self.invoice_model = self.model_factory.create_invoice_model()
        self.transaction_model = self.model_factory.create_transaction_model()
        self.transaction_failure_model = self.model_factory.create_transaction_failure_model(
        )

    def tearDown(self):
        self.session.close()
        self.session.remove()
        tables.DeclarativeBase.metadata.drop_all()
        self.session.bind.dispose()
        tables.set_now_func(self._old_now_func)
コード例 #2
0
ファイル: helper.py プロジェクト: Imaxinacion/billy
class ModelTestCase(unittest.TestCase):

    def setUp(self):
       
        self.session = create_session()
        self._old_now_func = tables.set_now_func(utc_now)

        self.dummy_processor = DummyProcessor()

        self.model_factory = ModelFactory(
            session=self.session,
            processor_factory=lambda: self.dummy_processor,
            settings={},
        )
        self.company_model = self.model_factory.create_company_model()
        self.customer_model = self.model_factory.create_customer_model()
        self.plan_model = self.model_factory.create_plan_model()
        self.subscription_model = self.model_factory.create_subscription_model()
        self.invoice_model = self.model_factory.create_invoice_model()
        self.transaction_model = self.model_factory.create_transaction_model()
        self.transaction_failure_model = self.model_factory.create_transaction_failure_model()

    def tearDown(self):
        self.session.close()
        self.session.remove()
        tables.DeclarativeBase.metadata.drop_all()
        self.session.bind.dispose()
        tables.set_now_func(self._old_now_func)
コード例 #3
0
ファイル: helper.py プロジェクト: winstonhoseadriggins/billy
    def setUp(self):
        self.dummy_processor = DummyProcessor()

        def model_factory_func():
            return self.model_factory

        if not hasattr(self, 'settings'):
            self.settings = {
                'billy.processor_factory': lambda: self.dummy_processor,
                'model_factory_func': model_factory_func,
                # do not remove when a request is processed, so that we don't
                # have to use session.add every time
                'db_session_cleanup': False,
            }

        # init database
        db_url = os.environ.get('BILLY_FUNC_TEST_DB', 'sqlite://')
        self.settings['sqlalchemy.url'] = db_url
        self.settings = setup_database({}, **self.settings)
        DeclarativeBase.metadata.bind = self.settings['engine']
        DeclarativeBase.metadata.create_all()

        app = main({}, **self.settings)
        self.testapp = TestApp(app)
        self.testapp.session = self.settings['session']

        self.dummy_request = DummyRequest()

        # create model factory
        self.model_factory = ModelFactory(
            session=self.testapp.session,
            processor_factory=lambda: self.dummy_processor,
            settings=self.settings,
        )

        # create all models
        self.company_model = self.model_factory.create_company_model()
        self.customer_model = self.model_factory.create_customer_model()
        self.plan_model = self.model_factory.create_plan_model()
        self.subscription_model = self.model_factory.create_subscription_model(
        )
        self.invoice_model = self.model_factory.create_invoice_model()
        self.transaction_model = self.model_factory.create_transaction_model()
        self.transaction_failure_model = self.model_factory.create_transaction_failure_model(
        )
コード例 #4
0
ファイル: helper.py プロジェクト: winstonhoseadriggins/billy
    def setUp(self):

        self.session = create_session()
        self._old_now_func = tables.set_now_func(utc_now)

        self.dummy_processor = DummyProcessor()

        self.model_factory = ModelFactory(
            session=self.session,
            processor_factory=lambda: self.dummy_processor,
            settings={},
        )
        self.company_model = self.model_factory.create_company_model()
        self.customer_model = self.model_factory.create_customer_model()
        self.plan_model = self.model_factory.create_plan_model()
        self.subscription_model = self.model_factory.create_subscription_model(
        )
        self.invoice_model = self.model_factory.create_invoice_model()
        self.transaction_model = self.model_factory.create_transaction_model()
        self.transaction_failure_model = self.model_factory.create_transaction_failure_model(
        )
コード例 #5
0
    def model_factory(self):
        """The factory for creating data models

        """
        settings = self.registry.settings
        model_factory_func = settings.get('model_factory_func')
        if model_factory_func is not None:
            return model_factory_func()
        processor_factory = get_processor_factory(settings)
        return ModelFactory(
            session=self.session,
            processor_factory=processor_factory,
            settings=settings,
        )
コード例 #6
0
def main(argv=sys.argv, processor=None):
    logger = logging.getLogger(__name__)

    if len(argv) != 2:
        usage(argv)
    config_uri = argv[1]
    setup_logging(config_uri)
    settings = get_appsettings(config_uri)
    settings = setup_database({}, **settings)

    session = settings['session']
    try:
        if processor is None:
            processor_factory = get_processor_factory(settings)
        else:
            processor_factory = lambda: processor
        factory = ModelFactory(
            session=session,
            processor_factory=processor_factory,
            settings=settings,
        )
        subscription_model = factory.create_subscription_model()
        tx_model = factory.create_transaction_model()

        # yield all transactions and commit before we process them, so that
        # we won't double process them.
        with db_transaction.manager:
            logger.info('Yielding transaction ...')
            subscription_model.yield_invoices()

        with db_transaction.manager:
            logger.info('Processing transaction ...')
            tx_model.process_transactions()
        logger.info('Done')
    finally:
        session.close()
コード例 #7
0
ファイル: helper.py プロジェクト: carriercomm/billy
class ViewTestCase(unittest.TestCase):
    def setUp(self):
        self.dummy_processor = DummyProcessor()

        def model_factory_func():
            return self.model_factory

        if not hasattr(self, "settings"):
            self.settings = {
                "billy.processor_factory": lambda: self.dummy_processor,
                "model_factory_func": model_factory_func,
                # do not remove when a request is processed, so that we don't
                # have to use session.add every time
                "db_session_cleanup": False,
            }

        # init database
        db_url = os.environ.get("BILLY_FUNC_TEST_DB", "sqlite://")
        self.settings["sqlalchemy.url"] = db_url
        self.settings = setup_database({}, **self.settings)
        DeclarativeBase.metadata.bind = self.settings["engine"]
        DeclarativeBase.metadata.create_all()

        app = main({}, **self.settings)
        self.testapp = TestApp(app)
        self.testapp.session = self.settings["session"]

        self.dummy_request = DummyRequest()

        # create model factory
        self.model_factory = ModelFactory(
            session=self.testapp.session, processor_factory=lambda: self.dummy_processor, settings=self.settings
        )

        # create all models
        self.company_model = self.model_factory.create_company_model()
        self.customer_model = self.model_factory.create_customer_model()
        self.plan_model = self.model_factory.create_plan_model()
        self.subscription_model = self.model_factory.create_subscription_model()
        self.invoice_model = self.model_factory.create_invoice_model()
        self.transaction_model = self.model_factory.create_transaction_model()
        self.transaction_failure_model = self.model_factory.create_transaction_failure_model()

    def tearDown(self):
        self.testapp.session.close()
        self.testapp.session.remove()
        DeclarativeBase.metadata.drop_all()
        self.testapp.session.bind.dispose()
コード例 #8
0
ファイル: helper.py プロジェクト: remotesyssupport/billy
class ViewTestCase(unittest.TestCase):
  
    def setUp(self):
        self.dummy_processor = DummyProcessor()

        def model_factory_func():
            return self.model_factory

        if not hasattr(self, 'settings'):
            self.settings = {
                'billy.processor_factory': lambda: self.dummy_processor,
                'model_factory_func': model_factory_func,
            }

        # init database
        db_url = os.environ.get('BILLY_FUNC_TEST_DB', 'sqlite://')
        self.settings['sqlalchemy.url'] = db_url
        self.settings = setup_database({}, **self.settings)
        DeclarativeBase.metadata.bind = self.settings['engine']
        DeclarativeBase.metadata.create_all()

        app = main({}, **self.settings)
        self.testapp = TestApp(app)
        self.testapp.session = self.settings['session']

        self.dummy_request = DummyRequest()

        # create model factory
        self.model_factory = ModelFactory(
            session=self.testapp.session,
            processor_factory=lambda: self.dummy_processor,
            settings=self.settings,
        )

        # create all models
        self.company_model = self.model_factory.create_company_model()
        self.customer_model = self.model_factory.create_customer_model()
        self.plan_model = self.model_factory.create_plan_model()
        self.subscription_model = self.model_factory.create_subscription_model()
        self.invoice_model = self.model_factory.create_invoice_model()
        self.transaction_model = self.model_factory.create_transaction_model()
        self.transaction_failure_model = self.model_factory.create_transaction_failure_model()

    def tearDown(self):
        self.testapp.session.close()
        self.testapp.session.remove()
        DeclarativeBase.metadata.drop_all()
        self.testapp.session.bind.dispose()
コード例 #9
0
ファイル: helper.py プロジェクト: Imaxinacion/billy
    def setUp(self):
       
        self.session = create_session()
        self._old_now_func = tables.set_now_func(utc_now)

        self.dummy_processor = DummyProcessor()

        self.model_factory = ModelFactory(
            session=self.session,
            processor_factory=lambda: self.dummy_processor,
            settings={},
        )
        self.company_model = self.model_factory.create_company_model()
        self.customer_model = self.model_factory.create_customer_model()
        self.plan_model = self.model_factory.create_plan_model()
        self.subscription_model = self.model_factory.create_subscription_model()
        self.invoice_model = self.model_factory.create_invoice_model()
        self.transaction_model = self.model_factory.create_transaction_model()
        self.transaction_failure_model = self.model_factory.create_transaction_failure_model()
コード例 #10
0
    def test_main_with_crash(self):
        dummy_processor = DummyProcessor()
        dummy_processor.debit = mock.Mock()
        tx_guids = set()
        debits = []

        def mock_charge(transaction):
            if dummy_processor.debit.call_count == 2:
                raise KeyboardInterrupt
            uri = 'MOCK_DEBIT_URI_FOR_{}'.format(transaction.guid)
            if transaction.guid in tx_guids:
                return dict(
                    processor_uri=uri,
                    status=TransactionModel.statuses.SUCCEEDED,
                )
            tx_guids.add(transaction.guid)
            debits.append(uri)
            return dict(
                processor_uri=uri,
                status=TransactionModel.statuses.SUCCEEDED,
            )

        dummy_processor.debit.side_effect = mock_charge

        cfg_path = os.path.join(self.temp_dir, 'config.ini')
        with open(cfg_path, 'wt') as f:
            f.write(
                textwrap.dedent("""\
            [app:main]
            use = egg:billy

            sqlalchemy.url = sqlite:///%(here)s/billy.sqlite
            """))
        initializedb.main([initializedb.__file__, cfg_path])

        settings = get_appsettings(cfg_path)
        settings = setup_database({}, **settings)
        session = settings['session']
        factory = ModelFactory(
            session=session,
            processor_factory=lambda: dummy_processor,
            settings=settings,
        )
        company_model = factory.create_company_model()
        customer_model = factory.create_customer_model()
        plan_model = factory.create_plan_model()
        subscription_model = factory.create_subscription_model()

        with db_transaction.manager:
            company = company_model.create('my_secret_key')
            plan = plan_model.create(
                company=company,
                plan_type=plan_model.types.DEBIT,
                amount=10,
                frequency=plan_model.frequencies.MONTHLY,
            )
            customer = customer_model.create(company=company, )
            subscription_model.create(
                customer=customer,
                plan=plan,
                funding_instrument_uri='/v1/cards/tester',
            )
            subscription_model.create(
                customer=customer,
                plan=plan,
                funding_instrument_uri='/v1/cards/tester',
            )

        with self.assertRaises(KeyboardInterrupt):
            process_transactions.main(
                [process_transactions.__file__, cfg_path],
                processor=dummy_processor)

        process_transactions.main([process_transactions.__file__, cfg_path],
                                  processor=dummy_processor)

        # here is the story, we have two subscriptions here
        #
        #   Subscription1
        #   Subscription2
        #
        # And the time is not advanced, so we should only have two transactions
        # to be yielded and processed. However, we assume bad thing happens
        # durring the process. We let the second call to charge of processor
        # raises a KeyboardInterrupt error. So, it would look like this
        #
        #   charge for transaction from Subscription1
        #   charge for transaction from Subscription2 (Crash)
        #
        # Then, we perform the process_transactions again, if it works
        # correctly, the first transaction is already yield and processed.
        #
        #   charge for transaction from Subscription2
        #
        # So, there would only be two charges in processor. This is mainly
        # for making sure we won't duplicate charges/payouts
        self.assertEqual(len(debits), 2)
コード例 #11
0
    def test_main_with_crash(self):
        dummy_processor = DummyProcessor()
        dummy_processor.debit = mock.Mock()
        tx_guids = set()
        debits = []

        def mock_charge(transaction):
            if dummy_processor.debit.call_count == 2:
                raise KeyboardInterrupt
            uri = 'MOCK_DEBIT_URI_FOR_{}'.format(transaction.guid)
            if transaction.guid in tx_guids:
                return dict(
                    processor_uri=uri,
                    status=TransactionModel.statuses.SUCCEEDED,
                )
            tx_guids.add(transaction.guid)
            debits.append(uri)
            return dict(
                processor_uri=uri,
                status=TransactionModel.statuses.SUCCEEDED,
            )

        dummy_processor.debit.side_effect = mock_charge

        cfg_path = os.path.join(self.temp_dir, 'config.ini')
        with open(cfg_path, 'wt') as f:
            f.write(textwrap.dedent("""\
            [app:main]
            use = egg:billy

            sqlalchemy.url = sqlite:///%(here)s/billy.sqlite
            """))
        initializedb.main([initializedb.__file__, cfg_path])

        settings = get_appsettings(cfg_path)
        settings = setup_database({}, **settings)
        session = settings['session']
        factory = ModelFactory(
            session=session,
            processor_factory=lambda: dummy_processor,
            settings=settings,
        )
        company_model = factory.create_company_model()
        customer_model = factory.create_customer_model()
        plan_model = factory.create_plan_model()
        subscription_model = factory.create_subscription_model()

        with db_transaction.manager:
            company = company_model.create('my_secret_key')
            plan = plan_model.create(
                company=company,
                plan_type=plan_model.types.DEBIT,
                amount=10,
                frequency=plan_model.frequencies.MONTHLY,
            )
            customer = customer_model.create(
                company=company,
            )
            subscription_model.create(
                customer=customer,
                plan=plan,
                funding_instrument_uri='/v1/cards/tester',
            )
            subscription_model.create(
                customer=customer,
                plan=plan,
                funding_instrument_uri='/v1/cards/tester',
            )

        with self.assertRaises(KeyboardInterrupt):
            process_transactions.main([process_transactions.__file__, cfg_path],
                                      processor=dummy_processor)

        process_transactions.main([process_transactions.__file__, cfg_path],
                                  processor=dummy_processor)

        # here is the story, we have two subscriptions here
        #
        #   Subscription1
        #   Subscription2
        #
        # And the time is not advanced, so we should only have two transactions
        # to be yielded and processed. However, we assume bad thing happens
        # durring the process. We let the second call to charge of processor
        # raises a KeyboardInterrupt error. So, it would look like this
        #
        #   charge for transaction from Subscription1
        #   charge for transaction from Subscription2 (Crash)
        #
        # Then, we perform the process_transactions again, if it works
        # correctly, the first transaction is already yield and processed.
        #
        #   charge for transaction from Subscription2
        #
        # So, there would only be two charges in processor. This is mainly
        # for making sure we won't duplicate charges/payouts
        self.assertEqual(len(debits), 2)