Esempio n. 1
0
def test__GgoComposer__build_batch__total_amount_exceeds_available_amount__should_raise_AmountUnavailable(
        datahub, transfer_amounts, retire_amounts):

    #  -- Arrange ------------------------------------------------------------

    sector = 'DK1'
    begin = datetime(2020, 1, 1, 0, 0, 0)

    ggo = Mock(amount=100, begin=begin, sector=sector, user_id=1)
    ggo.is_tradable.return_value = True
    ggo.is_expired.return_value = False

    datahub.get_consumption.return_value = Mock(measurement=Mock(
        sector=sector,
        begin=begin,
        amount=100,
    ))

    composer = GgoComposer(ggo=ggo, session=Mock())
    composer.get_retired_amount = Mock()
    composer.get_retired_amount.return_value = 0

    #  -- Act + Assert -------------------------------------------------------

    for transfer_amount in transfer_amounts:
        composer.add_transfer(user=Mock(), amount=transfer_amount)
    for retire_amount in retire_amounts:
        composer.add_retire(meteringpoint=Mock(
            user_id=1, type=MeteringPointType.CONSUMPTION),
                            amount=retire_amount)

    with pytest.raises(composer.AmountUnavailable):
        composer.build_batch()
Esempio n. 2
0
def test__GgoComposer__build_batch__nothing_added__should_raise_Empty():

    # Arrange
    ggo = Mock()
    ggo.is_tradable.return_value = True
    ggo.is_expired.return_value = False

    composer = GgoComposer(ggo=ggo, session=Mock())

    # Act + Assert
    with pytest.raises(composer.Empty):
        composer.build_batch()
Esempio n. 3
0
def test__GgoComposer__build_batch__retire_full_amount_to_one_gsrn__should_build_batch_with_one_RetireTransaction(
        datahub):

    #  -- Arrange ------------------------------------------------------------

    sector = 'DK1'
    begin = datetime(2020, 1, 1, 0, 0, 0)

    ggo = Mock(amount=100,
               begin=begin,
               sector=sector,
               stored=True,
               retired=False,
               locked=False,
               synchronized=True,
               user_id=1)
    ggo.is_tradable.return_value = True
    ggo.is_expired.return_value = False
    ggo.create_child.side_effect = lambda amount, user: Mock(amount=amount,
                                                             user=user)

    meteringpoint = Mock(gsrn='GSRN1',
                         user_id=1,
                         type=MeteringPointType.CONSUMPTION)
    measurement = Mock(sector=sector,
                       begin=begin,
                       amount=100,
                       address='MEASUREMENT-ADDRESS')

    datahub.get_consumption.return_value = Mock(measurement=measurement)

    composer = GgoComposer(ggo=ggo, session=Mock())
    composer.get_retired_amount = Mock()
    composer.get_retired_amount.return_value = 0

    #  -- Act ----------------------------------------------------------------

    composer.add_retire(meteringpoint=meteringpoint, amount=100)
    batch, recipients = composer.build_batch()

    #  -- Assert -------------------------------------------------------------

    assert len(recipients) == 0
    assert len(batch.transactions) == 1
    assert type(batch.transactions[0]) is RetireTransaction
    assert batch.transactions[0].parent_ggo is ggo
    assert batch.transactions[0].parent_ggo.retire_gsrn == 'GSRN1'
    assert batch.transactions[
        0].parent_ggo.retire_address == 'MEASUREMENT-ADDRESS'
    assert batch.transactions[0].meteringpoint is meteringpoint
    assert batch.transactions[0].measurement_address == 'MEASUREMENT-ADDRESS'
