def test__GgoQuery__has_address__Ggo_does_not_exist__returs_nothing(
        seeded_session, ggo_address):
    query = GgoQuery(seeded_session) \
        .has_address(ggo_address)

    assert query.count() == 0
    assert query.one_or_none() is None
def test__GgoQuery__get_total_amount__has_no_results__returns_zero(
        seeded_session):
    query = GgoQuery(seeded_session) \
        .has_address('AN-ADDRESS-THAT-DOESNT-EXISTS')

    assert query.count() == 0
    assert query.get_total_amount() == 0
def test__GgoQuery__get_distinct_begins__has_no_results__returns_empty_list(
        seeded_session):
    query = GgoQuery(seeded_session) \
        .has_address('AN-ADDRESS-THAT-DOESNT-EXISTS')

    assert query.count() == 0
    assert query.get_distinct_begins() == []
def test__GgoQuery__has_id__Ggo_exists__returns_correct_Ggo(
        seeded_session, ggo_id):
    query = GgoQuery(seeded_session) \
        .has_id(ggo_id)

    assert query.count() == 1
    assert query.one().id == ggo_id
def test__GgoQuery__has_address__Ggo_exists__returns_correct_Ggo(
        seeded_session, ggo_address):
    query = GgoQuery(seeded_session) \
        .has_address(ggo_address)

    assert query.count() == 1
    assert query.one().address == ggo_address
def test__GgoQuery__is_locked__returns_correct_ggos(seeded_session,
                                                    ggo_locked):
    query = GgoQuery(seeded_session) \
        .is_locked(ggo_locked)

    assert query.count() > 0
    assert all(ggo.locked == ggo_locked for ggo in query.all())
def test__GgoQuery__get_distinct_begins__has_results__returns_list_of_correct_begins(
        seeded_session):
    query = GgoQuery(seeded_session)
    distinct_begins = query.get_distinct_begins()

    assert len(distinct_begins) == 5
    assert sorted(distinct_begins) == [
        datetime(2020, 1, 1, 0, 0, 0, tzinfo=timezone.utc),
        datetime(2020, 1, 1, 1, 0, 0, tzinfo=timezone.utc),
        datetime(2020, 1, 2, 1, 0, 0, tzinfo=timezone.utc),
        datetime(2020, 2, 1, 1, 0, 0, tzinfo=timezone.utc),
        datetime(2021, 2, 1, 1, 0, 0, tzinfo=timezone.utc),
    ]
Пример #8
0
def test__Ggo__key__Ggo_was_issued__returns_get_key_for_issued_ggo(
        key_generator, seeded_session):
    ggo = GgoQuery(seeded_session).has_id(3).one()

    assert ggo.issued is True
    assert ggo.key is key_generator.get_key_for_issued_ggo.return_value
    key_generator.get_key_for_issued_ggo.assert_called_once_with(ggo)
Пример #9
0
def test__Ggo__create_child__returns_correctly_mapped_new_Ggo(
        ggo_id, seeded_session):
    parent_ggo = GgoQuery(seeded_session).has_id(ggo_id).one()
    child_ggo = parent_ggo.create_child(88, user2)

    assert child_ggo.parent_id == parent_ggo.id
    assert child_ggo.user_id == user2.id
    assert child_ggo.issue_time == parent_ggo.issue_time
    assert child_ggo.expire_time == parent_ggo.expire_time
    assert child_ggo.sector == parent_ggo.sector
    assert child_ggo.begin == parent_ggo.begin
    assert child_ggo.end == parent_ggo.end
    assert child_ggo.technology_code == parent_ggo.technology_code
    assert child_ggo.fuel_code == parent_ggo.fuel_code
    assert child_ggo.amount == 88
    assert child_ggo.issued is False
    assert child_ggo.stored is False
    assert child_ggo.retired is False
    assert child_ggo.synchronized is False
    assert child_ggo.locked is False
