def test_validate_write_once_fields():
    offchain.validate_write_once_fields("payment", None, None)

    payment = offchain.PaymentObject(
        reference_id="4185027f-0574-6f55-2668-3a38fdb5de98",
        sender=offchain.PaymentActorObject(
            address="lbr1p7ujcndcl7nudzwt8fglhx6wxn08kgs5tm6mz4usw5p72t",
            status=offchain.StatusObject(status=offchain.Status.needs_kyc_data),
            kyc_data=offchain.individual_kyc_data(
                given_name="hello",
            ),
            metadata=["hello", "world"],
        ),
        receiver=offchain.PaymentActorObject(
            address="lbr1p7ujcndcl7nudzwt8fglhx6wxnvqqqqqqqqqqqqelu3xv",
            status=offchain.StatusObject(
                status=offchain.Status.abort,
                abort_code="code1",
                abort_message="code1 message",
            ),
        ),
        action=offchain.PaymentActionObject(amount=1_000_000_000_000, currency="XUS", timestamp=1604902048),
        original_payment_reference_id="0185027f-0574-6f55-2668-3a38fdb5de98",
    )
    offchain.validate_write_once_fields("payment", payment, payment)
    offchain.validate_write_once_fields("payment", payment, None)
    offchain.validate_write_once_fields("payment", None, payment)

    new_payment = dataclasses.replace(
        payment, sender=offchain.replace_payment_actor(payment.sender, kyc_data=offchain.individual_kyc_data())
    )
    with pytest.raises(offchain.InvalidOverwriteError):
        offchain.validate_write_once_fields("payment", new_payment, payment)
def test_match_state_validation(factory):
    payment = factory.new_payment_object()
    invalid_payment = dataclasses.replace(
        payment,
        receiver=replace_payment_actor(payment.receiver,
                                       status=Status.ready_for_settlement),
    )
    with pytest.raises(state.ConditionValidationError):
        machine.match_state(invalid_payment)
def test_match_receiver_ready_payment_state(factory):
    payment = factory.new_payment_object()
    receiver_ready_payment = dataclasses.replace(
        payment,
        receiver=replace_payment_actor(
            payment.receiver,
            status=Status.ready_for_settlement,
            kyc_data=individual_kyc_data(given_name="Rose"),
        ),
        recipient_signature="signature",
    )

    receiver_ready = machine.match_state(receiver_ready_payment)
    assert receiver_ready == R_SEND

    initial_state = machine.match_state(payment)
    assert machine.is_valid_transition(initial_state, receiver_ready,
                                       receiver_ready_payment)