Esempio n. 1
0
def postgres_dsn(postgres):
    """ Returns a dsn to a temporary postgres server. Cleans up the database
    after running the tests.

    """
    postgres.reset_snapshots()

    yield postgres.url()

    transaction.abort()

    manager = SessionManager(postgres.url(), None)
    manager.session().close_all()
    manager.dispose()

    engine = create_engine(postgres.url())
    results = engine.execute(
        "SELECT DISTINCT table_schema FROM information_schema.tables")

    schemas = set(r['table_schema'] for r in results)

    for schema in schemas:
        if schema.startswith('pg_'):
            continue

        if schema in ('information_schema', 'public'):
            continue

        # having a bad day because your test doesn't work if run with others?
        # did you use a session manager? if yes, make sure to use mgr.dispose()
        # before finishing your test, or use the sesion_manager fixture!
        engine.execute(f'DROP SCHEMA "{schema}" CASCADE')

    engine.raw_connection().invalidate()
    engine.dispose()
Esempio n. 2
0
def cli(ctx, dsn, schema):
    ctx.obj = {}

    mgr = SessionManager(dsn, base=Base)
    mgr.set_current_schema(schema)

    ctx.obj["schema"] = schema
    ctx.obj["session"] = mgr.session()
Esempio n. 3
0
def cli(ctx, dsn, schema):
    ctx.obj = {}

    mgr = SessionManager(dsn, base=Base)
    mgr.bases.append(ORMBase)
    mgr.set_current_schema(schema)

    ctx.obj['schema'] = schema
    ctx.obj['session_manager'] = mgr
    ctx.obj['session'] = mgr.session()
    ctx.obj['libres_registry'] = create_default_registry()
Esempio n. 4
0
def test_payable_collection(postgres_dsn):

    MyBase = declarative_base()

    class Order(MyBase, Payable):
        __tablename__ = 'orders'

        id = Column(UUID, primary_key=True, default=uuid4)
        title = Column(Text)

    class Newspaper(MyBase, Payable):
        __tablename__ = 'newspapers'

        id = Column(UUID, primary_key=True, default=uuid4)
        title = Column(Text)

    mgr = SessionManager(postgres_dsn, Base)
    mgr.bases.append(MyBase)
    mgr.set_current_schema('foobar')
    session = mgr.session()

    provider = PaymentProvider()

    carbonara = Order(title="Carbonara")
    coca_cola = Order(title="Coca Cola")

    the_wapo = Newspaper(title="The Washington Post")
    ny_times = Newspaper(title="The New York Times")

    carbonara.payment = coca_cola.payment = provider.payment(amount=25)
    the_wapo.payment = provider.payment(amount=4.50)
    ny_times.payment = provider.payment(amount=5.50)

    session.add_all((carbonara, coca_cola, the_wapo, ny_times))
    session.flush()

    payables = PayableCollection(session)
    payables.batch_size = 3

    assert payables.query().count() == 4
    assert len(payables.batch) == 3

    payables = payables.page_by_index(1)
    payables.batch_size = 3
    assert len(payables.batch) == 1

    orders = PayableCollection(session, cls=Order)
    assert orders.query().count() == 2