Пример #10
0
 def fetch_retired_ggos_from_db(self, meteringpoints, begin_range, session):
     """
     :param list[MeteringPoint] meteringpoints:
     :param DateTimeRange begin_range:
     :param sqlalchemy.orm.Session session:
     :rtype: list[Ggo]
     """
     return GgoQuery(session) \
         .is_retired_to_any_gsrn([m.gsrn for m in meteringpoints]) \
         .begins_within(begin_range) \
         .all()
Пример #11
0
def invoke_on_ggo_received(task, subject, ggo_id, subscription_id, session,
                           **logging_kwargs):
    """
    :param celery.Task task:
    :param str subject:
    :param int ggo_id:
    :param int subscription_id:
    :param sqlalchemy.orm.Session session:
    """
    __log_extra = logging_kwargs.copy()
    __log_extra.update({
        'subject': subject,
        'ggo_id': str(ggo_id),
        'subscription_id': str(subscription_id),
        'pipeline': 'webhooks',
        'task': 'invoke_on_ggo_received',
    })

    # Get GGO from database
    try:
        ggo = GgoQuery(session) \
            .has_id(ggo_id) \
            .one()
    except orm.exc.NoResultFound:
        raise
    except Exception as e:
        logger.exception('Failed to load Ggo from database', extra=__log_extra)
        raise task.retry(exc=e)

    # Get webhook subscription from database
    try:
        subscription = webhook_service.get_subscription(
            subscription_id, session)
    except orm.exc.NoResultFound:
        raise
    except Exception as e:
        logger.exception('Failed to load WebhookSubscription from database',
                         extra=__log_extra)
        raise task.retry(exc=e)

    # Publish event to webhook
    try:
        webhook_service.on_ggo_received(subscription, ggo)
    except WebhookConnectionError as e:
        logger.exception(
            'Failed to invoke webhook: ON_GGO_RECEIVED (Connection error)',
            extra=__log_extra)
        raise task.retry(exc=e)
    except WebhookError as e:
        logger.exception('Failed to invoke webhook: ON_GGO_RECEIVED',
                         extra=__log_extra)
        raise task.retry(exc=e)
def test__GgoQuery__is_tradable__returns_correct_ggos(seeded_session):
    query = GgoQuery(seeded_session) \
        .is_tradable()

    assert query.count() > 0
    assert all(ggo.stored is True for ggo in query.all())
    # assert all(ggo.expired is False for ggo in query.all())
    assert all(ggo.retired is False for ggo in query.all())

    assert all(ggo.synchronized is True for ggo in query.all())
    assert all(ggo.locked is False for ggo in query.all())
def test__GgoQuery__is_NOT_retired__returns_correct_ggos(seeded_session):
    query = GgoQuery(seeded_session) \
        .is_retired(False)

    assert query.count() > 0
    assert all(ggo.retired is False for ggo in query.all())
    assert all(ggo.retire_gsrn is None for ggo in query.all())
    assert all(ggo.retire_address is None for ggo in query.all())
def test__GgoQuery__is_retired_to_gsrn__returns_correct_ggos(
        seeded_session, ggo_retire_gsrn):
    query = GgoQuery(seeded_session) \
        .is_retired_to_gsrn(ggo_retire_gsrn)

    assert query.count() > 0
    assert all(ggo.retired is True for ggo in query.all())
    assert all(ggo.retire_address is not None for ggo in query.all())
    assert all(ggo.retire_gsrn == ggo_retire_gsrn for ggo in query.all())
    def trigger_ggo_received_webhooks_for(self, subject, session):
        user = UserQuery(session) \
            .has_sub(subject) \
            .one()

        ggos = GgoQuery(session) \
            .belongs_to(user) \
            .is_tradable()

        for ggo in ggos:
            start_invoke_on_ggo_received_tasks(
                subject=user.sub,
                ggo_id=ggo.id,
                session=session,
            )