Esempio n. 4
0
def test__GgoComposer__build_batch__multiple_retires_and_transfers__should_build_batch_with_one_SplitTransaction_and_multiple_RetireTransactions(
        datahub):

    #  -- Arrange ------------------------------------------------------------

    sector = 'DK1'
    begin = datetime(2020, 1, 1, 0, 0, 0)

    ggo = Mock(amount=100,
               begin=begin,
               sector=sector,
               stored=True,
               retired=False,
               locked=False,
               synchronized=True,
               user_id=1)
    ggo.is_tradable.return_value = True
    ggo.is_expired.return_value = False
    ggo.create_child.side_effect = lambda amount, user: Mock(
        amount=amount, user=user, begin=begin)

    user1 = Mock()
    user2 = Mock()

    meteringpoint1 = Mock(gsrn='GSRN1',
                          user_id=1,
                          type=MeteringPointType.CONSUMPTION)
    meteringpoint2 = Mock(gsrn='GSRN2',
                          user_id=1,
                          type=MeteringPointType.CONSUMPTION)
    measurement = Mock(sector=sector,
                       begin=begin,
                       amount=100,
                       address='MEASUREMENT-ADDRESS')

    datahub.get_consumption.return_value = Mock(measurement=measurement)

    composer = GgoComposer(ggo=ggo, session=Mock())
    composer.get_retired_amount = Mock()
    composer.get_retired_amount.return_value = 0

    #  -- Act ----------------------------------------------------------------

    composer.add_transfer(user=user1, amount=15, reference='REF1')
    composer.add_transfer(user=user2, amount=30, reference='REF2')
    composer.add_retire(meteringpoint=meteringpoint1, amount=10)
    composer.add_retire(meteringpoint=meteringpoint2, amount=40)

    # Sum of transfers + retires = 95 (5 remaining)

    batch, recipients = composer.build_batch()

    #  -- Assert -------------------------------------------------------------

    assert len(recipients) == 3
    assert len(batch.transactions) == 3

    split = batch.transactions[0]
    retire1 = batch.transactions[1]
    retire2 = batch.transactions[2]

    # SplitTransaction
    assert type(split) is SplitTransaction
    assert len(split.targets) == 5
    assert split.parent_ggo is ggo
    assert split.targets[0].ggo.user is user1
    assert split.targets[0].ggo.amount == 15
    assert split.targets[0].reference == 'REF1'
    assert split.targets[1].ggo.user is user2
    assert split.targets[1].ggo.amount == 30
    assert split.targets[1].reference == 'REF2'
    assert split.targets[2].ggo.user is ggo.user
    assert split.targets[2].ggo.amount == 5
    assert split.targets[2].reference is None

    # RetireTransaction 1
    assert type(retire1) is RetireTransaction
    assert retire1.begin == begin
    assert retire1.parent_ggo is split.targets[3].ggo
    assert retire1.parent_ggo.retire_gsrn == 'GSRN1'
    assert retire1.parent_ggo.retire_address == 'MEASUREMENT-ADDRESS'
    assert retire1.parent_ggo.amount == 10
    assert retire1.meteringpoint is meteringpoint1
    assert retire1.measurement_address == 'MEASUREMENT-ADDRESS'

    # RetireTransaction 2
    assert type(retire2) is RetireTransaction
    assert retire2.begin == begin
    assert retire2.parent_ggo is split.targets[4].ggo
    assert retire2.parent_ggo.retire_gsrn == 'GSRN2'
    assert retire2.parent_ggo.retire_address == 'MEASUREMENT-ADDRESS'
    assert retire2.parent_ggo.amount == 40
    assert retire2.meteringpoint is meteringpoint2
    assert retire2.measurement_address == 'MEASUREMENT-ADDRESS'
Esempio n. 5
0
def test__GgoComposer__build_batch__only_transfer__should_build_batch_and_add_remaining_to_current_owner(
        datahub, transfer_amounts, remaining_amount):
    """
    :param list[int] transfer_amounts:
    :param int remaining_amount:
    """

    #  -- Arrange ------------------------------------------------------------

    sector = 'DK1'
    begin = datetime(2020, 1, 1, 0, 0, 0)

    ggo = Mock(amount=100,
               begin=begin,
               sector=sector,
               stored=True,
               retired=False,
               locked=False,
               synchronized=True)
    ggo.is_tradable.return_value = True
    ggo.is_expired.return_value = False
    ggo.create_child.side_effect = lambda amount, user: Mock(amount=amount,
                                                             user=user)

    datahub.get_consumption.return_value = Mock(measurement=Mock(
        sector=sector,
        begin=begin,
        amount=100,
    ))

    composer = GgoComposer(ggo=ggo, session=Mock())
    composer.get_retired_amount = Mock()
    composer.get_retired_amount.return_value = 0

    transfer_users = [
        Mock(name=f'User {i}') for i in range(len(transfer_amounts))
    ]

    #  -- Act ----------------------------------------------------------------

    for user, amount in zip(transfer_users, transfer_amounts):
        composer.add_transfer(user, amount)

    batch, recipients = composer.build_batch()

    #  -- Assert -------------------------------------------------------------

    assert len(batch.transactions) == 1
    assert type(batch.transactions[0]) is SplitTransaction

    if remaining_amount > 0:
        assert len(recipients) == len(transfer_amounts) + 1
    else:
        assert len(recipients) == len(transfer_amounts)

    recipients_dict = dict(recipients)  # {User: Ggo}

    for i, (user, amount) in enumerate(zip(transfer_users, transfer_amounts)):
        assert user in recipients_dict
        assert recipients_dict[user].amount == amount
        assert batch.transactions[0].parent_ggo is ggo
        assert batch.transactions[0].targets[i].ggo.user is user
        assert batch.transactions[0].targets[i].ggo.amount == amount