Esempio n. 5
0
def test_backref(postgres_dsn):

    MyBase = declarative_base()

    class Product(MyBase, Payable):
        __tablename__ = 'products'

        id = Column(UUID, primary_key=True, default=uuid4)
        title = Column(Text)

    class Part(MyBase, Payable):
        __tablename__ = 'parts'

        id = Column(UUID, primary_key=True, default=uuid4)
        title = Column(Text)

    mgr = SessionManager(postgres_dsn, Base)
    mgr.bases.append(MyBase)
    mgr.set_current_schema('foobar')
    session = mgr.session()

    provider = PaymentProvider()

    car = Product(title="Car", payment=provider.payment(amount=10000))
    nut = Part(title="Nut", payment=provider.payment(amount=10))
    session.add_all((car, nut))
    session.flush()

    payments = session.query(Payment).all()
    assert [t.title for p in payments for t in p.linked_products] == ["Car"]
    assert [t.title for p in payments for t in p.linked_parts] == ["Nut"]

    assert len(car.payment.linked_products) == 1
    assert len(car.payment.linked_parts) == 0
    assert len(nut.payment.linked_products) == 0
    assert len(nut.payment.linked_parts) == 1

    assert car.payment.links.count() == 1
    assert car.payment.links.first().title == "Car"
    assert nut.payment.links.count() == 1
    assert nut.payment.links.first().title == "Nut"

    assert len(PaymentCollection(session).payment_links_by_batch()) == 2

    session.delete(nut.payment)
    nut.payment = car.payment
    session.flush()

    assert len(car.payment.linked_products) == 1
    assert len(car.payment.linked_parts) == 1
    assert len(nut.payment.linked_products) == 1
    assert len(nut.payment.linked_parts) == 1

    assert car.payment.links.count() == 2
    assert {r.title for r in car.payment.links} == {"Car", "Nut"}

    assert len(PaymentCollection(session).payment_links_by_batch()) == 1

    mgr.dispose()
Esempio n. 6
0
def session_manager(postgres_dsn):
    """ Provides a :class:`onegov.core.orm.session_manager.SessionManager`
    setup with :func:`postgres_dsn`.

    """

    # in testing we often reuse loaded values after commiting a transaction,
    # so we set expire_on_commit to False. The test applications will still
    # use the default value of True however. This only affects unit tests
    # not working with the app.
    mgr = SessionManager(
        postgres_dsn, Base,
        session_config={
            'expire_on_commit': False
        },
        engine_config={
            'echo': 'ECHO' in os.environ
        }
    )
    yield mgr
    mgr.dispose()
Esempio n. 7
0
def session_manager(postgres_dsn):
    """ Provides a :class:`onegov.core.orm.session_manager.SessionManager`
    setup with :func:`postgres_dsn`.

    """

    # in testing we often reuse loaded values after commiting a transaction,
    # so we set expire_on_commit to False. The test applications will still
    # use the default value of True however. This only affects unit tests
    # not working with the app.
    mgr = SessionManager(
        postgres_dsn, Base,
        session_config={
            'expire_on_commit': False
        },
        engine_config={
            'echo': 'ECHO' in os.environ
        }
    )
    yield mgr
    mgr.dispose()
Esempio n. 8
0
def postgres_dsn(postgres):
    """ Returns a dsn to a temporary postgres server. Cleans up the database
    after running the tests.

    """
    postgres.reset_snapshots()

    yield postgres.url()

    transaction.abort()

    manager = SessionManager(postgres.url(), None)
    manager.session().close_all()
    manager.dispose()

    engine = create_engine(postgres.url())
    results = engine.execute(
        "SELECT DISTINCT table_schema FROM information_schema.tables")

    schemas = set(r['table_schema'] for r in results)

    for schema in schemas:
        if schema.startswith('pg_'):
            continue

        if schema in ('information_schema', 'public'):
            continue

        # having a bad day because your test doesn't work if run with others?
        # did you use a session manager? if yes, make sure to use mgr.dispose()
        # before finishing your test, or use the sesion_manager fixture!
        engine.execute(f'DROP SCHEMA "{schema}" CASCADE')

    engine.raw_connection().invalidate()
    engine.dispose()
Esempio n. 9
0
def test_mutable_coordinates(postgres_dsn):
    Base = declarative_base(cls=ModelBase)

    class Monument(Base, ContentMixin, CoordinatesMixin):
        __tablename__ = 'monument'
        id = Column(Integer, primary_key=True)

    mgr = SessionManager(postgres_dsn, Base)
    mgr.set_current_schema('foo')

    session = mgr.session()
    session.add(Monument())
    session.flush()

    washington = session.query(Monument).one()
    assert washington.coordinates.lat is None
    assert washington.coordinates.lon is None
    assert washington.coordinates.zoom is None

    washington = session.query(Monument).one()
    washington.coordinates = Coordinates(38.889484, -77.035278)
    assert washington.coordinates.lat == 38.889484
    assert washington.coordinates.lon == -77.035278
    assert washington.coordinates.zoom is None
    session.flush()

    washington = session.query(Monument).one()
    washington.coordinates.zoom = 10
    session.flush()

    assert session.query(Monument).one().coordinates.zoom == 10

    mgr.dispose()