def test__GgoImportController__integration(datahub_service, seeded_session):
    def __get_ggo_list(access_token, request):
        datahub_response_schema = md.class_schema(GetGgoListResponse)
        datahub_response = datahub_response_schema()
        return datahub_response.loads(IMPORT_GGO_DATA1)

    # Arrange
    datahub_service.get_ggo_list.side_effect = __get_ggo_list
    begin_from = datetime(2020, 9, 1, 0, 0, tzinfo=timezone.utc)
    begin_to = datetime(2020, 9, 30, 23, 0, tzinfo=timezone.utc)
    uut = GgoImportController()

    # Act
    uut.import_ggos(user, '571313180400240049', begin_from, begin_to,
                    seeded_session)
    seeded_session.commit()

    # Assert
    query = GgoQuery(seeded_session).belongs_to(user)
    begins = query.get_distinct_begins()
    assert query.count() == 720
    assert min(begins).astimezone(timezone.utc) == datetime(
        2019, 9, 1, 0, 0, tzinfo=timezone.utc)
    assert max(begins).astimezone(timezone.utc) == datetime(
        2019, 9, 30, 23, 0, tzinfo=timezone.utc)

    # Second time should not do anything
    uut.import_ggos(user, '571313180400240049', begin_from, begin_to,
                    seeded_session)
    seeded_session.commit()

    # Assert
    query = GgoQuery(seeded_session).belongs_to(user)
    begins = query.get_distinct_begins()
    assert query.count() == 720
    assert min(begins).astimezone(timezone.utc) == datetime(
        2019, 9, 1, 0, 0, tzinfo=timezone.utc)
    assert max(begins).astimezone(timezone.utc) == datetime(
        2019, 9, 30, 23, 0, tzinfo=timezone.utc)
Пример #17
0
def test__Ggo__technology__Technology_exists__returns_correct_Technology(
        seeded_session, ggo_id, technology):
    query = GgoQuery(seeded_session).has_id(ggo_id)

    assert query.count() == 1
    assert query.one().technology.technology == technology
