data_directory.rs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. #![cfg(test)]
  2. use frame_support::dispatch::DispatchError;
  3. use sp_std::collections::btree_map::BTreeMap;
  4. use system::RawOrigin;
  5. use super::mock::*;
  6. #[test]
  7. fn succeed_adding_content() {
  8. with_default_mock_builder(|| {
  9. let sender = 1u64;
  10. let member_id = 1u64;
  11. // Register a content with 1234 bytes of type 1, which should be recognized.
  12. let res = TestDataDirectory::add_content(
  13. Origin::signed(sender),
  14. member_id,
  15. 1,
  16. 1234,
  17. 0,
  18. vec![1, 3, 3, 7],
  19. );
  20. assert!(res.is_ok());
  21. });
  22. }
  23. #[test]
  24. fn add_content_fails_with_invalid_origin() {
  25. with_default_mock_builder(|| {
  26. let member_id = 1u64;
  27. // Register a content with 1234 bytes of type 1, which should be recognized.
  28. let res = TestDataDirectory::add_content(
  29. RawOrigin::Root.into(),
  30. member_id,
  31. 1,
  32. 1234,
  33. 0,
  34. vec![1, 3, 3, 7],
  35. );
  36. assert_eq!(res, Err(DispatchError::Other("Bad origin")));
  37. });
  38. }
  39. #[test]
  40. fn accept_and_reject_content_fail_with_invalid_storage_provider() {
  41. with_default_mock_builder(|| {
  42. /*
  43. Events are not emitted on block 0.
  44. So any dispatchable calls made during genesis block formation will have no events emitted.
  45. https://substrate.dev/recipes/2-appetizers/4-events.html
  46. */
  47. run_to_block(1);
  48. let sender = 1u64;
  49. let member_id = 1u64;
  50. let res = TestDataDirectory::add_content(
  51. Origin::signed(sender),
  52. member_id,
  53. 1,
  54. 1234,
  55. 0,
  56. vec![1, 2, 3, 4],
  57. );
  58. assert!(res.is_ok());
  59. let (content_id, _) = match System::events().last().unwrap().event {
  60. MetaEvent::data_directory(data_directory::RawEvent::ContentAdded(
  61. content_id,
  62. creator,
  63. )) => (content_id, creator),
  64. _ => (0u64, 0xdeadbeefu64), // invalid value, unlikely to match
  65. };
  66. // invalid data
  67. let (storage_provider_account_id, storage_provider_id) = (1, 5);
  68. let res = TestDataDirectory::accept_content(
  69. Origin::signed(storage_provider_account_id),
  70. storage_provider_id,
  71. content_id,
  72. );
  73. assert_eq!(res, Err(working_group::Error::<Test, crate::StorageWorkingGroupInstance>::WorkerDoesNotExist.into()));
  74. let res = TestDataDirectory::reject_content(
  75. Origin::signed(storage_provider_account_id),
  76. storage_provider_id,
  77. content_id,
  78. );
  79. assert_eq!(res, Err(working_group::Error::<Test, crate::StorageWorkingGroupInstance>::WorkerDoesNotExist.into()));
  80. });
  81. }
  82. #[test]
  83. fn accept_content_as_liaison() {
  84. with_default_mock_builder(|| {
  85. /*
  86. Events are not emitted on block 0.
  87. So any dispatchable calls made during genesis block formation will have no events emitted.
  88. https://substrate.dev/recipes/2-appetizers/4-events.html
  89. */
  90. run_to_block(1);
  91. let sender = 1u64;
  92. let member_id = 1u64;
  93. let res = TestDataDirectory::add_content(
  94. Origin::signed(sender),
  95. member_id,
  96. 1,
  97. 1234,
  98. 0,
  99. vec![1, 2, 3, 4],
  100. );
  101. assert!(res.is_ok());
  102. // An appropriate event should have been fired.
  103. let (content_id, creator) = match System::events().last().unwrap().event {
  104. MetaEvent::data_directory(data_directory::RawEvent::ContentAdded(
  105. content_id,
  106. creator,
  107. )) => (content_id, creator),
  108. _ => (0u64, 0xdeadbeefu64), // invalid value, unlikely to match
  109. };
  110. assert_ne!(creator, 0xdeadbeefu64);
  111. assert_eq!(creator, sender);
  112. let (storage_provider_account_id, storage_provider_id) = hire_storage_provider();
  113. // Accepting content should not work with some random origin
  114. let res =
  115. TestDataDirectory::accept_content(Origin::signed(55), storage_provider_id, content_id);
  116. assert!(res.is_err());
  117. // However, with the liaison as origin it should.
  118. let res = TestDataDirectory::accept_content(
  119. Origin::signed(storage_provider_account_id),
  120. storage_provider_id,
  121. content_id,
  122. );
  123. assert_eq!(res, Ok(()));
  124. });
  125. }
  126. #[test]
  127. fn reject_content_as_liaison() {
  128. with_default_mock_builder(|| {
  129. /*
  130. Events are not emitted on block 0.
  131. So any dispatchable calls made during genesis block formation will have no events emitted.
  132. https://substrate.dev/recipes/2-appetizers/4-events.html
  133. */
  134. run_to_block(1);
  135. let sender = 1u64;
  136. let member_id = 1u64;
  137. let res = TestDataDirectory::add_content(
  138. Origin::signed(sender),
  139. member_id,
  140. 1,
  141. 1234,
  142. 0,
  143. vec![1, 2, 3, 4],
  144. );
  145. assert!(res.is_ok());
  146. // An appropriate event should have been fired.
  147. let (content_id, creator) = match System::events().last().unwrap().event {
  148. MetaEvent::data_directory(data_directory::RawEvent::ContentAdded(
  149. content_id,
  150. creator,
  151. )) => (content_id, creator),
  152. _ => (0u64, 0xdeadbeefu64), // invalid value, unlikely to match
  153. };
  154. assert_ne!(creator, 0xdeadbeefu64);
  155. assert_eq!(creator, sender);
  156. let (storage_provider_account_id, storage_provider_id) = hire_storage_provider();
  157. // Rejecting content should not work with some random origin
  158. let res =
  159. TestDataDirectory::reject_content(Origin::signed(55), storage_provider_id, content_id);
  160. assert!(res.is_err());
  161. // However, with the liaison as origin it should.
  162. let res = TestDataDirectory::reject_content(
  163. Origin::signed(storage_provider_account_id),
  164. storage_provider_id,
  165. content_id,
  166. );
  167. assert_eq!(res, Ok(()));
  168. });
  169. }
  170. #[test]
  171. fn data_object_injection_works() {
  172. with_default_mock_builder(|| {
  173. // No objects in directory before injection
  174. assert_eq!(TestDataDirectory::known_content_ids(), vec![]);
  175. // new objects to inject into the directory
  176. let mut objects = BTreeMap::new();
  177. let object = data_directory::DataObjectInternal {
  178. type_id: 1,
  179. size: 1234,
  180. added_at: data_directory::BlockAndTime {
  181. block: 10,
  182. time: 1024,
  183. },
  184. owner: 1,
  185. liaison: TEST_MOCK_LIAISON_STORAGE_PROVIDER_ID,
  186. liaison_judgement: data_directory::LiaisonJudgement::Pending,
  187. ipfs_content_id: vec![],
  188. };
  189. let content_id_1 = 1;
  190. objects.insert(content_id_1, object.clone());
  191. let content_id_2 = 2;
  192. objects.insert(content_id_2, object.clone());
  193. let res = TestDataDirectory::inject_data_objects(RawOrigin::Root.into(), objects);
  194. assert!(res.is_ok());
  195. assert_eq!(
  196. TestDataDirectory::known_content_ids(),
  197. vec![content_id_1, content_id_2]
  198. );
  199. assert_eq!(
  200. TestDataDirectory::data_object_by_content_id(content_id_1),
  201. Some(object.clone())
  202. );
  203. assert_eq!(
  204. TestDataDirectory::data_object_by_content_id(content_id_2),
  205. Some(object)
  206. );
  207. });
  208. }
  209. #[test]
  210. fn data_object_injection_overwrites_and_removes_duplicate_ids() {
  211. with_default_mock_builder(|| {
  212. let sender = 1u64;
  213. let member_id = 1u64;
  214. let content_id_1 = 1;
  215. let content_id_2 = 2;
  216. // Start with some existing objects in directory which will be
  217. // overwritten
  218. let res = TestDataDirectory::add_content(
  219. Origin::signed(sender),
  220. member_id,
  221. content_id_1,
  222. 1,
  223. 10,
  224. vec![8, 8, 8, 8],
  225. );
  226. assert!(res.is_ok());
  227. let res = TestDataDirectory::add_content(
  228. Origin::signed(sender),
  229. member_id,
  230. content_id_2,
  231. 2,
  232. 20,
  233. vec![9, 9, 9, 9],
  234. );
  235. assert!(res.is_ok());
  236. let mut objects = BTreeMap::new();
  237. let object1 = data_directory::DataObjectInternal {
  238. type_id: 1,
  239. size: 6666,
  240. added_at: data_directory::BlockAndTime {
  241. block: 10,
  242. time: 1000,
  243. },
  244. owner: 5,
  245. liaison: TEST_MOCK_LIAISON_STORAGE_PROVIDER_ID,
  246. liaison_judgement: data_directory::LiaisonJudgement::Pending,
  247. ipfs_content_id: vec![5, 6, 7],
  248. };
  249. let object2 = data_directory::DataObjectInternal {
  250. type_id: 1,
  251. size: 7777,
  252. added_at: data_directory::BlockAndTime {
  253. block: 20,
  254. time: 2000,
  255. },
  256. owner: 6,
  257. liaison: TEST_MOCK_LIAISON_STORAGE_PROVIDER_ID,
  258. liaison_judgement: data_directory::LiaisonJudgement::Pending,
  259. ipfs_content_id: vec![5, 6, 7],
  260. };
  261. objects.insert(content_id_1, object1.clone());
  262. objects.insert(content_id_2, object2.clone());
  263. let res = TestDataDirectory::inject_data_objects(RawOrigin::Root.into(), objects);
  264. assert!(res.is_ok());
  265. assert_eq!(
  266. TestDataDirectory::known_content_ids(),
  267. vec![content_id_1, content_id_2]
  268. );
  269. assert_eq!(
  270. TestDataDirectory::data_object_by_content_id(content_id_1),
  271. Some(object1.clone())
  272. );
  273. assert_eq!(
  274. TestDataDirectory::data_object_by_content_id(content_id_2),
  275. Some(object2)
  276. );
  277. });
  278. }