Esempio n. 10
0
def test_payment_with_different_bases(postgres_dsn):

    MyBase = declarative_base()

    class Order(MyBase, Payable):
        __tablename__ = 'orders'

        id = Column(UUID, primary_key=True, default=uuid4)
        title = Column(Text)

    class Subscription(Base, Payable):
        __tablename__ = 'subscriptions'

        id = Column(UUID, primary_key=True, default=uuid4)
        title = Column(Text)

    mgr = SessionManager(postgres_dsn, Base)
    mgr.bases.append(MyBase)
    mgr.set_current_schema('foobar')
    session = mgr.session()

    provider = PaymentProvider()

    apple = Order(title="Apple")
    pizza = Order(title="Pizza")
    kebab = Order(title="Kebab")
    times = Subscription(title="Times")

    apple.payment = provider.payment(amount=100)
    pizza.payment = provider.payment(amount=200)
    kebab.payment = apple.payment
    times.payment = pizza.payment

    session.add_all((apple, pizza, kebab, times))
    session.flush()

    assert session.query(Payment).count() == 2
    assert session.query(Order).count() == 3
    assert session.query(Subscription).count() == 1

    apple = session.query(Order).filter_by(title="Apple").one()
    pizza = session.query(Order).filter_by(title="Pizza").one()
    kebab = session.query(Order).filter_by(title="Kebab").one()
    times = session.query(Subscription).filter_by(title="Times").one()

    assert apple.payment.amount == 100
    assert pizza.payment.amount == 200
    assert kebab.payment.amount == 100
    assert times.payment.amount == 200

    mgr.dispose()
Esempio n. 11
0
def test_payment_referential_integrity(postgres_dsn):

    MyBase = declarative_base()

    class Order(MyBase, Payable):
        __tablename__ = 'orders'

        id = Column(UUID, primary_key=True, default=uuid4)
        title = Column(Text)

    mgr = SessionManager(postgres_dsn, Base)
    mgr.bases.append(MyBase)
    mgr.set_current_schema('foobar')
    session = mgr.session()

    apple = Order(title="Apple", payment=PaymentProvider().payment(amount=100))
    session.add(apple)
    transaction.commit()

    with pytest.raises(IntegrityError):
        session.delete(session.query(PaymentProvider).one())
        session.flush()

    transaction.abort()

    # as a precaution we only allow deletion of elements after the payment
    # has been explicitly deleted
    with pytest.raises(IntegrityError):
        session.delete(session.query(Order).one())
        session.flush()

    transaction.abort()

    with pytest.raises(IntegrityError):
        session.delete(session.query(Order).one())
        session.delete(session.query(Payment).one())
        session.flush()

    transaction.abort()

    session.delete(session.query(Payment).one())
    session.delete(session.query(Order).one())
    transaction.commit()

    assert not list(session.execute("select * from orders"))
    assert not list(session.execute("select * from payments"))
    assert not list(
        session.execute("select * from payments_for_orders_payment"))

    mgr.dispose()
Esempio n. 12
0
def test_manual_payment(postgres_dsn):

    MyBase = declarative_base()

    class Product(MyBase, Payable):
        __tablename__ = 'products'

        id = Column(UUID, primary_key=True, default=uuid4)
        title = Column(Text)

    mgr = SessionManager(postgres_dsn, Base)
    mgr.bases.append(MyBase)
    mgr.set_current_schema('foobar')
    session = mgr.session()

    car = Product(title="Car", payment=ManualPayment(amount=10000))
    session.add(car)
    session.flush()

    payments = session.query(Payment).all()
    assert [t.title for p in payments for t in p.linked_products] == ["Car"]

    mgr.dispose()