Пример #18
0
def test__integration__compose(datahub_importing, datahub_composer,
                               seeded_session):

    sector = 'DK1'
    begin = datetime(2020, 5, 1, 0, 0, 0, tzinfo=timezone.utc)
    end = begin + timedelta(hours=1)
    ref1 = 'REF1'
    ref2 = 'REF2'
    gsrn1 = '1111111111'
    gsrn2 = '2222222222'

    issued_ggo1 = GgoDataHub(
        address='address1',
        gsrn=gsrn1,
        begin=begin,
        end=end,
        sector=sector,
        amount=100,
        issue_time=datetime(2020, 1, 1, 0, 0, 0, tzinfo=timezone.utc),
        expire_time=datetime(2050, 1, 1, 0, 0, 0, tzinfo=timezone.utc),
        technology_code='T000000',
        fuel_code='F00000000',
    )

    issued_ggo2 = GgoDataHub(
        address='address2',
        gsrn=gsrn1,
        begin=begin,
        end=end,
        sector=sector,
        amount=100,
        issue_time=datetime(2020, 1, 1, 0, 0, 0, tzinfo=timezone.utc),
        expire_time=datetime(2050, 1, 1, 0, 0, 0, tzinfo=timezone.utc),
        technology_code='T000000',
        fuel_code='F00000000',
    )

    measurement1 = Measurement(
        address='measurement1',
        gsrn=gsrn1,
        begin=begin,
        end=end,
        type=MeasurementType.CONSUMPTION,
        sector=sector,
        amount=10,
    )

    measurement2 = Measurement(
        address='measurement2',
        gsrn=gsrn2,
        begin=begin,
        end=end,
        type=MeasurementType.CONSUMPTION,
        sector=sector,
        amount=10,
    )

    meteringpoint1 = MeteringPoint.create(
        user=user1,
        session=seeded_session,
        gsrn=gsrn1,
        sector=sector,
        type=MeteringPointType.CONSUMPTION,
    )

    meteringpoint2 = MeteringPoint.create(
        user=user1,
        session=seeded_session,
        gsrn=gsrn2,
        sector=sector,
        type=MeteringPointType.CONSUMPTION,
    )

    seeded_session.add(meteringpoint1)
    seeded_session.add(meteringpoint2)
    seeded_session.flush()
    seeded_session.commit()

    # -- ARRANGE DATAHUB MOCK (for issuer) -----------------------------------

    datahub_importing.get_ggo_list.side_effect = \
        lambda *args, **kwargs: GetGgoListResponse(success=True, ggos=[issued_ggo1, issued_ggo2])

    # -- ARRANGE DATAHUB MOCK (for composer) ---------------------------------

    def __get_consumption(access_token, request):
        if (request.gsrn, request.begin) == (meteringpoint1.gsrn, begin):
            m = measurement1
        elif (request.gsrn, request.begin) == (meteringpoint2.gsrn, begin):
            m = measurement2
        else:
            raise RuntimeError

        return GetMeasurementResponse(success=True, measurement=m)

    datahub_composer.get_consumption.side_effect = __get_consumption

    # -- ISSUE GGOS ----------------------------------------------------------

    issuer = GgoImportController()
    issuer.import_ggos(user1, meteringpoint1.gsrn, begin, begin,
                       seeded_session)

    seeded_session.commit()

    parent_ggo1 = GgoQuery(seeded_session).has_address('address1').one()
    parent_ggo2 = GgoQuery(seeded_session).has_address('address2').one()

    # -- ASSERT --------------------------------------------------------------

    assert GgoQuery(seeded_session).belongs_to(
        user1).is_stored().get_total_amount() == 200
    assert GgoQuery(seeded_session).belongs_to(
        user2).is_stored().get_total_amount() == 0
    assert GgoQuery(seeded_session).belongs_to(
        user3).is_stored().get_total_amount() == 0
    assert TransactionQuery(seeded_session).sent_by_user(
        user1).get_total_amount() == 0
    assert TransactionQuery(seeded_session).sent_by_user(
        user2).get_total_amount() == 0
    assert TransactionQuery(seeded_session).sent_by_user(
        user3).get_total_amount() == 0
    assert TransactionQuery(seeded_session).received_by_user(
        user1).get_total_amount() == 0
    assert TransactionQuery(seeded_session).received_by_user(
        user2).get_total_amount() == 0
    assert TransactionQuery(seeded_session).received_by_user(
        user3).get_total_amount() == 0
    assert GgoQuery(seeded_session).is_retired(True).belongs_to(
        user1).get_total_amount() == 0
    assert GgoQuery(seeded_session).is_retired(True).belongs_to(
        user2).get_total_amount() == 0
    assert GgoQuery(seeded_session).is_retired(True).belongs_to(
        user3).get_total_amount() == 0
    assert GgoQuery(seeded_session).is_retired(True).is_retired_to_gsrn(
        meteringpoint1.gsrn).get_total_amount() == 0
    assert GgoQuery(seeded_session).is_retired(True).is_retired_to_gsrn(
        meteringpoint2.gsrn).get_total_amount() == 0

    # -- ACT -----------------------------------------------------------------

    # TRANSFER 40, RETIRE 15 (5 + 10) = TOTAL 60, REMAINING 40
    composer = GgoComposer(ggo=parent_ggo1, session=seeded_session)
    composer.add_transfer(user2, 10, ref1)
    composer.add_transfer(user3, 30, ref2)
    composer.add_retire(meteringpoint1, 5)  # Measurement = 10
    composer.add_retire(meteringpoint2, 10)  # Measurement = 10

    batch1, recipients = composer.build_batch()

    seeded_session.add(batch1)
    seeded_session.commit()

    # -- ASSERT --------------------------------------------------------------

    assert GgoQuery(seeded_session).belongs_to(
        user1).is_stored().get_total_amount() == 145
    assert GgoQuery(seeded_session).belongs_to(
        user2).is_stored().get_total_amount() == 10
    assert GgoQuery(seeded_session).belongs_to(
        user3).is_stored().get_total_amount() == 30
    assert TransactionQuery(seeded_session).sent_by_user(
        user1).get_total_amount() == 40
    assert TransactionQuery(seeded_session).sent_by_user(
        user2).get_total_amount() == 0
    assert TransactionQuery(seeded_session).sent_by_user(
        user3).get_total_amount() == 0
    assert TransactionQuery(seeded_session).received_by_user(
        user1).get_total_amount() == 0
    assert TransactionQuery(seeded_session).received_by_user(
        user2).get_total_amount() == 10
    assert TransactionQuery(seeded_session).received_by_user(
        user3).get_total_amount() == 30
    assert GgoQuery(seeded_session).is_retired(True).belongs_to(
        user1).get_total_amount() == 15
    assert GgoQuery(seeded_session).is_retired(True).belongs_to(
        user2).get_total_amount() == 0
    assert GgoQuery(seeded_session).is_retired(True).belongs_to(
        user3).get_total_amount() == 0
    assert GgoQuery(seeded_session).is_retired(True).is_retired_to_gsrn(
        meteringpoint1.gsrn).get_total_amount() == 5
    assert GgoQuery(seeded_session).is_retired(True).is_retired_to_gsrn(
        meteringpoint2.gsrn).get_total_amount() == 10

    # -- ACT -----------------------------------------------------------------

    batch1.on_commit()
    seeded_session.commit()

    # -- ASSERT --------------------------------------------------------------

    assert GgoQuery(seeded_session).belongs_to(
        user1).is_stored().get_total_amount() == 145
    assert GgoQuery(seeded_session).belongs_to(
        user2).is_stored().get_total_amount() == 10
    assert GgoQuery(seeded_session).belongs_to(
        user3).is_stored().get_total_amount() == 30
    assert TransactionQuery(seeded_session).sent_by_user(
        user1).get_total_amount() == 40
    assert TransactionQuery(seeded_session).sent_by_user(
        user2).get_total_amount() == 0
    assert TransactionQuery(seeded_session).sent_by_user(
        user3).get_total_amount() == 0
    assert TransactionQuery(seeded_session).received_by_user(
        user1).get_total_amount() == 0
    assert TransactionQuery(seeded_session).received_by_user(
        user2).get_total_amount() == 10
    assert TransactionQuery(seeded_session).received_by_user(
        user3).get_total_amount() == 30
    assert GgoQuery(seeded_session).is_retired(True).belongs_to(
        user1).get_total_amount() == 15
    assert GgoQuery(seeded_session).is_retired(True).belongs_to(
        user2).get_total_amount() == 0
    assert GgoQuery(seeded_session).is_retired(True).belongs_to(
        user3).get_total_amount() == 0
    assert GgoQuery(seeded_session).is_retired(True).is_retired_to_gsrn(
        meteringpoint1.gsrn).get_total_amount() == 5
    assert GgoQuery(seeded_session).is_retired(True).is_retired_to_gsrn(
        meteringpoint2.gsrn).get_total_amount() == 10

    # -- ACT -----------------------------------------------------------------

    # TRANSFER 40, RETIRE 5 (5 + 0) = TOTAL 45, REMAINING 55
    composer = GgoComposer(ggo=parent_ggo2, session=seeded_session)
    composer.add_transfer(user2, 10, ref1)
    composer.add_transfer(user3, 30, ref2)
    composer.add_retire(meteringpoint1, 5)

    batch2, recipients = composer.build_batch()

    seeded_session.add(batch2)
    seeded_session.commit()

    # -- ASSERT --------------------------------------------------------------

    assert GgoQuery(seeded_session).belongs_to(
        user1).is_stored().get_total_amount() == 100
    assert GgoQuery(seeded_session).belongs_to(
        user2).is_stored().get_total_amount() == 20
    assert GgoQuery(seeded_session).belongs_to(
        user3).is_stored().get_total_amount() == 60
    assert TransactionQuery(seeded_session).sent_by_user(
        user1).get_total_amount() == 80
    assert TransactionQuery(seeded_session).sent_by_user(
        user2).get_total_amount() == 0
    assert TransactionQuery(seeded_session).sent_by_user(
        user3).get_total_amount() == 0
    assert TransactionQuery(seeded_session).received_by_user(
        user1).get_total_amount() == 0
    assert TransactionQuery(seeded_session).received_by_user(
        user2).get_total_amount() == 20
    assert TransactionQuery(seeded_session).received_by_user(
        user3).get_total_amount() == 60
    assert GgoQuery(seeded_session).is_retired(True).belongs_to(
        user1).get_total_amount() == 20
    assert GgoQuery(seeded_session).is_retired(True).belongs_to(
        user2).get_total_amount() == 0
    assert GgoQuery(seeded_session).is_retired(True).belongs_to(
        user3).get_total_amount() == 0
    assert GgoQuery(seeded_session).is_retired(True).is_retired_to_gsrn(
        meteringpoint1.gsrn).get_total_amount() == 10
    assert GgoQuery(seeded_session).is_retired(True).is_retired_to_gsrn(
        meteringpoint2.gsrn).get_total_amount() == 10

    # -- ACT -----------------------------------------------------------------

    batch2.on_rollback()
    seeded_session.commit()

    # -- ASSERT --------------------------------------------------------------

    assert GgoQuery(seeded_session).belongs_to(
        user1).is_stored().get_total_amount() == 145
    assert GgoQuery(seeded_session).belongs_to(
        user2).is_stored().get_total_amount() == 10
    assert GgoQuery(seeded_session).belongs_to(
        user3).is_stored().get_total_amount() == 30
    assert TransactionQuery(seeded_session).sent_by_user(
        user1).get_total_amount() == 40
    assert TransactionQuery(seeded_session).sent_by_user(
        user2).get_total_amount() == 0
    assert TransactionQuery(seeded_session).sent_by_user(
        user3).get_total_amount() == 0
    assert TransactionQuery(seeded_session).received_by_user(
        user1).get_total_amount() == 0
    assert TransactionQuery(seeded_session).received_by_user(
        user2).get_total_amount() == 10
    assert TransactionQuery(seeded_session).received_by_user(
        user3).get_total_amount() == 30
    assert GgoQuery(seeded_session).is_retired(True).belongs_to(
        user1).get_total_amount() == 15
    assert GgoQuery(seeded_session).is_retired(True).belongs_to(
        user2).get_total_amount() == 0
    assert GgoQuery(seeded_session).is_retired(True).belongs_to(
        user3).get_total_amount() == 0
    assert GgoQuery(seeded_session).is_retired(True).is_retired_to_gsrn(
        meteringpoint1.gsrn).get_total_amount() == 5
    assert GgoQuery(seeded_session).is_retired(True).is_retired_to_gsrn(
        meteringpoint2.gsrn).get_total_amount() == 10
