data_directory.rs 10.0 KB

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