transaction.rs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. use super::*;
  2. #[test]
  3. fn transaction_success() {
  4. with_test_externalities(|| {
  5. // Create class with default permissions
  6. assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
  7. // Create single reference property
  8. let property_type_reference = Type::Reference(FIRST_CLASS_ID, true);
  9. let property = Property::<ClassId>::with_name_and_type(
  10. PropertyNameLengthConstraint::get().max() as usize,
  11. PropertyType::Single(property_type_reference),
  12. true,
  13. false,
  14. );
  15. // Add Schema to the Class
  16. assert_ok!(add_class_schema(
  17. LEAD_ORIGIN,
  18. FIRST_CLASS_ID,
  19. BTreeSet::new(),
  20. vec![property]
  21. ));
  22. let operations = vec![
  23. OperationType::CreateEntity(CreateEntityOperation {
  24. class_id: FIRST_CLASS_ID,
  25. }),
  26. OperationType::AddSchemaSupportToEntity(AddSchemaSupportToEntityOperation {
  27. entity_id: ParameterizedEntity::InternalEntityJustAdded(0), // index 0 (prior operation)
  28. schema_id: 0,
  29. parametrized_property_values: vec![ParametrizedClassPropertyValue {
  30. in_class_index: 0,
  31. value: ParametrizedPropertyValue::InternalEntityJustAdded(0),
  32. }],
  33. }),
  34. OperationType::CreateEntity(CreateEntityOperation {
  35. class_id: FIRST_CLASS_ID,
  36. }),
  37. OperationType::UpdatePropertyValues(UpdatePropertyValuesOperation {
  38. entity_id: ParameterizedEntity::InternalEntityJustAdded(0), // index 0 (prior operation)
  39. new_parametrized_property_values: vec![ParametrizedClassPropertyValue {
  40. in_class_index: 0,
  41. value: ParametrizedPropertyValue::InternalEntityJustAdded(2),
  42. }],
  43. }),
  44. ];
  45. // Runtime state before tested call
  46. // Events number before tested call
  47. let number_of_events_before_calls = System::events().len();
  48. let actor = Actor::Lead;
  49. // Number of operations to be performed
  50. let operations_count = operations.len();
  51. // Complete transaction
  52. assert_ok!(transaction(LEAD_ORIGIN, actor.clone(), operations));
  53. // Runtime tested state after call
  54. let transaction_completed_event = get_test_event(RawEvent::TransactionCompleted(actor));
  55. // Last event checked
  56. assert_event(
  57. transaction_completed_event,
  58. number_of_events_before_calls + operations_count + 1,
  59. );
  60. })
  61. }
  62. #[test]
  63. fn transaction_limit_reached() {
  64. with_test_externalities(|| {
  65. // Create class with default permissions
  66. assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
  67. let operation = OperationType::CreateEntity(CreateEntityOperation {
  68. class_id: FIRST_CLASS_ID,
  69. });
  70. let operations =
  71. vec![operation; MaxNumberOfOperationsDuringAtomicBatching::get() as usize + 1];
  72. // Runtime state before tested call
  73. // Events number before tested call
  74. let number_of_events_before_call = System::events().len();
  75. let actor = Actor::Lead;
  76. // Make an attempt to complete transaction with operations, which total number exceeds MaxNumberOfOperationsDuringAtomicBatching runtime constraint
  77. let transaction_result = transaction(LEAD_ORIGIN, actor, operations);
  78. // Failure checked
  79. assert_failure(
  80. transaction_result,
  81. Error::<Runtime>::NumberOfOperationsDuringAtomicBatchingLimitReached,
  82. number_of_events_before_call,
  83. );
  84. })
  85. }
  86. #[test]
  87. fn transaction_failed() {
  88. with_test_externalities(|| {
  89. // Create class with default permissions
  90. assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
  91. let operation = OperationType::CreateEntity(CreateEntityOperation {
  92. class_id: FIRST_CLASS_ID,
  93. });
  94. let failed_operation = OperationType::CreateEntity(CreateEntityOperation {
  95. class_id: UNKNOWN_CLASS_ID,
  96. });
  97. let operations = vec![
  98. operation.clone(),
  99. operation.clone(),
  100. failed_operation,
  101. operation,
  102. ];
  103. // Runtime state before tested call
  104. // Events number before tested call
  105. let number_of_events_before_call = System::events().len();
  106. let actor = Actor::Lead;
  107. // Make an attempt to complete transaction with CreateEntity operation, when provided class_id does not exist on runtime level
  108. let transaction_result = transaction(LEAD_ORIGIN, actor, operations.clone());
  109. let failed_operation_index = 2;
  110. // Failure checked
  111. // Ensure call result is equal to expected error
  112. assert_err!(transaction_result, Error::<Runtime>::ClassNotFound);
  113. let transaction_failed_event =
  114. get_test_event(RawEvent::TransactionFailed(actor, failed_operation_index));
  115. // Last event checked
  116. assert_event(
  117. transaction_failed_event,
  118. // two operations succeded and one TransactionFailed event
  119. number_of_events_before_call + operations[..failed_operation_index as usize].len() + 1,
  120. );
  121. })
  122. }