Пример #19
0
def test__Ggo__create_child__amount_invalid__should_raise_AssertionError(
        amount, seeded_session):
    parent_ggo = GgoQuery(seeded_session).has_id(1).one()

    with pytest.raises(AssertionError):
        parent_ggo.create_child(amount, user2)
def test__GgoQuery__belongs_to__returns_correct_ggos(seeded_session):
    query = GgoQuery(seeded_session) \
        .belongs_to(user1)

    assert query.count() > 0
    assert all(ggo.user_id == 1 for ggo in query.all())
def test__GgoQuery__begins_at__returns_correct_ggos(seeded_session, ggo_begin):
    query = GgoQuery(seeded_session) \
        .begins_at(ggo_begin)

    assert query.count() > 0
    assert all(ggo.begin == ggo_begin for ggo in query.all())
def test__GgoQuery__begins_at__Ggo_does_not_exist__returs_nothing(
        seeded_session, ggo_begin):
    query = GgoQuery(seeded_session) \
        .begins_at(ggo_begin)

    assert query.count() == 0
def test__GgoQuery__get_total_amount__has_results__returns_correct_amount(
        seeded_session):
    query = GgoQuery(seeded_session)

    assert query.count() > 0
    assert query.get_total_amount() == query.count() * GGO_AMOUNT
Пример #24
0
def test__Ggo__technology__Technology_does_not_exist__returns_None(
        seeded_session):
    query = GgoQuery(seeded_session).has_id(3)

    assert query.count() == 1
    assert query.one().technology is None