瀏覽代碼

Merge remote-tracking branch 'upstream/sumer' into qnode-indexer-processor

metmirr 4 年之前
父節點
當前提交
2491892f61
共有 100 個文件被更改,包括 7710 次插入16831 次删除
  1. 0 20
      .github/workflows/content-directory-schemas.yml
  2. 28 0
      .github/workflows/content-metadata.yml
  3. 123 92
      Cargo.lock
  4. 1 3
      Cargo.toml
  5. 0 2
      build.sh
  6. 4 0
      content-metadata-protobuf/.eslintignore
  7. 16 0
      content-metadata-protobuf/.eslintrc.js
  8. 2 0
      content-metadata-protobuf/.gitignore
  9. 4 0
      content-metadata-protobuf/.prettierignore
  10. 53 0
      content-metadata-protobuf/README.md
  11. 15 0
      content-metadata-protobuf/compile.sh
  12. 85 0
      content-metadata-protobuf/compiled/proto/Channel_pb.d.ts
  13. 645 0
      content-metadata-protobuf/compiled/proto/Channel_pb.js
  14. 57 0
      content-metadata-protobuf/compiled/proto/Person_pb.d.ts
  15. 427 0
      content-metadata-protobuf/compiled/proto/Person_pb.js
  16. 33 0
      content-metadata-protobuf/compiled/proto/Playlist_pb.d.ts
  17. 245 0
      content-metadata-protobuf/compiled/proto/Playlist_pb.js
  18. 85 0
      content-metadata-protobuf/compiled/proto/Series_pb.d.ts
  19. 665 0
      content-metadata-protobuf/compiled/proto/Series_pb.js
  20. 235 0
      content-metadata-protobuf/compiled/proto/Video_pb.d.ts
  21. 1846 0
      content-metadata-protobuf/compiled/proto/Video_pb.js
  22. 41 0
      content-metadata-protobuf/doc-appendix.md
  23. 374 0
      content-metadata-protobuf/doc/index.md
  24. 13 0
      content-metadata-protobuf/generate-md-doc.sh
  25. 41 0
      content-metadata-protobuf/package.json
  26. 28 0
      content-metadata-protobuf/proto/Channel.proto
  27. 13 0
      content-metadata-protobuf/proto/Person.proto
  28. 7 0
      content-metadata-protobuf/proto/Playlist.proto
  29. 19 0
      content-metadata-protobuf/proto/Series.proto
  30. 88 0
      content-metadata-protobuf/proto/Video.proto
  31. 74 0
      content-metadata-protobuf/src/KnownLicenses.json
  32. 10 0
      content-metadata-protobuf/src/index.ts
  33. 70 0
      content-metadata-protobuf/src/licenses.ts
  34. 33 0
      content-metadata-protobuf/test/channel.ts
  35. 42 0
      content-metadata-protobuf/test/license-codes.ts
  36. 115 0
      content-metadata-protobuf/test/video.ts
  37. 15 0
      content-metadata-protobuf/tsconfig.json
  38. 77 13
      node/src/chain_spec/content_config.rs
  39. 29 12
      node/src/chain_spec/mod.rs
  40. 3 2
      package.json
  41. 4 0
      runtime-modules/common/Cargo.toml
  42. 80 1
      runtime-modules/common/src/lib.rs
  43. 59 0
      runtime-modules/common/src/storage.rs
  44. 5 1
      runtime-modules/common/src/working_group.rs
  45. 0 30
      runtime-modules/content-directory/Cargo.toml
  46. 0 243
      runtime-modules/content-directory/src/class.rs
  47. 0 213
      runtime-modules/content-directory/src/entity.rs
  48. 0 239
      runtime-modules/content-directory/src/errors.rs
  49. 0 346
      runtime-modules/content-directory/src/helpers.rs
  50. 0 2920
      runtime-modules/content-directory/src/lib.rs
  51. 0 1041
      runtime-modules/content-directory/src/mock.rs
  52. 0 141
      runtime-modules/content-directory/src/operations.rs
  53. 0 107
      runtime-modules/content-directory/src/permissions/class.rs
  54. 0 175
      runtime-modules/content-directory/src/permissions/entity.rs
  55. 0 56
      runtime-modules/content-directory/src/permissions/entity_creation_voucher.rs
  56. 0 91
      runtime-modules/content-directory/src/schema.rs
  57. 0 62
      runtime-modules/content-directory/src/schema/convert.rs
  58. 0 137
      runtime-modules/content-directory/src/schema/input.rs
  59. 0 348
      runtime-modules/content-directory/src/schema/output.rs
  60. 0 634
      runtime-modules/content-directory/src/schema/property.rs
  61. 0 350
      runtime-modules/content-directory/src/tests.rs
  62. 0 507
      runtime-modules/content-directory/src/tests/add_class_schema.rs
  63. 0 59
      runtime-modules/content-directory/src/tests/add_curator_group.rs
  64. 0 162
      runtime-modules/content-directory/src/tests/add_curator_to_group.rs
  65. 0 195
      runtime-modules/content-directory/src/tests/add_maintainer_to_class.rs
  66. 0 1458
      runtime-modules/content-directory/src/tests/add_schema_support_to_entity.rs
  67. 0 557
      runtime-modules/content-directory/src/tests/clear_entity_property_vector.rs
  68. 0 275
      runtime-modules/content-directory/src/tests/create_class.rs
  69. 0 446
      runtime-modules/content-directory/src/tests/create_entity.rs
  70. 0 1271
      runtime-modules/content-directory/src/tests/insert_at_entity_property_vector.rs
  71. 0 776
      runtime-modules/content-directory/src/tests/remove_at_entity_property_vector.rs
  72. 0 131
      runtime-modules/content-directory/src/tests/remove_curator_from_group.rs
  73. 0 110
      runtime-modules/content-directory/src/tests/remove_curator_group.rs
  74. 0 302
      runtime-modules/content-directory/src/tests/remove_entity.rs
  75. 0 147
      runtime-modules/content-directory/src/tests/remove_maintainer_from_class.rs
  76. 0 84
      runtime-modules/content-directory/src/tests/set_curator_group_status.rs
  77. 0 155
      runtime-modules/content-directory/src/tests/transaction.rs
  78. 0 738
      runtime-modules/content-directory/src/tests/transfer_entity_ownership.rs
  79. 0 227
      runtime-modules/content-directory/src/tests/update_class_permissions.rs
  80. 0 145
      runtime-modules/content-directory/src/tests/update_class_schema_status.rs
  81. 0 197
      runtime-modules/content-directory/src/tests/update_entity_creation_voucher.rs
  82. 0 104
      runtime-modules/content-directory/src/tests/update_entity_permissions.rs
  83. 0 1025
      runtime-modules/content-directory/src/tests/update_entity_property_values.rs
  84. 2 0
      runtime-modules/content/Cargo.toml
  85. 0 104
      runtime-modules/content/lib.rs
  86. 47 0
      runtime-modules/content/src/errors.rs
  87. 1140 0
      runtime-modules/content/src/lib.rs
  88. 16 16
      runtime-modules/content/src/permissions/curator_group.rs
  89. 2 20
      runtime-modules/content/src/permissions/mod.rs
  90. 2 1
      runtime-modules/service-discovery/Cargo.toml
  91. 2 3
      runtime-modules/service-discovery/src/lib.rs
  92. 503 84
      runtime-modules/storage/src/data_directory.rs
  93. 8 5
      runtime-modules/storage/src/data_object_storage_registry.rs
  94. 25 29
      runtime-modules/storage/src/data_object_type_registry.rs
  95. 13 1
      runtime-modules/storage/src/lib.rs
  96. 83 199
      runtime-modules/storage/src/tests/data_directory.rs
  97. 3 1
      runtime-modules/storage/src/tests/data_object_storage_registry.rs
  98. 12 8
      runtime-modules/storage/src/tests/data_object_type_registry.rs
  99. 41 7
      runtime-modules/storage/src/tests/mock.rs
  100. 2 3
      runtime/Cargo.toml

+ 0 - 20
.github/workflows/content-directory-schemas.yml

@@ -1,20 +0,0 @@
-name: content-directory-schemas
-on: [pull_request, push]
-
-jobs:
-  schemas_checks:
-    name: Checks
-    runs-on: ubuntu-latest
-    strategy:
-      matrix:
-        node-version: [12.x]
-    steps:
-    - uses: actions/checkout@v1
-    - name: Use Node.js ${{ matrix.node-version }}
-      uses: actions/setup-node@v1
-      with:
-        node-version: ${{ matrix.node-version }}
-    - name: validate
-      run: |
-        yarn install --frozen-lockfile
-        yarn workspace @joystream/cd-schemas checks --quiet

+ 28 - 0
.github/workflows/content-metadata.yml

@@ -0,0 +1,28 @@
+name: content-metadata
+on: [pull_request, push]
+
+jobs:
+  schemas_checks:
+    name: Checks
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        node-version: [12.x]
+    steps:
+    - uses: actions/checkout@v1
+    - name: Use Node.js ${{ matrix.node-version }}
+      uses: actions/setup-node@v1
+      with:
+        node-version: ${{ matrix.node-version }}
+    - name: test protobuf
+      run: |
+        # # Install protoc compiler
+        # sudo apt-get install -y protobuf-compiler
+        # protoc --version
+        # # Install documentation plugin
+        # sudo apt-get install -y golang-go
+        # go get -u github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc
+        yarn install --frozen-lockfile
+        # yarn workspace @joystream/content-metadata-protobuf build
+        yarn workspace @joystream/content-metadata-protobuf checks --quiet
+        yarn workspace @joystream/content-metadata-protobuf test

+ 123 - 92
Cargo.lock

@@ -1115,7 +1115,7 @@ dependencies = [
  "sp-io",
  "sp-runtime",
  "sp-runtime-interface",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -1147,7 +1147,7 @@ dependencies = [
  "serde",
  "sp-io",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-tracing",
 ]
 
@@ -1159,7 +1159,7 @@ dependencies = [
  "parity-scale-codec",
  "serde",
  "sp-core",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -1177,13 +1177,13 @@ dependencies = [
  "paste",
  "serde",
  "smallvec 1.4.1",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-core",
  "sp-inherents",
  "sp-io",
  "sp-runtime",
  "sp-state-machine",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-tracing",
 ]
 
@@ -1232,7 +1232,7 @@ dependencies = [
  "sp-core",
  "sp-io",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-version",
 ]
 
@@ -1247,7 +1247,7 @@ dependencies = [
  "parity-scale-codec",
  "sp-core",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -2067,7 +2067,7 @@ dependencies = [
  "pallet-balances",
  "pallet-collective",
  "pallet-common",
- "pallet-content-directory",
+ "pallet-content",
  "pallet-finality-tracker",
  "pallet-forum",
  "pallet-governance",
@@ -2101,7 +2101,7 @@ dependencies = [
  "serde",
  "sp-api",
  "sp-application-crypto",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-authority-discovery",
  "sp-block-builder",
  "sp-consensus-babe",
@@ -2111,7 +2111,7 @@ dependencies = [
  "sp-runtime",
  "sp-session",
  "sp-staking",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-transaction-pool",
  "sp-version",
  "strum 0.19.2",
@@ -3219,7 +3219,7 @@ dependencies = [
  "sp-application-crypto",
  "sp-authority-discovery",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3234,7 +3234,7 @@ dependencies = [
  "sp-authorship",
  "sp-inherents",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3255,7 +3255,7 @@ dependencies = [
  "sp-io",
  "sp-runtime",
  "sp-staking",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-timestamp",
 ]
 
@@ -3270,7 +3270,7 @@ dependencies = [
  "parity-scale-codec",
  "serde",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3286,7 +3286,7 @@ dependencies = [
  "sp-core",
  "sp-io",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3298,24 +3298,27 @@ dependencies = [
  "pallet-timestamp",
  "parity-scale-codec",
  "serde",
+ "sp-arithmetic 2.0.0",
  "sp-runtime",
+ "sp-std 2.0.0-rc4",
  "strum 0.19.2",
  "strum_macros 0.19.2",
 ]
 
 [[package]]
-name = "pallet-content-directory"
+name = "pallet-content"
 version = "3.0.0"
 dependencies = [
  "frame-support",
  "frame-system",
+ "pallet-common",
  "parity-scale-codec",
  "serde",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-core",
  "sp-io",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3331,7 +3334,7 @@ dependencies = [
  "sp-finality-tracker",
  "sp-inherents",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3344,11 +3347,11 @@ dependencies = [
  "pallet-timestamp",
  "parity-scale-codec",
  "serde",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-core",
  "sp-io",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3365,11 +3368,11 @@ dependencies = [
  "pallet-token-mint",
  "parity-scale-codec",
  "serde",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-core",
  "sp-io",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3389,7 +3392,7 @@ dependencies = [
  "sp-runtime",
  "sp-session",
  "sp-staking",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3403,11 +3406,11 @@ dependencies = [
  "pallet-stake",
  "parity-scale-codec",
  "serde",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-core",
  "sp-io",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3427,7 +3430,7 @@ dependencies = [
  "sp-io",
  "sp-runtime",
  "sp-staking",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3441,11 +3444,11 @@ dependencies = [
  "pallet-timestamp",
  "parity-scale-codec",
  "serde",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-core",
  "sp-io",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3456,8 +3459,8 @@ dependencies = [
  "frame-system",
  "pallet-common",
  "parity-scale-codec",
- "sp-arithmetic",
- "sp-std",
+ "sp-arithmetic 2.0.0-rc4",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3472,7 +3475,7 @@ dependencies = [
  "serde",
  "sp-runtime",
  "sp-staking",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3493,7 +3496,7 @@ dependencies = [
  "parity-scale-codec",
  "sp-runtime",
  "sp-staking",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3518,12 +3521,12 @@ dependencies = [
  "pallet-working-group",
  "parity-scale-codec",
  "serde",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-core",
  "sp-io",
  "sp-runtime",
  "sp-staking",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "strum 0.19.2",
 ]
 
@@ -3542,7 +3545,7 @@ dependencies = [
  "sp-core",
  "sp-io",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3559,11 +3562,11 @@ dependencies = [
  "pallet-timestamp",
  "parity-scale-codec",
  "serde",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-core",
  "sp-io",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3576,7 +3579,7 @@ dependencies = [
  "parity-scale-codec",
  "safe-mix",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3588,7 +3591,7 @@ dependencies = [
  "pallet-balances",
  "pallet-token-mint",
  "parity-scale-codec",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-core",
  "sp-io",
  "sp-runtime",
@@ -3614,7 +3617,7 @@ dependencies = [
  "sp-core",
  "sp-io",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3633,7 +3636,7 @@ dependencies = [
  "sp-runtime",
  "sp-session",
  "sp-staking",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-trie",
 ]
 
@@ -3648,7 +3651,7 @@ dependencies = [
  "pallet-session",
  "pallet-staking",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3660,11 +3663,11 @@ dependencies = [
  "pallet-balances",
  "pallet-timestamp",
  "parity-scale-codec",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-core",
  "sp-io",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3685,7 +3688,7 @@ dependencies = [
  "sp-npos-elections",
  "sp-runtime",
  "sp-staking",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "static_assertions",
 ]
 
@@ -3717,11 +3720,11 @@ dependencies = [
  "pallet-working-group",
  "parity-scale-codec",
  "serde",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-core",
  "sp-io",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3735,7 +3738,7 @@ dependencies = [
  "serde",
  "sp-io",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3752,7 +3755,7 @@ dependencies = [
  "sp-inherents",
  "sp-io",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-timestamp",
 ]
 
@@ -3764,7 +3767,7 @@ dependencies = [
  "frame-system",
  "pallet-balances",
  "parity-scale-codec",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-core",
  "sp-io",
  "sp-runtime",
@@ -3782,7 +3785,7 @@ dependencies = [
  "serde",
  "smallvec 1.4.1",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3813,7 +3816,7 @@ dependencies = [
  "serde",
  "sp-api",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3829,7 +3832,7 @@ dependencies = [
  "sp-core",
  "sp-io",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -3848,11 +3851,11 @@ dependencies = [
  "pallet-token-mint",
  "parity-scale-codec",
  "serde",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-core",
  "sp-io",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -5019,7 +5022,7 @@ dependencies = [
  "sp-keyring",
  "sp-runtime",
  "sp-state-machine",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-storage",
  "sp-transaction-pool",
  "sp-trie",
@@ -5268,7 +5271,7 @@ dependencies = [
  "serde_json",
  "sp-api",
  "sp-application-crypto",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-blockchain",
  "sp-consensus",
  "sp-core",
@@ -5389,7 +5392,7 @@ dependencies = [
  "slog",
  "slog_derive",
  "smallvec 0.6.13",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-blockchain",
  "sp-consensus",
  "sp-core",
@@ -6075,7 +6078,7 @@ dependencies = [
  "derive_more",
  "log",
  "sp-core",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-wasm-interface",
 ]
 
@@ -6090,7 +6093,7 @@ dependencies = [
  "sp-core",
  "sp-runtime",
  "sp-state-machine",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-version",
 ]
 
@@ -6115,7 +6118,7 @@ dependencies = [
  "serde",
  "sp-core",
  "sp-io",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -6127,8 +6130,21 @@ dependencies = [
  "num-traits 0.2.11",
  "parity-scale-codec",
  "serde",
- "sp-debug-derive",
- "sp-std",
+ "sp-debug-derive 2.0.0-rc4",
+ "sp-std 2.0.0-rc4",
+]
+
+[[package]]
+name = "sp-arithmetic"
+version = "2.0.0"
+source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+dependencies = [
+ "integer-sqrt",
+ "num-traits 0.2.11",
+ "parity-scale-codec",
+ "serde",
+ "sp-debug-derive 2.0.0",
+ "sp-std 2.0.0",
 ]
 
 [[package]]
@@ -6140,7 +6156,7 @@ dependencies = [
  "sp-api",
  "sp-application-crypto",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -6151,7 +6167,7 @@ dependencies = [
  "parity-scale-codec",
  "sp-inherents",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -6163,7 +6179,7 @@ dependencies = [
  "sp-api",
  "sp-inherents",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -6208,7 +6224,7 @@ dependencies = [
  "sp-inherents",
  "sp-runtime",
  "sp-state-machine",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-utils",
  "sp-version",
  "substrate-prometheus-endpoint",
@@ -6225,7 +6241,7 @@ dependencies = [
  "sp-application-crypto",
  "sp-inherents",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-timestamp",
 ]
 
@@ -6243,7 +6259,7 @@ dependencies = [
  "sp-core",
  "sp-inherents",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-timestamp",
 ]
 
@@ -6256,7 +6272,7 @@ dependencies = [
  "schnorrkel",
  "sp-core",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -6288,10 +6304,10 @@ dependencies = [
  "schnorrkel",
  "serde",
  "sha2 0.8.1",
- "sp-debug-derive",
+ "sp-debug-derive 2.0.0-rc4",
  "sp-externalities",
  "sp-runtime-interface",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-storage",
  "substrate-bip39",
  "tiny-bip39",
@@ -6320,6 +6336,16 @@ dependencies = [
  "syn 1.0.17",
 ]
 
+[[package]]
+name = "sp-debug-derive"
+version = "2.0.0"
+source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+dependencies = [
+ "proc-macro2",
+ "quote 1.0.7",
+ "syn 1.0.17",
+]
+
 [[package]]
 name = "sp-externalities"
 version = "0.8.0-rc4"
@@ -6327,7 +6353,7 @@ source = "git+https://github.com/paritytech/substrate.git?rev=00768a1f21a579c478
 dependencies = [
  "environmental",
  "parity-scale-codec",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-storage",
 ]
 
@@ -6344,7 +6370,7 @@ dependencies = [
  "sp-application-crypto",
  "sp-core",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -6354,7 +6380,7 @@ source = "git+https://github.com/paritytech/substrate.git?rev=00768a1f21a579c478
 dependencies = [
  "parity-scale-codec",
  "sp-inherents",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -6366,7 +6392,7 @@ dependencies = [
  "parity-scale-codec",
  "parking_lot 0.10.2",
  "sp-core",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -6384,7 +6410,7 @@ dependencies = [
  "sp-externalities",
  "sp-runtime-interface",
  "sp-state-machine",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-tracing",
  "sp-trie",
  "sp-wasm-interface",
@@ -6408,9 +6434,9 @@ source = "git+https://github.com/paritytech/substrate.git?rev=00768a1f21a579c478
 dependencies = [
  "parity-scale-codec",
  "serde",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-npos-elections-compact",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -6467,11 +6493,11 @@ dependencies = [
  "rand 0.7.3",
  "serde",
  "sp-application-crypto",
- "sp-arithmetic",
+ "sp-arithmetic 2.0.0-rc4",
  "sp-core",
  "sp-inherents",
  "sp-io",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -6483,7 +6509,7 @@ dependencies = [
  "primitive-types",
  "sp-externalities",
  "sp-runtime-interface-proc-macro",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-tracing",
  "sp-wasm-interface",
  "static_assertions",
@@ -6520,7 +6546,7 @@ dependencies = [
  "sp-core",
  "sp-runtime",
  "sp-staking",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -6530,7 +6556,7 @@ source = "git+https://github.com/paritytech/substrate.git?rev=00768a1f21a579c478
 dependencies = [
  "parity-scale-codec",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -6559,6 +6585,11 @@ name = "sp-std"
 version = "2.0.0-rc4"
 source = "git+https://github.com/paritytech/substrate.git?rev=00768a1f21a579c478fe5d4f51e1fa71f7db9fd4#00768a1f21a579c478fe5d4f51e1fa71f7db9fd4"
 
+[[package]]
+name = "sp-std"
+version = "2.0.0"
+source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
+
 [[package]]
 name = "sp-storage"
 version = "2.0.0-rc4"
@@ -6567,8 +6598,8 @@ dependencies = [
  "impl-serde 0.2.3",
  "ref-cast",
  "serde",
- "sp-debug-derive",
- "sp-std",
+ "sp-debug-derive 2.0.0-rc4",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -6581,7 +6612,7 @@ dependencies = [
  "sp-api",
  "sp-inherents",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "wasm-timer",
 ]
 
@@ -6620,7 +6651,7 @@ dependencies = [
  "memory-db",
  "parity-scale-codec",
  "sp-core",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "trie-db",
  "trie-root",
 ]
@@ -6646,7 +6677,7 @@ dependencies = [
  "parity-scale-codec",
  "serde",
  "sp-runtime",
- "sp-std",
+ "sp-std 2.0.0-rc4",
 ]
 
 [[package]]
@@ -6656,7 +6687,7 @@ source = "git+https://github.com/paritytech/substrate.git?rev=00768a1f21a579c478
 dependencies = [
  "impl-trait-for-tuples",
  "parity-scale-codec",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "wasmi",
 ]
 
@@ -6912,7 +6943,7 @@ dependencies = [
  "sp-runtime",
  "sp-runtime-interface",
  "sp-session",
- "sp-std",
+ "sp-std 2.0.0-rc4",
  "sp-transaction-pool",
  "sp-trie",
  "sp-version",

+ 1 - 3
Cargo.toml

@@ -16,9 +16,7 @@ members = [
 	"runtime-modules/storage",
 	"runtime-modules/token-minting",
 	"runtime-modules/working-group",
-	"runtime-modules/content-directory",
-	# New content directory
-	# "runtime-modules/content",
+	"runtime-modules/content",
 	"node",
 	"utils/chain-spec-builder/"
 ]

+ 0 - 2
build.sh

@@ -4,8 +4,6 @@ set -e
 
 yarn
 yarn workspace @joystream/types build
-yarn workspace @joystream/cd-schemas generate:all
-yarn workspace @joystream/cd-schemas build
 yarn workspace @joystream/cli build
 yarn workspace query-node-root build
 yarn workspace storage-node build

+ 4 - 0
content-metadata-protobuf/.eslintignore

@@ -0,0 +1,4 @@
+lib/
+proto/
+compiled/
+.eslintrc.js

+ 16 - 0
content-metadata-protobuf/.eslintrc.js

@@ -0,0 +1,16 @@
+module.exports = {
+  env: {
+    mocha: true,
+  },
+  parserOptions: {
+    project: './tsconfig.json'
+  },
+  extends: [
+    '@joystream/eslint-config'
+  ],
+  rules: {
+    'no-unused-vars': 'off', // Required by the typescript rule below
+    '@typescript-eslint/no-unused-vars': ['error'],
+    '@typescript-eslint/no-floating-promises': 'error',
+  },
+}

+ 2 - 0
content-metadata-protobuf/.gitignore

@@ -0,0 +1,2 @@
+node_modules/
+lib/

+ 4 - 0
content-metadata-protobuf/.prettierignore

@@ -0,0 +1,4 @@
+lib/
+doc/
+proto/
+compiled/

+ 53 - 0
content-metadata-protobuf/README.md

@@ -0,0 +1,53 @@
+## Joystream Content Directory Metadata Library
+
+This package contains protobuf message definitions compiled to Javascript/Typescript used for creating and updating various metadata blobs in the joystream content directory.
+
+### Message Specs
+
+Documented in [doc](./doc) folder
+
+### Choice of protobuf protocol v2
+
+For our usecase we wish to re-use same message to create and update  subset of fields.
+For this reason we need the explicit information about wether a field has been set or not and this is only possible with proto v2.
+
+Background: required/optional feilds are deprecated in [proto v3](https://www.ben-morris.com/handling-protocol-buffers-backwards-compatibility-between-versions-2-and-3-using-c/)
+
+
+### Helper methods
+The custom Joystream types such as License have helper methods to construct pre-defined well known values.
+
+### Example code:
+
+Best place to look at are the [tests specs](./test)
+
+### Opaque types
+We use simple [ISO_639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) code representation for Language.
+useful npm package https://www.npmjs.com/package/iso-639-1
+
+### Building the package
+
+Building will compile the protofiles and build the library from source.
+
+- pre-requisists for compiling protofiles:
+    - [protoc](https://github.com/protocolbuffers/protobuf/releases)
+
+- pre-requisists for generating documentation:
+    - [golang](https://golang.org/)
+    - [protoc-gen-doc](https://github.com/pseudomuto/protoc-gen-doc) to generate docs
+
+```
+yarn && yarn build
+```
+
+### Generating docs
+
+```
+yarn generate-docs
+```
+
+### Tests
+
+```
+yarn test
+```

+ 15 - 0
content-metadata-protobuf/compile.sh

@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+
+# Path to this plugin
+PROTOC_GEN_TS_PATH="./node_modules/.bin/protoc-gen-ts"
+
+# Directory to write generated code to (.js and .d.ts files)
+OUT_DIR="./compiled"
+mkdir -p ${OUT_DIR}
+
+# Compile proto files
+protoc \
+    --plugin="protoc-gen-ts=${PROTOC_GEN_TS_PATH}" \
+    --js_out="import_style=commonjs,binary:${OUT_DIR}" \
+    --ts_out="${OUT_DIR}" \
+    proto/*.proto

+ 85 - 0
content-metadata-protobuf/compiled/proto/Channel_pb.d.ts

@@ -0,0 +1,85 @@
+// package: 
+// file: proto/Channel.proto
+
+import * as jspb from "google-protobuf";
+
+export class ChannelMetadata extends jspb.Message {
+  hasTitle(): boolean;
+  clearTitle(): void;
+  getTitle(): string | undefined;
+  setTitle(value: string): void;
+
+  hasDescription(): boolean;
+  clearDescription(): void;
+  getDescription(): string | undefined;
+  setDescription(value: string): void;
+
+  hasIsPublic(): boolean;
+  clearIsPublic(): void;
+  getIsPublic(): boolean | undefined;
+  setIsPublic(value: boolean): void;
+
+  hasLanguage(): boolean;
+  clearLanguage(): void;
+  getLanguage(): string | undefined;
+  setLanguage(value: string): void;
+
+  hasCoverPhoto(): boolean;
+  clearCoverPhoto(): void;
+  getCoverPhoto(): number | undefined;
+  setCoverPhoto(value: number): void;
+
+  hasAvatarPhoto(): boolean;
+  clearAvatarPhoto(): void;
+  getAvatarPhoto(): number | undefined;
+  setAvatarPhoto(value: number): void;
+
+  hasCategory(): boolean;
+  clearCategory(): void;
+  getCategory(): number | undefined;
+  setCategory(value: number): void;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): ChannelMetadata.AsObject;
+  static toObject(includeInstance: boolean, msg: ChannelMetadata): ChannelMetadata.AsObject;
+  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+  static serializeBinaryToWriter(message: ChannelMetadata, writer: jspb.BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): ChannelMetadata;
+  static deserializeBinaryFromReader(message: ChannelMetadata, reader: jspb.BinaryReader): ChannelMetadata;
+}
+
+export namespace ChannelMetadata {
+  export type AsObject = {
+    title?: string,
+    description?: string,
+    isPublic?: boolean,
+    language?: string,
+    coverPhoto?: number,
+    avatarPhoto?: number,
+    category?: number,
+  }
+}
+
+export class ChannelCategoryMetadata extends jspb.Message {
+  hasName(): boolean;
+  clearName(): void;
+  getName(): string | undefined;
+  setName(value: string): void;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): ChannelCategoryMetadata.AsObject;
+  static toObject(includeInstance: boolean, msg: ChannelCategoryMetadata): ChannelCategoryMetadata.AsObject;
+  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+  static serializeBinaryToWriter(message: ChannelCategoryMetadata, writer: jspb.BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): ChannelCategoryMetadata;
+  static deserializeBinaryFromReader(message: ChannelCategoryMetadata, reader: jspb.BinaryReader): ChannelCategoryMetadata;
+}
+
+export namespace ChannelCategoryMetadata {
+  export type AsObject = {
+    name?: string,
+  }
+}
+

+ 645 - 0
content-metadata-protobuf/compiled/proto/Channel_pb.js

@@ -0,0 +1,645 @@
+// source: proto/Channel.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+goog.exportSymbol('proto.ChannelCategoryMetadata', null, global);
+goog.exportSymbol('proto.ChannelMetadata', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.ChannelMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.ChannelMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.ChannelMetadata.displayName = 'proto.ChannelMetadata';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.ChannelCategoryMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.ChannelCategoryMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.ChannelCategoryMetadata.displayName = 'proto.ChannelCategoryMetadata';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.ChannelMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.ChannelMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.ChannelMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ChannelMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    title: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    description: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    isPublic: (f = jspb.Message.getBooleanField(msg, 3)) == null ? undefined : f,
+    language: (f = jspb.Message.getField(msg, 4)) == null ? undefined : f,
+    coverPhoto: (f = jspb.Message.getField(msg, 5)) == null ? undefined : f,
+    avatarPhoto: (f = jspb.Message.getField(msg, 6)) == null ? undefined : f,
+    category: (f = jspb.Message.getField(msg, 7)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.ChannelMetadata}
+ */
+proto.ChannelMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.ChannelMetadata;
+  return proto.ChannelMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.ChannelMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.ChannelMetadata}
+ */
+proto.ChannelMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTitle(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDescription(value);
+      break;
+    case 3:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setIsPublic(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setLanguage(value);
+      break;
+    case 5:
+      var value = /** @type {number} */ (reader.readUint32());
+      msg.setCoverPhoto(value);
+      break;
+    case 6:
+      var value = /** @type {number} */ (reader.readUint32());
+      msg.setAvatarPhoto(value);
+      break;
+    case 7:
+      var value = /** @type {number} */ (reader.readUint64());
+      msg.setCategory(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.ChannelMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.ChannelMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.ChannelMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ChannelMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 3));
+  if (f != null) {
+    writer.writeBool(
+      3,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 4));
+  if (f != null) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 5));
+  if (f != null) {
+    writer.writeUint32(
+      5,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 6));
+  if (f != null) {
+    writer.writeUint32(
+      6,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 7));
+  if (f != null) {
+    writer.writeUint64(
+      7,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string title = 1;
+ * @return {string}
+ */
+proto.ChannelMetadata.prototype.getTitle = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.setTitle = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.clearTitle = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.ChannelMetadata.prototype.hasTitle = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional string description = 2;
+ * @return {string}
+ */
+proto.ChannelMetadata.prototype.getDescription = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.setDescription = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.clearDescription = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.ChannelMetadata.prototype.hasDescription = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional bool is_public = 3;
+ * @return {boolean}
+ */
+proto.ChannelMetadata.prototype.getIsPublic = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.setIsPublic = function(value) {
+  return jspb.Message.setField(this, 3, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.clearIsPublic = function() {
+  return jspb.Message.setField(this, 3, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.ChannelMetadata.prototype.hasIsPublic = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional string language = 4;
+ * @return {string}
+ */
+proto.ChannelMetadata.prototype.getLanguage = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.setLanguage = function(value) {
+  return jspb.Message.setField(this, 4, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.clearLanguage = function() {
+  return jspb.Message.setField(this, 4, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.ChannelMetadata.prototype.hasLanguage = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+/**
+ * optional uint32 cover_photo = 5;
+ * @return {number}
+ */
+proto.ChannelMetadata.prototype.getCoverPhoto = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.setCoverPhoto = function(value) {
+  return jspb.Message.setField(this, 5, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.clearCoverPhoto = function() {
+  return jspb.Message.setField(this, 5, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.ChannelMetadata.prototype.hasCoverPhoto = function() {
+  return jspb.Message.getField(this, 5) != null;
+};
+
+
+/**
+ * optional uint32 avatar_photo = 6;
+ * @return {number}
+ */
+proto.ChannelMetadata.prototype.getAvatarPhoto = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.setAvatarPhoto = function(value) {
+  return jspb.Message.setField(this, 6, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.clearAvatarPhoto = function() {
+  return jspb.Message.setField(this, 6, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.ChannelMetadata.prototype.hasAvatarPhoto = function() {
+  return jspb.Message.getField(this, 6) != null;
+};
+
+
+/**
+ * optional uint64 category = 7;
+ * @return {number}
+ */
+proto.ChannelMetadata.prototype.getCategory = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 7, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.setCategory = function(value) {
+  return jspb.Message.setField(this, 7, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.clearCategory = function() {
+  return jspb.Message.setField(this, 7, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.ChannelMetadata.prototype.hasCategory = function() {
+  return jspb.Message.getField(this, 7) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.ChannelCategoryMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.ChannelCategoryMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.ChannelCategoryMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ChannelCategoryMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.ChannelCategoryMetadata}
+ */
+proto.ChannelCategoryMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.ChannelCategoryMetadata;
+  return proto.ChannelCategoryMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.ChannelCategoryMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.ChannelCategoryMetadata}
+ */
+proto.ChannelCategoryMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.ChannelCategoryMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.ChannelCategoryMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.ChannelCategoryMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.ChannelCategoryMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.ChannelCategoryMetadata.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.ChannelCategoryMetadata} returns this
+ */
+proto.ChannelCategoryMetadata.prototype.setName = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.ChannelCategoryMetadata} returns this
+ */
+proto.ChannelCategoryMetadata.prototype.clearName = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.ChannelCategoryMetadata.prototype.hasName = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+goog.object.extend(exports, proto);

+ 57 - 0
content-metadata-protobuf/compiled/proto/Person_pb.d.ts

@@ -0,0 +1,57 @@
+// package: 
+// file: proto/Person.proto
+
+import * as jspb from "google-protobuf";
+
+export class PersonMetadata extends jspb.Message {
+  hasFirstName(): boolean;
+  clearFirstName(): void;
+  getFirstName(): string | undefined;
+  setFirstName(value: string): void;
+
+  hasMiddleName(): boolean;
+  clearMiddleName(): void;
+  getMiddleName(): string | undefined;
+  setMiddleName(value: string): void;
+
+  hasLastName(): boolean;
+  clearLastName(): void;
+  getLastName(): string | undefined;
+  setLastName(value: string): void;
+
+  hasAbout(): boolean;
+  clearAbout(): void;
+  getAbout(): string | undefined;
+  setAbout(value: string): void;
+
+  hasCoverPhoto(): boolean;
+  clearCoverPhoto(): void;
+  getCoverPhoto(): number | undefined;
+  setCoverPhoto(value: number): void;
+
+  hasAvatarPhoto(): boolean;
+  clearAvatarPhoto(): void;
+  getAvatarPhoto(): number | undefined;
+  setAvatarPhoto(value: number): void;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): PersonMetadata.AsObject;
+  static toObject(includeInstance: boolean, msg: PersonMetadata): PersonMetadata.AsObject;
+  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+  static serializeBinaryToWriter(message: PersonMetadata, writer: jspb.BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): PersonMetadata;
+  static deserializeBinaryFromReader(message: PersonMetadata, reader: jspb.BinaryReader): PersonMetadata;
+}
+
+export namespace PersonMetadata {
+  export type AsObject = {
+    firstName?: string,
+    middleName?: string,
+    lastName?: string,
+    about?: string,
+    coverPhoto?: number,
+    avatarPhoto?: number,
+  }
+}
+

+ 427 - 0
content-metadata-protobuf/compiled/proto/Person_pb.js

@@ -0,0 +1,427 @@
+// source: proto/Person.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+goog.exportSymbol('proto.PersonMetadata', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.PersonMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.PersonMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.PersonMetadata.displayName = 'proto.PersonMetadata';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.PersonMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.PersonMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.PersonMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.PersonMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    firstName: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    middleName: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    lastName: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
+    about: (f = jspb.Message.getField(msg, 4)) == null ? undefined : f,
+    coverPhoto: (f = jspb.Message.getField(msg, 5)) == null ? undefined : f,
+    avatarPhoto: (f = jspb.Message.getField(msg, 6)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.PersonMetadata}
+ */
+proto.PersonMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.PersonMetadata;
+  return proto.PersonMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.PersonMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.PersonMetadata}
+ */
+proto.PersonMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setFirstName(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setMiddleName(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setLastName(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAbout(value);
+      break;
+    case 5:
+      var value = /** @type {number} */ (reader.readUint32());
+      msg.setCoverPhoto(value);
+      break;
+    case 6:
+      var value = /** @type {number} */ (reader.readUint32());
+      msg.setAvatarPhoto(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.PersonMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.PersonMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.PersonMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.PersonMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 3));
+  if (f != null) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 4));
+  if (f != null) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 5));
+  if (f != null) {
+    writer.writeUint32(
+      5,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 6));
+  if (f != null) {
+    writer.writeUint32(
+      6,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string first_name = 1;
+ * @return {string}
+ */
+proto.PersonMetadata.prototype.getFirstName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.PersonMetadata} returns this
+ */
+proto.PersonMetadata.prototype.setFirstName = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.PersonMetadata} returns this
+ */
+proto.PersonMetadata.prototype.clearFirstName = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.PersonMetadata.prototype.hasFirstName = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional string middle_name = 2;
+ * @return {string}
+ */
+proto.PersonMetadata.prototype.getMiddleName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.PersonMetadata} returns this
+ */
+proto.PersonMetadata.prototype.setMiddleName = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.PersonMetadata} returns this
+ */
+proto.PersonMetadata.prototype.clearMiddleName = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.PersonMetadata.prototype.hasMiddleName = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional string last_name = 3;
+ * @return {string}
+ */
+proto.PersonMetadata.prototype.getLastName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.PersonMetadata} returns this
+ */
+proto.PersonMetadata.prototype.setLastName = function(value) {
+  return jspb.Message.setField(this, 3, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.PersonMetadata} returns this
+ */
+proto.PersonMetadata.prototype.clearLastName = function() {
+  return jspb.Message.setField(this, 3, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.PersonMetadata.prototype.hasLastName = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional string about = 4;
+ * @return {string}
+ */
+proto.PersonMetadata.prototype.getAbout = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.PersonMetadata} returns this
+ */
+proto.PersonMetadata.prototype.setAbout = function(value) {
+  return jspb.Message.setField(this, 4, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.PersonMetadata} returns this
+ */
+proto.PersonMetadata.prototype.clearAbout = function() {
+  return jspb.Message.setField(this, 4, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.PersonMetadata.prototype.hasAbout = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+/**
+ * optional uint32 cover_photo = 5;
+ * @return {number}
+ */
+proto.PersonMetadata.prototype.getCoverPhoto = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.PersonMetadata} returns this
+ */
+proto.PersonMetadata.prototype.setCoverPhoto = function(value) {
+  return jspb.Message.setField(this, 5, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.PersonMetadata} returns this
+ */
+proto.PersonMetadata.prototype.clearCoverPhoto = function() {
+  return jspb.Message.setField(this, 5, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.PersonMetadata.prototype.hasCoverPhoto = function() {
+  return jspb.Message.getField(this, 5) != null;
+};
+
+
+/**
+ * optional uint32 avatar_photo = 6;
+ * @return {number}
+ */
+proto.PersonMetadata.prototype.getAvatarPhoto = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.PersonMetadata} returns this
+ */
+proto.PersonMetadata.prototype.setAvatarPhoto = function(value) {
+  return jspb.Message.setField(this, 6, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.PersonMetadata} returns this
+ */
+proto.PersonMetadata.prototype.clearAvatarPhoto = function() {
+  return jspb.Message.setField(this, 6, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.PersonMetadata.prototype.hasAvatarPhoto = function() {
+  return jspb.Message.getField(this, 6) != null;
+};
+
+
+goog.object.extend(exports, proto);

+ 33 - 0
content-metadata-protobuf/compiled/proto/Playlist_pb.d.ts

@@ -0,0 +1,33 @@
+// package: 
+// file: proto/Playlist.proto
+
+import * as jspb from "google-protobuf";
+
+export class PlaylistMetadata extends jspb.Message {
+  hasTitle(): boolean;
+  clearTitle(): void;
+  getTitle(): string | undefined;
+  setTitle(value: string): void;
+
+  clearVideosList(): void;
+  getVideosList(): Array<number>;
+  setVideosList(value: Array<number>): void;
+  addVideos(value: number, index?: number): number;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): PlaylistMetadata.AsObject;
+  static toObject(includeInstance: boolean, msg: PlaylistMetadata): PlaylistMetadata.AsObject;
+  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+  static serializeBinaryToWriter(message: PlaylistMetadata, writer: jspb.BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): PlaylistMetadata;
+  static deserializeBinaryFromReader(message: PlaylistMetadata, reader: jspb.BinaryReader): PlaylistMetadata;
+}
+
+export namespace PlaylistMetadata {
+  export type AsObject = {
+    title?: string,
+    videosList: Array<number>,
+  }
+}
+

+ 245 - 0
content-metadata-protobuf/compiled/proto/Playlist_pb.js

@@ -0,0 +1,245 @@
+// source: proto/Playlist.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+goog.exportSymbol('proto.PlaylistMetadata', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.PlaylistMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.PlaylistMetadata.repeatedFields_, null);
+};
+goog.inherits(proto.PlaylistMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.PlaylistMetadata.displayName = 'proto.PlaylistMetadata';
+}
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.PlaylistMetadata.repeatedFields_ = [2];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.PlaylistMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.PlaylistMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.PlaylistMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.PlaylistMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    title: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    videosList: (f = jspb.Message.getRepeatedField(msg, 2)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.PlaylistMetadata}
+ */
+proto.PlaylistMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.PlaylistMetadata;
+  return proto.PlaylistMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.PlaylistMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.PlaylistMetadata}
+ */
+proto.PlaylistMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTitle(value);
+      break;
+    case 2:
+      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedUint64() : [reader.readUint64()]);
+      for (var i = 0; i < values.length; i++) {
+        msg.addVideos(values[i]);
+      }
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.PlaylistMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.PlaylistMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.PlaylistMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.PlaylistMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getVideosList();
+  if (f.length > 0) {
+    writer.writeRepeatedUint64(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string title = 1;
+ * @return {string}
+ */
+proto.PlaylistMetadata.prototype.getTitle = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.PlaylistMetadata} returns this
+ */
+proto.PlaylistMetadata.prototype.setTitle = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.PlaylistMetadata} returns this
+ */
+proto.PlaylistMetadata.prototype.clearTitle = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.PlaylistMetadata.prototype.hasTitle = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * repeated uint64 videos = 2;
+ * @return {!Array<number>}
+ */
+proto.PlaylistMetadata.prototype.getVideosList = function() {
+  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 2));
+};
+
+
+/**
+ * @param {!Array<number>} value
+ * @return {!proto.PlaylistMetadata} returns this
+ */
+proto.PlaylistMetadata.prototype.setVideosList = function(value) {
+  return jspb.Message.setField(this, 2, value || []);
+};
+
+
+/**
+ * @param {number} value
+ * @param {number=} opt_index
+ * @return {!proto.PlaylistMetadata} returns this
+ */
+proto.PlaylistMetadata.prototype.addVideos = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 2, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.PlaylistMetadata} returns this
+ */
+proto.PlaylistMetadata.prototype.clearVideosList = function() {
+  return this.setVideosList([]);
+};
+
+
+goog.object.extend(exports, proto);

+ 85 - 0
content-metadata-protobuf/compiled/proto/Series_pb.d.ts

@@ -0,0 +1,85 @@
+// package: 
+// file: proto/Series.proto
+
+import * as jspb from "google-protobuf";
+
+export class SeriesMetadata extends jspb.Message {
+  hasTitle(): boolean;
+  clearTitle(): void;
+  getTitle(): string | undefined;
+  setTitle(value: string): void;
+
+  hasDescription(): boolean;
+  clearDescription(): void;
+  getDescription(): string | undefined;
+  setDescription(value: string): void;
+
+  hasCoverPhoto(): boolean;
+  clearCoverPhoto(): void;
+  getCoverPhoto(): number | undefined;
+  setCoverPhoto(value: number): void;
+
+  clearPersonsList(): void;
+  getPersonsList(): Array<number>;
+  setPersonsList(value: Array<number>): void;
+  addPersons(value: number, index?: number): number;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): SeriesMetadata.AsObject;
+  static toObject(includeInstance: boolean, msg: SeriesMetadata): SeriesMetadata.AsObject;
+  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+  static serializeBinaryToWriter(message: SeriesMetadata, writer: jspb.BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): SeriesMetadata;
+  static deserializeBinaryFromReader(message: SeriesMetadata, reader: jspb.BinaryReader): SeriesMetadata;
+}
+
+export namespace SeriesMetadata {
+  export type AsObject = {
+    title?: string,
+    description?: string,
+    coverPhoto?: number,
+    personsList: Array<number>,
+  }
+}
+
+export class SeasonMetadata extends jspb.Message {
+  hasTitle(): boolean;
+  clearTitle(): void;
+  getTitle(): string | undefined;
+  setTitle(value: string): void;
+
+  hasDescription(): boolean;
+  clearDescription(): void;
+  getDescription(): string | undefined;
+  setDescription(value: string): void;
+
+  hasCoverPhoto(): boolean;
+  clearCoverPhoto(): void;
+  getCoverPhoto(): number | undefined;
+  setCoverPhoto(value: number): void;
+
+  clearPersonsList(): void;
+  getPersonsList(): Array<number>;
+  setPersonsList(value: Array<number>): void;
+  addPersons(value: number, index?: number): number;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): SeasonMetadata.AsObject;
+  static toObject(includeInstance: boolean, msg: SeasonMetadata): SeasonMetadata.AsObject;
+  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+  static serializeBinaryToWriter(message: SeasonMetadata, writer: jspb.BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): SeasonMetadata;
+  static deserializeBinaryFromReader(message: SeasonMetadata, reader: jspb.BinaryReader): SeasonMetadata;
+}
+
+export namespace SeasonMetadata {
+  export type AsObject = {
+    title?: string,
+    description?: string,
+    coverPhoto?: number,
+    personsList: Array<number>,
+  }
+}
+

+ 665 - 0
content-metadata-protobuf/compiled/proto/Series_pb.js

@@ -0,0 +1,665 @@
+// source: proto/Series.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+goog.exportSymbol('proto.SeasonMetadata', null, global);
+goog.exportSymbol('proto.SeriesMetadata', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.SeriesMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.SeriesMetadata.repeatedFields_, null);
+};
+goog.inherits(proto.SeriesMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.SeriesMetadata.displayName = 'proto.SeriesMetadata';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.SeasonMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.SeasonMetadata.repeatedFields_, null);
+};
+goog.inherits(proto.SeasonMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.SeasonMetadata.displayName = 'proto.SeasonMetadata';
+}
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.SeriesMetadata.repeatedFields_ = [4];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.SeriesMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.SeriesMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.SeriesMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.SeriesMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    title: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    description: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    coverPhoto: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
+    personsList: (f = jspb.Message.getRepeatedField(msg, 4)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.SeriesMetadata}
+ */
+proto.SeriesMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.SeriesMetadata;
+  return proto.SeriesMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.SeriesMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.SeriesMetadata}
+ */
+proto.SeriesMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTitle(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDescription(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readUint32());
+      msg.setCoverPhoto(value);
+      break;
+    case 4:
+      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedUint64() : [reader.readUint64()]);
+      for (var i = 0; i < values.length; i++) {
+        msg.addPersons(values[i]);
+      }
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.SeriesMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.SeriesMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.SeriesMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.SeriesMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 3));
+  if (f != null) {
+    writer.writeUint32(
+      3,
+      f
+    );
+  }
+  f = message.getPersonsList();
+  if (f.length > 0) {
+    writer.writePackedUint64(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string title = 1;
+ * @return {string}
+ */
+proto.SeriesMetadata.prototype.getTitle = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.SeriesMetadata} returns this
+ */
+proto.SeriesMetadata.prototype.setTitle = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.SeriesMetadata} returns this
+ */
+proto.SeriesMetadata.prototype.clearTitle = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.SeriesMetadata.prototype.hasTitle = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional string description = 2;
+ * @return {string}
+ */
+proto.SeriesMetadata.prototype.getDescription = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.SeriesMetadata} returns this
+ */
+proto.SeriesMetadata.prototype.setDescription = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.SeriesMetadata} returns this
+ */
+proto.SeriesMetadata.prototype.clearDescription = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.SeriesMetadata.prototype.hasDescription = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional uint32 cover_photo = 3;
+ * @return {number}
+ */
+proto.SeriesMetadata.prototype.getCoverPhoto = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.SeriesMetadata} returns this
+ */
+proto.SeriesMetadata.prototype.setCoverPhoto = function(value) {
+  return jspb.Message.setField(this, 3, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.SeriesMetadata} returns this
+ */
+proto.SeriesMetadata.prototype.clearCoverPhoto = function() {
+  return jspb.Message.setField(this, 3, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.SeriesMetadata.prototype.hasCoverPhoto = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * repeated uint64 persons = 4;
+ * @return {!Array<number>}
+ */
+proto.SeriesMetadata.prototype.getPersonsList = function() {
+  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 4));
+};
+
+
+/**
+ * @param {!Array<number>} value
+ * @return {!proto.SeriesMetadata} returns this
+ */
+proto.SeriesMetadata.prototype.setPersonsList = function(value) {
+  return jspb.Message.setField(this, 4, value || []);
+};
+
+
+/**
+ * @param {number} value
+ * @param {number=} opt_index
+ * @return {!proto.SeriesMetadata} returns this
+ */
+proto.SeriesMetadata.prototype.addPersons = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 4, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.SeriesMetadata} returns this
+ */
+proto.SeriesMetadata.prototype.clearPersonsList = function() {
+  return this.setPersonsList([]);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.SeasonMetadata.repeatedFields_ = [4];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.SeasonMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.SeasonMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.SeasonMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.SeasonMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    title: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    description: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    coverPhoto: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
+    personsList: (f = jspb.Message.getRepeatedField(msg, 4)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.SeasonMetadata}
+ */
+proto.SeasonMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.SeasonMetadata;
+  return proto.SeasonMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.SeasonMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.SeasonMetadata}
+ */
+proto.SeasonMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTitle(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDescription(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readUint32());
+      msg.setCoverPhoto(value);
+      break;
+    case 4:
+      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedUint64() : [reader.readUint64()]);
+      for (var i = 0; i < values.length; i++) {
+        msg.addPersons(values[i]);
+      }
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.SeasonMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.SeasonMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.SeasonMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.SeasonMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 3));
+  if (f != null) {
+    writer.writeUint32(
+      3,
+      f
+    );
+  }
+  f = message.getPersonsList();
+  if (f.length > 0) {
+    writer.writePackedUint64(
+      4,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string title = 1;
+ * @return {string}
+ */
+proto.SeasonMetadata.prototype.getTitle = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.SeasonMetadata} returns this
+ */
+proto.SeasonMetadata.prototype.setTitle = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.SeasonMetadata} returns this
+ */
+proto.SeasonMetadata.prototype.clearTitle = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.SeasonMetadata.prototype.hasTitle = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional string description = 2;
+ * @return {string}
+ */
+proto.SeasonMetadata.prototype.getDescription = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.SeasonMetadata} returns this
+ */
+proto.SeasonMetadata.prototype.setDescription = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.SeasonMetadata} returns this
+ */
+proto.SeasonMetadata.prototype.clearDescription = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.SeasonMetadata.prototype.hasDescription = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional uint32 cover_photo = 3;
+ * @return {number}
+ */
+proto.SeasonMetadata.prototype.getCoverPhoto = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.SeasonMetadata} returns this
+ */
+proto.SeasonMetadata.prototype.setCoverPhoto = function(value) {
+  return jspb.Message.setField(this, 3, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.SeasonMetadata} returns this
+ */
+proto.SeasonMetadata.prototype.clearCoverPhoto = function() {
+  return jspb.Message.setField(this, 3, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.SeasonMetadata.prototype.hasCoverPhoto = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * repeated uint64 persons = 4;
+ * @return {!Array<number>}
+ */
+proto.SeasonMetadata.prototype.getPersonsList = function() {
+  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 4));
+};
+
+
+/**
+ * @param {!Array<number>} value
+ * @return {!proto.SeasonMetadata} returns this
+ */
+proto.SeasonMetadata.prototype.setPersonsList = function(value) {
+  return jspb.Message.setField(this, 4, value || []);
+};
+
+
+/**
+ * @param {number} value
+ * @param {number=} opt_index
+ * @return {!proto.SeasonMetadata} returns this
+ */
+proto.SeasonMetadata.prototype.addPersons = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 4, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.SeasonMetadata} returns this
+ */
+proto.SeasonMetadata.prototype.clearPersonsList = function() {
+  return this.setPersonsList([]);
+};
+
+
+goog.object.extend(exports, proto);

+ 235 - 0
content-metadata-protobuf/compiled/proto/Video_pb.d.ts

@@ -0,0 +1,235 @@
+// package: 
+// file: proto/Video.proto
+
+import * as jspb from "google-protobuf";
+
+export class PublishedBeforeJoystream extends jspb.Message {
+  hasIsPublished(): boolean;
+  clearIsPublished(): void;
+  getIsPublished(): boolean | undefined;
+  setIsPublished(value: boolean): void;
+
+  hasDate(): boolean;
+  clearDate(): void;
+  getDate(): string | undefined;
+  setDate(value: string): void;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): PublishedBeforeJoystream.AsObject;
+  static toObject(includeInstance: boolean, msg: PublishedBeforeJoystream): PublishedBeforeJoystream.AsObject;
+  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+  static serializeBinaryToWriter(message: PublishedBeforeJoystream, writer: jspb.BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): PublishedBeforeJoystream;
+  static deserializeBinaryFromReader(message: PublishedBeforeJoystream, reader: jspb.BinaryReader): PublishedBeforeJoystream;
+}
+
+export namespace PublishedBeforeJoystream {
+  export type AsObject = {
+    isPublished?: boolean,
+    date?: string,
+  }
+}
+
+export class License extends jspb.Message {
+  hasCode(): boolean;
+  clearCode(): void;
+  getCode(): number | undefined;
+  setCode(value: number): void;
+
+  hasAttribution(): boolean;
+  clearAttribution(): void;
+  getAttribution(): string | undefined;
+  setAttribution(value: string): void;
+
+  hasCustomText(): boolean;
+  clearCustomText(): void;
+  getCustomText(): string | undefined;
+  setCustomText(value: string): void;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): License.AsObject;
+  static toObject(includeInstance: boolean, msg: License): License.AsObject;
+  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+  static serializeBinaryToWriter(message: License, writer: jspb.BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): License;
+  static deserializeBinaryFromReader(message: License, reader: jspb.BinaryReader): License;
+}
+
+export namespace License {
+  export type AsObject = {
+    code?: number,
+    attribution?: string,
+    customText?: string,
+  }
+}
+
+export class MediaType extends jspb.Message {
+  hasCodecName(): boolean;
+  clearCodecName(): void;
+  getCodecName(): string | undefined;
+  setCodecName(value: string): void;
+
+  hasContainer(): boolean;
+  clearContainer(): void;
+  getContainer(): string | undefined;
+  setContainer(value: string): void;
+
+  hasMimeMediaType(): boolean;
+  clearMimeMediaType(): void;
+  getMimeMediaType(): string | undefined;
+  setMimeMediaType(value: string): void;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): MediaType.AsObject;
+  static toObject(includeInstance: boolean, msg: MediaType): MediaType.AsObject;
+  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+  static serializeBinaryToWriter(message: MediaType, writer: jspb.BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): MediaType;
+  static deserializeBinaryFromReader(message: MediaType, reader: jspb.BinaryReader): MediaType;
+}
+
+export namespace MediaType {
+  export type AsObject = {
+    codecName?: string,
+    container?: string,
+    mimeMediaType?: string,
+  }
+}
+
+export class VideoMetadata extends jspb.Message {
+  hasTitle(): boolean;
+  clearTitle(): void;
+  getTitle(): string | undefined;
+  setTitle(value: string): void;
+
+  hasDescription(): boolean;
+  clearDescription(): void;
+  getDescription(): string | undefined;
+  setDescription(value: string): void;
+
+  hasVideo(): boolean;
+  clearVideo(): void;
+  getVideo(): number | undefined;
+  setVideo(value: number): void;
+
+  hasThumbnailPhoto(): boolean;
+  clearThumbnailPhoto(): void;
+  getThumbnailPhoto(): number | undefined;
+  setThumbnailPhoto(value: number): void;
+
+  hasDuration(): boolean;
+  clearDuration(): void;
+  getDuration(): number | undefined;
+  setDuration(value: number): void;
+
+  hasMediaPixelHeight(): boolean;
+  clearMediaPixelHeight(): void;
+  getMediaPixelHeight(): number | undefined;
+  setMediaPixelHeight(value: number): void;
+
+  hasMediaPixelWidth(): boolean;
+  clearMediaPixelWidth(): void;
+  getMediaPixelWidth(): number | undefined;
+  setMediaPixelWidth(value: number): void;
+
+  hasMediaType(): boolean;
+  clearMediaType(): void;
+  getMediaType(): MediaType | undefined;
+  setMediaType(value?: MediaType): void;
+
+  hasLanguage(): boolean;
+  clearLanguage(): void;
+  getLanguage(): string | undefined;
+  setLanguage(value: string): void;
+
+  hasLicense(): boolean;
+  clearLicense(): void;
+  getLicense(): License | undefined;
+  setLicense(value?: License): void;
+
+  hasPublishedBeforeJoystream(): boolean;
+  clearPublishedBeforeJoystream(): void;
+  getPublishedBeforeJoystream(): PublishedBeforeJoystream | undefined;
+  setPublishedBeforeJoystream(value?: PublishedBeforeJoystream): void;
+
+  hasHasMarketing(): boolean;
+  clearHasMarketing(): void;
+  getHasMarketing(): boolean | undefined;
+  setHasMarketing(value: boolean): void;
+
+  hasIsPublic(): boolean;
+  clearIsPublic(): void;
+  getIsPublic(): boolean | undefined;
+  setIsPublic(value: boolean): void;
+
+  hasIsExplicit(): boolean;
+  clearIsExplicit(): void;
+  getIsExplicit(): boolean | undefined;
+  setIsExplicit(value: boolean): void;
+
+  clearPersonsList(): void;
+  getPersonsList(): Array<number>;
+  setPersonsList(value: Array<number>): void;
+  addPersons(value: number, index?: number): number;
+
+  hasCategory(): boolean;
+  clearCategory(): void;
+  getCategory(): number | undefined;
+  setCategory(value: number): void;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): VideoMetadata.AsObject;
+  static toObject(includeInstance: boolean, msg: VideoMetadata): VideoMetadata.AsObject;
+  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+  static serializeBinaryToWriter(message: VideoMetadata, writer: jspb.BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): VideoMetadata;
+  static deserializeBinaryFromReader(message: VideoMetadata, reader: jspb.BinaryReader): VideoMetadata;
+}
+
+export namespace VideoMetadata {
+  export type AsObject = {
+    title?: string,
+    description?: string,
+    video?: number,
+    thumbnailPhoto?: number,
+    duration?: number,
+    mediaPixelHeight?: number,
+    mediaPixelWidth?: number,
+    mediaType?: MediaType.AsObject,
+    language?: string,
+    license?: License.AsObject,
+    publishedBeforeJoystream?: PublishedBeforeJoystream.AsObject,
+    hasMarketing?: boolean,
+    isPublic?: boolean,
+    isExplicit?: boolean,
+    personsList: Array<number>,
+    category?: number,
+  }
+}
+
+export class VideoCategoryMetadata extends jspb.Message {
+  hasName(): boolean;
+  clearName(): void;
+  getName(): string | undefined;
+  setName(value: string): void;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): VideoCategoryMetadata.AsObject;
+  static toObject(includeInstance: boolean, msg: VideoCategoryMetadata): VideoCategoryMetadata.AsObject;
+  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+  static serializeBinaryToWriter(message: VideoCategoryMetadata, writer: jspb.BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): VideoCategoryMetadata;
+  static deserializeBinaryFromReader(message: VideoCategoryMetadata, reader: jspb.BinaryReader): VideoCategoryMetadata;
+}
+
+export namespace VideoCategoryMetadata {
+  export type AsObject = {
+    name?: string,
+  }
+}
+

+ 1846 - 0
content-metadata-protobuf/compiled/proto/Video_pb.js

@@ -0,0 +1,1846 @@
+// source: proto/Video.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global = Function('return this')();
+
+goog.exportSymbol('proto.License', null, global);
+goog.exportSymbol('proto.MediaType', null, global);
+goog.exportSymbol('proto.PublishedBeforeJoystream', null, global);
+goog.exportSymbol('proto.VideoCategoryMetadata', null, global);
+goog.exportSymbol('proto.VideoMetadata', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.PublishedBeforeJoystream = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.PublishedBeforeJoystream, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.PublishedBeforeJoystream.displayName = 'proto.PublishedBeforeJoystream';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.License = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.License, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.License.displayName = 'proto.License';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.MediaType = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.MediaType, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.MediaType.displayName = 'proto.MediaType';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.VideoMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.VideoMetadata.repeatedFields_, null);
+};
+goog.inherits(proto.VideoMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.VideoMetadata.displayName = 'proto.VideoMetadata';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.VideoCategoryMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.VideoCategoryMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.VideoCategoryMetadata.displayName = 'proto.VideoCategoryMetadata';
+}
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.PublishedBeforeJoystream.prototype.toObject = function(opt_includeInstance) {
+  return proto.PublishedBeforeJoystream.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.PublishedBeforeJoystream} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.PublishedBeforeJoystream.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    isPublished: (f = jspb.Message.getBooleanField(msg, 1)) == null ? undefined : f,
+    date: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.PublishedBeforeJoystream}
+ */
+proto.PublishedBeforeJoystream.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.PublishedBeforeJoystream;
+  return proto.PublishedBeforeJoystream.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.PublishedBeforeJoystream} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.PublishedBeforeJoystream}
+ */
+proto.PublishedBeforeJoystream.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setIsPublished(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDate(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.PublishedBeforeJoystream.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.PublishedBeforeJoystream.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.PublishedBeforeJoystream} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.PublishedBeforeJoystream.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeBool(
+      1,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional bool is_published = 1;
+ * @return {boolean}
+ */
+proto.PublishedBeforeJoystream.prototype.getIsPublished = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.PublishedBeforeJoystream} returns this
+ */
+proto.PublishedBeforeJoystream.prototype.setIsPublished = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.PublishedBeforeJoystream} returns this
+ */
+proto.PublishedBeforeJoystream.prototype.clearIsPublished = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.PublishedBeforeJoystream.prototype.hasIsPublished = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional string date = 2;
+ * @return {string}
+ */
+proto.PublishedBeforeJoystream.prototype.getDate = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.PublishedBeforeJoystream} returns this
+ */
+proto.PublishedBeforeJoystream.prototype.setDate = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.PublishedBeforeJoystream} returns this
+ */
+proto.PublishedBeforeJoystream.prototype.clearDate = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.PublishedBeforeJoystream.prototype.hasDate = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.License.prototype.toObject = function(opt_includeInstance) {
+  return proto.License.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.License} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.License.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    code: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    attribution: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    customText: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.License}
+ */
+proto.License.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.License;
+  return proto.License.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.License} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.License}
+ */
+proto.License.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readUint32());
+      msg.setCode(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setAttribution(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCustomText(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.License.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.License.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.License} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.License.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {number} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeUint32(
+      1,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 3));
+  if (f != null) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional uint32 code = 1;
+ * @return {number}
+ */
+proto.License.prototype.getCode = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.License} returns this
+ */
+proto.License.prototype.setCode = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.License} returns this
+ */
+proto.License.prototype.clearCode = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.License.prototype.hasCode = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional string attribution = 2;
+ * @return {string}
+ */
+proto.License.prototype.getAttribution = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.License} returns this
+ */
+proto.License.prototype.setAttribution = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.License} returns this
+ */
+proto.License.prototype.clearAttribution = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.License.prototype.hasAttribution = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional string custom_text = 3;
+ * @return {string}
+ */
+proto.License.prototype.getCustomText = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.License} returns this
+ */
+proto.License.prototype.setCustomText = function(value) {
+  return jspb.Message.setField(this, 3, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.License} returns this
+ */
+proto.License.prototype.clearCustomText = function() {
+  return jspb.Message.setField(this, 3, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.License.prototype.hasCustomText = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.MediaType.prototype.toObject = function(opt_includeInstance) {
+  return proto.MediaType.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.MediaType} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.MediaType.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    codecName: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    container: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    mimeMediaType: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.MediaType}
+ */
+proto.MediaType.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.MediaType;
+  return proto.MediaType.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.MediaType} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.MediaType}
+ */
+proto.MediaType.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setCodecName(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setContainer(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setMimeMediaType(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.MediaType.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.MediaType.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.MediaType} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.MediaType.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 3));
+  if (f != null) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string codec_name = 1;
+ * @return {string}
+ */
+proto.MediaType.prototype.getCodecName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.MediaType} returns this
+ */
+proto.MediaType.prototype.setCodecName = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.MediaType} returns this
+ */
+proto.MediaType.prototype.clearCodecName = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.MediaType.prototype.hasCodecName = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional string container = 2;
+ * @return {string}
+ */
+proto.MediaType.prototype.getContainer = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.MediaType} returns this
+ */
+proto.MediaType.prototype.setContainer = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.MediaType} returns this
+ */
+proto.MediaType.prototype.clearContainer = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.MediaType.prototype.hasContainer = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional string mime_media_type = 3;
+ * @return {string}
+ */
+proto.MediaType.prototype.getMimeMediaType = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.MediaType} returns this
+ */
+proto.MediaType.prototype.setMimeMediaType = function(value) {
+  return jspb.Message.setField(this, 3, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.MediaType} returns this
+ */
+proto.MediaType.prototype.clearMimeMediaType = function() {
+  return jspb.Message.setField(this, 3, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.MediaType.prototype.hasMimeMediaType = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.VideoMetadata.repeatedFields_ = [15];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.VideoMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.VideoMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.VideoMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.VideoMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    title: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    description: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    video: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
+    thumbnailPhoto: (f = jspb.Message.getField(msg, 4)) == null ? undefined : f,
+    duration: (f = jspb.Message.getField(msg, 5)) == null ? undefined : f,
+    mediaPixelHeight: (f = jspb.Message.getField(msg, 6)) == null ? undefined : f,
+    mediaPixelWidth: (f = jspb.Message.getField(msg, 7)) == null ? undefined : f,
+    mediaType: (f = msg.getMediaType()) && proto.MediaType.toObject(includeInstance, f),
+    language: (f = jspb.Message.getField(msg, 9)) == null ? undefined : f,
+    license: (f = msg.getLicense()) && proto.License.toObject(includeInstance, f),
+    publishedBeforeJoystream: (f = msg.getPublishedBeforeJoystream()) && proto.PublishedBeforeJoystream.toObject(includeInstance, f),
+    hasMarketing: (f = jspb.Message.getBooleanField(msg, 12)) == null ? undefined : f,
+    isPublic: (f = jspb.Message.getBooleanField(msg, 13)) == null ? undefined : f,
+    isExplicit: (f = jspb.Message.getBooleanField(msg, 14)) == null ? undefined : f,
+    personsList: (f = jspb.Message.getRepeatedField(msg, 15)) == null ? undefined : f,
+    category: (f = jspb.Message.getField(msg, 16)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.VideoMetadata}
+ */
+proto.VideoMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.VideoMetadata;
+  return proto.VideoMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.VideoMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.VideoMetadata}
+ */
+proto.VideoMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setTitle(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setDescription(value);
+      break;
+    case 3:
+      var value = /** @type {number} */ (reader.readUint32());
+      msg.setVideo(value);
+      break;
+    case 4:
+      var value = /** @type {number} */ (reader.readUint32());
+      msg.setThumbnailPhoto(value);
+      break;
+    case 5:
+      var value = /** @type {number} */ (reader.readUint32());
+      msg.setDuration(value);
+      break;
+    case 6:
+      var value = /** @type {number} */ (reader.readUint32());
+      msg.setMediaPixelHeight(value);
+      break;
+    case 7:
+      var value = /** @type {number} */ (reader.readUint32());
+      msg.setMediaPixelWidth(value);
+      break;
+    case 8:
+      var value = new proto.MediaType;
+      reader.readMessage(value,proto.MediaType.deserializeBinaryFromReader);
+      msg.setMediaType(value);
+      break;
+    case 9:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setLanguage(value);
+      break;
+    case 10:
+      var value = new proto.License;
+      reader.readMessage(value,proto.License.deserializeBinaryFromReader);
+      msg.setLicense(value);
+      break;
+    case 11:
+      var value = new proto.PublishedBeforeJoystream;
+      reader.readMessage(value,proto.PublishedBeforeJoystream.deserializeBinaryFromReader);
+      msg.setPublishedBeforeJoystream(value);
+      break;
+    case 12:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setHasMarketing(value);
+      break;
+    case 13:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setIsPublic(value);
+      break;
+    case 14:
+      var value = /** @type {boolean} */ (reader.readBool());
+      msg.setIsExplicit(value);
+      break;
+    case 15:
+      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedUint64() : [reader.readUint64()]);
+      for (var i = 0; i < values.length; i++) {
+        msg.addPersons(values[i]);
+      }
+      break;
+    case 16:
+      var value = /** @type {number} */ (reader.readUint64());
+      msg.setCategory(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.VideoMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.VideoMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.VideoMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.VideoMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 2));
+  if (f != null) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 3));
+  if (f != null) {
+    writer.writeUint32(
+      3,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 4));
+  if (f != null) {
+    writer.writeUint32(
+      4,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 5));
+  if (f != null) {
+    writer.writeUint32(
+      5,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 6));
+  if (f != null) {
+    writer.writeUint32(
+      6,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 7));
+  if (f != null) {
+    writer.writeUint32(
+      7,
+      f
+    );
+  }
+  f = message.getMediaType();
+  if (f != null) {
+    writer.writeMessage(
+      8,
+      f,
+      proto.MediaType.serializeBinaryToWriter
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 9));
+  if (f != null) {
+    writer.writeString(
+      9,
+      f
+    );
+  }
+  f = message.getLicense();
+  if (f != null) {
+    writer.writeMessage(
+      10,
+      f,
+      proto.License.serializeBinaryToWriter
+    );
+  }
+  f = message.getPublishedBeforeJoystream();
+  if (f != null) {
+    writer.writeMessage(
+      11,
+      f,
+      proto.PublishedBeforeJoystream.serializeBinaryToWriter
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 12));
+  if (f != null) {
+    writer.writeBool(
+      12,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 13));
+  if (f != null) {
+    writer.writeBool(
+      13,
+      f
+    );
+  }
+  f = /** @type {boolean} */ (jspb.Message.getField(message, 14));
+  if (f != null) {
+    writer.writeBool(
+      14,
+      f
+    );
+  }
+  f = message.getPersonsList();
+  if (f.length > 0) {
+    writer.writePackedUint64(
+      15,
+      f
+    );
+  }
+  f = /** @type {number} */ (jspb.Message.getField(message, 16));
+  if (f != null) {
+    writer.writeUint64(
+      16,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string title = 1;
+ * @return {string}
+ */
+proto.VideoMetadata.prototype.getTitle = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.setTitle = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.clearTitle = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.hasTitle = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional string description = 2;
+ * @return {string}
+ */
+proto.VideoMetadata.prototype.getDescription = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.setDescription = function(value) {
+  return jspb.Message.setField(this, 2, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.clearDescription = function() {
+  return jspb.Message.setField(this, 2, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.hasDescription = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional uint32 video = 3;
+ * @return {number}
+ */
+proto.VideoMetadata.prototype.getVideo = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.setVideo = function(value) {
+  return jspb.Message.setField(this, 3, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.clearVideo = function() {
+  return jspb.Message.setField(this, 3, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.hasVideo = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional uint32 thumbnail_photo = 4;
+ * @return {number}
+ */
+proto.VideoMetadata.prototype.getThumbnailPhoto = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.setThumbnailPhoto = function(value) {
+  return jspb.Message.setField(this, 4, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.clearThumbnailPhoto = function() {
+  return jspb.Message.setField(this, 4, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.hasThumbnailPhoto = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+/**
+ * optional uint32 duration = 5;
+ * @return {number}
+ */
+proto.VideoMetadata.prototype.getDuration = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.setDuration = function(value) {
+  return jspb.Message.setField(this, 5, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.clearDuration = function() {
+  return jspb.Message.setField(this, 5, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.hasDuration = function() {
+  return jspb.Message.getField(this, 5) != null;
+};
+
+
+/**
+ * optional uint32 media_pixel_height = 6;
+ * @return {number}
+ */
+proto.VideoMetadata.prototype.getMediaPixelHeight = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.setMediaPixelHeight = function(value) {
+  return jspb.Message.setField(this, 6, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.clearMediaPixelHeight = function() {
+  return jspb.Message.setField(this, 6, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.hasMediaPixelHeight = function() {
+  return jspb.Message.getField(this, 6) != null;
+};
+
+
+/**
+ * optional uint32 media_pixel_width = 7;
+ * @return {number}
+ */
+proto.VideoMetadata.prototype.getMediaPixelWidth = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 7, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.setMediaPixelWidth = function(value) {
+  return jspb.Message.setField(this, 7, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.clearMediaPixelWidth = function() {
+  return jspb.Message.setField(this, 7, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.hasMediaPixelWidth = function() {
+  return jspb.Message.getField(this, 7) != null;
+};
+
+
+/**
+ * optional MediaType media_type = 8;
+ * @return {?proto.MediaType}
+ */
+proto.VideoMetadata.prototype.getMediaType = function() {
+  return /** @type{?proto.MediaType} */ (
+    jspb.Message.getWrapperField(this, proto.MediaType, 8));
+};
+
+
+/**
+ * @param {?proto.MediaType|undefined} value
+ * @return {!proto.VideoMetadata} returns this
+*/
+proto.VideoMetadata.prototype.setMediaType = function(value) {
+  return jspb.Message.setWrapperField(this, 8, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.clearMediaType = function() {
+  return this.setMediaType(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.hasMediaType = function() {
+  return jspb.Message.getField(this, 8) != null;
+};
+
+
+/**
+ * optional string language = 9;
+ * @return {string}
+ */
+proto.VideoMetadata.prototype.getLanguage = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 9, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.setLanguage = function(value) {
+  return jspb.Message.setField(this, 9, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.clearLanguage = function() {
+  return jspb.Message.setField(this, 9, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.hasLanguage = function() {
+  return jspb.Message.getField(this, 9) != null;
+};
+
+
+/**
+ * optional License license = 10;
+ * @return {?proto.License}
+ */
+proto.VideoMetadata.prototype.getLicense = function() {
+  return /** @type{?proto.License} */ (
+    jspb.Message.getWrapperField(this, proto.License, 10));
+};
+
+
+/**
+ * @param {?proto.License|undefined} value
+ * @return {!proto.VideoMetadata} returns this
+*/
+proto.VideoMetadata.prototype.setLicense = function(value) {
+  return jspb.Message.setWrapperField(this, 10, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.clearLicense = function() {
+  return this.setLicense(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.hasLicense = function() {
+  return jspb.Message.getField(this, 10) != null;
+};
+
+
+/**
+ * optional PublishedBeforeJoystream published_before_joystream = 11;
+ * @return {?proto.PublishedBeforeJoystream}
+ */
+proto.VideoMetadata.prototype.getPublishedBeforeJoystream = function() {
+  return /** @type{?proto.PublishedBeforeJoystream} */ (
+    jspb.Message.getWrapperField(this, proto.PublishedBeforeJoystream, 11));
+};
+
+
+/**
+ * @param {?proto.PublishedBeforeJoystream|undefined} value
+ * @return {!proto.VideoMetadata} returns this
+*/
+proto.VideoMetadata.prototype.setPublishedBeforeJoystream = function(value) {
+  return jspb.Message.setWrapperField(this, 11, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.clearPublishedBeforeJoystream = function() {
+  return this.setPublishedBeforeJoystream(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.hasPublishedBeforeJoystream = function() {
+  return jspb.Message.getField(this, 11) != null;
+};
+
+
+/**
+ * optional bool has_marketing = 12;
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.getHasMarketing = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 12, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.setHasMarketing = function(value) {
+  return jspb.Message.setField(this, 12, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.clearHasMarketing = function() {
+  return jspb.Message.setField(this, 12, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.hasHasMarketing = function() {
+  return jspb.Message.getField(this, 12) != null;
+};
+
+
+/**
+ * optional bool is_public = 13;
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.getIsPublic = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 13, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.setIsPublic = function(value) {
+  return jspb.Message.setField(this, 13, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.clearIsPublic = function() {
+  return jspb.Message.setField(this, 13, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.hasIsPublic = function() {
+  return jspb.Message.getField(this, 13) != null;
+};
+
+
+/**
+ * optional bool is_explicit = 14;
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.getIsExplicit = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 14, false));
+};
+
+
+/**
+ * @param {boolean} value
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.setIsExplicit = function(value) {
+  return jspb.Message.setField(this, 14, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.clearIsExplicit = function() {
+  return jspb.Message.setField(this, 14, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.hasIsExplicit = function() {
+  return jspb.Message.getField(this, 14) != null;
+};
+
+
+/**
+ * repeated uint64 persons = 15;
+ * @return {!Array<number>}
+ */
+proto.VideoMetadata.prototype.getPersonsList = function() {
+  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 15));
+};
+
+
+/**
+ * @param {!Array<number>} value
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.setPersonsList = function(value) {
+  return jspb.Message.setField(this, 15, value || []);
+};
+
+
+/**
+ * @param {number} value
+ * @param {number=} opt_index
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.addPersons = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 15, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.clearPersonsList = function() {
+  return this.setPersonsList([]);
+};
+
+
+/**
+ * optional uint64 category = 16;
+ * @return {number}
+ */
+proto.VideoMetadata.prototype.getCategory = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 16, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.setCategory = function(value) {
+  return jspb.Message.setField(this, 16, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.VideoMetadata} returns this
+ */
+proto.VideoMetadata.prototype.clearCategory = function() {
+  return jspb.Message.setField(this, 16, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.VideoMetadata.prototype.hasCategory = function() {
+  return jspb.Message.getField(this, 16) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.VideoCategoryMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.VideoCategoryMetadata.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.VideoCategoryMetadata} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.VideoCategoryMetadata.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.VideoCategoryMetadata}
+ */
+proto.VideoCategoryMetadata.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.VideoCategoryMetadata;
+  return proto.VideoCategoryMetadata.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.VideoCategoryMetadata} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.VideoCategoryMetadata}
+ */
+proto.VideoCategoryMetadata.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.VideoCategoryMetadata.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.VideoCategoryMetadata.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.VideoCategoryMetadata} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.VideoCategoryMetadata.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = /** @type {string} */ (jspb.Message.getField(message, 1));
+  if (f != null) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.VideoCategoryMetadata.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.VideoCategoryMetadata} returns this
+ */
+proto.VideoCategoryMetadata.prototype.setName = function(value) {
+  return jspb.Message.setField(this, 1, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.VideoCategoryMetadata} returns this
+ */
+proto.VideoCategoryMetadata.prototype.clearName = function() {
+  return jspb.Message.setField(this, 1, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.VideoCategoryMetadata.prototype.hasName = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+goog.object.extend(exports, proto);

+ 41 - 0
content-metadata-protobuf/doc-appendix.md

@@ -0,0 +1,41 @@
+<!-- 
+    This extra documentation will be appended to the generated docs.
+-->
+
+## Referencing Assets
+<a name=".Assets"></a>
+
+Applications that process messages that contain a `uint32` field that references an asset such as a cover photo or video, should interpret this value as a zero based index into an array/vector that is received external (out of band) to the protobuf message.
+
+Example in context of query-node processing the runtime event `VideoCreated`
+
+```rust
+// Runtime event associated with creating a Video
+VideoCreated(video_id: VideoId, video: Video, assets: Vec<NewAsset>, params: VideoCreationParameters)
+
+struct VideoCreationParameters {
+  in_category: VideoCategoryId,
+  // binary serialized VideoMetadata protobuf message
+  meta: Vec<u8>,
+}
+
+// suppose assets is a vector of two elements. This is the "out of band" array being referenced by the VideoMetadata message
+assets = [
+    NewAsset::Uri("https://mydomain.net/thumbnail.png"),
+    NewAsset::Upload({
+       content_id,
+       ipfs_hash,
+       size,
+       ...
+    }),
+];
+
+meta = VideoMetadata {
+    ...
+    // refers to second element: assets[1] which is being uploaded to the storage system
+    video: 1,
+    // refers to the first element assets[0] which is being referneced by a url string.
+    thumbnail_photo: 0,
+    ...
+};
+```

+ 374 - 0
content-metadata-protobuf/doc/index.md

@@ -0,0 +1,374 @@
+# Protocol Documentation
+<a name="top"></a>
+
+## Table of Contents
+
+- [proto/Channel.proto](#proto/Channel.proto)
+    - [ChannelCategoryMetadata](#.ChannelCategoryMetadata)
+    - [ChannelMetadata](#.ChannelMetadata)
+  
+- [proto/Person.proto](#proto/Person.proto)
+    - [PersonMetadata](#.PersonMetadata)
+  
+- [proto/Playlist.proto](#proto/Playlist.proto)
+    - [PlaylistMetadata](#.PlaylistMetadata)
+  
+- [proto/Series.proto](#proto/Series.proto)
+    - [SeasonMetadata](#.SeasonMetadata)
+    - [SeriesMetadata](#.SeriesMetadata)
+  
+- [proto/Video.proto](#proto/Video.proto)
+    - [License](#.License)
+    - [MediaType](#.MediaType)
+    - [PublishedBeforeJoystream](#.PublishedBeforeJoystream)
+    - [VideoCategoryMetadata](#.VideoCategoryMetadata)
+    - [VideoMetadata](#.VideoMetadata)
+  
+- [Scalar Value Types](#scalar-value-types)
+
+
+
+<a name="proto/Channel.proto"></a>
+<p align="right"><a href="#top">Top</a></p>
+
+## proto/Channel.proto
+
+
+
+<a name=".ChannelCategoryMetadata"></a>
+
+### ChannelCategoryMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| name | [string](#string) | optional | Category Name |
+
+
+
+
+
+
+<a name=".ChannelMetadata"></a>
+
+### ChannelMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| title | [string](#string) | optional | Channel Title |
+| description | [string](#string) | optional | Channel Description |
+| is_public | [bool](#bool) | optional | Wether to display channel to the public |
+| language | [string](#string) | optional | ISO_639-1 Language [Code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) |
+| cover_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
+| avatar_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
+| category | [uint64](#uint64) | optional | Channel Category Id |
+
+
+
+
+
+ 
+
+ 
+
+ 
+
+ 
+
+
+
+<a name="proto/Person.proto"></a>
+<p align="right"><a href="#top">Top</a></p>
+
+## proto/Person.proto
+
+
+
+<a name=".PersonMetadata"></a>
+
+### PersonMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| first_name | [string](#string) | optional |  |
+| middle_name | [string](#string) | optional |  |
+| last_name | [string](#string) | optional |  |
+| about | [string](#string) | optional |  |
+| cover_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
+| avatar_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
+
+
+
+
+
+ 
+
+ 
+
+ 
+
+ 
+
+
+
+<a name="proto/Playlist.proto"></a>
+<p align="right"><a href="#top">Top</a></p>
+
+## proto/Playlist.proto
+
+
+
+<a name=".PlaylistMetadata"></a>
+
+### PlaylistMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| title | [string](#string) | optional |  |
+| videos | [uint64](#uint64) | repeated | Videos in the playlist |
+
+
+
+
+
+ 
+
+ 
+
+ 
+
+ 
+
+
+
+<a name="proto/Series.proto"></a>
+<p align="right"><a href="#top">Top</a></p>
+
+## proto/Series.proto
+
+
+
+<a name=".SeasonMetadata"></a>
+
+### SeasonMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| title | [string](#string) | optional |  |
+| description | [string](#string) | optional |  |
+| cover_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
+| persons | [uint64](#uint64) | repeated | Person(s) referenced by PersonId involved in this Season |
+
+
+
+
+
+
+<a name=".SeriesMetadata"></a>
+
+### SeriesMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| title | [string](#string) | optional |  |
+| description | [string](#string) | optional |  |
+| cover_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
+| persons | [uint64](#uint64) | repeated | Person(s) referenced by PersonId involved in this Series |
+
+
+
+
+
+ 
+
+ 
+
+ 
+
+ 
+
+
+
+<a name="proto/Video.proto"></a>
+<p align="right"><a href="#top">Top</a></p>
+
+## proto/Video.proto
+
+
+
+<a name=".License"></a>
+
+### License
+License types defined by Joystream
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| code | [uint32](#uint32) | optional | License code defined by Joystream. [reference](../src/KnownLicenses.json) |
+| attribution | [string](#string) | optional | Text for licenses that require an attribution |
+| custom_text | [string](#string) | optional | Text for custom license type |
+
+
+
+
+
+
+<a name=".MediaType"></a>
+
+### MediaType
+Codec, Container, MIME media-type information
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| codec_name | [string](#string) | optional | Codec corresponding to `name` field from [FFmpeg](https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/codec_desc.c) |
+| container | [string](#string) | optional | Video container format, eg. &#39;MP4&#39;, &#39;WebM&#39;, &#39;Ogg&#39; [ref](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_codecs) |
+| mime_media_type | [string](#string) | optional | MIME Media Type, eg. &#39;video/mp4&#39; [ref](https://www.iana.org/assignments/media-types/media-types.xhtml#video) |
+
+
+
+
+
+
+<a name=".PublishedBeforeJoystream"></a>
+
+### PublishedBeforeJoystream
+Publication status before joystream
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| is_published | [bool](#bool) | optional | Was video published before joystream platform |
+| date | [string](#string) | optional | Date of publication: &#39;YYYY-MM-DD&#39; [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html) |
+
+
+
+
+
+
+<a name=".VideoCategoryMetadata"></a>
+
+### VideoCategoryMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| name | [string](#string) | optional | Category name |
+
+
+
+
+
+
+<a name=".VideoMetadata"></a>
+
+### VideoMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| title | [string](#string) | optional | Video Title |
+| description | [string](#string) | optional | Video Description |
+| video | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
+| thumbnail_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
+| duration | [uint32](#uint32) | optional | Lengths of video in seconds |
+| media_pixel_height | [uint32](#uint32) | optional | Resolution of the video (Height) |
+| media_pixel_width | [uint32](#uint32) | optional | Resolution of the video (Width) |
+| media_type | [MediaType](#MediaType) | optional | Encoding and Container format used |
+| language | [string](#string) | optional | ISO_639-1 Language [Code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) |
+| license | [License](#License) | optional | License type for the media |
+| published_before_joystream | [PublishedBeforeJoystream](#PublishedBeforeJoystream) | optional | Date of publication |
+| has_marketing | [bool](#bool) | optional | Does video have marketing or advertising in the stream |
+| is_public | [bool](#bool) | optional | Should video be publicy visible yet |
+| is_explicit | [bool](#bool) | optional | Does Video have explicit language or scenes |
+| persons | [uint64](#uint64) | repeated | Person(s) referenced by PersonId involved in this video |
+| category | [uint64](#uint64) | optional | Video Category Id |
+
+
+
+
+
+ 
+
+ 
+
+ 
+
+ 
+
+
+
+## Scalar Value Types
+
+| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |
+| ----------- | ----- | --- | ---- | ------ | -- | -- | --- | ---- |
+| <a name="double" /> double |  | double | double | float | float64 | double | float | Float |
+| <a name="float" /> float |  | float | float | float | float32 | float | float | Float |
+| <a name="int32" /> int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
+| <a name="int64" /> int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum |
+| <a name="uint32" /> uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) |
+| <a name="uint64" /> uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) |
+| <a name="sint32" /> sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
+| <a name="sint64" /> sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum |
+| <a name="fixed32" /> fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) |
+| <a name="fixed64" /> fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum |
+| <a name="sfixed32" /> sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
+| <a name="sfixed64" /> sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum |
+| <a name="bool" /> bool |  | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass |
+| <a name="string" /> string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) |
+| <a name="bytes" /> bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) |
+
+<!-- 
+    This extra documentation will be appended to the generated docs.
+-->
+
+## Referencing Assets
+<a name=".Assets"></a>
+
+Applications that process messages that contain a `uint32` field that references an asset such as a cover photo or video, should interpret this value as a zero based index into an array/vector that is received external (out of band) to the protobuf message.
+
+Example in context of query-node processing the runtime event `VideoCreated`
+
+```rust
+// Runtime event associated with creating a Video
+VideoCreated(video_id: VideoId, video: Video, assets: Vec<NewAsset>, params: VideoCreationParameters)
+
+struct VideoCreationParameters {
+  in_category: VideoCategoryId,
+  // binary serialized VideoMetadata protobuf message
+  meta: Vec<u8>,
+}
+
+// suppose assets is a vector of two elements. This is the "out of band" array being referenced by the VideoMetadata message
+assets = [
+    NewAsset::Uri("https://mydomain.net/thumbnail.png"),
+    NewAsset::Upload({
+       content_id,
+       ipfs_hash,
+       size,
+       ...
+    }),
+];
+
+meta = VideoMetadata {
+    ...
+    // refers to second element: assets[1] which is being uploaded to the storage system
+    video: 1,
+    // refers to the first element assets[0] which is being referneced by a url string.
+    thumbnail_photo: 0,
+    ...
+};
+```

+ 13 - 0
content-metadata-protobuf/generate-md-doc.sh

@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+# Directory to write generated documentation to
+OUT_DIR_DOC="./doc"
+mkdir -p ${OUT_DIR_DOC}
+
+# Gernerate Markdown docs
+protoc \
+    --doc_out="${OUT_DIR_DOC}" --doc_opt=markdown,index.md \
+    proto/*.proto
+
+# Append some custom docs to generated protocol docs
+cat doc-appendix.md >> ${OUT_DIR_DOC}/index.md

+ 41 - 0
content-metadata-protobuf/package.json

@@ -0,0 +1,41 @@
+{
+  "name": "@joystream/content-metadata-protobuf",
+  "version": "1.0.0",
+  "description": "Joystream Content Metadata Protobuf Library ",
+  "main": "lib/index.js",
+  "types": "lib/index.d.ts",
+  "repository": "https://github.com/joystream/joystream",
+  "author": "Joystream Contributors",
+  "license": "MIT",
+  "private": false,
+  "scripts": {
+    "build": "./compile.sh && tsc",
+    "compile": "./compile.sh",
+    "generate-doc": "./generate-md-doc.sh",
+    "test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha -r ts-node/register 'test/**/*.ts'",
+    "lint": "eslint ./src --ext .ts",
+    "checks": "tsc --noEmit --pretty && prettier ./ --check && yarn lint",
+    "format": "prettier ./ --write"
+  },
+  "files": [
+    "lib/**/*",
+    "doc/**",
+    "proto/**",
+    "compiled/**/*",
+    "README.md"
+  ],
+  "dependencies": {
+    "google-protobuf": "^3.14.0"
+  },
+  "devDependencies": {
+    "@types/chai": "^4.2.11",
+    "@types/mocha": "^8.2.0",
+    "chai": "^4.2.0",
+    "eslint": "^7.6.0",
+    "mocha": "^8.2.1",
+    "prettier": "2.0.2",
+    "ts-node": "^8.8.1",
+    "ts-protoc-gen": "^0.14.0",
+    "typescript": "^4.1.3"
+  }
+}

+ 28 - 0
content-metadata-protobuf/proto/Channel.proto

@@ -0,0 +1,28 @@
+syntax = "proto2";
+
+message ChannelMetadata {
+    // Channel Title
+    optional string title = 1;
+
+    // Channel Description
+    optional string description = 2;
+
+    // Wether to display channel to the public
+    optional bool is_public = 3;
+
+    // ISO_639-1 Language [Code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)
+    optional string language = 4;
+
+    // index into external [assets array](#.Assets)
+    optional uint32 cover_photo = 5;
+    // index into external [assets array](#.Assets)
+    optional uint32 avatar_photo  = 6;
+
+    // Channel Category Id
+    optional uint64 category = 7;
+}
+
+message ChannelCategoryMetadata {
+    // Category Name
+    optional string name = 1;
+}

+ 13 - 0
content-metadata-protobuf/proto/Person.proto

@@ -0,0 +1,13 @@
+syntax = "proto2";
+
+message PersonMetadata {
+    optional string first_name = 1;
+    optional string middle_name = 2;
+    optional string last_name = 3;
+    optional string about = 4;
+    
+    // index into external [assets array](#.Assets)
+    optional uint32 cover_photo = 5;
+    // index into external [assets array](#.Assets)
+    optional uint32 avatar_photo = 6;
+}

+ 7 - 0
content-metadata-protobuf/proto/Playlist.proto

@@ -0,0 +1,7 @@
+syntax = "proto2";
+
+message PlaylistMetadata {
+    optional string title = 1;
+    // Videos in the playlist
+    repeated uint64 videos = 2;
+}

+ 19 - 0
content-metadata-protobuf/proto/Series.proto

@@ -0,0 +1,19 @@
+syntax = "proto2";
+
+message SeriesMetadata {
+    optional string title = 1;
+    optional string description = 2;
+    // index into external [assets array](#.Assets)
+    optional uint32 cover_photo = 3;
+    // Person(s) referenced by PersonId involved in this Series
+    repeated uint64 persons = 4 [packed=true];
+}
+
+message SeasonMetadata {
+    optional string title = 1;
+    optional string description = 2; 
+    // index into external [assets array](#.Assets)
+    optional uint32 cover_photo = 3;
+    // Person(s) referenced by PersonId involved in this Season
+    repeated uint64 persons = 4 [packed=true];
+}

+ 88 - 0
content-metadata-protobuf/proto/Video.proto

@@ -0,0 +1,88 @@
+syntax = "proto2";
+
+// Publication status before joystream
+message PublishedBeforeJoystream {
+    // Was video published before joystream platform
+    optional bool is_published = 1;
+    // Date of publication: 'YYYY-MM-DD' [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html)
+    optional string date = 2;
+}
+
+// License types defined by Joystream
+message License {
+    // License code defined by Joystream. [reference](../src/KnownLicenses.json)
+    optional uint32 code = 1;
+    // Text for licenses that require an attribution
+    optional string attribution = 2;
+    // Text for custom license type
+    optional string custom_text = 3;
+}
+
+// Codec, Container, MIME media-type information
+message MediaType {
+    // Codec corresponding to `name` field from [FFmpeg](https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/codec_desc.c)
+    optional string codec_name = 1;
+
+    // Video container format, eg. 'MP4', 'WebM', 'Ogg' [ref](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_codecs)
+    optional string container = 2;
+
+    // MIME Media Type, eg. 'video/mp4' [ref](https://www.iana.org/assignments/media-types/media-types.xhtml#video)
+    optional string mime_media_type = 3;
+}
+
+message VideoMetadata {
+    // Video Title
+    optional string title = 1;
+
+    // Video Description
+    optional string description = 2;
+
+    // Assets
+    
+    // index into external [assets array](#.Assets)
+    optional uint32 video = 3;
+
+    // index into external [assets array](#.Assets)
+    optional uint32 thumbnail_photo = 4;
+
+    // Lengths of video in seconds
+    optional uint32 duration = 5;
+
+    // Resolution of the video (Height)
+    optional uint32 media_pixel_height = 6;
+    
+    // Resolution of the video (Width)
+    optional uint32 media_pixel_width = 7;
+
+    // Encoding and Container format used
+    optional MediaType media_type = 8;
+
+    // ISO_639-1 Language [Code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)
+    optional string language = 9;
+
+    // License type for the media
+    optional License license = 10;
+
+    // Date of publication
+    optional PublishedBeforeJoystream published_before_joystream = 11;
+
+    // Does video have marketing or advertising in the stream
+    optional bool has_marketing = 12;
+
+    // Should video be publicy visible yet
+    optional bool is_public = 13;
+
+    // Does Video have explicit language or scenes
+    optional bool is_explicit = 14;
+
+    // Person(s) referenced by PersonId involved in this video
+    repeated uint64 persons = 15 [packed=true];
+
+    // Video Category Id
+    optional uint64 category = 16;
+}
+
+message VideoCategoryMetadata {
+    // Category name
+    optional string name = 1;
+}

+ 74 - 0
content-metadata-protobuf/src/KnownLicenses.json

@@ -0,0 +1,74 @@
+[
+  {
+    "code": 1000,
+    "name": "CUSTOM",
+    "longName": "Custom License",
+    "description": "A user defined License",
+    "url": "",
+    "attributionRequired": false
+  },
+  {
+    "code": 1001,
+    "name": "PDM",
+    "longName": "Public Domain",
+    "description": "For items which are not protected by copyright. This is not a license, but rather a copyright status. Some government-produced works, items with expired copyrights, and those which are ineligible for copyright protection may be included in this category.",
+    "url": "https://creativecommons.org/share-your-work/public-domain/pdm",
+    "attributionRequired": false
+  },
+  {
+    "code": 1002,
+    "name": "CC0",
+    "longName": "Public Domain Dedication",
+    "description": "The CC0 (Public Domain Dedication) License allows creators to waive all rights to their creations and release them into the Public Domain.",
+    "url": "https://creativecommons.org/share-your-work/public-domain/cc0",
+    "attributionRequired": true
+  },
+  {
+    "code": 1003,
+    "name": "CC_BY",
+    "longName": "Creative Commons Attribution License",
+    "description": "Sharing and adapting this content is permitted, but attribution must be provided. Read the License Deed for more information.",
+    "url": "https://creativecommons.org/licenses/by/4.0",
+    "attributionRequired": true
+  },
+  {
+    "code": 1004,
+    "name": "CC_BY_SA",
+    "longName": "Creative Commons Attribution-ShareAlike License",
+    "description": "Sharing and adapting this content is permitted, but attribution must be provided. Any derivative works must be distributed under the same license. Read the License Deed for more information.",
+    "url": "https://creativecommons.org/licenses/by-sa/4.0",
+    "attributionRequired": true
+  },
+  {
+    "code": 1005,
+    "name": "CC_BY_ND",
+    "longName": "Creative Commons Attribution-NoDerivs License",
+    "description": "Sharing this content is permitted, but attribution must be provided. You may not remix, transform, or build upon the material. Read the License Deed for more information.",
+    "url": "https://creativecommons.org/licenses/by-nd/4.0",
+    "attributionRequired": true
+  },
+  {
+    "code": 1006,
+    "name": "CC_BY_NC",
+    "longName": "Creative Commons Attribution-NonCommercial License",
+    "description": "Sharing and adapting this content is permitted, but attribution must be provided. Commercial use is not permitted. Read the License Deed for more information.",
+    "url": "https://creativecommons.org/licenses/by-nc/4.0",
+    "attributionRequired": true
+  },
+  {
+    "code": 1007,
+    "name": "CC_BY_NC_SA",
+    "longName": "Creative Commons Attribution-NonCommercial-ShareAlike License",
+    "description": "Sharing and adapting this content is permitted, but attribution must be provided. Any derivative works must be distributed under the same license. Commercial use is not permitted. Read the License Deed for more information.",
+    "url": "https://creativecommons.org/licenses/by-nc-sa/4.0",
+    "attributionRequired": true
+  },
+  {
+    "code": 1008,
+    "name": "CC_BY_NC_ND",
+    "longName": "Creative Commons Attribution-NonCommercial-NoDerivs License",
+    "description": "Sharing this content is permitted, but attribution must be provided. You may not remix, transform, or build upon the material. Commercial use is not permitted. Read the License Deed for more information.",
+    "url": "https://creativecommons.org/licenses/by-nc-nd/4.0",
+    "attributionRequired": true
+  }
+]

+ 10 - 0
content-metadata-protobuf/src/index.ts

@@ -0,0 +1,10 @@
+// Some helpers for constructing known licences
+import licences from './licenses'
+export { licences }
+
+// protobuf message constructors
+export * from '../compiled/proto/Video_pb'
+export * from '../compiled/proto/Channel_pb'
+export * from '../compiled/proto/Person_pb'
+export * from '../compiled/proto/Playlist_pb'
+export * from '../compiled/proto/Series_pb'

+ 70 - 0
content-metadata-protobuf/src/licenses.ts

@@ -0,0 +1,70 @@
+// Helper methods to handle joystream defined licence types
+// This should be factored out into a separate package
+
+import LICENSES from './KnownLicenses.json'
+import { License } from '../compiled/proto/Video_pb'
+
+export type LicenseCode = number
+export const CUSTOM_LICENSE_CODE: LicenseCode = 1000
+
+type KnownLicense = {
+  code: LicenseCode
+  name: string
+  longName: string
+  description: string
+  url: string
+  attributionRequired: boolean
+}
+
+export const KnownLicenses = new Map<LicenseCode, KnownLicense>()
+
+LICENSES.forEach((license: KnownLicense) => {
+  KnownLicenses.set(license.code, license)
+})
+
+export function getLicenseCodeByName(name: string): LicenseCode | undefined {
+  for (const [code, license] of KnownLicenses) {
+    if (license.name === name) return code
+  }
+}
+
+export function createKnownLicenseFromCode(code: LicenseCode, attribution?: string): License {
+  if (code === CUSTOM_LICENSE_CODE) {
+    throw new Error('Use createCustomLicense() instead')
+  }
+
+  const knownLicense = KnownLicenses.get(code)
+
+  if (!knownLicense) {
+    throw new Error('Unknown License Code')
+  }
+
+  const license = new License()
+
+  license.setCode(code)
+
+  if (knownLicense.attributionRequired) {
+    if (attribution === undefined) {
+      throw new Error('Attribution required for selected license')
+    }
+    license.setAttribution(attribution)
+  }
+
+  return license
+}
+
+export function createCustomKnownLicense(customText: string): License {
+  const license = new License()
+
+  license.setCode(CUSTOM_LICENSE_CODE)
+  license.setCustomText(customText)
+  return license
+}
+
+export default {
+  CUSTOM_LICENSE_CODE,
+  KnownLicenses,
+  createCustomKnownLicense,
+  createKnownLicenseFromCode,
+  getLicenseCodeByName,
+}

+ 33 - 0
content-metadata-protobuf/test/channel.ts

@@ -0,0 +1,33 @@
+import { ChannelMetadata } from '../src'
+import { assert } from 'chai'
+
+describe('Channel Metadata', () => {
+  it('Message', () => {
+    const channel = new ChannelMetadata()
+
+    const title = 'title'
+    const description = 'description'
+    const isPublic = false
+    const language = 'fr'
+
+    channel.setTitle(title)
+    channel.setDescription(description)
+    channel.setIsPublic(isPublic)
+    channel.setLanguage(language)
+    channel.setAvatarPhoto(0)
+    channel.setCoverPhoto(1)
+    channel.setCategory(100)
+
+    assert.deepEqual(channel.toObject(), {
+      title,
+      description,
+      isPublic,
+      language,
+      avatarPhoto: 0,
+      coverPhoto: 1,
+      category: 100,
+    })
+
+    assert.deepEqual(ChannelMetadata.deserializeBinary(channel.serializeBinary()), channel)
+  })
+})

+ 42 - 0
content-metadata-protobuf/test/license-codes.ts

@@ -0,0 +1,42 @@
+import {
+  KnownLicenses,
+  CUSTOM_LICENSE_CODE,
+  getLicenseCodeByName,
+  createKnownLicenseFromCode,
+  createCustomKnownLicense,
+} from '../src/licenses'
+import { VideoMetadata } from '../src/index'
+import { assert } from 'chai'
+
+describe('Known License Codes', () => {
+  it('Excludes default value 0', () => {
+    assert(!KnownLicenses.has(0))
+  })
+
+  it('Pre-defined Joystream license codes', () => {
+    // Make sure we have correct known custom licence
+    assert(KnownLicenses.has(CUSTOM_LICENSE_CODE))
+    assert.equal(KnownLicenses.get(CUSTOM_LICENSE_CODE)!.name, 'CUSTOM')
+
+    assert(KnownLicenses.has(1001))
+    assert(KnownLicenses.has(1002))
+    assert(KnownLicenses.has(1003))
+    assert(KnownLicenses.has(1004))
+    assert(KnownLicenses.has(1005))
+    assert(KnownLicenses.has(1006))
+    assert(KnownLicenses.has(1007))
+    assert(KnownLicenses.has(1008))
+  })
+
+  it('createCustomKnownLicense(): uses correct code', () => {
+    const license = createCustomKnownLicense('custom text')
+    assert.equal(license.getCode(), CUSTOM_LICENSE_CODE)
+  })
+
+  it('createKnownLicenseFromCode(): Licence can be created by name', () => {
+    const licenseCode = getLicenseCodeByName('CC_BY') as number
+    const license = createKnownLicenseFromCode(licenseCode as number, 'Attribution: Joystream')
+    const videoMeta = new VideoMetadata()
+    videoMeta.setLicense(license)
+  })
+})

+ 115 - 0
content-metadata-protobuf/test/video.ts

@@ -0,0 +1,115 @@
+import { VideoMetadata, PublishedBeforeJoystream, MediaType, License } from '../src'
+import { assert, expect } from 'chai'
+
+describe('Video Metadata', () => {
+  it('Message', () => {
+    const meta = new VideoMetadata()
+
+    const title = 'Video Title'
+    const description = 'Video Description'
+    const duration = 100
+
+    meta.setTitle(title)
+    meta.setDescription(description)
+    meta.setDuration(duration)
+    meta.setMediaPixelHeight(1)
+    meta.setMediaPixelWidth(2)
+    meta.setMediaType(new MediaType())
+    meta.setLanguage('en')
+    meta.setLicense(new License())
+    meta.setPublishedBeforeJoystream(new PublishedBeforeJoystream())
+    meta.setHasMarketing(true)
+    meta.setIsPublic(true)
+    meta.setIsExplicit(false)
+    meta.setVideo(0)
+    meta.setThumbnailPhoto(1)
+    meta.setCategory(101)
+
+    assert.deepEqual(meta.toObject(), {
+      title,
+      description,
+      duration,
+      mediaPixelHeight: 1,
+      mediaPixelWidth: 2,
+      mediaType: {
+        codecName: undefined,
+        container: undefined,
+        mimeMediaType: undefined,
+      },
+      language: 'en',
+      license: {
+        code: undefined,
+        attribution: undefined,
+        customText: undefined,
+      },
+      publishedBeforeJoystream: { isPublished: undefined, date: undefined },
+      hasMarketing: true,
+      isPublic: true,
+      isExplicit: false,
+      thumbnailPhoto: 1,
+      video: 0,
+      personsList: [],
+      category: 101,
+    })
+
+    // sanity check - encoding / decoding works
+    assert.deepEqual(VideoMetadata.deserializeBinary(meta.serializeBinary()), meta)
+  })
+
+  it('Message: PublishedBeforeJoystream', () => {
+    const meta = new VideoMetadata()
+
+    expect(meta.hasPublishedBeforeJoystream()).equals(false, 'PublishedBeforeJoystream field should NOT be set')
+
+    const published = new PublishedBeforeJoystream()
+    const isPublished = true
+    const date = '1950-12-24'
+    published.setIsPublished(isPublished)
+    published.setDate(date)
+
+    meta.setPublishedBeforeJoystream(published)
+
+    // Field should now be set
+    expect(meta.hasPublishedBeforeJoystream()).equals(true, 'PublishedBeforeJoystream field should be set')
+
+    assert.deepEqual(published.toObject(), {
+      isPublished,
+      date,
+    })
+  })
+
+  it('Message: Licence', () => {
+    const license = new License()
+
+    const code = 1000
+    const attribution = 'Attribution Text'
+    const customText = 'Custom License Details'
+    license.setCode(code)
+    license.setAttribution(attribution)
+    license.setCustomText(customText)
+
+    assert.deepEqual(license.toObject(), {
+      code,
+      attribution,
+      customText,
+    })
+  })
+
+  it('Message: MediaType', () => {
+    const mediaType = new MediaType()
+
+    const codecName = 'mpeg4'
+    const container = 'avi'
+    const mimeMediaType = 'videp/mp4'
+
+    mediaType.setCodecName(codecName)
+    mediaType.setContainer(container)
+    mediaType.setMimeMediaType(mimeMediaType)
+
+    assert.deepEqual(mediaType.toObject(), {
+      codecName,
+      container,
+      mimeMediaType,
+    })
+  })
+})

+ 15 - 0
content-metadata-protobuf/tsconfig.json

@@ -0,0 +1,15 @@
+{
+  "compilerOptions": {
+    "target": "esnext",
+    "module": "commonjs",
+    "outDir": "lib",
+    "strict": true,
+    "declaration": true,
+    "esModuleInterop": true,
+    "forceConsistentCasingInFileNames": true,
+    "skipLibCheck": true,
+    "resolveJsonModule": true,
+  },
+  "include": ["src"],
+  "exclude": ["node_modules", "test"]
+}

+ 77 - 13
node/src/chain_spec/content_config.rs

@@ -1,5 +1,9 @@
 use codec::Decode;
-use node_runtime::{data_directory::DataObject, ContentId, DataDirectoryConfig, Runtime};
+use node_runtime::{
+    common::storage::StorageObjectOwner,
+    data_directory::{DataObject, Quota},
+    ChannelId, ContentId, DAOId, DataDirectoryConfig, MemberId, Runtime,
+};
 use serde::Deserialize;
 use std::{fs, path::Path};
 
@@ -8,43 +12,68 @@ use std::{fs, path::Path};
 // them to json we get a string rather than an array of bytes, so deserializing them
 // is failing. So we are relying on parity codec encoding instead..
 #[derive(Decode)]
-struct DataObjectAndContentId {
+struct Content {
     content_id: ContentId,
     data_object: DataObject<Runtime>,
+    storage_object_owner: StorageObjectOwner<MemberId, ChannelId, DAOId>,
+    quota: Quota,
 }
 
 #[derive(Decode)]
 struct ContentData {
     /// DataObject(s) and ContentId
-    data_objects: Vec<DataObjectAndContentId>,
+    data_objects: Vec<Content>,
+    quota_size_limit_upper_bound: u64,
+    quota_objects_limit_upper_bound: u64,
+    global_quota: Quota,
+    uploading_blocked: bool,
 }
 
 #[derive(Deserialize)]
-struct EncodedDataObjectAndContentId {
+struct EncodedContent {
     /// hex encoded ContentId
     content_id: String,
     /// hex encoded DataObject<Runtime>
     data_object: String,
+    /// hex encoded StorageObjectOwner
+    storage_object_owner: String,
+    /// hex encoded Quota
+    quota: String,
 }
 
-impl EncodedDataObjectAndContentId {
-    fn decode(&self) -> DataObjectAndContentId {
+impl EncodedContent {
+    fn decode(&self) -> Content {
         // hex string must not include '0x' prefix!
         let encoded_content_id = hex::decode(&self.content_id[2..].as_bytes())
             .expect("failed to parse content_id hex string");
         let encoded_data_object = hex::decode(&self.data_object[2..].as_bytes())
             .expect("failed to parse data_object hex string");
-        DataObjectAndContentId {
+        let encoded_storage_object_owner = hex::decode(&self.storage_object_owner[2..].as_bytes())
+            .expect("failed to parse content_id hex string");
+        let encoded_quota = hex::decode(&self.quota[2..].as_bytes())
+            .expect("failed to parse data_object hex string");
+        Content {
             content_id: Decode::decode(&mut encoded_content_id.as_slice()).unwrap(),
             data_object: Decode::decode(&mut encoded_data_object.as_slice()).unwrap(),
+            storage_object_owner: Decode::decode(&mut encoded_storage_object_owner.as_slice())
+                .unwrap(),
+            quota: Decode::decode(&mut encoded_quota.as_slice()).unwrap(),
         }
     }
 }
 
 #[derive(Deserialize)]
 struct EncodedContentData {
-    /// DataObject(s) and ContentId
-    data_objects: Vec<EncodedDataObjectAndContentId>,
+    /// EncodedContent
+    data_objects: Vec<EncodedContent>,
+    /// hex encoded QuotaSizeLimitUpperBound
+    quota_size_limit_upper_bound: String,
+    /// hex encoded QuotaObjectsLimitUpperBound
+    quota_objects_limit_upper_bound: String,
+    /// hex encoded GlobalQuota
+    global_quota: String,
+    /// hex encoded UploadingBlocked flag
+    uploading_blocked: String,
 }
 
 fn parse_content_data(data_file: &Path) -> EncodedContentData {
@@ -60,6 +89,33 @@ impl EncodedContentData {
                 .iter()
                 .map(|data_objects| data_objects.decode())
                 .collect(),
+            quota_size_limit_upper_bound: {
+                let encoded_quota_size_limit_upper_bound =
+                    hex::decode(&self.quota_size_limit_upper_bound[2..].as_bytes())
+                        .expect("failed to parse data_object hex string");
+
+                Decode::decode(&mut encoded_quota_size_limit_upper_bound.as_slice()).unwrap()
+            },
+            quota_objects_limit_upper_bound: {
+                let encoded_quota_objects_limit_upper_bound =
+                    hex::decode(&self.quota_objects_limit_upper_bound[2..].as_bytes())
+                        .expect("failed to parse data_object hex string");
+
+                Decode::decode(&mut encoded_quota_objects_limit_upper_bound.as_slice()).unwrap()
+            },
+            global_quota: {
+                let encoded_global_quota = hex::decode(&self.global_quota[2..].as_bytes())
+                    .expect("failed to parse data_object hex string");
+
+                Decode::decode(&mut encoded_global_quota.as_slice()).unwrap()
+            },
+            uploading_blocked: {
+                let encoded_uploading_blocked =
+                    hex::decode(&self.uploading_blocked[2..].as_bytes())
+                        .expect("failed to parse data_object hex string");
+
+                Decode::decode(&mut encoded_uploading_blocked.as_slice()).unwrap()
+            },
         }
     }
 }
@@ -68,7 +124,11 @@ impl EncodedContentData {
 pub fn empty_data_directory_config() -> DataDirectoryConfig {
     DataDirectoryConfig {
         data_object_by_content_id: vec![],
-        known_content_ids: vec![],
+        quotas: vec![],
+        quota_size_limit_upper_bound: 20000,
+        quota_objects_limit_upper_bound: 200,
+        global_quota: Quota::new(2000000, 2000),
+        uploading_blocked: false,
     }
 }
 
@@ -84,10 +144,14 @@ pub fn data_directory_config_from_json(data_file: &Path) -> DataDirectoryConfig
             .iter()
             .map(|object| (object.content_id, object.data_object.clone()))
             .collect(),
-        known_content_ids: content
+        quotas: content
             .data_objects
-            .into_iter()
-            .map(|object| object.content_id)
+            .iter()
+            .map(|object| (object.storage_object_owner.clone(), object.quota))
             .collect(),
+        quota_size_limit_upper_bound: content.quota_size_limit_upper_bound,
+        quota_objects_limit_upper_bound: content.quota_objects_limit_upper_bound,
+        global_quota: content.global_quota,
+        uploading_blocked: content.uploading_blocked,
     }
 }

+ 29 - 12
node/src/chain_spec/mod.rs

@@ -30,12 +30,12 @@ use sp_runtime::Perbill;
 
 use node_runtime::{
     membership, AuthorityDiscoveryConfig, BabeConfig, Balance, BalancesConfig,
-    ContentDirectoryConfig, ContentDirectoryWorkingGroupConfig, CouncilConfig,
+    BuilderWorkingGroupConfig, ContentConfig, ContentDirectoryWorkingGroupConfig, CouncilConfig,
     CouncilElectionConfig, DataDirectoryConfig, DataObjectStorageRegistryConfig,
-    DataObjectTypeRegistryConfig, ElectionParameters, ForumConfig, GrandpaConfig, ImOnlineConfig,
-    MembersConfig, Moment, ProposalsCodexConfig, SessionConfig, SessionKeys, Signature,
-    StakerStatus, StakingConfig, StorageWorkingGroupConfig, SudoConfig, SystemConfig, DAYS,
-    WASM_BINARY,
+    DataObjectTypeRegistryConfig, ElectionParameters, ForumConfig, GatewayWorkingGroupConfig,
+    GrandpaConfig, ImOnlineConfig, MembersConfig, Moment, ProposalsCodexConfig, SessionConfig,
+    SessionKeys, Signature, StakerStatus, StakingConfig, StorageWorkingGroupConfig, SudoConfig,
+    SystemConfig, DAYS, WASM_BINARY,
 };
 
 // Exported to be used by chain-spec-builder
@@ -319,14 +319,31 @@ pub fn testnet_genesis(
             worker_application_human_readable_text_constraint: default_text_constraint,
             worker_exit_rationale_text_constraint: default_text_constraint,
         }),
-        content_directory: Some({
-            ContentDirectoryConfig {
-                class_by_id: vec![],
-                entity_by_id: vec![],
-                curator_group_by_id: vec![],
-                next_class_id: 1,
-                next_entity_id: 1,
+        working_group_Instance4: Some(BuilderWorkingGroupConfig {
+            phantom: Default::default(),
+            working_group_mint_capacity: 0,
+            opening_human_readable_text_constraint: default_text_constraint,
+            worker_application_human_readable_text_constraint: default_text_constraint,
+            worker_exit_rationale_text_constraint: default_text_constraint,
+        }),
+        working_group_Instance5: Some(GatewayWorkingGroupConfig {
+            phantom: Default::default(),
+            working_group_mint_capacity: 0,
+            opening_human_readable_text_constraint: default_text_constraint,
+            worker_application_human_readable_text_constraint: default_text_constraint,
+            worker_exit_rationale_text_constraint: default_text_constraint,
+        }),
+        content: Some({
+            ContentConfig {
                 next_curator_group_id: 1,
+                next_channel_category_id: 1,
+                next_channel_id: 1,
+                next_video_category_id: 1,
+                next_video_id: 1,
+                next_playlist_id: 1,
+                next_series_id: 1,
+                next_person_id: 1,
+                next_channel_transfer_request_id: 1,
             }
         }),
         proposals_codex: Some(ProposalsCodexConfig {

+ 3 - 2
package.json

@@ -4,7 +4,7 @@
   "version": "1.0.0",
   "license": "GPL-3.0-only",
   "scripts": {
-    "postinstall": "yarn workspace @joystream/types build && yarn workspace @joystream/cd-schemas generate:all && yarn workspace @joystream/cd-schemas build && yarn workspace @joystream/cli build",
+    "postinstall": "yarn workspace @joystream/types build",
     "build": "./build.sh",
     "start": "./start.sh",
     "cargo-checks": "devops/git-hooks/pre-commit && devops/git-hooks/pre-push",
@@ -23,7 +23,8 @@
     "utils/api-scripts",
     "content-directory-schemas",
     "query-node",
-    "query-node/generated/*"
+    "query-node/generated/*",
+    "content-metadata-protobuf"
   ],
   "resolutions": {
     "@polkadot/api": "1.26.1",

+ 4 - 0
runtime-modules/common/Cargo.toml

@@ -13,6 +13,8 @@ sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://
 frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
 system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
 pallet-timestamp = { package = 'pallet-timestamp', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-arithmetic = { package = 'sp-arithmetic', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
+sp-std = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
 
 [features]
 default = ['std']
@@ -22,6 +24,8 @@ std = [
 	'strum_macros',
 	'codec/std',
 	'sp-runtime/std',
+	'sp-arithmetic/std',
+	'sp-std/std',
 	'frame-support/std',
 	'system/std',
 	'pallet-timestamp/std',

+ 80 - 1
runtime-modules/common/src/lib.rs

@@ -4,12 +4,91 @@
 pub mod constraints;
 pub mod currency;
 pub mod origin;
+pub mod storage;
 pub mod working_group;
 
-use codec::{Decode, Encode};
+use codec::{Codec, Decode, Encode};
 #[cfg(feature = "std")]
 use serde::{Deserialize, Serialize};
 
+use frame_support::Parameter;
+use sp_arithmetic::traits::BaseArithmetic;
+use sp_runtime::traits::{MaybeSerialize, Member};
+use sp_std::vec::Vec;
+
+/// Member id type alias
+pub type MemberId<T> = <T as MembershipTypes>::MemberId;
+
+/// Actor id type alias
+pub type ActorId<T> = <T as MembershipTypes>::ActorId;
+
+/// HTTP Url string
+pub type Url = Vec<u8>;
+
+/// Generic trait for membership dependent pallets.
+pub trait MembershipTypes: system::Trait {
+    /// Describes the common type for the members.
+    type MemberId: Parameter
+        + Member
+        + BaseArithmetic
+        + Codec
+        + Default
+        + Copy
+        + MaybeSerialize
+        + Ord
+        + PartialEq;
+
+    /// Describes the common type for the working group members (workers).
+    type ActorId: Parameter
+        + Member
+        + BaseArithmetic
+        + Codec
+        + Default
+        + Copy
+        + MaybeSerialize
+        + Ord
+        + PartialEq;
+}
+
+/// Generic trait for strorage ownership dependent pallets.
+pub trait StorageOwnership {
+    /// Channel id representation.
+    type ChannelId: Parameter
+        + Member
+        + BaseArithmetic
+        + Codec
+        + Default
+        + Copy
+        + MaybeSerialize
+        + Ord
+        + PartialEq;
+
+    /// DAO id representation.
+    type DAOId: Parameter
+        + Member
+        + BaseArithmetic
+        + Codec
+        + Default
+        + Copy
+        + MaybeSerialize
+        + Ord
+        + PartialEq;
+
+    /// Content id representation.
+    type ContentId: Parameter + Member + Codec + Default + Copy + MaybeSerialize + Ord + PartialEq;
+
+    /// Data object type id.
+    type DataObjectTypeId: Parameter
+        + Member
+        + BaseArithmetic
+        + Codec
+        + Default
+        + Copy
+        + MaybeSerialize
+        + Ord
+        + PartialEq;
+}
+
 /// Defines time in both block number and substrate time abstraction.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Clone, Encode, Decode, PartialEq, Eq, Debug, Default)]

+ 59 - 0
runtime-modules/common/src/storage.rs

@@ -0,0 +1,59 @@
+use crate::working_group::WorkingGroup;
+use codec::{Decode, Encode};
+#[cfg(feature = "std")]
+use serde::{Deserialize, Serialize};
+use sp_runtime::DispatchResult;
+use sp_std::vec::Vec;
+
+#[derive(Clone, Encode, Decode, PartialEq, Eq, Debug)]
+pub struct ContentParameters<ContentId, DataObjectTypeId> {
+    pub content_id: ContentId,
+    pub type_id: DataObjectTypeId,
+    pub size: u64,
+    pub ipfs_content_id: Vec<u8>,
+}
+
+// New owner type for storage object struct
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Clone, Encode, Decode, PartialEq, Eq, Debug)]
+pub enum StorageObjectOwner<MemberId, ChannelId, DAOId> {
+    Member(MemberId),
+    Channel(ChannelId), // acts through content directory module, where again DAOs can own channels for example
+    DAO(DAOId),         // acts through upcoming `content_finance` module
+    Council,            // acts through proposal system
+    WorkingGroup(WorkingGroup), // acts through new extrinsic in working group
+}
+
+// To be implemented by current storage data_directory runtime module.
+// Defined in 'common' package
+pub trait StorageSystem<T: crate::StorageOwnership + crate::MembershipTypes> {
+    // Should hook into call on storage system,
+    // but requires rich error (with reasons)  types.
+    // caller already knows the `ContentId`s as they are part of
+    // the ContentUploadParameters
+    fn atomically_add_content(
+        owner: StorageObjectOwner<T::MemberId, T::ChannelId, T::DAOId>,
+        content_parameters: Vec<ContentParameters<T::ContentId, T::DataObjectTypeId>>,
+    ) -> DispatchResult;
+
+    // Checks if given owner can add provided content to the storage system
+    fn can_add_content(
+        owner: StorageObjectOwner<T::MemberId, T::ChannelId, T::DAOId>,
+        content_parameters: Vec<ContentParameters<T::ContentId, T::DataObjectTypeId>>,
+    ) -> DispatchResult;
+
+    // Should hook into call on storage system,
+    // but requires rich error (with reasons)  types.
+    // caller already knows the `ContentId`s as they are part of
+    // the ContentUploadParameters
+    fn atomically_remove_content(
+        owner: &StorageObjectOwner<T::MemberId, T::ChannelId, T::DAOId>,
+        content_ids: &[T::ContentId],
+    ) -> DispatchResult;
+
+    // Checks if given owner can remove content under givencontent ids from the storage system
+    fn can_remove_content(
+        owner: &StorageObjectOwner<T::MemberId, T::ChannelId, T::DAOId>,
+        content_ids: &[T::ContentId],
+    ) -> DispatchResult;
+}

+ 5 - 1
runtime-modules/common/src/working_group.rs

@@ -6,7 +6,7 @@ use strum_macros::EnumIter;
 
 /// Defines well-known working groups.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize, EnumIter))]
-#[derive(Encode, Decode, Clone, PartialEq, Eq, Copy, Debug)]
+#[derive(Clone, Copy, Encode, Decode, PartialEq, Eq, Debug)]
 pub enum WorkingGroup {
     /* Reserved
         /// Forum working group: working_group::Instance1.
@@ -16,4 +16,8 @@ pub enum WorkingGroup {
     Storage,
     /// Storage working group: working_group::Instance3.
     Content,
+    /// Builder working group: working_group::Instance4.
+    Builder,
+    /// Gateway working group: working_group::Instance5.
+    Gateway,
 }

+ 0 - 30
runtime-modules/content-directory/Cargo.toml

@@ -1,30 +0,0 @@
-[package]
-name = 'pallet-content-directory'
-version = '3.0.0'
-authors = ['Joystream contributors']
-edition = '2018'
-
-[dependencies]
-sp-std = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
-sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
-frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
-system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
-sp-arithmetic = { package = 'sp-arithmetic', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
-codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
-serde = {version = '1.0.101', features = ['derive'], optional = true}
-
-[dev-dependencies]
-sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
-sp-core = { package = 'sp-core', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
-
-[features]
-default = ['std']
-std = [
-	'sp-std/std',
-	'sp-runtime/std',
-	'frame-support/std',
-	'system/std',
-	'sp-arithmetic/std',
-	'codec/std',
-	'serde',
-]

+ 0 - 243
runtime-modules/content-directory/src/class.rs

@@ -1,243 +0,0 @@
-use super::*;
-
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
-#[derive(Encode, Decode, Eq, PartialEq, Default, Clone)]
-pub struct Class<
-    EntityId: Default + BaseArithmetic + Clone + Copy,
-    ClassId: Default + BaseArithmetic + Clone + Copy,
-    CuratorGroupId: Ord + Default,
-> {
-    /// Permissions for an instance of a Class.
-    class_permissions: ClassPermissions<CuratorGroupId>,
-    /// All properties that have been used on this class across different class schemas.
-    /// Unlikely to be more than roughly 20 properties per class, often less.
-    /// For Person, think "height", "weight", etc.
-    properties: Vec<Property<ClassId>>,
-
-    /// All schemas that are available for this class, think v0.0 Person, v.1.0 Person, etc.
-    schemas: Vec<Schema>,
-
-    name: Vec<u8>,
-
-    description: Vec<u8>,
-
-    /// The maximum number of entities which can be created.
-    maximum_entities_count: EntityId,
-
-    /// The current number of entities which exist.
-    current_number_of_entities: EntityId,
-
-    /// How many entities a given controller may create at most.
-    default_entity_creation_voucher_upper_bound: EntityId,
-}
-
-impl<
-        EntityId: Default + BaseArithmetic + Clone + Copy,
-        ClassId: Default + BaseArithmetic + Clone + Copy,
-        CuratorGroupId: Ord + Default,
-    > Class<EntityId, ClassId, CuratorGroupId>
-{
-    /// Create new `Class` with provided parameters
-    pub fn new(
-        class_permissions: ClassPermissions<CuratorGroupId>,
-        name: Vec<u8>,
-        description: Vec<u8>,
-        maximum_entities_count: EntityId,
-        default_entity_creation_voucher_upper_bound: EntityId,
-    ) -> Self {
-        Self {
-            class_permissions,
-            properties: vec![],
-            schemas: vec![],
-            name,
-            description,
-            maximum_entities_count,
-            current_number_of_entities: EntityId::zero(),
-            default_entity_creation_voucher_upper_bound,
-        }
-    }
-
-    pub fn get_name(&self) -> &[u8] {
-        &self.name
-    }
-
-    pub fn get_description(&self) -> &[u8] {
-        &self.description
-    }
-
-    pub fn set_name(&mut self, name: Vec<u8>) {
-        self.name = name;
-    }
-
-    pub fn set_description(&mut self, description: Vec<u8>) {
-        self.description = description;
-    }
-
-    /// Used to update `Schema` status under given `schema_index`
-    pub fn update_schema_status(&mut self, schema_index: SchemaId, schema_status: bool) {
-        if let Some(schema) = self.schemas.get_mut(schema_index as usize) {
-            schema.set_status(schema_status);
-        };
-    }
-
-    /// Used to update `Class` permissions
-    pub fn update_permissions(&mut self, permissions: ClassPermissions<CuratorGroupId>) {
-        self.class_permissions = permissions
-    }
-
-    /// Get Class schemas by mutable reference
-    pub fn get_schemas_mut(&mut self) -> &mut Vec<Schema> {
-        &mut self.schemas
-    }
-
-    /// Get Class schemas by reference
-    pub fn get_schemas(&self) -> &Vec<Schema> {
-        &self.schemas
-    }
-
-    /// Increment number of entities, associated with this class
-    pub fn increment_entities_count(&mut self) {
-        self.current_number_of_entities += EntityId::one();
-    }
-
-    /// Decrement number of entities, associated with this class
-    pub fn decrement_entities_count(&mut self) {
-        self.current_number_of_entities -= EntityId::one();
-    }
-
-    /// Retrieve `ClassPermissions` by mutable reference
-    pub fn get_permissions_mut(&mut self) -> &mut ClassPermissions<CuratorGroupId> {
-        &mut self.class_permissions
-    }
-
-    /// Retrieve `ClassPermissions` by reference
-    pub fn get_permissions_ref(&self) -> &ClassPermissions<CuratorGroupId> {
-        &self.class_permissions
-    }
-
-    /// Retrieve `ClassPermissions` by value
-    pub fn get_permissions(self) -> ClassPermissions<CuratorGroupId> {
-        self.class_permissions
-    }
-
-    /// Retrieve `Class` properties by value  
-    pub fn get_properties(self) -> Vec<Property<ClassId>> {
-        self.properties
-    }
-
-    /// Replace `Class` properties with updated_class_properties
-    pub fn set_properties(&mut self, updated_class_properties: Vec<Property<ClassId>>) {
-        self.properties = updated_class_properties;
-    }
-
-    /// Get per controller `Class`- specific limit
-    pub fn get_default_entity_creation_voucher_upper_bound(&self) -> EntityId {
-        self.default_entity_creation_voucher_upper_bound
-    }
-
-    /// Retrive the maximum entities count, which can be created for given `Class`
-    pub fn get_maximum_entities_count(&self) -> EntityId {
-        self.maximum_entities_count
-    }
-
-    /// Set per controller `Class`- specific limit
-    pub fn set_default_entity_creation_voucher_upper_bound(
-        &mut self,
-        new_default_entity_creation_voucher_upper_bound: EntityId,
-    ) {
-        self.default_entity_creation_voucher_upper_bound =
-            new_default_entity_creation_voucher_upper_bound;
-    }
-
-    /// Set the maximum entities count, which can be created for given `Class`
-    pub fn set_maximum_entities_count(&mut self, maximum_entities_count: EntityId) {
-        self.maximum_entities_count = maximum_entities_count;
-    }
-
-    /// Ensure `Class` `Schema` under given index exist, return corresponding `Schema`
-    pub fn ensure_schema_exists<T: Trait>(
-        &self,
-        schema_index: SchemaId,
-    ) -> Result<&Schema, Error<T>> {
-        self.schemas
-            .get(schema_index as usize)
-            .ok_or(Error::<T>::UnknownClassSchemaId)
-    }
-
-    /// Ensure `schema_id` is a valid index of `Class` schemas vector
-    pub fn ensure_schema_id_exists<T: Trait>(&self, schema_id: SchemaId) -> Result<(), Error<T>> {
-        ensure!(
-            schema_id < self.schemas.len() as SchemaId,
-            Error::<T>::UnknownClassSchemaId
-        );
-        Ok(())
-    }
-
-    /// Ensure `Schema`s limit per `Class` not reached
-    pub fn ensure_schemas_limit_not_reached<T: Trait>(&self) -> Result<(), Error<T>> {
-        ensure!(
-            (self.schemas.len() as MaxNumber) < T::MaxNumberOfSchemasPerClass::get(),
-            Error::<T>::ClassSchemasLimitReached
-        );
-        Ok(())
-    }
-
-    /// Ensure properties limit per `Schema` not reached
-    pub fn ensure_properties_limit_not_reached<T: Trait>(
-        &self,
-        new_properties: &[Property<ClassId>],
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            T::MaxNumberOfPropertiesPerSchema::get()
-                >= (self.properties.len() + new_properties.len()) as MaxNumber,
-            Error::<T>::SchemaPropertiesLimitReached
-        );
-        Ok(())
-    }
-
-    /// Ensure `Class` specific entities limit not reached
-    pub fn ensure_maximum_entities_count_limit_not_reached<T: Trait>(
-        &self,
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            self.current_number_of_entities < self.maximum_entities_count,
-            Error::<T>::NumberOfEntitiesPerClassLimitReached
-        );
-        Ok(())
-    }
-
-    /// Ensure `Property` under given `PropertyId` is unlocked from actor with given `EntityAccessLevel`
-    /// return corresponding `Property` by value
-    pub fn ensure_class_property_type_unlocked_from<T: Trait>(
-        self,
-        in_class_schema_property_id: PropertyId,
-        entity_access_level: EntityAccessLevel,
-    ) -> Result<Property<ClassId>, Error<T>> {
-        // Ensure property values were not locked on Class level
-        self.ensure_property_values_unlocked()?;
-
-        // Get class-level information about this `Property`
-        let class_property = self
-            .properties
-            .get(in_class_schema_property_id as usize)
-            // Throw an error if a property was not found on class
-            // by an in-class index of a property.
-            .ok_or(Error::<T>::ClassPropertyNotFound)?;
-
-        // Ensure Property is unlocked from Actor with given EntityAccessLevel
-        class_property.ensure_unlocked_from::<T>(entity_access_level)?;
-
-        Ok(class_property.clone())
-    }
-
-    /// Ensure property values were not locked on `Class` level
-    pub fn ensure_property_values_unlocked<T: Trait>(&self) -> Result<(), Error<T>> {
-        ensure!(
-            !self
-                .get_permissions_ref()
-                .all_entity_property_values_locked(),
-            Error::<T>::AllPropertiesWereLockedOnClassLevel
-        );
-        Ok(())
-    }
-}

+ 0 - 213
runtime-modules/content-directory/src/entity.rs

@@ -1,213 +0,0 @@
-use super::*;
-
-/// Represents `Entity`, related to a specific `Class`
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
-#[derive(Encode, Decode, Default, Clone, PartialEq, Eq)]
-pub struct Entity<
-    ClassId: Default + BaseArithmetic + Clone + Copy,
-    MemberId: Default + PartialEq + Clone + Copy,
-    Hashed: Default + Clone + Codec,
-    EntityId: Default + Clone + Copy + Codec,
-    Nonce: Default + BaseArithmetic + Clone + Copy,
-> {
-    /// Permissions for an instance of an Entity.
-    entity_permissions: EntityPermissions<MemberId>,
-
-    /// The class id of this entity.
-    class_id: ClassId,
-
-    /// What schemas under which entity of the respective class is available, think
-    /// v.2.0 Person schema for John, v3.0 Person schema for John
-    /// Unlikely to be more than roughly 20ish, assuming schemas for a given class eventually stableize,
-    /// or that very old schema are eventually removed.
-    supported_schemas: BTreeSet<SchemaId>, // indices of schema in corresponding class
-
-    /// Values for properties on class that are used by some schema used by this entity
-    /// Length is no more than Class.properties.
-    values: BTreeMap<PropertyId, StoredPropertyValue<Hashed, EntityId, Nonce>>,
-
-    /// Number of property values referencing current entity
-    reference_counter: InboundReferenceCounter,
-}
-
-impl<
-        ClassId: Default + BaseArithmetic + Clone + Copy,
-        MemberId: Default + PartialEq + Clone + Copy,
-        Hashed: Default + Clone + Codec,
-        EntityId: Default + Clone + Copy + Codec,
-        Nonce: Default + BaseArithmetic + Clone + Copy,
-    > Entity<ClassId, MemberId, Hashed, EntityId, Nonce>
-{
-    /// Create new `Entity` instance, related to a given `class_id` with provided parameters,  
-    pub fn new(
-        controller: EntityController<MemberId>,
-        class_id: ClassId,
-        supported_schemas: BTreeSet<SchemaId>,
-        values: BTreeMap<PropertyId, StoredPropertyValue<Hashed, EntityId, Nonce>>,
-    ) -> Self {
-        Self {
-            entity_permissions: EntityPermissions::<MemberId>::default_with_controller(controller),
-            class_id,
-            supported_schemas,
-            values,
-            reference_counter: InboundReferenceCounter::default(),
-        }
-    }
-
-    /// Get `class_id` of this `Entity`
-    pub fn get_class_id(&self) -> ClassId {
-        self.class_id
-    }
-
-    /// Get Entity supported schemas by mutable reference
-    pub fn get_supported_schemas_mut(&mut self) -> &mut BTreeSet<SchemaId> {
-        &mut self.supported_schemas
-    }
-
-    /// Get `Entity` values by value
-    pub fn get_values(self) -> BTreeMap<PropertyId, StoredPropertyValue<Hashed, EntityId, Nonce>> {
-        self.values
-    }
-
-    /// Get `Entity` values by reference
-    pub fn get_values_ref(
-        &self,
-    ) -> &BTreeMap<PropertyId, StoredPropertyValue<Hashed, EntityId, Nonce>> {
-        &self.values
-    }
-
-    /// Get `Entity` values by mutable reference
-    pub fn get_values_mut(
-        &mut self,
-    ) -> &mut BTreeMap<PropertyId, StoredPropertyValue<Hashed, EntityId, Nonce>> {
-        &mut self.values
-    }
-
-    /// Get mutable reference to `Entity` values
-    pub fn set_values(
-        &mut self,
-        new_values: BTreeMap<PropertyId, StoredPropertyValue<Hashed, EntityId, Nonce>>,
-    ) {
-        self.values = new_values;
-    }
-
-    /// Get mutable `EntityPermissions` reference, related to given `Entity`
-    pub fn get_permissions_mut(&mut self) -> &mut EntityPermissions<MemberId> {
-        &mut self.entity_permissions
-    }
-
-    /// Get `EntityPermissions` reference, related to given `Entity`
-    pub fn get_permissions_ref(&self) -> &EntityPermissions<MemberId> {
-        &self.entity_permissions
-    }
-
-    /// Get `EntityPermissions`, related to given `Entity` by value
-    pub fn get_permissions(self) -> EntityPermissions<MemberId> {
-        self.entity_permissions
-    }
-
-    /// Update existing `EntityPermissions` with newly provided
-    pub fn update_permissions(&mut self, permissions: EntityPermissions<MemberId>) {
-        self.entity_permissions = permissions
-    }
-
-    /// Ensure `Schema` under given id is not added to given `Entity` yet
-    pub fn ensure_schema_id_is_not_added<T: Trait>(
-        &self,
-        schema_id: SchemaId,
-    ) -> Result<(), Error<T>> {
-        let schema_not_added = !self.supported_schemas.contains(&schema_id);
-        ensure!(schema_not_added, Error::<T>::SchemaAlreadyAddedToTheEntity);
-        Ok(())
-    }
-
-    /// Ensure provided `property_values` are not added to the `Entity` `values` map yet
-    pub fn ensure_property_values_are_not_added<T: Trait>(
-        &self,
-        property_values: &BTreeMap<PropertyId, InputPropertyValue<T>>,
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            property_values
-                .keys()
-                .all(|key| !self.values.contains_key(key)),
-            Error::<T>::EntityAlreadyContainsGivenPropertyId
-        );
-        Ok(())
-    }
-
-    /// Ensure InputPropertyValue under given `in_class_schema_property_id` is Vector
-    pub fn ensure_property_value_is_vec<T: Trait>(
-        &self,
-        in_class_schema_property_id: PropertyId,
-    ) -> Result<VecStoredPropertyValue<Hashed, EntityId, Nonce>, Error<T>> {
-        self.values
-            .get(&in_class_schema_property_id)
-            // Throw an error if a property was not found on entity
-            // by an in-class index of a property.
-            .ok_or(Error::<T>::UnknownEntityPropertyId)?
-            .as_vec_property_value()
-            .cloned()
-            // Ensure prop value under given class schema property id is vector
-            .ok_or(Error::<T>::PropertyValueUnderGivenIndexIsNotAVector)
-    }
-
-    /// Ensure any `InputPropertyValue` from external entity does not point to the given `Entity`
-    pub fn ensure_rc_is_zero<T: Trait>(&self) -> Result<(), Error<T>> {
-        ensure!(
-            self.reference_counter.is_total_equal_to_zero(),
-            Error::<T>::EntityRcDoesNotEqualToZero
-        );
-        Ok(())
-    }
-
-    /// Ensure any inbound `InputPropertyValue` with `same_owner` flag set points to the given `Entity`
-    pub fn ensure_inbound_same_owner_rc_is_zero<T: Trait>(&self) -> Result<(), Error<T>> {
-        ensure!(
-            self.reference_counter.is_same_owner_equal_to_zero(),
-            Error::<T>::EntityInboundSameOwnerRcDoesNotEqualToZero
-        );
-        Ok(())
-    }
-
-    /// Get mutable reference to the `Entity`'s `InboundReferenceCounter` instance
-    pub fn get_reference_counter_mut(&mut self) -> &mut InboundReferenceCounter {
-        &mut self.reference_counter
-    }
-}
-
-/// Structure, respresenting inbound entity rcs for each `Entity`
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
-#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Copy)]
-pub struct InboundReferenceCounter {
-    /// Total number of inbound references from another entities
-    pub total: u32,
-    /// Number of inbound references from another entities with `SameOwner` flag set
-    pub same_owner: u32,
-}
-
-impl InboundReferenceCounter {
-    /// Create simple `InboundReferenceCounter` instance, based on `same_owner` flag provided
-    pub fn new(reference_counter: u32, same_owner: bool) -> Self {
-        if same_owner {
-            Self {
-                total: reference_counter,
-                same_owner: reference_counter,
-            }
-        } else {
-            Self {
-                total: reference_counter,
-                same_owner: 0,
-            }
-        }
-    }
-
-    /// Check if `total` is equal to zero
-    pub fn is_total_equal_to_zero(self) -> bool {
-        self.total == 0
-    }
-
-    /// Check if `same_owner` is equal to zero
-    pub fn is_same_owner_equal_to_zero(self) -> bool {
-        self.same_owner == 0
-    }
-}

+ 0 - 239
runtime-modules/content-directory/src/errors.rs

@@ -1,239 +0,0 @@
-use crate::*;
-use frame_support::decl_error;
-
-decl_error! {
-    /// Content directory errors
-    pub enum Error for Module<T: Trait> {
-
-        /// Validation errors
-        /// --------------------------------------
-
-
-        /// Property name is too short
-        PropertyNameTooShort,
-
-        /// Property name is too long
-        PropertyNameTooLong,
-
-        /// Property description is too short
-        PropertyDescriptionTooShort,
-
-        /// Property description is too long
-        PropertyDescriptionTooLong,
-
-        /// Class name is too short
-        ClassNameTooShort,
-
-        /// Class name is too long
-        ClassNameTooLong,
-
-        /// Class description is too short
-        ClassDescriptionTooShort,
-
-        /// Class description is too long
-        ClassDescriptionTooLong,
-
-        /// Maximum number of classes limit reached
-        ClassLimitReached,
-
-        /// Maximum number of given class schemas limit reached
-        ClassSchemasLimitReached,
-
-        /// Maximum number of properties in schema limit reached
-        SchemaPropertiesLimitReached,
-
-        /// Entities creation limit per controller should be less than overall entities creation limit
-        PerControllerEntitiesCreationLimitExceedsOverallLimit,
-
-        /// Number of entities per class is to big
-        EntitiesNumberPerClassConstraintViolated,
-
-        /// Number of class entities per actor constraint violated
-        NumberOfClassEntitiesPerActorConstraintViolated,
-
-        /// Individual number of class entities per actor is too big
-        IndividualNumberOfClassEntitiesPerActorIsTooBig,
-
-        /// Number of operations during atomic batching limit reached
-        NumberOfOperationsDuringAtomicBatchingLimitReached,
-
-        /// Text property is too long
-        TextPropertyTooLong,
-
-        /// Text property to be hashed is too long
-        HashedTextPropertyTooLong,
-
-        /// Vector property is too long
-        VecPropertyTooLong,
-
-        /// Propery value vector can`t contain more values
-        EntityPropertyValueVectorIsTooLong,
-
-        /// Given property value vector index is out of range
-        EntityPropertyValueVectorIndexIsOutOfRange,
-
-
-        /// Main logic errors
-        /// --------------------------------------
-
-
-        /// Class was not found by id
-        ClassNotFound,
-
-        /// Class property under given index not found
-        ClassPropertyNotFound,
-
-        /// Unknown class schema id
-        UnknownClassSchemaId,
-
-        /// Given class schema is not active
-        ClassSchemaNotActive,
-
-        /// New class schema refers to an unknown property index
-        ClassSchemaRefersUnknownPropertyIndex,
-
-        /// New class schema refers to an unknown class id
-        ClassSchemaRefersUnknownClass,
-
-        /// Cannot add a class schema with an empty list of properties
-        NoPropertiesInClassSchema,
-
-        /// Entity was not found by id
-        EntityNotFound,
-
-        /// Cannot add a schema that is already added to this entity
-        SchemaAlreadyAddedToTheEntity,
-
-        /// Some of the provided property values don't match the expected property type
-        PropertyValueDoNotMatchType,
-
-        /// Property value don't match the expected vector property type
-        PropertyValueDoNotMatchVecType,
-
-        /// Property value under given index is not a vector
-        PropertyValueUnderGivenIndexIsNotAVector,
-
-        /// Current property value vector nonce does not equal to provided one
-        PropertyValueVecNoncesDoesNotMatch,
-
-        /// Property name is not unique within its class
-        PropertyNameNotUniqueInAClass,
-
-        /// Some required property was not found when adding schema support to entity
-        MissingRequiredProperty,
-
-        /// Schema under provided schema_id does not contain given property
-        SchemaDoesNotContainProvidedPropertyId,
-
-        /// Some of the provided property ids cannot be found on the current list of propery values of this entity
-        UnknownEntityPropertyId,
-
-        /// Entity already contains property under provided index
-        EntityAlreadyContainsGivenPropertyId,
-
-        /// Propery value type does not match internal entity vector type
-        PropertyValueTypeDoesNotMatchInternalVectorType,
-
-        /// Provided property references entity, which class_id is not equal to class_id, declared in corresponding property type
-        ReferencedEntityDoesNotMatchItsClass,
-
-        /// Entity removal can`t be completed, as there are some property values pointing to given entity
-        EntityRcDoesNotEqualToZero,
-
-        /// Entity ownership transfer can`t be completed, as there are some property values pointing to given entity with same owner flag set
-        EntityInboundSameOwnerRcDoesNotEqualToZero,
-
-        /// Provided entity controller is equal to the current one
-        ProvidedEntityControllerIsEqualToTheCurrentOne,
-
-        /// All ids of new property value references with same owner flag set should match their respective Properties defined on Class level
-        AllProvidedPropertyValueIdsMustBeReferencesWithSameOwnerFlagSet,
-
-        /// Entity was not created in batched transaction
-        EntityNotCreatedByOperation,
-
-        /// Permission errors
-        /// --------------------------------------
-
-        /// Curator group can`t be removed, as it currently maintains at least one class
-        CuratorGroupRemovalForbidden,
-
-        /// All property values, related to a given Entity were locked on Class level
-        AllPropertiesWereLockedOnClassLevel,
-
-        /// Curator under provided curator id is not a member of curaror group under given id
-        CuratorIsNotAMemberOfGivenCuratorGroup,
-
-        /// Curator under provided curator id is already a member of curaror group under given id
-        CuratorIsAlreadyAMemberOfGivenCuratorGroup,
-
-        /// Given curator group does not exist
-        CuratorGroupDoesNotExist,
-
-        /// Entity should be referenced from the entity, owned by the same controller
-        SameControllerConstraintViolation,
-
-        /// Given maintainer does not exist
-        MaintainerDoesNotExist,
-
-        /// Given maintainer already exist
-        MaintainerAlreadyExists,
-
-        /// Provided actor can`t create entities of given class
-        ActorCanNotCreateEntities,
-
-        /// Maximum numbers of entities per class limit reached
-        NumberOfEntitiesPerClassLimitReached,
-
-        /// Current class entities creation blocked
-        EntitiesCreationBlocked,
-
-        /// Entities voucher limit reached
-        VoucherLimitReached,
-
-        /// Lead authentication failed
-        LeadAuthFailed,
-
-        /// Member authentication failed
-        MemberAuthFailed,
-
-        /// Curator authentication failed
-        CuratorAuthFailed,
-
-        /// Expected root or signed origin
-        BadOrigin,
-
-        /// Entity removal access denied
-        EntityRemovalAccessDenied,
-
-        /// Add entity schema support access denied
-        EntityAddSchemaSupportAccessDenied,
-
-        /// Class access denied
-        ClassAccessDenied,
-
-        /// Entity access denied
-        EntityAccessDenied,
-
-        /// Given entity can`t be referenced
-        EntityCanNotBeReferenced,
-
-        /// Given class property type is locked for given actor
-        ClassPropertyTypeLockedForGivenActor,
-
-        /// Number of maintainers per class limit reached
-        ClassMaintainersLimitReached,
-
-        /// Max number of curators per group limit reached
-        CuratorsPerGroupLimitReached,
-
-        /// Curator group is not active
-        CuratorGroupIsNotActive,
-
-        /// Origin cannot be made into raw origin
-        OriginCanNotBeMadeIntoRawOrigin,
-
-        /// Property value should be unique across all Entities of this Class
-        PropertyValueShouldBeUnique
-    }
-}

+ 0 - 346
runtime-modules/content-directory/src/helpers.rs

@@ -1,346 +0,0 @@
-use crate::*;
-use core::ops::{Deref, DerefMut};
-
-/// Wrapper for existing `InputPropertyValue` and its respective `Class` `Property`
-pub struct InputValueForExistingProperty<'a, T: Trait>(
-    &'a Property<T::ClassId>,
-    &'a InputPropertyValue<T>,
-);
-
-impl<'a, T: Trait> InputValueForExistingProperty<'a, T> {
-    /// Create single instance of `InputValueForExistingProperty` from provided `property` and `value`
-    fn new(property: &'a Property<T::ClassId>, value: &'a InputPropertyValue<T>) -> Self {
-        Self(property, value)
-    }
-
-    /// Retrieve `Property` reference
-    pub fn get_property(&self) -> &Property<T::ClassId> {
-        self.0
-    }
-
-    /// Retrieve `InputPropertyValue` reference
-    pub fn get_value(&self) -> &InputPropertyValue<T> {
-        self.1
-    }
-
-    /// Retrieve `Property` and `InputPropertyValue` references
-    pub fn unzip(&self) -> (&Property<T::ClassId>, &InputPropertyValue<T>) {
-        (self.0, self.1)
-    }
-}
-
-/// Mapping, used to represent `PropertyId` relation to its respective `InputValueForExistingProperty` structure
-pub struct InputValuesForExistingProperties<'a, T: Trait>(
-    BTreeMap<PropertyId, InputValueForExistingProperty<'a, T>>,
-);
-
-impl<'a, T: Trait> Default for InputValuesForExistingProperties<'a, T> {
-    fn default() -> Self {
-        Self(BTreeMap::default())
-    }
-}
-
-impl<'a, T: Trait> Deref for InputValuesForExistingProperties<'a, T> {
-    type Target = BTreeMap<PropertyId, InputValueForExistingProperty<'a, T>>;
-
-    fn deref(&self) -> &Self::Target {
-        &self.0
-    }
-}
-
-impl<'a, T: Trait> DerefMut for InputValuesForExistingProperties<'a, T> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        &mut self.0
-    }
-}
-
-impl<'a, T: Trait> InputValuesForExistingProperties<'a, T> {
-    /// Create `InputValuesForExistingProperties` helper structure from provided `property_values` and their corresponding `Class` properties.
-    /// Throws an error, when `Class` `Property` under `property_id`, corresponding to provided `property_value` not found
-    pub fn from(
-        properties: &'a [Property<T::ClassId>],
-        property_values: &'a BTreeMap<PropertyId, InputPropertyValue<T>>,
-    ) -> Result<Self, Error<T>> {
-        let mut values_for_existing_properties = InputValuesForExistingProperties::<T>::default();
-        for (&property_id, property_value) in property_values {
-            let property = properties
-                .get(property_id as usize)
-                .ok_or(Error::<T>::ClassPropertyNotFound)?;
-            values_for_existing_properties.insert(
-                property_id,
-                InputValueForExistingProperty::new(property, property_value),
-            );
-        }
-        Ok(values_for_existing_properties)
-    }
-}
-
-/// Wrapper for existing `StoredPropertyValue` and its respective `Class` `Property`
-pub struct StoredValueForExistingProperty<'a, T: Trait>(
-    &'a Property<T::ClassId>,
-    &'a StoredPropertyValueOf<T>,
-);
-
-impl<'a, T: Trait> StoredValueForExistingProperty<'a, T> {
-    /// Create single instance of `StoredValueForExistingProperty` from provided `property` and `value`
-    pub fn new(property: &'a Property<T::ClassId>, value: &'a StoredPropertyValueOf<T>) -> Self {
-        Self(property, value)
-    }
-
-    /// Retrieve `Property` reference
-    pub fn get_property(&self) -> &Property<T::ClassId> {
-        self.0
-    }
-
-    /// Retrieve `StoredPropertyValue` reference
-    pub fn get_value(&self) -> &StoredPropertyValueOf<T> {
-        self.1
-    }
-
-    /// Retrieve `Property` and `StoredPropertyValue` references
-    pub fn unzip(&self) -> (&Property<T::ClassId>, &StoredPropertyValueOf<T>) {
-        (self.0, self.1)
-    }
-
-    /// Check if Property is default and non `required`
-    pub fn is_default(&self) -> bool {
-        let (property, property_value) = self.unzip();
-        !property.required
-            && *property_value == StoredPropertyValue::<T::Hash, T::EntityId, T::Nonce>::default()
-    }
-}
-
-/// Mapping, used to represent `PropertyId` relation to its respective `StoredValuesForExistingProperties` structure
-pub struct StoredValuesForExistingProperties<'a, T: Trait>(
-    BTreeMap<PropertyId, StoredValueForExistingProperty<'a, T>>,
-);
-
-impl<'a, T: Trait> Default for StoredValuesForExistingProperties<'a, T> {
-    fn default() -> Self {
-        Self(BTreeMap::default())
-    }
-}
-
-impl<'a, T: Trait> Deref for StoredValuesForExistingProperties<'a, T> {
-    type Target = BTreeMap<PropertyId, StoredValueForExistingProperty<'a, T>>;
-
-    fn deref(&self) -> &Self::Target {
-        &self.0
-    }
-}
-
-impl<'a, T: Trait> DerefMut for StoredValuesForExistingProperties<'a, T> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        &mut self.0
-    }
-}
-
-impl<'a, T: Trait> StoredValuesForExistingProperties<'a, T> {
-    /// Create `StoredValuesForExistingProperties` helper structure from provided `property_values` and their corresponding `Class` properties.
-    pub fn from(
-        properties: &'a [Property<T::ClassId>],
-        property_values: &'a BTreeMap<PropertyId, StoredPropertyValueOf<T>>,
-    ) -> Result<Self, Error<T>> {
-        let mut values_for_existing_properties = StoredValuesForExistingProperties::<T>::default();
-
-        for (&property_id, property_value) in property_values {
-            let property = properties
-                .get(property_id as usize)
-                .ok_or(Error::<T>::ClassPropertyNotFound)?;
-            values_for_existing_properties.insert(
-                property_id,
-                StoredValueForExistingProperty::new(property, property_value),
-            );
-        }
-        Ok(values_for_existing_properties)
-    }
-
-    /// Used to compute hashes from `StoredPropertyValue`s and their respective property ids, which respective `Properties` have `unique` flag set
-    /// (skip `PropertyId`s, which respective `property values` under this `Entity` are default and non `required`)
-    pub fn compute_unique_hashes(&self) -> BTreeMap<PropertyId, T::Hash> {
-        self.iter()
-            .filter(|(_, value_for_property)| {
-                // skip `PropertyId`s, which respective `property values` under this `Entity` are default and non `required`
-                value_for_property.get_property().unique && !value_for_property.is_default()
-            })
-            .map(|(&property_id, property_value)| {
-                (
-                    property_id,
-                    property_value
-                        .get_value()
-                        .compute_unique_hash::<T>(property_id),
-                )
-            })
-            .collect()
-    }
-}
-
-/// Length constraint for input validation
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
-#[derive(Encode, Decode, Default, Clone, Copy, PartialEq, Eq)]
-pub struct InputValidationLengthConstraint {
-    /// Minimum length
-    min: u16,
-
-    /// Difference between minimum length and max length.
-    /// While having max would have been more direct, this
-    /// way makes max < min unrepresentable semantically,
-    /// which is safer.
-    max_min_diff: u16,
-}
-
-impl InputValidationLengthConstraint {
-    /// Create new `InputValidationLengthConstraint` constraint
-    pub const fn new(min: u16, max_min_diff: u16) -> Self {
-        Self { min, max_min_diff }
-    }
-
-    /// Helper for computing max
-    pub fn max(self) -> u16 {
-        self.min + self.max_min_diff
-    }
-
-    /// Retrieve min length value
-    pub fn min(self) -> u16 {
-        self.min
-    }
-
-    /// Ensure length is valid
-    pub fn ensure_valid<T: Trait>(
-        self,
-        len: usize,
-        too_short_msg: Error<T>,
-        too_long_msg: Error<T>,
-    ) -> Result<(), Error<T>> {
-        let length = len as u16;
-        if length < self.min {
-            Err(too_short_msg)
-        } else if length > self.max() {
-            Err(too_long_msg)
-        } else {
-            Ok(())
-        }
-    }
-}
-
-/// Enum, used to specify, which mode of operation should be chosen
-#[derive(Clone, PartialEq, Eq, Copy)]
-pub enum DeltaMode {
-    Increment,
-    Decrement,
-}
-
-impl Default for DeltaMode {
-    fn default() -> Self {
-        Self::Increment
-    }
-}
-
-/// Representing delta on which respective `InboundReferenceCounter` should be changed.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
-#[derive(Encode, Decode, Default, PartialEq, Eq)]
-pub struct EntityReferenceCounterSideEffect {
-    /// Delta number of all inbound references from another entities
-    pub total: i32,
-    /// Delta number of inbound references from another entities with `SameOwner` flag set
-    pub same_owner: i32,
-}
-
-impl Clone for EntityReferenceCounterSideEffect {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-
-impl Copy for EntityReferenceCounterSideEffect {}
-
-impl EntityReferenceCounterSideEffect {
-    /// Create atomic `EntityReferenceCounterSideEffect` instance, based on `same_owner` flag provided and `DeltaMode`
-    pub fn atomic(same_owner: bool, delta_mode: DeltaMode) -> Self {
-        let counter = if let DeltaMode::Increment = delta_mode {
-            1
-        } else {
-            -1
-        };
-
-        if same_owner {
-            Self {
-                total: counter,
-                same_owner: counter,
-            }
-        } else {
-            Self {
-                total: counter,
-                same_owner: 0,
-            }
-        }
-    }
-}
-
-impl AddAssign for EntityReferenceCounterSideEffect {
-    fn add_assign(&mut self, other: EntityReferenceCounterSideEffect) {
-        *self = Self {
-            total: self.total + other.total,
-            same_owner: self.same_owner + other.same_owner,
-        };
-    }
-}
-
-/// The net side effect on a set of entities from some operations.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
-#[derive(Encode, Decode, Clone, PartialEq, Eq)]
-pub struct ReferenceCounterSideEffects<T: Trait>(
-    BTreeMap<T::EntityId, EntityReferenceCounterSideEffect>,
-);
-
-impl<T: Trait> Deref for ReferenceCounterSideEffects<T> {
-    type Target = BTreeMap<T::EntityId, EntityReferenceCounterSideEffect>;
-
-    fn deref(&self) -> &Self::Target {
-        &self.0
-    }
-}
-
-impl<T: Trait> DerefMut for ReferenceCounterSideEffects<T> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        &mut self.0
-    }
-}
-
-impl<T: Trait> Default for ReferenceCounterSideEffects<T> {
-    fn default() -> Self {
-        Self(BTreeMap::default())
-    }
-}
-
-impl<T: Trait> ReferenceCounterSideEffects<T> {
-    /// Updates all the elements of `other` with `Self`
-    pub fn update(mut self, other: Self) -> Self {
-        // Make a set, that includes both self and other entity_id keys
-        let entity_ids: BTreeSet<T::EntityId> = self.keys().chain(other.keys()).copied().collect();
-
-        for entity_id in entity_ids {
-            // If `self` contains value under provided `entity_id`,
-            // increase it on `EntityReferenceCounterSideEffect` value from `other` if exists,
-            // otherwise update `self` entry under provided `entity_id` with `EntityReferenceCounterSideEffect` from `other`
-            match (self.get_mut(&entity_id), other.get(&entity_id)) {
-                (Some(self_entity_rc_side_effect), Some(other_entity_rc_side_effect)) => {
-                    *self_entity_rc_side_effect += *other_entity_rc_side_effect
-                }
-                (_, Some(other_entity_rc_side_effect)) => {
-                    self.insert(entity_id, *other_entity_rc_side_effect);
-                }
-                _ => (),
-            }
-        }
-        self
-    }
-
-    /// Traverse `ReferenceCounterSideEffects`, updating each `Entity` respective reference counters
-    pub fn update_entities_rcs(&self) {
-        self.iter()
-            .for_each(|(entity_id, inbound_reference_counter_delta)| {
-                Module::<T>::update_entity_rc(*entity_id, *inbound_reference_counter_delta);
-            });
-    }
-}

+ 0 - 2920
runtime-modules/content-directory/src/lib.rs

@@ -1,2920 +0,0 @@
-//! # Content Directory Module
-//!
-//! The content directory is an on-chain index of all content and metadata,
-//! and related concepts - such as channels and playlists.
-//!
-//! - [`substrate_content_directory_module::Trait`](./trait.Trait.html)
-//! - [`Call`](./enum.Call.html)
-//! - [`Module`](./struct.Module.html)
-//!
-//! ## Overview
-//!
-//! The content directory provides functions for:
-//!
-//! - Creating/removal and managing curator groups
-//! - Creating classes and managing their permissions
-//! - Adding schemas to the class
-//! - Creating and removal of entities and managing their permissions
-//! - Adding schemas support to the respective class entities
-//! - Transfering entities ownership
-//! - Updating entity property values
-//!
-//! ## Terminology
-//!
-//! ### Class
-//!
-//! - **Class Properties:** All properties that have been used on this class across different class schemas.
-//! Unlikely to be more than roughly 20 properties per class, often less.
-//! For Person, think "height", "weight", etc.
-//!
-//! - **Schemas:**  All schemas, that are available for this class, think v0.0 Person, v.1.0 Person, etc.
-//!
-//! ### Entity
-//!
-//! - **Supported Schemas:**  What schemas under which entity of the respective class is available, think
-//! v.2.0 Person schema for John, v3.0 Person schema for John
-//! Unlikely to be more than roughly 20ish, assuming schemas for a given class eventually stableize,
-//! or that very old schema are eventually removed.
-//!
-//! - **Property Values:**  Values for properties, declared on class level,
-//! that are used in respective Class Entity after adding Schema support.
-//!
-//! ## Interface
-//!
-//! ### Dispatchable Functions
-//!
-//! #### Curator groups
-//!
-//! - `add_curator_group` - Add new curator group to the runtime storage
-//! - `remove_curator_group` - Remove curator group under given `curator_group_id` from runtime storage.
-//! The origin of this call must be a blog owner.
-//! - `set_curator_group_status` - Set activity status for curator group under given `curator_group_id`
-//! - `add_curator_to_group` - Add curator to curator group under given `curator_group_id`
-//! - `remove_curator_from_group` - Remove curator from a given curator group.
-//!
-//! #### Classes
-//!
-//! - `create_class` - Create new class with provided parameters
-//! - `add_maintainer_to_class` - Add curator group under given curator_group_id as class maintainer
-//! - `remove_maintainer_from_class` - Remove curator group under given curator_group_id from class maintainers set
-//! - `update_class_permissions` - Update class permissions under specific class_id
-//! - `add_class_schema` - Create new class schema from existing property ids and new properties
-//! - `update_class_schema_status` - Update schema status  under specific schema_id in class
-//!
-//! #### Entities
-//!
-//! - `create_entity` - Create new entity of respective class
-//! - `remove_entity` - Remove entity under provided entity_id
-//! - `update_entity_permissions` - Update entity permissions
-//! - `add_schema_support_to_entity` - add schema support to entity under given schema_id and provided property values
-//! - `update_entity_property_values` - Update entity property values with provided ones
-//! - `clear_entity_property_vector` - Clear property value vector under given entity_id & in class schema property id
-//! - `remove_at_entity_property_vector` - Remove value at given index_in_property_vector
-//! from property values vector under in_class schema property id
-//! - `insert_at_entity_property_vector` - Insert single input property values at given index in property vector
-//! into  property values vector under in class schema property id
-//!
-//! #### Others
-//!
-//! - `update_entity_creation_voucher` - Update/create new entity creation voucher for given entity controller with individual limit
-//! - `transaction` - This extrinsic allows a batch operation, which is atomic, over the following operations:
-//! **Entity creation**
-//! **Adding schema support to the entity**
-//! **Update property values of the entity**
-//!
-//! ## Usage
-//!
-//! The following example shows how to use the content directory module in your custom module.
-//!
-//! ### Prerequisites
-//!
-//! Import the content directory module into your custom module and derive the module configuration
-//! trait from the content directory trait.
-//!
-//! ### Add curator group
-//!
-//! ```
-//! use frame_support::{decl_module, assert_ok};
-//! use system::{self as system, ensure_signed};
-//!
-//! pub trait Trait: pallet_content_directory::Trait {}
-//!
-//! decl_module! {
-//!     pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-//!         #[weight = 10_000_000]
-//!         pub fn add_curator_group(origin) -> Result<(), &'static str> {
-//!             <pallet_content_directory::Module<T>>::add_curator_group(origin)?;
-//!             Ok(())
-//!         }
-//!     }
-//! }
-//! # fn main() {}
-//! ```
-
-// Ensure we're `no_std` when compiling for Wasm.
-#![cfg_attr(not(feature = "std"), no_std)]
-#![recursion_limit = "256"]
-
-#[cfg(test)]
-mod tests;
-
-mod class;
-mod entity;
-mod errors;
-mod helpers;
-mod mock;
-mod operations;
-mod permissions;
-mod schema;
-
-pub use class::*;
-pub use entity::*;
-pub use errors::*;
-pub use helpers::*;
-pub use operations::*;
-pub use permissions::*;
-pub use schema::*;
-
-use core::hash::Hash;
-use core::ops::AddAssign;
-
-use codec::{Codec, Decode, Encode};
-use frame_support::storage::IterableStorageMap;
-
-use frame_support::{
-    decl_event, decl_module, decl_storage,
-    dispatch::{DispatchError, DispatchResult},
-    ensure,
-    traits::Get,
-    Parameter,
-};
-#[cfg(feature = "std")]
-pub use serde::{Deserialize, Serialize};
-use sp_arithmetic::traits::{BaseArithmetic, One, Zero};
-use sp_runtime::traits::{MaybeSerializeDeserialize, Member};
-use sp_std::borrow::ToOwned;
-use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
-use sp_std::vec;
-use sp_std::vec::Vec;
-use system::ensure_signed;
-
-pub use errors::Error;
-
-use core::debug_assert;
-
-/// Type, used in diffrent numeric constraints representations
-pub type MaxNumber = u32;
-
-/// Type simplification
-pub type EntityOf<T> = Entity<
-    <T as Trait>::ClassId,
-    <T as ActorAuthenticator>::MemberId,
-    <T as system::Trait>::Hash,
-    <T as Trait>::EntityId,
-    <T as Trait>::Nonce,
->;
-
-/// Type simplification
-pub type ClassOf<T> =
-    Class<<T as Trait>::EntityId, <T as Trait>::ClassId, <T as ActorAuthenticator>::CuratorGroupId>;
-
-/// Type simplification
-pub type StoredPropertyValueOf<T> =
-    StoredPropertyValue<<T as system::Trait>::Hash, <T as Trait>::EntityId, <T as Trait>::Nonce>;
-
-/// Module configuration trait for this Substrate module.
-pub trait Trait: system::Trait + ActorAuthenticator + Clone {
-    /// The overarching event type.
-    type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
-
-    /// Nonce type is used to avoid data race update conditions, when performing property value vector operations
-    type Nonce: Parameter
-        + Member
-        + BaseArithmetic
-        + Codec
-        + Default
-        + Copy
-        + Clone
-        + MaybeSerializeDeserialize
-        + Eq
-        + PartialEq
-        + Ord
-        + From<u32>;
-
-    /// Type of identifier for classes
-    type ClassId: Parameter
-        + Member
-        + BaseArithmetic
-        + Codec
-        + Default
-        + Copy
-        + Clone
-        + Hash
-        + MaybeSerializeDeserialize
-        + Eq
-        + PartialEq
-        + Ord;
-
-    /// Type of identifier for entities
-    type EntityId: Parameter
-        + Member
-        + BaseArithmetic
-        + Codec
-        + Default
-        + Copy
-        + Clone
-        + Hash
-        + MaybeSerializeDeserialize
-        + Eq
-        + PartialEq
-        + Ord;
-
-    /// Security/configuration constraints
-
-    /// Type, representing min & max property name length constraints
-    type PropertyNameLengthConstraint: Get<InputValidationLengthConstraint>;
-
-    /// Type, representing min & max property description length constraints
-    type PropertyDescriptionLengthConstraint: Get<InputValidationLengthConstraint>;
-
-    /// Type, representing min & max class name length constraints
-    type ClassNameLengthConstraint: Get<InputValidationLengthConstraint>;
-
-    /// Type, representing min & max class description length constraints
-    type ClassDescriptionLengthConstraint: Get<InputValidationLengthConstraint>;
-
-    /// The maximum number of classes
-    type MaxNumberOfClasses: Get<MaxNumber>;
-
-    /// The maximum number of maintainers per class constraint
-    type MaxNumberOfMaintainersPerClass: Get<MaxNumber>;
-
-    /// The maximum number of curators per group constraint
-    type MaxNumberOfCuratorsPerGroup: Get<MaxNumber>;
-
-    /// The maximum number of schemas per class constraint
-    type MaxNumberOfSchemasPerClass: Get<MaxNumber>;
-
-    /// The maximum number of properties per class constraint
-    type MaxNumberOfPropertiesPerSchema: Get<MaxNumber>;
-
-    /// The maximum number of operations during single invocation of `transaction`
-    type MaxNumberOfOperationsDuringAtomicBatching: Get<MaxNumber>;
-
-    /// The maximum length of vector property value constarint
-    type VecMaxLengthConstraint: Get<VecMaxLength>;
-
-    /// The maximum length of text property value constarint
-    type TextMaxLengthConstraint: Get<TextMaxLength>;
-
-    /// The maximum length of text, that will be hashed property value constarint
-    type HashedTextMaxLengthConstraint: Get<HashedTextMaxLength>;
-
-    /// Entities creation constraint per class
-    type MaxNumberOfEntitiesPerClass: Get<Self::EntityId>;
-
-    /// Entities creation constraint per individual
-    type IndividualEntitiesCreationLimit: Get<Self::EntityId>;
-}
-
-decl_storage! {
-    trait Store for Module<T: Trait> as ContentDirectory {
-
-        /// Map, representing ClassId -> Class relation
-        pub ClassById get(fn class_by_id) config(): map hasher(blake2_128_concat) T::ClassId => ClassOf<T>;
-
-        /// Map, representing EntityId -> Entity relation
-        pub EntityById get(fn entity_by_id) config(): map hasher(blake2_128_concat) T::EntityId => EntityOf<T>;
-
-        /// Map, representing  CuratorGroupId -> CuratorGroup relation
-        pub CuratorGroupById get(fn curator_group_by_id) config(): map hasher(blake2_128_concat) T::CuratorGroupId => CuratorGroup<T>;
-
-        /// Mapping of class id and its property id to the respective entity id and property value hash.
-        pub UniquePropertyValueHashes get(fn unique_property_value_hashes): double_map hasher(blake2_128_concat) (T::ClassId, PropertyId), hasher(blake2_128_concat) T::Hash => ();
-
-        /// Next runtime storage values used to maintain next id value, used on creation of respective curator groups, classes and entities
-
-        pub NextClassId get(fn next_class_id) config(): T::ClassId;
-
-        pub NextEntityId get(fn next_entity_id) config(): T::EntityId;
-
-        pub NextCuratorGroupId get(fn next_curator_group_id) config(): T::CuratorGroupId;
-
-        // The voucher associated with entity creation for a given class and controller.
-        // Is updated whenever an entity is created in a given class by a given controller.
-        // Constraint is updated by Root, an initial value comes from `ClassPermissions::default_entity_creation_voucher_upper_bound`.
-        pub EntityCreationVouchers get(fn entity_creation_vouchers):
-            double_map hasher(blake2_128_concat) T::ClassId, hasher(blake2_128_concat) EntityController<T::MemberId> => EntityCreationVoucher<T>;
-    }
-}
-
-decl_module! {
-    pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-        /// Predefined errors
-        type Error = Error<T>;
-
-        /// Initializing events
-        fn deposit_event() = default;
-
-        // ======
-        // Next set of extrinsics can only be invoked by lead.
-        // ======
-
-        /// Add new curator group to runtime storage
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn add_curator_group(
-            origin,
-        ) -> DispatchResult {
-
-            // Ensure given origin is lead
-            ensure_is_lead::<T>(origin)?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            let curator_group_id = Self::next_curator_group_id();
-
-            // Insert empty curator group with `active` parameter set to false
-            <CuratorGroupById<T>>::insert(curator_group_id, CuratorGroup::<T>::default());
-
-            // Increment the next curator curator_group_id:
-            <NextCuratorGroupId<T>>::mutate(|n| *n += T::CuratorGroupId::one());
-
-            // Trigger event
-            Self::deposit_event(RawEvent::CuratorGroupAdded(curator_group_id));
-            Ok(())
-        }
-
-        /// Remove curator group under given `curator_group_id` from runtime storage
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn remove_curator_group(
-            origin,
-            curator_group_id: T::CuratorGroupId,
-        ) -> DispatchResult {
-
-            // Ensure given origin is lead
-            ensure_is_lead::<T>(origin)?;
-
-            // Ensure CuratorGroup under given curator_group_id exists
-            let curator_group = Self::ensure_curator_group_exists(&curator_group_id)?;
-
-            // We should previously ensure that curator_group  maintains no classes to be able to remove it
-            curator_group.ensure_curator_group_maintains_no_classes()?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-
-            // Remove curator group under given curator group id from runtime storage
-            <CuratorGroupById<T>>::remove(curator_group_id);
-
-            // Trigger event
-            Self::deposit_event(RawEvent::CuratorGroupRemoved(curator_group_id));
-            Ok(())
-        }
-
-        /// Set `is_active` status for curator group under given `curator_group_id`
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn set_curator_group_status(
-            origin,
-            curator_group_id: T::CuratorGroupId,
-            is_active: bool,
-        ) -> DispatchResult {
-
-            // Ensure given origin is lead
-            ensure_is_lead::<T>(origin)?;
-
-            // Ensure curator group under provided curator_group_id already exist
-            Self::ensure_curator_group_under_given_id_exists(&curator_group_id)?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Set `is_active` status for curator group under given `curator_group_id`
-            <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
-                curator_group.set_status(is_active)
-            });
-
-            // Trigger event
-            Self::deposit_event(RawEvent::CuratorGroupStatusSet(curator_group_id, is_active));
-            Ok(())
-        }
-
-        /// Add curator to curator group under given `curator_group_id`
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn add_curator_to_group(
-            origin,
-            curator_group_id: T::CuratorGroupId,
-            curator_id: T::CuratorId,
-        ) -> DispatchResult {
-
-            // Ensure given origin is lead
-            ensure_is_lead::<T>(origin)?;
-
-            // Ensure curator group under provided curator_group_id already exist, retrieve corresponding one
-            let curator_group = Self::ensure_curator_group_exists(&curator_group_id)?;
-
-            // Ensure max number of curators per group limit not reached yet
-            curator_group.ensure_max_number_of_curators_limit_not_reached()?;
-
-            // Ensure curator under provided curator_id isn`t a CuratorGroup member yet
-            curator_group.ensure_curator_in_group_does_not_exist(&curator_id)?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Insert curator_id into curator_group under given curator_group_id
-            <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
-                curator_group.get_curators_mut().insert(curator_id);
-            });
-
-            // Trigger event
-            Self::deposit_event(RawEvent::CuratorAdded(curator_group_id, curator_id));
-            Ok(())
-        }
-
-        /// Remove curator from a given curator group
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn remove_curator_from_group(
-            origin,
-            curator_group_id: T::CuratorGroupId,
-            curator_id: T::CuratorId,
-        ) -> DispatchResult {
-
-            // Ensure given origin is lead
-            ensure_is_lead::<T>(origin)?;
-
-            // Ensure curator group under provided curator_group_id already exist, retrieve corresponding one
-            let curator_group = Self::ensure_curator_group_exists(&curator_group_id)?;
-
-            // Ensure curator under provided curator_id is CuratorGroup member
-            curator_group.ensure_curator_in_group_exists(&curator_id)?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Remove curator_id from curator_group under given curator_group_id
-            <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
-                curator_group.get_curators_mut().remove(&curator_id);
-            });
-
-            // Trigger event
-            Self::deposit_event(RawEvent::CuratorRemoved(curator_group_id, curator_id));
-            Ok(())
-        }
-
-        /// Updates or creates new `EntityCreationVoucher` for given `EntityController` with individual limit
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn update_entity_creation_voucher(
-            origin,
-            class_id: T::ClassId,
-            controller: EntityController<T::MemberId>,
-            maximum_entities_count: T::EntityId
-        ) -> DispatchResult {
-
-            // Ensure given origin is lead
-            ensure_is_lead::<T>(origin)?;
-
-            // Ensure Class under given id exists, return corresponding one
-            Self::ensure_known_class_id(class_id)?;
-
-            // Ensure maximum_entities_count does not exceed individual entities creation limit
-            Self::ensure_valid_number_of_class_entities_per_actor_constraint(maximum_entities_count)?;
-
-            // Check voucher existance
-            let voucher_exists = <EntityCreationVouchers<T>>::contains_key(class_id, &controller);
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            if voucher_exists {
-
-                // Set new maximum_entities_count limit for selected voucher
-                let mut entity_creation_voucher = Self::entity_creation_vouchers(class_id, &controller);
-
-                entity_creation_voucher.set_maximum_entities_count(maximum_entities_count);
-
-                <EntityCreationVouchers<T>>::insert(class_id, controller.clone(), entity_creation_voucher.clone());
-
-                // Trigger event
-                Self::deposit_event(RawEvent::EntityCreationVoucherUpdated(controller, entity_creation_voucher))
-            } else {
-                // Create new EntityCreationVoucher instance with provided maximum_entities_count
-                let entity_creation_voucher = EntityCreationVoucher::new(maximum_entities_count);
-
-                // Add newly created `EntityCreationVoucher` into `EntityCreationVouchers`
-                // runtime storage under given `class_id`, `controller` key
-                <EntityCreationVouchers<T>>::insert(class_id, controller.clone(), entity_creation_voucher.clone());
-
-                // Trigger event
-                Self::deposit_event(RawEvent::EntityCreationVoucherCreated(controller, entity_creation_voucher));
-            }
-
-            Ok(())
-        }
-
-        /// Create new `Class` with provided parameters
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn create_class(
-            origin,
-            name: Vec<u8>,
-            description: Vec<u8>,
-            class_permissions: ClassPermissions<T::CuratorGroupId>,
-            maximum_entities_count: T::EntityId,
-            default_entity_creation_voucher_upper_bound: T::EntityId
-        ) -> DispatchResult {
-
-            // Ensure given origin is lead
-            ensure_is_lead::<T>(origin)?;
-
-            // Ensure, that all entities creation limits, defined for a given Class, are valid
-            Self::ensure_entities_creation_limits_are_valid(maximum_entities_count, default_entity_creation_voucher_upper_bound)?;
-
-            // Ensure max number of classes limit not reached
-            Self::ensure_class_limit_not_reached()?;
-
-            // Ensure ClassNameLengthConstraint conditions satisfied
-            Self::ensure_class_name_is_valid(&name)?;
-
-            // Ensure ClassDescriptionLengthConstraint conditions satisfied
-            Self::ensure_class_description_is_valid(&description)?;
-
-            // Perform required checks to ensure class_maintainers under provided class_permissions are valid
-            let class_maintainers = class_permissions.get_maintainers();
-            Self::ensure_class_maintainers_are_valid(class_maintainers)?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Create new Class instance from provided values
-            let class = Class::new(
-                class_permissions, name, description, maximum_entities_count, default_entity_creation_voucher_upper_bound
-            );
-
-            let class_id = Self::next_class_id();
-
-            // Add new `Class` to runtime storage
-            <ClassById<T>>::insert(&class_id, class);
-
-            // Increment the next class id:
-            <NextClassId<T>>::mutate(|n| *n += T::ClassId::one());
-
-            // Trigger event
-            Self::deposit_event(RawEvent::ClassCreated(class_id));
-            Ok(())
-        }
-
-        /// Add curator group under given `curator_group_id` as `Class` maintainer
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn add_maintainer_to_class(
-            origin,
-            class_id: T::ClassId,
-            curator_group_id: T::CuratorGroupId,
-        ) -> DispatchResult {
-
-            // Ensure given origin is lead
-            ensure_is_lead::<T>(origin)?;
-
-            // Ensure Class under provided class_id exist, retrieve corresponding one
-            let class = Self::ensure_known_class_id(class_id)?;
-
-            // Ensure CuratorGroup under provided curator_group_id exist, retrieve corresponding one
-            Self::ensure_curator_group_under_given_id_exists(&curator_group_id)?;
-
-            // Ensure the max number of maintainers per Class limit not reached
-            let class_permissions = class.get_permissions_ref();
-
-            // Ensure max number of maintainers per Class constraint satisfied
-            Self::ensure_maintainers_limit_not_reached(class_permissions.get_maintainers())?;
-
-            // Ensure maintainer under provided curator_group_id is not added to the Class maintainers set yet
-            class_permissions.ensure_maintainer_does_not_exist::<T>(&curator_group_id)?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Insert `curator_group_id` into `maintainers` set, associated with given `Class`
-            <ClassById<T>>::mutate(class_id, |class|
-                class.get_permissions_mut().get_maintainers_mut().insert(curator_group_id)
-            );
-
-            // Increment the number of classes, curator group under given `curator_group_id` maintains
-            Self::increment_number_of_classes_maintained_by_curator_group(curator_group_id);
-
-            // Trigger event
-            Self::deposit_event(RawEvent::MaintainerAdded(class_id, curator_group_id));
-            Ok(())
-        }
-
-        /// Remove curator group under given `curator_group_id` from `Class` maintainers set
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn remove_maintainer_from_class(
-            origin,
-            class_id: T::ClassId,
-            curator_group_id: T::CuratorGroupId,
-        ) -> DispatchResult {
-
-            // Ensure given origin is lead
-            ensure_is_lead::<T>(origin)?;
-
-            // Ensure Class under given id exists, return corresponding one
-            let class = Self::ensure_known_class_id(class_id)?;
-
-            // Ensure maintainer under provided curator_group_id was previously added
-            // to the maintainers set, associated with corresponding Class
-            class.get_permissions_ref().ensure_maintainer_exists::<T>(&curator_group_id)?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Remove `curator_group_id` from `maintainers` set, associated with given `Class`
-            <ClassById<T>>::mutate(class_id, |class|
-                class.get_permissions_mut().get_maintainers_mut().remove(&curator_group_id)
-            );
-
-            // Decrement the number of classes, curator group under given `curator_group_id` maintains
-            Self::decrement_number_of_classes_maintained_by_curator_group(curator_group_id);
-
-            // Trigger event
-            Self::deposit_event(RawEvent::MaintainerRemoved(class_id, curator_group_id));
-            Ok(())
-        }
-
-        /// Update `ClassPermissions` under specific `class_id`
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn update_class_permissions(
-            origin,
-            class_id: T::ClassId,
-            updated_any_member: Option<bool>,
-            updated_entity_creation_blocked: Option<bool>,
-            updated_all_entity_property_values_locked: Option<bool>,
-            updated_maintainers: Option<BTreeSet<T::CuratorGroupId>>,
-        ) -> DispatchResult {
-
-            // Ensure given origin is lead
-            ensure_is_lead::<T>(origin)?;
-
-            // Ensure Class under given id exists, return corresponding one
-            let class = Self::ensure_known_class_id(class_id)?;
-
-            // Perform required checks to ensure class_maintainers are valid
-            if let Some(ref updated_maintainers) = updated_maintainers {
-                Self::ensure_class_maintainers_are_valid(updated_maintainers)?;
-            }
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            let class_permissions = class.get_permissions();
-
-            // Make updated class_permissions from parameters provided
-            let updated_class_permissions = Self::make_updated_class_permissions(
-                &class_permissions, updated_any_member, updated_entity_creation_blocked,
-                updated_all_entity_property_values_locked, updated_maintainers
-            );
-
-            // If class_permissions update has been performed
-            if let Some(updated_class_permissions) = updated_class_permissions  {
-
-                // Decrement number of classes, maintained by each curator group removed from maintainers set.
-                let curator_group_ids_to_decrement_number_of_classes: BTreeSet<_> =
-                    class_permissions.get_maintainers().difference(updated_class_permissions.get_maintainers()).cloned().collect();
-
-                Self::decrement_number_of_classes_maintained_by_curator_groups(curator_group_ids_to_decrement_number_of_classes);
-
-                // Increment number of classes, maintained by each curator group added to maintainers set.
-                let curator_group_ids_to_increment_number_of_classes: BTreeSet<_> =
-                    updated_class_permissions.get_maintainers().difference(class_permissions.get_maintainers()).cloned().collect();
-
-                Self::increment_number_of_classes_maintained_by_curator_groups(curator_group_ids_to_increment_number_of_classes);
-
-                // Update `class_permissions` under given class id
-                <ClassById<T>>::mutate(class_id, |class| {
-                    class.update_permissions(updated_class_permissions)
-                });
-
-                // Trigger event
-                Self::deposit_event(RawEvent::ClassPermissionsUpdated(class_id));
-            }
-
-            Ok(())
-        }
-
-        /// Create new class schema from existing property ids and new properties
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn add_class_schema(
-            origin,
-            class_id: T::ClassId,
-            existing_properties: BTreeSet<PropertyId>,
-            new_properties: Vec<Property<T::ClassId>>
-        ) -> DispatchResult {
-
-            // Ensure given origin is lead
-            ensure_is_lead::<T>(origin)?;
-
-            // Ensure Class under given id exists, return corresponding one
-            let class = Self::ensure_known_class_id(class_id)?;
-
-            // Ensure Schemas limit per Class not reached
-            class.ensure_schemas_limit_not_reached::<T>()?;
-
-            // Ensure both existing and new properties for future Schema are not empty
-            Self::ensure_non_empty_schema(&existing_properties, &new_properties)?;
-
-            // Ensure max number of properties per Schema limit not reached
-            class.ensure_properties_limit_not_reached::<T>(&new_properties)?;
-
-            // Complete all checks to ensure all provided new_properties are valid
-            Self::ensure_all_properties_are_valid(&new_properties)?;
-
-            // Id of next Class Schema being added
-            let schema_id = class.get_schemas().len() as SchemaId;
-
-            let class_properties = class.get_properties();
-
-            // Ensure all Property names are unique within Class
-            Self::ensure_all_property_names_are_unique(&class_properties, &new_properties)?;
-
-            // Ensure existing_properties are valid indices of properties, corresponding to chosen Class
-            Self::ensure_schema_properties_are_valid_indices(&existing_properties, &class_properties)?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Create `Schema` instance from existing and new property ids
-            let schema = Self::create_class_schema(existing_properties, &class_properties, &new_properties);
-
-            // Update class properties after new `Schema` added
-            let updated_class_properties = Self::make_updated_class_properties(class_properties, new_properties);
-
-            // Update Class properties and schemas
-            <ClassById<T>>::mutate(class_id, |class| {
-                class.set_properties(updated_class_properties);
-                class.get_schemas_mut().push(schema);
-            });
-
-            // Trigger event
-            Self::deposit_event(RawEvent::ClassSchemaAdded(class_id, schema_id));
-
-            Ok(())
-        }
-
-        /// Update `schema_status` under specific `schema_id` in `Class`
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn update_class_schema_status(
-            origin,
-            class_id: T::ClassId,
-            schema_id: SchemaId,
-            schema_status: bool
-        ) -> DispatchResult {
-
-            // Ensure given origin is lead
-            ensure_is_lead::<T>(origin)?;
-
-            // Ensure Class under given id exists, return corresponding one
-            let class = Self::ensure_known_class_id(class_id)?;
-
-            // Ensure Class already contains schema under provided schema_id
-            class.ensure_schema_id_exists::<T>(schema_id)?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Update class schema status
-            <ClassById<T>>::mutate(class_id, |class| {
-                class.update_schema_status(schema_id, schema_status)
-            });
-
-            // Trigger event
-            Self::deposit_event(RawEvent::ClassSchemaStatusUpdated(class_id, schema_id, schema_status));
-            Ok(())
-        }
-
-        /// Update entity permissions
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn update_entity_permissions(
-            origin,
-            entity_id: T::EntityId,
-            updated_frozen: Option<bool>,
-            updated_referenceable: Option<bool>
-        ) -> DispatchResult {
-
-            // Ensure given origin is lead
-            ensure_is_lead::<T>(origin)?;
-
-            // Ensure Entity under given id exists, return corresponding one
-            let entity = Self::ensure_known_entity_id(entity_id)?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Make updated entity_permissions from parameters provided
-            let entity_permissions = entity.get_permissions();
-
-            let updated_entity_permissions =
-                Self::make_updated_entity_permissions(entity_permissions, updated_frozen, updated_referenceable);
-
-            // Update entity permissions under given entity id
-            if let Some(updated_entity_permissions) = updated_entity_permissions {
-
-                <EntityById<T>>::mutate(entity_id, |entity| {
-                    entity.update_permissions(updated_entity_permissions)
-                });
-
-                // Trigger event
-                Self::deposit_event(RawEvent::EntityPermissionsUpdated(entity_id));
-            }
-            Ok(())
-        }
-
-        /// Transfer ownership to new `EntityController` for `Entity` under given `entity_id`
-        /// `new_property_value_references_with_same_owner_flag_set` should be provided manually
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn transfer_entity_ownership(
-            origin,
-            entity_id: T::EntityId,
-            new_controller: EntityController<T::MemberId>,
-            new_property_value_references_with_same_owner_flag_set: BTreeMap<PropertyId, InputPropertyValue<T>>
-        ) -> DispatchResult {
-
-            // Ensure given origin is lead
-            ensure_is_lead::<T>(origin)?;
-
-            // Ensure Entity under given entity_id exists, retrieve corresponding Entity & Class
-            let (entity, class) = Self::ensure_known_entity_and_class(entity_id)?;
-
-            // Ensure provided new_entity_controller is not equal to current one
-            entity.get_permissions_ref().ensure_controllers_are_not_equal::<T>(&new_controller)?;
-
-            // Ensure any inbound InputPropertyValue::Reference with same_owner flag set points to the given Entity
-            entity.ensure_inbound_same_owner_rc_is_zero::<T>()?;
-
-            let class_properties = class.get_properties();
-
-            let class_id = entity.get_class_id();
-
-            let entity_property_values = entity.get_values();
-
-            // Create wrapper structure from provided entity_property_values and their corresponding Class properties
-            let values_for_existing_properties = match StoredValuesForExistingProperties::from(&class_properties, &entity_property_values) {
-                Ok(values_for_existing_properties) => values_for_existing_properties,
-                Err(e) => {
-                    debug_assert!(false, "Should not fail! {:?}", e);
-                    return Err(e.into())
-                }
-            };
-
-            // Filter provided values_for_existing_properties, leaving only `Reference`'s with `SameOwner` flag set
-            // Retrieve the set of corresponding property ids
-            let entity_property_id_references_with_same_owner_flag_set =
-                Self::get_property_id_references_with_same_owner_flag_set(values_for_existing_properties);
-
-            // Ensure all ids of provided `new_property_value_references_with_same_owner_flag_set`
-            // corresponding to property ids of respective Class Property references with same owner flag set
-            Self::ensure_only_reference_ids_with_same_owner_flag_set_provided(
-                &entity_property_id_references_with_same_owner_flag_set,
-                &new_property_value_references_with_same_owner_flag_set
-            )?;
-
-            // Retrieve ids of all entity property values, that are references with same owner flag set and which are not provided
-            // in new property value references with same owner flag set
-            let unused_property_id_references_with_same_owner_flag_set = Self::compute_unused_property_ids(
-                &new_property_value_references_with_same_owner_flag_set, &entity_property_id_references_with_same_owner_flag_set
-            );
-
-            // Perform checks to ensure all required property_values under provided unused_schema_property_ids provided
-            Self::ensure_all_required_properties_provided(&class_properties, &unused_property_id_references_with_same_owner_flag_set)?;
-
-            // Create wrapper structure from provided new_property_value_references_with_same_owner_flag_set and their corresponding Class properties
-            let new_values_for_existing_properties = InputValuesForExistingProperties::from(
-                &class_properties, &new_property_value_references_with_same_owner_flag_set
-            )?;
-
-            // Ensure all provided `new_property_value_references_with_same_owner_flag_set` are valid
-            Self::ensure_are_valid_references_with_same_owner_flag_set(
-                new_values_for_existing_properties, &new_controller
-            )?;
-
-            let new_output_property_value_references_with_same_owner_flag_set = Self::make_output_property_values(new_property_value_references_with_same_owner_flag_set);
-
-            // Compute StoredPropertyValues, which respective Properties have unique flag set
-            // (skip PropertyIds, which respective property values under this Entity are default and non required)
-            let new_output_values_for_existing_properties =
-                StoredValuesForExistingProperties::from(&class_properties, &new_output_property_value_references_with_same_owner_flag_set)?;
-
-            // Compute new unique property value hashes.
-            // Ensure new property value hashes with `unique` flag set are `unique` on `Class` level
-            let new_unique_hashes = Self::ensure_new_property_values_respect_uniquness(
-                class_id, new_output_values_for_existing_properties,
-            )?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Used to compute old unique hashes, that should be substituted with new ones.
-            let old_unique_hashes =
-                Self::compute_old_unique_hashes(&new_output_property_value_references_with_same_owner_flag_set, &entity_property_values);
-
-            // Add property values, that should be unique on Class level
-            Self::add_unique_property_value_hashes(class_id, new_unique_hashes);
-
-            // Remove unique hashes, that were substituted with new ones.
-            Self::remove_unique_property_value_hashes(class_id, old_unique_hashes);
-
-            // Make updated entity_property_values from parameters provided
-            let entity_property_values_updated =
-                    Self::make_updated_property_value_references_with_same_owner_flag_set(
-                        unused_property_id_references_with_same_owner_flag_set, &entity_property_values,
-                        &new_output_property_value_references_with_same_owner_flag_set,
-                    );
-
-            // Transfer entity ownership
-            let entities_inbound_rcs_delta = if let Some(entity_property_values_updated) = entity_property_values_updated {
-
-
-                // Calculate entities reference counter side effects for current operation
-                let entities_inbound_rcs_delta =
-                    Self::get_updated_inbound_rcs_delta(
-                        entity_id, class_properties, entity_property_values, new_output_property_value_references_with_same_owner_flag_set
-                    )?;
-
-                // Update InboundReferenceCounter, based on previously calculated ReferenceCounterSideEffects, for each Entity involved
-                Self::update_entities_rcs(&entities_inbound_rcs_delta);
-
-                <EntityById<T>>::mutate(entity_id, |entity| {
-
-                    // Update current Entity property values with updated ones
-                    entity.set_values(entity_property_values_updated);
-
-                    // Set up new controller for the current Entity instance
-                    entity.get_permissions_mut().set_conroller(new_controller.clone());
-                });
-
-                entities_inbound_rcs_delta
-            } else {
-                // Set up new controller for the current Entity instance
-                <EntityById<T>>::mutate(entity_id, |entity| {
-                    entity.get_permissions_mut().set_conroller(new_controller.clone());
-                });
-
-                None
-            };
-
-            // Trigger event
-            Self::deposit_event(RawEvent::EntityOwnershipTransfered(entity_id, new_controller, entities_inbound_rcs_delta));
-
-            Ok(())
-        }
-
-        // ======
-        // The next set of extrinsics can be invoked by anyone who can properly sign for provided value of `Actor<T::CuratorGroupId, T::CuratorId, T::MemberId>`.
-        // ======
-
-        /// Create entity.
-        /// If someone is making an entity of this class for first time,
-        /// then a voucher is also added with the class limit as the default limit value.
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn create_entity(
-            origin,
-            class_id: T::ClassId,
-            actor: Actor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
-        ) -> DispatchResult {
-
-            let account_id = ensure_signed(origin)?;
-
-            // Ensure Class under given id exists, return corresponding one
-            let class = Self::ensure_class_exists(class_id)?;
-
-            // Ensure maximum entities limit per class not reached
-            class.ensure_maximum_entities_count_limit_not_reached::<T>()?;
-
-            let class_permissions = class.get_permissions_ref();
-
-            // Ensure entities creation is not blocked on Class level
-            class_permissions.ensure_entity_creation_not_blocked::<T>()?;
-
-            // Ensure actor can create entities
-            Self::ensure_can_create_entities(&class_permissions, &account_id, &actor)?;
-
-            let entity_controller = EntityController::<T::MemberId>::from_actor::<T>(&actor);
-
-            // Check if entity creation voucher exists
-            let voucher_exists = if <EntityCreationVouchers<T>>::contains_key(class_id, &entity_controller) {
-
-                // Ensure voucher limit not reached
-                Self::entity_creation_vouchers(class_id, &entity_controller).ensure_voucher_limit_not_reached()?;
-                true
-            } else {
-                false
-            };
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Create voucher, update if exists
-
-            if voucher_exists {
-
-                // Increment number of created entities count, if specified voucher already exist
-                <EntityCreationVouchers<T>>::mutate(class_id, &entity_controller, |entity_creation_voucher| {
-                    entity_creation_voucher.increment_created_entities_count()
-                });
-            } else {
-
-                // Create new voucher for given entity creator with default limit
-                let mut entity_creation_voucher = EntityCreationVoucher::new(class.get_default_entity_creation_voucher_upper_bound());
-
-                // Increase created entities count by 1 to maintain valid entity_creation_voucher state after following Entity added
-                entity_creation_voucher.increment_created_entities_count();
-                <EntityCreationVouchers<T>>::insert(class_id, entity_controller.clone(), entity_creation_voucher);
-            }
-
-            // Create new entity
-
-            let entity_id = Self::next_entity_id();
-
-            let new_entity = Entity::<T::ClassId, T::MemberId, T::Hash, T::EntityId, T::Nonce>::new(
-                entity_controller,
-                class_id,
-                BTreeSet::new(),
-                BTreeMap::new(),
-            );
-
-            // Save newly created entity:
-            <EntityById<T>>::insert(entity_id, new_entity);
-
-            // Increment the next entity id:
-            <NextEntityId<T>>::mutate(|n| *n += T::EntityId::one());
-
-            // Increment number of entities, associated with this class
-            <ClassById<T>>::mutate(class_id, |class| {
-                class.increment_entities_count();
-            });
-
-            // Trigger event
-            Self::deposit_event(RawEvent::EntityCreated(actor, entity_id));
-            Ok(())
-        }
-
-        /// Remove `Entity` under provided `entity_id`
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn remove_entity(
-            origin,
-            actor: Actor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
-            entity_id: T::EntityId,
-        ) -> DispatchResult {
-
-            let account_id = ensure_signed(origin)?;
-
-            // Retrieve Class, Entity and EntityAccessLevel for the actor, attemting to perform operation
-            let (class, entity, access_level) = Self::ensure_class_entity_and_access_level(account_id, entity_id, &actor)?;
-
-            // Ensure actor with given EntityAccessLevel can remove entity
-            EntityPermissions::<T::MemberId>::ensure_group_can_remove_entity::<T>(access_level)?;
-
-            // Ensure any inbound InputPropertyValue::Reference points to the given Entity
-            entity.ensure_rc_is_zero::<T>()?;
-
-            let class_properties = class.get_properties();
-
-            let class_id = entity.get_class_id();
-
-            let entity_values = entity.get_values();
-
-            let values_for_existing_properties = match StoredValuesForExistingProperties::<T>::from(&class_properties, &entity_values) {
-                Ok(values_for_existing_properties) => values_for_existing_properties,
-                Err(e) => {
-                    debug_assert!(false, "Should not fail! {:?}", e);
-                    return Err(e.into())
-                }
-            };
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            let unique_property_value_hashes = values_for_existing_properties.compute_unique_hashes();
-
-            // Calculate entities reference counter side effects for current operation
-            let entities_inbound_rcs_delta = Self::calculate_entities_inbound_rcs_delta(entity_id, values_for_existing_properties, DeltaMode::Decrement);
-
-            // Update InboundReferenceCounter, based on previously calculated entities_inbound_rcs_delta, for each Entity involved
-            Self::update_entities_rcs(&entities_inbound_rcs_delta);
-
-            // Remove property value entries, that should be unique on Class level
-            Self::remove_unique_property_value_hashes(class_id, unique_property_value_hashes);
-
-            // Remove entity
-            <EntityById<T>>::remove(entity_id);
-
-            // Decrement class entities counter
-            <ClassById<T>>::mutate(class_id, |class| class.decrement_entities_count());
-
-            let entity_controller = EntityController::<T::MemberId>::from_actor::<T>(&actor);
-
-            // Decrement entity_creation_voucher after entity removal perfomed
-            <EntityCreationVouchers<T>>::mutate(class_id, entity_controller, |entity_creation_voucher| {
-                entity_creation_voucher.decrement_created_entities_count();
-            });
-
-            // Trigger event
-            Self::deposit_event(RawEvent::EntityRemoved(actor, entity_id));
-            Ok(())
-        }
-
-        /// Add schema support to entity under given `schema_id` and provided `property_values`
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn add_schema_support_to_entity(
-            origin,
-            actor: Actor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
-            entity_id: T::EntityId,
-            schema_id: SchemaId,
-            new_property_values: BTreeMap<PropertyId, InputPropertyValue<T>>
-        ) -> DispatchResult {
-
-            let account_id = ensure_signed(origin)?;
-
-            // Retrieve Class, Entity and EntityAccessLevel for the actor, attemting to perform operation
-            let (class, entity, _) = Self::ensure_class_entity_and_access_level(account_id, entity_id, &actor)?;
-
-            // Ensure Class Schema under given index exists, return corresponding Schema
-            let schema = class.ensure_schema_exists::<T>(schema_id)?.to_owned();
-
-            let class_properties = class.get_properties();
-
-            // Create wrapper structure from provided new_property_values and their corresponding Class properties
-            let new_values_for_existing_properties = InputValuesForExistingProperties::from(&class_properties, &new_property_values)?;
-
-            // Ensure Schema under given id is not added to given Entity yet
-            entity.ensure_schema_id_is_not_added::<T>(schema_id)?;
-
-            // Ensure provided new_property_values are not added to the Entity values map yet
-            entity.ensure_property_values_are_not_added(&new_property_values)?;
-
-            // Ensure provided schema can be added to the Entity
-            schema.ensure_is_active::<T>()?;
-
-            // Ensure all provided new property values are for properties in the given schema
-            schema.ensure_has_properties(&new_property_values)?;
-
-            // Retrieve Schema property ids, which are not provided in new_property_values
-            let unused_schema_property_ids = Self::compute_unused_property_ids(&new_property_values, schema.get_properties());
-
-            // Perform checks to ensure all required property_values under provided unused_schema_property_ids provided
-            Self::ensure_all_required_properties_provided(&class_properties, &unused_schema_property_ids)?;
-
-            // Ensure all property_values under given Schema property ids are valid
-            let entity_controller = entity.get_permissions_ref().get_controller();
-
-            // Validate all values, provided in new_values_for_existing_properties,
-            // against the type of its Property and check any additional constraints
-            Self::ensure_property_values_are_valid(&entity_controller, &new_values_for_existing_properties)?;
-
-            let class_id = entity.get_class_id();
-
-            let entity_property_values = entity.get_values();
-
-            let new_output_property_values = Self::make_output_property_values(new_property_values);
-
-            // Compute updated entity values, after new schema support added
-            let entity_values_updated = Self::make_updated_entity_property_values(
-                schema, entity_property_values, &new_output_property_values
-            );
-
-            let new_output_values_for_existing_properties = StoredValuesForExistingProperties::from(&class_properties, &new_output_property_values)?;
-
-            // Retrieve StoredPropertyValues, which respective Properties have unique flag set
-            // (skip PropertyIds, which respective property values under this Entity are default and non required)
-            let new_unique_property_value_hashes = new_output_values_for_existing_properties.compute_unique_hashes();
-
-            // Ensure all provided Properties with unique flag set are unique on Class level
-            Self::ensure_property_value_hashes_unique_option_satisfied(class_id, &new_unique_property_value_hashes)?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Add property value hashes, that should be unique on Class level
-            Self::add_unique_property_value_hashes(class_id, new_unique_property_value_hashes);
-
-            // Calculate entities reference counter side effects for current operation
-            let entities_inbound_rcs_delta = Self::calculate_entities_inbound_rcs_delta(
-                entity_id, new_output_values_for_existing_properties, DeltaMode::Increment
-            );
-
-            // Update InboundReferenceCounter, based on previously calculated entities_inbound_rcs_delta, for each Entity involved
-            Self::update_entities_rcs(&entities_inbound_rcs_delta);
-
-            // Add schema support to `Entity` under given `entity_id`
-            <EntityById<T>>::mutate(entity_id, |entity| {
-
-                // Add a new schema to the list of schemas supported by this entity.
-                entity.get_supported_schemas_mut().insert(schema_id);
-
-                // Update entity values only if new properties have been added.
-                if entity_values_updated.len() > entity.get_values_ref().len() {
-                    entity.set_values(entity_values_updated);
-                }
-            });
-
-            // Trigger event
-            Self::deposit_event(RawEvent::EntitySchemaSupportAdded(actor, entity_id, schema_id, entities_inbound_rcs_delta));
-            Ok(())
-        }
-
-        /// Update `Entity` `InputPropertyValue`'s with provided ones
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn update_entity_property_values(
-            origin,
-            actor: Actor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
-            entity_id: T::EntityId,
-            new_property_values: BTreeMap<PropertyId, InputPropertyValue<T>>
-        ) -> DispatchResult {
-
-            let account_id = ensure_signed(origin)?;
-
-            // Retrieve Class, Entity and EntityAccessLevel for the actor, attemting to perform operation
-            let (class, entity, access_level) = Self::ensure_class_entity_and_access_level(account_id, entity_id, &actor)?;
-
-            // Ensure property values were not locked on Class level
-            class.ensure_property_values_unlocked::<T>()?;
-
-            let entity_values_ref = entity.get_values_ref();
-
-            // Filter new_property_values, that are identical to entity_property_values.
-            // Get `new_property_values`, that are not in `entity_property_values`
-            let new_property_values = Self::try_filter_identical_property_values(entity_values_ref, new_property_values);
-
-            // Ensure all provided new_property_values are already added to the current Entity instance
-            Self::ensure_all_property_values_are_already_added(entity_values_ref, &new_property_values)?;
-
-            let class_properties = class.get_properties();
-
-            // Create wrapper structure from new_property_values and their corresponding Class properties
-            let new_values_for_existing_properties = InputValuesForExistingProperties::from(&class_properties, &new_property_values)?;
-
-            // Ensure all provided property values are unlocked for the actor with given access_level
-            Self::ensure_all_property_values_are_unlocked_from(&new_values_for_existing_properties, access_level)?;
-
-            let entity_controller = entity.get_permissions_ref().get_controller();
-
-            // Validate all values, provided in values_for_existing_properties,
-            // against the type of its Property and check any additional constraints
-            Self::ensure_property_values_are_valid(&entity_controller, &new_values_for_existing_properties)?;
-
-            let class_id = entity.get_class_id();
-
-            // Get current property values of an Entity
-
-            let entity_property_values = entity.get_values();
-
-            let new_output_property_values = Self::make_output_property_values(new_property_values);
-
-            // Compute StoredPropertyValues, which respective Properties have unique flag set
-            // (skip PropertyIds, which respective property values under this Entity are default and non required)
-            let new_output_values_for_existing_properties =
-                StoredValuesForExistingProperties::from(&class_properties, &new_output_property_values)?;
-
-            // Compute new unique property value hashes.
-            // Ensure new property value hashes with `unique` flag set are `unique` on `Class` level
-            let new_unique_hashes = Self::ensure_new_property_values_respect_uniquness(
-                class_id, new_output_values_for_existing_properties,
-            )?;
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            // Used to compute old unique hashes, that should be substituted with new ones.
-            let old_unique_hashes =
-                Self::compute_old_unique_hashes(&new_output_property_values, &entity_property_values);
-
-            // Add property value hashes, that should be unique on Class level
-            Self::add_unique_property_value_hashes(class_id, new_unique_hashes);
-
-            // Remove unique hashes, that were substituted with new ones. (if some).
-            Self::remove_unique_property_value_hashes(class_id, old_unique_hashes);
-
-            // Make updated entity_property_values from current entity_property_values and new_output_property_values provided
-            let entity_property_values_updated =
-                Self::make_updated_property_values(&entity_property_values, &new_output_property_values);
-
-            // If property values should be updated
-            if let Some(entity_property_values_updated) = entity_property_values_updated {
-
-                // Calculate entities reference counter side effects for current operation (should always be safe)
-                let entities_inbound_rcs_delta =
-                    Self::get_updated_inbound_rcs_delta(entity_id, class_properties, entity_property_values, new_output_property_values)?;
-
-                // Update InboundReferenceCounter, based on previously calculated entities_inbound_rcs_delta, for each Entity involved
-                Self::update_entities_rcs(&entities_inbound_rcs_delta);
-
-                // Update entity property values
-                <EntityById<T>>::mutate(entity_id, |entity| {
-                    entity.set_values(entity_property_values_updated);
-                });
-
-                // Trigger event
-                Self::deposit_event(RawEvent::EntityPropertyValuesUpdated(actor, entity_id, entities_inbound_rcs_delta));
-            }
-
-            Ok(())
-        }
-
-        /// Clear `PropertyValueVec` under given `entity_id` & `in_class_schema_property_id`
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn clear_entity_property_vector(
-            origin,
-            actor: Actor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
-            entity_id: T::EntityId,
-            in_class_schema_property_id: PropertyId
-        ) -> DispatchResult {
-
-            let account_id = ensure_signed(origin)?;
-
-            // Retrieve Class, Entity and EntityAccessLevel for the actor, attemting to perform operation
-            let (class, entity, access_level) = Self::ensure_class_entity_and_access_level(account_id, entity_id, &actor)?;
-
-            // Ensure Property under given PropertyId is unlocked from actor with given EntityAccessLevel
-            // Retrieve corresponding Property by value
-            let property = class.ensure_class_property_type_unlocked_from::<T>(
-                in_class_schema_property_id,
-                access_level,
-            )?;
-
-            // Ensure InputPropertyValue under given in_class_schema_property_id is Vector
-            let property_value_vector =
-                entity.ensure_property_value_is_vec::<T>(in_class_schema_property_id)?;
-
-            // Calculate side effects for clear_property_vector operation, based on property_value_vector provided and its respective property.
-            let entities_inbound_rcs_delta = Self::make_side_effects_for_clear_property_vector_operation(&property_value_vector, &property);
-
-            // Clear property_value_vector.
-            let empty_property_value_vector = Self::clear_property_vector(property_value_vector.clone());
-
-            let class_id = entity.get_class_id();
-
-            // Compute old and new vec unique property value hash.
-            // Ensure new property value hash with `unique` flag set is `unique` on `Class` level
-            let vec_property_value_hashes = if property.unique {
-                Some(
-                    Self::ensure_vec_property_value_hashes(class_id, in_class_schema_property_id, &empty_property_value_vector, property_value_vector)?
-                )
-            } else {
-                None
-            };
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            if let Some((new_property_value_hash, old_property_value_hash)) = vec_property_value_hashes {
-                // Add property value hash, that should be unique on `Class` level
-                Self::add_unique_property_value_hash(class_id, in_class_schema_property_id, new_property_value_hash);
-
-                // Remove property value hash, that should be unique on `Class` level
-                Self::remove_unique_property_value_hash(class_id, in_class_schema_property_id, old_property_value_hash);
-            }
-
-            // Decrease reference counters of involved entities (if some)
-            Self::update_entities_rcs(&entities_inbound_rcs_delta);
-
-            // Insert empty_property_value_vector into entity_property_values mapping at in_class_schema_property_id.
-            // Retrieve updated entity_property_values
-            let entity_values_updated = Self::insert_at_in_class_schema_property_id(
-                entity.get_values(), in_class_schema_property_id, empty_property_value_vector
-            );
-
-            // Update entity property values
-            <EntityById<T>>::mutate(entity_id, |entity| {
-                entity.set_values(entity_values_updated);
-            });
-
-            // Trigger event
-            Self::deposit_event(
-                RawEvent::VectorCleared(
-                    actor, entity_id, in_class_schema_property_id, entities_inbound_rcs_delta
-                )
-            );
-
-            Ok(())
-        }
-
-        /// Remove value at given `index_in_property_vector`
-        /// from `PropertyValueVec` under `in_class_schema_property_id`
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn remove_at_entity_property_vector(
-            origin,
-            actor: Actor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
-            entity_id: T::EntityId,
-            in_class_schema_property_id: PropertyId,
-            index_in_property_vector: VecMaxLength,
-            nonce: T::Nonce
-        ) -> DispatchResult {
-
-            let account_id = ensure_signed(origin)?;
-
-            // Retrieve Class, Entity and EntityAccessLevel for the actor, attemting to perform operation
-            let (class, entity, access_level) = Self::ensure_class_entity_and_access_level(account_id, entity_id, &actor)?;
-
-            // Ensure Property under given PropertyId is unlocked from actor with given EntityAccessLevel
-            // Retrieve corresponding Property by value
-            let property = class.ensure_class_property_type_unlocked_from::<T>(
-                in_class_schema_property_id,
-                access_level,
-            )?;
-
-            // Ensure InputPropertyValue under given in_class_schema_property_id is Vector
-            let property_value_vector =
-                entity.ensure_property_value_is_vec::<T>(in_class_schema_property_id)?;
-
-            // Ensure `VecInputPropertyValue` nonce is equal to the provided one.
-            // Used to to avoid possible data races, when performing vector specific operations
-            property_value_vector.ensure_nonce_equality::<T>(nonce)?;
-
-            // Ensure, provided index_in_property_vec is valid index of VecInputValue
-            property_value_vector
-                .ensure_index_in_property_vector_is_valid::<T>(index_in_property_vector)?;
-
-            let involved_entity_id = property_value_vector
-                .get_vec_value_ref()
-                .get_involved_entities()
-                .and_then(|involved_entities| involved_entities.get(index_in_property_vector as usize).copied());
-
-            // Remove value at in_class_schema_property_id in property value vector
-            // Get VecInputPropertyValue wrapped in InputPropertyValue
-            let property_value_vector_updated = Self::remove_at_index_in_property_vector(
-                property_value_vector.clone(), index_in_property_vector
-            );
-
-            let class_id = entity.get_class_id();
-
-            // Compute old and new vec unique property value hash.
-            // Ensure new property value hash with `unique` flag set is `unique` on `Class` level
-            let vec_property_value_hashes = if property.unique {
-                Some(
-                    Self::ensure_vec_property_value_hashes(class_id, in_class_schema_property_id, &property_value_vector_updated, property_value_vector)?
-                )
-            } else {
-                None
-            };
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            if let Some((new_property_value_hash, old_property_value_hash)) = vec_property_value_hashes {
-                // Add property value hash, that should be unique on `Class` level
-                Self::add_unique_property_value_hash(class_id, in_class_schema_property_id, new_property_value_hash);
-
-                // Remove property value hash, that should be unique on `Class` level
-                Self::remove_unique_property_value_hash(class_id, in_class_schema_property_id, old_property_value_hash);
-            }
-
-            // Insert updated propery value into entity_property_values mapping at in_class_schema_property_id.
-            let entity_values_updated = Self::insert_at_in_class_schema_property_id(
-                entity.get_values(), in_class_schema_property_id, property_value_vector_updated
-            );
-
-            let involved_entity_and_side_effect = if let Some(involved_entity_id) = involved_entity_id {
-                // Decrease reference counter of involved entity (if some)
-                let same_controller_status = property.property_type.same_controller_status();
-                let rc_delta = EntityReferenceCounterSideEffect::atomic(same_controller_status, DeltaMode::Decrement);
-
-                // Update InboundReferenceCounter of involved entity, based on previously calculated rc_delta
-                Self::update_entity_rc(involved_entity_id, rc_delta);
-                Some((involved_entity_id, rc_delta))
-            } else {
-                None
-            };
-
-            // Update entity property values
-            <EntityById<T>>::mutate(entity_id, |entity| {
-                entity.set_values(entity_values_updated);
-            });
-
-            // Trigger event
-            Self::deposit_event(
-                RawEvent::RemovedAtVectorIndex(
-                    actor, entity_id, in_class_schema_property_id, index_in_property_vector,
-                    nonce + T::Nonce::one(), involved_entity_and_side_effect
-                )
-            );
-
-            Ok(())
-        }
-
-        /// Insert `SingleInputPropertyValue` at given `index_in_property_vector`
-        /// into `PropertyValueVec` under `in_class_schema_property_id`
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn insert_at_entity_property_vector(
-            origin,
-            actor: Actor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
-            entity_id: T::EntityId,
-            in_class_schema_property_id: PropertyId,
-            index_in_property_vector: VecMaxLength,
-            value: InputValue<T>,
-            nonce: T::Nonce
-        ) -> DispatchResult {
-
-            let account_id = ensure_signed(origin)?;
-
-            // Retrieve Class, Entity and EntityAccessLevel for the actor, attemting to perform operation
-            let (class, entity, access_level) = Self::ensure_class_entity_and_access_level(account_id, entity_id, &actor)?;
-
-            // Ensure Property under given PropertyId is unlocked from actor with given EntityAccessLevel
-            // Retrieve corresponding Property by value
-            let property = class.ensure_class_property_type_unlocked_from::<T>(
-                in_class_schema_property_id,
-                access_level,
-            )?;
-
-            // Ensure InputPropertyValue under given in_class_schema_property_id is Vector
-            let property_value_vector =
-                entity.ensure_property_value_is_vec::<T>(in_class_schema_property_id)?;
-
-            // Ensure `VecInputPropertyValue` nonce is equal to the provided one.
-            // Used to to avoid possible data races, when performing vector specific operations
-            property_value_vector.ensure_nonce_equality::<T>(nonce)?;
-
-            let entity_controller = entity.get_permissions_ref().get_controller();
-
-            // Ensure property_value type is equal to the property_value_vector type and check all constraints
-            Property::<T::ClassId>::ensure_property_value_can_be_inserted_at_property_vector(
-                &property,
-                &value,
-                &property_value_vector,
-                index_in_property_vector,
-                entity_controller,
-            )?;
-
-            let involved_entity = value.get_involved_entity();
-
-            // Insert SingleInputPropertyValue at in_class_schema_property_id into property value vector
-            // Get VecInputPropertyValue wrapped in InputPropertyValue
-            let property_value_vector_updated = Self::insert_at_index_in_property_vector(
-                property_value_vector.clone(), index_in_property_vector, value
-            );
-
-            let class_id = entity.get_class_id();
-
-            // Compute old and new vec unique property value hash.
-            // Ensure new property value hash with `unique` flag set is `unique` on `Class` level
-            let vec_property_value_hashes = if property.unique {
-                Some(
-                    Self::ensure_vec_property_value_hashes(class_id, in_class_schema_property_id, &property_value_vector_updated, property_value_vector)?
-                )
-            } else {
-                None
-            };
-
-            //
-            // == MUTATION SAFE ==
-            //
-
-            if let Some((new_property_value_hash, old_property_value_hash)) = vec_property_value_hashes {
-                // Add property value hash, that should be unique on `Class` level
-                Self::add_unique_property_value_hash(class_id, in_class_schema_property_id, new_property_value_hash);
-
-                // Remove property value hash, that should be unique on `Class` level
-                Self::remove_unique_property_value_hash(class_id, in_class_schema_property_id, old_property_value_hash);
-            }
-
-            // Insert updated property value into entity_property_values mapping at in_class_schema_property_id.
-            // Retrieve updated entity_property_values
-            let entity_values_updated = Self::insert_at_in_class_schema_property_id(
-                entity.get_values(), in_class_schema_property_id, property_value_vector_updated
-            );
-
-            // Increase reference counter of involved entity (if some)
-            let involved_entity_and_side_effect = if let Some(entity_rc_to_increment) = involved_entity {
-                let same_controller_status = property.property_type.same_controller_status();
-                let rc_delta = EntityReferenceCounterSideEffect::atomic(same_controller_status, DeltaMode::Increment);
-
-                // Update InboundReferenceCounter of involved entity, based on previously calculated ReferenceCounterSideEffect
-                Self::update_entity_rc(entity_rc_to_increment, rc_delta);
-                Some((entity_rc_to_increment, rc_delta))
-            } else {
-                None
-            };
-
-            // Update entity property values
-            <EntityById<T>>::mutate(entity_id, |entity| {
-                entity.set_values(entity_values_updated);
-            });
-
-            // Trigger event
-            Self::deposit_event(
-                RawEvent::InsertedAtVectorIndex(
-                    actor, entity_id, in_class_schema_property_id, index_in_property_vector,
-                    nonce + T::Nonce::one(), involved_entity_and_side_effect
-                )
-            );
-
-            Ok(())
-        }
-
-       /// Batch transaction
-       #[weight = 10_000_000] // TODO: adjust weight
-       pub fn transaction(origin, actor: Actor<T::CuratorGroupId, T::CuratorId, T::MemberId>, operations: Vec<OperationType<T>>) -> DispatchResult {
-
-           // Ensure maximum number of operations during atomic batching limit not reached
-           Self::ensure_number_of_operations_during_atomic_batching_limit_not_reached(&operations)?;
-
-           //
-           // == MUTATION SAFE ==
-           //
-
-           // This BTreeMap holds the T::EntityId of the entity created as a result of executing a `CreateEntity` `Operation`
-           let mut entity_created_in_operation = BTreeMap::new();
-
-           // Create raw origin
-           let raw_origin = origin.into().map_err(|_| Error::<T>::OriginCanNotBeMadeIntoRawOrigin)?;
-
-           for (index, operation_type) in operations.into_iter().enumerate() {
-               let origin = T::Origin::from(raw_origin.clone());
-               match operation_type {
-                   OperationType::CreateEntity(create_entity_operation) => {
-                        Self::ensure_transaction_failed_event(
-                            Self::create_entity(origin, create_entity_operation.class_id, actor),
-                            actor,
-                            index
-                        )?;
-
-                        // entity id of newly created entity
-                        let entity_id = Self::next_entity_id() - T::EntityId::one();
-                        entity_created_in_operation.insert(index, entity_id);
-                   },
-                   OperationType::AddSchemaSupportToEntity(add_schema_support_to_entity_operation) => {
-                       let entity_id =
-                            Self::ensure_transaction_failed_event(
-                                operations::parametrized_entity_to_entity_id(
-                                    &entity_created_in_operation, add_schema_support_to_entity_operation.entity_id
-                                ),
-                                actor,
-                                index
-                            )?;
-
-                       let schema_id = add_schema_support_to_entity_operation.schema_id;
-
-                       let property_values =
-                            Self::ensure_transaction_failed_event(
-                                operations::parametrized_property_values_to_property_values(
-                                    &entity_created_in_operation, add_schema_support_to_entity_operation.parametrized_property_values
-                                ),
-                                actor,
-                                index
-                            )?;
-                        Self::ensure_transaction_failed_event(
-                            Self::add_schema_support_to_entity(origin, actor, entity_id, schema_id, property_values),
-                            actor,
-                            index
-                        )?;
-                   },
-                   OperationType::UpdatePropertyValues(update_property_values_operation) => {
-                       let entity_id =
-                            Self::ensure_transaction_failed_event(
-                                operations::parametrized_entity_to_entity_id(
-                                    &entity_created_in_operation, update_property_values_operation.entity_id
-                                ),
-                                actor,
-                                index
-                            )?;
-
-                       let property_values =
-                            Self::ensure_transaction_failed_event(
-                                operations::parametrized_property_values_to_property_values(
-                                    &entity_created_in_operation, update_property_values_operation.new_parametrized_property_values
-                                ),
-                                actor,
-                                index
-                            )?;
-
-                       Self::ensure_transaction_failed_event(
-                            Self::update_entity_property_values(origin, actor, entity_id, property_values),
-                            actor,
-                            index
-                       )?;
-                   },
-               }
-           }
-
-           // Trigger event
-           Self::deposit_event(RawEvent::TransactionCompleted(actor));
-
-           Ok(())
-       }
-    }
-}
-
-impl<T: Trait> Module<T> {
-    /// Deposits an `TransactionFailed` event if an error during `transaction` extrinsic execution occured
-    fn ensure_transaction_failed_event<R, E: Into<DispatchError>>(
-        result: Result<R, E>,
-        actor: Actor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
-        index: usize,
-    ) -> Result<R, DispatchError> {
-        match result {
-            Err(e) => {
-                Self::deposit_event(RawEvent::TransactionFailed(actor, index as u32));
-                Err(e.into())
-            }
-            Ok(result) => Ok(result),
-        }
-    }
-
-    /// Updates corresponding `Entity` `reference_counter` by `reference_counter_delta`.
-    fn update_entity_rc(
-        entity_id: T::EntityId,
-        reference_counter_delta: EntityReferenceCounterSideEffect,
-    ) {
-        // Update both `total` and `same owner` number of inbound references for the Entity instance under given `entity_id`
-        <EntityById<T>>::mutate(entity_id, |entity| {
-            let entity_inbound_rc = entity.get_reference_counter_mut();
-            entity_inbound_rc.total =
-                (entity_inbound_rc.total as i32 + reference_counter_delta.total) as u32;
-            entity_inbound_rc.same_owner =
-                (entity_inbound_rc.same_owner as i32 + reference_counter_delta.same_owner) as u32;
-        })
-    }
-
-    /// Increment number of classes, maintained by each curator group
-    fn increment_number_of_classes_maintained_by_curator_groups(
-        curator_group_ids: BTreeSet<T::CuratorGroupId>,
-    ) {
-        curator_group_ids.into_iter().for_each(|curator_group_id| {
-            Self::increment_number_of_classes_maintained_by_curator_group(curator_group_id);
-        });
-    }
-
-    /// Decrement number of classes, maintained by each curator group
-    fn decrement_number_of_classes_maintained_by_curator_groups(
-        curator_group_ids: BTreeSet<T::CuratorGroupId>,
-    ) {
-        curator_group_ids.into_iter().for_each(|curator_group_id| {
-            Self::decrement_number_of_classes_maintained_by_curator_group(curator_group_id);
-        });
-    }
-
-    /// Increment number of classes, maintained by curator group
-    fn increment_number_of_classes_maintained_by_curator_group(
-        curator_group_id: T::CuratorGroupId,
-    ) {
-        <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
-            curator_group.increment_number_of_classes_maintained_count();
-        });
-    }
-
-    /// Decrement number of classes, maintained by curator group
-    fn decrement_number_of_classes_maintained_by_curator_group(
-        curator_group_id: T::CuratorGroupId,
-    ) {
-        <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
-            curator_group.decrement_number_of_classes_maintained_count();
-        });
-    }
-
-    /// Add property value hash, that should be unique on `Class` level
-    pub fn add_unique_property_value_hash(
-        class_id: T::ClassId,
-        property_id: PropertyId,
-        hash: T::Hash,
-    ) {
-        <UniquePropertyValueHashes<T>>::insert((class_id, property_id), hash, ());
-    }
-
-    /// Remove property value hash, that should be unique on `Class` level
-    pub fn remove_unique_property_value_hash(
-        class_id: T::ClassId,
-        property_id: PropertyId,
-        hash: T::Hash,
-    ) {
-        <UniquePropertyValueHashes<T>>::remove((class_id, property_id), hash);
-    }
-
-    /// Add property value hashes, that should be unique on `Class` level
-    pub fn add_unique_property_value_hashes(
-        class_id: T::ClassId,
-        unique_property_value_hashes: BTreeMap<PropertyId, T::Hash>,
-    ) {
-        unique_property_value_hashes
-            .into_iter()
-            .for_each(|(property_id, hash)| {
-                Self::add_unique_property_value_hash(class_id, property_id, hash);
-            });
-    }
-
-    /// Remove property value hashes, that should be unique on `Class` level
-    pub fn remove_unique_property_value_hashes(
-        class_id: T::ClassId,
-        unique_property_value_hashes: BTreeMap<PropertyId, T::Hash>,
-    ) {
-        unique_property_value_hashes
-            .into_iter()
-            .for_each(|(property_id, hash)| {
-                Self::remove_unique_property_value_hash(class_id, property_id, hash);
-            });
-    }
-
-    /// Convert all provided `InputPropertyValue`'s into `StoredPropertyValue`'s
-    pub fn make_output_property_values(
-        input_property_values: BTreeMap<PropertyId, InputPropertyValue<T>>,
-    ) -> BTreeMap<PropertyId, StoredPropertyValueOf<T>> {
-        input_property_values
-            .into_iter()
-            .map(|(property_id, property_value)| (property_id, property_value.into()))
-            .collect()
-    }
-
-    /// Update `entity_property_values` with `property_values`
-    /// Returns updated `entity_property_values`
-    fn make_updated_entity_property_values(
-        schema: Schema,
-        entity_property_values: BTreeMap<PropertyId, StoredPropertyValueOf<T>>,
-        output_property_values: &BTreeMap<PropertyId, StoredPropertyValueOf<T>>,
-    ) -> BTreeMap<PropertyId, StoredPropertyValueOf<T>> {
-        // Concatenate existing `entity_property_values` with `property_values`, provided, when adding `Schema` support.
-        let updated_entity_property_values: BTreeMap<PropertyId, StoredPropertyValueOf<T>> =
-            entity_property_values
-                .into_iter()
-                .chain(output_property_values.to_owned().into_iter())
-                .collect();
-
-        // Write all missing non required `Schema` `property_values` as `InputPropertyValue::default()`
-        let non_required_property_values: BTreeMap<PropertyId, StoredPropertyValueOf<T>> = schema
-            .get_properties()
-            .iter()
-            .filter_map(|property_id| {
-                if !updated_entity_property_values.contains_key(property_id) {
-                    Some((*property_id, StoredPropertyValue::default()))
-                } else {
-                    None
-                }
-            })
-            .collect();
-
-        // Extend updated_entity_property_values with given Schema non_required_property_values
-        updated_entity_property_values
-            .into_iter()
-            .chain(non_required_property_values.into_iter())
-            .collect()
-    }
-
-    /// Calculate side effects for clear_property_vector operation, based on `property_value_vector` provided and its respective `property`.
-    /// Returns calculated `ReferenceCounterSideEffects`
-    pub fn make_side_effects_for_clear_property_vector_operation(
-        property_value_vector: &VecStoredPropertyValue<T::Hash, T::EntityId, T::Nonce>,
-        property: &Property<T::ClassId>,
-    ) -> Option<ReferenceCounterSideEffects<T>> {
-        let entity_ids_to_decrease_rc = property_value_vector
-            .get_vec_value_ref()
-            .get_involved_entities();
-
-        if let Some(entity_ids_to_decrease_rcs) = entity_ids_to_decrease_rc {
-            // Calculate `ReferenceCounterSideEffects`, based on entity_ids involved, same_controller_status and chosen `DeltaMode`
-            let same_controller_status = property.property_type.same_controller_status();
-            let entities_inbound_rcs_delta = Self::perform_entities_inbound_rcs_delta_calculation(
-                ReferenceCounterSideEffects::<T>::default(),
-                entity_ids_to_decrease_rcs,
-                same_controller_status,
-                DeltaMode::Decrement,
-            );
-
-            if !entities_inbound_rcs_delta.is_empty() {
-                Some(entities_inbound_rcs_delta)
-            } else {
-                None
-            }
-        } else {
-            None
-        }
-    }
-
-    /// Update `inbound_rcs_delta`, based on `involved_entity_ids`, `same_controller_status` provided and chosen `DeltaMode`
-    /// Returns updated `inbound_rcs_delta`
-    fn perform_entities_inbound_rcs_delta_calculation(
-        mut inbound_rcs_delta: ReferenceCounterSideEffects<T>,
-        involved_entity_ids: Vec<T::EntityId>,
-        same_controller_status: bool,
-        delta_mode: DeltaMode,
-    ) -> ReferenceCounterSideEffects<T> {
-        for involved_entity_id in involved_entity_ids {
-            // If inbound_rcs_delta already contains entry for the given involved_entity_id, increment it
-            // with atomic EntityReferenceCounterSideEffect instance, based on same_owner flag provided and DeltaMode,
-            // otherwise create new atomic EntityReferenceCounterSideEffect instance
-            if let Some(inbound_rc_delta) = inbound_rcs_delta.get_mut(&involved_entity_id) {
-                *inbound_rc_delta +=
-                    EntityReferenceCounterSideEffect::atomic(same_controller_status, delta_mode);
-            } else {
-                inbound_rcs_delta.insert(
-                    involved_entity_id,
-                    EntityReferenceCounterSideEffect::atomic(same_controller_status, delta_mode),
-                );
-            }
-        }
-        inbound_rcs_delta
-    }
-
-    /// Filter references, pointing to the same `Entity`
-    fn filter_references_to_the_same_entity(
-        current_entity_id: T::EntityId,
-        involved_entity_ids: Vec<T::EntityId>,
-    ) -> Vec<T::EntityId> {
-        involved_entity_ids
-            .into_iter()
-            .filter(|involved_entity_id| current_entity_id != *involved_entity_id)
-            .collect()
-    }
-
-    /// Calculate `ReferenceCounterSideEffects`, based on `values_for_existing_properties` provided and chosen `DeltaMode`
-    /// Returns calculated `ReferenceCounterSideEffects`
-    fn calculate_entities_inbound_rcs_delta(
-        current_entity_id: T::EntityId,
-        values_for_existing_properties: StoredValuesForExistingProperties<T>,
-        delta_mode: DeltaMode,
-    ) -> Option<ReferenceCounterSideEffects<T>> {
-        let entities_inbound_rcs_delta = values_for_existing_properties
-            .values()
-            .map(|value_for_existing_property| value_for_existing_property.unzip())
-            .filter_map(|(property, value)| {
-                let involved_entity_ids =
-                    value.get_involved_entities().map(|involved_entity_ids| {
-                        Self::filter_references_to_the_same_entity(
-                            current_entity_id,
-                            involved_entity_ids,
-                        )
-                    });
-                match involved_entity_ids {
-                    Some(involved_entity_ids) if !involved_entity_ids.is_empty() => Some((
-                        involved_entity_ids,
-                        property.property_type.same_controller_status(),
-                    )),
-                    _ => None,
-                }
-            })
-            // Aggeregate all sideffects on a single entity together into one side effect map
-            .fold(
-                ReferenceCounterSideEffects::default(),
-                |inbound_rcs_delta, (involved_entity_ids, same_controller_status)| {
-                    Self::perform_entities_inbound_rcs_delta_calculation(
-                        inbound_rcs_delta,
-                        involved_entity_ids,
-                        same_controller_status,
-                        delta_mode,
-                    )
-                },
-            );
-
-        if !entities_inbound_rcs_delta.is_empty() {
-            Some(entities_inbound_rcs_delta)
-        } else {
-            None
-        }
-    }
-
-    /// Compute `ReferenceCounterSideEffects`, based on `InputPropertyValue` `Reference`'s involved into update process.
-    /// Returns updated `ReferenceCounterSideEffects`
-    pub fn get_updated_inbound_rcs_delta(
-        current_entity_id: T::EntityId,
-        class_properties: Vec<Property<T::ClassId>>,
-        entity_property_values: BTreeMap<PropertyId, StoredPropertyValueOf<T>>,
-        new_output_property_values: BTreeMap<PropertyId, StoredPropertyValueOf<T>>,
-    ) -> Result<Option<ReferenceCounterSideEffects<T>>, Error<T>> {
-        // Filter entity_property_values to get only those, which will be substituted with new_property_values
-        let entity_property_values_to_update: BTreeMap<PropertyId, StoredPropertyValueOf<T>> =
-            entity_property_values
-                .into_iter()
-                .filter(|(entity_id, _)| new_output_property_values.contains_key(entity_id))
-                .collect();
-
-        // Calculate entities reference counter side effects for update operation
-
-        let stored_values_for_entity_property_values_to_update =
-            match StoredValuesForExistingProperties::from(
-                &class_properties,
-                &entity_property_values_to_update,
-            ) {
-                Ok(stored_values_for_entity_property_values_to_update) => {
-                    stored_values_for_entity_property_values_to_update
-                }
-                Err(e) => {
-                    debug_assert!(false, "Should not fail! {:?}", e);
-                    return Err(e);
-                }
-            };
-
-        // Calculate entities inbound reference counter delta with Decrement DeltaMode for entity_property_values_to_update,
-        // as involved InputPropertyValue References will be substituted with new ones
-        let decremental_reference_counter_side_effects = Self::calculate_entities_inbound_rcs_delta(
-            current_entity_id,
-            stored_values_for_entity_property_values_to_update,
-            DeltaMode::Decrement,
-        );
-
-        // Calculate entities inbound reference counter delta with Increment DeltaMode for new_property_values,
-        // as involved InputPropertyValue References will substitute the old ones
-        let incremental_reference_counter_side_effects = Self::calculate_entities_inbound_rcs_delta(
-            current_entity_id,
-            StoredValuesForExistingProperties::from(
-                &class_properties,
-                &new_output_property_values,
-            )?,
-            DeltaMode::Increment,
-        );
-
-        // Add up both net decremental_reference_counter_side_effects and incremental_reference_counter_side_effects
-        // to get one net sideffect per entity.
-        Ok(Self::calculate_updated_inbound_rcs_delta(
-            decremental_reference_counter_side_effects,
-            incremental_reference_counter_side_effects,
-        ))
-    }
-
-    /// Add up both net first_reference_counter_side_effects and second_reference_counter_side_effects (if some)
-    /// to get one net sideffect per entity.
-    /// Returns updated `ReferenceCounterSideEffects`
-    pub fn calculate_updated_inbound_rcs_delta(
-        first_reference_counter_side_effects: Option<ReferenceCounterSideEffects<T>>,
-        second_reference_counter_side_effects: Option<ReferenceCounterSideEffects<T>>,
-    ) -> Option<ReferenceCounterSideEffects<T>> {
-        match (
-            first_reference_counter_side_effects,
-            second_reference_counter_side_effects,
-        ) {
-            (
-                Some(first_reference_counter_side_effects),
-                Some(second_reference_counter_side_effects),
-            ) => {
-                let reference_counter_side_effects = first_reference_counter_side_effects
-                    .update(second_reference_counter_side_effects);
-                Some(reference_counter_side_effects)
-            }
-            (Some(first_reference_counter_side_effects), _) => {
-                Some(first_reference_counter_side_effects)
-            }
-            (_, Some(second_reference_counter_side_effects)) => {
-                Some(second_reference_counter_side_effects)
-            }
-            _ => None,
-        }
-    }
-
-    /// Used to update `class_permissions` with parameters provided.
-    /// Returns updated `class_permissions` if update performed
-    pub fn make_updated_class_permissions(
-        class_permissions: &ClassPermissions<T::CuratorGroupId>,
-        updated_any_member: Option<bool>,
-        updated_entity_creation_blocked: Option<bool>,
-        updated_all_entity_property_values_locked: Option<bool>,
-        updated_maintainers: Option<BTreeSet<T::CuratorGroupId>>,
-    ) -> Option<ClassPermissions<T::CuratorGroupId>> {
-        // Used to check if update performed
-        let mut updated_class_permissions = class_permissions.clone();
-
-        if let Some(updated_any_member) = updated_any_member {
-            updated_class_permissions.set_any_member_status(updated_any_member);
-        }
-
-        if let Some(updated_entity_creation_blocked) = updated_entity_creation_blocked {
-            updated_class_permissions.set_entity_creation_blocked(updated_entity_creation_blocked);
-        }
-
-        if let Some(updated_all_entity_property_values_locked) =
-            updated_all_entity_property_values_locked
-        {
-            updated_class_permissions
-                .set_all_entity_property_values_locked(updated_all_entity_property_values_locked);
-        }
-
-        if let Some(updated_maintainers) = updated_maintainers {
-            updated_class_permissions.set_maintainers(updated_maintainers);
-        }
-
-        if updated_class_permissions != *class_permissions {
-            Some(updated_class_permissions)
-        } else {
-            None
-        }
-    }
-
-    /// Used to update `entity_permissions` with parameters provided.
-    /// Returns updated `entity_permissions` if update performed
-    pub fn make_updated_entity_permissions(
-        entity_permissions: EntityPermissions<T::MemberId>,
-        updated_frozen: Option<bool>,
-        updated_referenceable: Option<bool>,
-    ) -> Option<EntityPermissions<T::MemberId>> {
-        // Used to check if update performed
-        let mut updated_entity_permissions = entity_permissions.clone();
-
-        if let Some(updated_frozen) = updated_frozen {
-            updated_entity_permissions.set_frozen(updated_frozen);
-        }
-
-        if let Some(updated_referenceable) = updated_referenceable {
-            updated_entity_permissions.set_referencable(updated_referenceable);
-        }
-
-        if updated_entity_permissions != entity_permissions {
-            Some(updated_entity_permissions)
-        } else {
-            None
-        }
-    }
-
-    /// Ensure property value hash with `unique` flag set is `unique` on `Class` level
-    pub fn ensure_property_value_hash_unique_option_satisfied(
-        class_id: T::ClassId,
-        property_id: PropertyId,
-        unique_property_value_hash: &T::Hash,
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            !<UniquePropertyValueHashes<T>>::contains_key(
-                (class_id, property_id),
-                unique_property_value_hash
-            ),
-            Error::<T>::PropertyValueShouldBeUnique
-        );
-        Ok(())
-    }
-
-    /// Ensure all property value hashes with `unique` flag set are `unique` on `Class` level
-    pub fn ensure_property_value_hashes_unique_option_satisfied(
-        class_id: T::ClassId,
-        unique_property_value_hashes: &BTreeMap<PropertyId, T::Hash>,
-    ) -> Result<(), Error<T>> {
-        for (&property_id, unique_property_value_hash) in unique_property_value_hashes {
-            Self::ensure_property_value_hash_unique_option_satisfied(
-                class_id,
-                property_id,
-                unique_property_value_hash,
-            )?;
-        }
-        Ok(())
-    }
-
-    /// Compute old and new vec unique property value hash.
-    /// Ensure new property value hash with `unique` flag set is `unique` on `Class` level
-    pub fn ensure_vec_property_value_hashes(
-        class_id: T::ClassId,
-        in_class_schema_property_id: PropertyId,
-        property_value_vector_updated: &StoredPropertyValueOf<T>,
-        property_value_vector: VecStoredPropertyValue<T::Hash, T::EntityId, T::Nonce>,
-    ) -> Result<(T::Hash, T::Hash), Error<T>> {
-        // Compute new hash from unique property value and its respective property id
-        let new_property_value_hash =
-            property_value_vector_updated.compute_unique_hash::<T>(in_class_schema_property_id);
-
-        // Ensure `Property` with `unique` flag set is `unique` on `Class` level
-        Self::ensure_property_value_hash_unique_option_satisfied(
-            class_id,
-            in_class_schema_property_id,
-            &new_property_value_hash,
-        )?;
-
-        // Compute old hash from the old unique property value and its respective property id
-        let old_property_value_hash =
-            property_value_vector.compute_unique_hash::<T>(in_class_schema_property_id);
-
-        Ok((new_property_value_hash, old_property_value_hash))
-    }
-
-    /// Compute new unique property value hashes.
-    /// Ensure new property value hashes with `unique` flag set are `unique` on `Class` level
-    pub fn ensure_new_property_values_respect_uniquness(
-        class_id: T::ClassId,
-        new_output_values_for_existing_properties: StoredValuesForExistingProperties<T>,
-    ) -> Result<BTreeMap<PropertyId, T::Hash>, Error<T>> {
-        let new_unique_property_value_hashes =
-            new_output_values_for_existing_properties.compute_unique_hashes();
-
-        // Ensure all provided Properties with unique flag set are unique on Class level
-        Self::ensure_property_value_hashes_unique_option_satisfied(
-            class_id,
-            &new_unique_property_value_hashes,
-        )?;
-
-        Ok(new_unique_property_value_hashes)
-    }
-
-    /// Returns the stored `Class` if exist, error otherwise.
-    fn ensure_class_exists(class_id: T::ClassId) -> Result<ClassOf<T>, Error<T>> {
-        ensure!(
-            <ClassById<T>>::contains_key(class_id),
-            Error::<T>::ClassNotFound
-        );
-        Ok(Self::class_by_id(class_id))
-    }
-
-    /// Returns `Class` and `Entity` under given id, if exists, and `EntityAccessLevel` corresponding to `origin`, if permitted
-    fn ensure_class_entity_and_access_level(
-        account_id: T::AccountId,
-        entity_id: T::EntityId,
-        actor: &Actor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
-    ) -> Result<(ClassOf<T>, EntityOf<T>, EntityAccessLevel), Error<T>> {
-        // Ensure Entity under given id exists, retrieve corresponding one
-        let entity = Self::ensure_known_entity_id(entity_id)?;
-
-        // Retrieve corresponding Class
-        let class = Self::class_by_id(entity.get_class_id());
-
-        // Derive EntityAccessLevel for the actor, attempting to act.
-        let access_level = EntityAccessLevel::derive(
-            &account_id,
-            entity.get_permissions_ref(),
-            class.get_permissions_ref(),
-            actor,
-        )?;
-
-        Ok((class, entity, access_level))
-    }
-
-    /// Ensure `Entity` under given `entity_id` exists, retrieve corresponding `Entity` & `Class`
-    pub fn ensure_known_entity_and_class(
-        entity_id: T::EntityId,
-    ) -> Result<(EntityOf<T>, ClassOf<T>), Error<T>> {
-        // Ensure Entity under given id exists, retrieve corresponding one
-        let entity = Self::ensure_known_entity_id(entity_id)?;
-
-        let class = ClassById::<T>::get(entity.get_class_id());
-        Ok((entity, class))
-    }
-
-    /// Filter `provided values_for_existing_properties`, leaving only `Reference`'s with `SameOwner` flag set
-    /// Returns the set of corresponding property ids
-    pub fn get_property_id_references_with_same_owner_flag_set(
-        values_for_existing_properties: StoredValuesForExistingProperties<T>,
-    ) -> BTreeSet<PropertyId> {
-        values_for_existing_properties
-            // Iterate over the PropertyId's
-            .keys()
-            // Filter provided values_for_existing_properties, leaving only `Reference`'s with `SameOwner` flag set
-            .filter(|property_id| {
-                if let Some(value_for_existing_property) =
-                    values_for_existing_properties.get(property_id)
-                {
-                    value_for_existing_property
-                        .get_property()
-                        .property_type
-                        .same_controller_status()
-                } else {
-                    false
-                }
-            })
-            .copied()
-            .collect()
-    }
-
-    /// Ensure all ids of provided `new_property_value_references_with_same_owner_flag_set`
-    /// corresponding to property ids of respective Class Property references with same owner flag set
-    pub fn ensure_only_reference_ids_with_same_owner_flag_set_provided(
-        entity_property_id_references_with_same_owner_flag_set: &BTreeSet<PropertyId>,
-        new_property_value_references_with_same_owner_flag_set: &BTreeMap<
-            PropertyId,
-            InputPropertyValue<T>,
-        >,
-    ) -> Result<(), Error<T>> {
-        let new_property_value_id_references_with_same_owner_flag_set: BTreeSet<PropertyId> =
-            new_property_value_references_with_same_owner_flag_set
-                .keys()
-                .copied()
-                .collect();
-
-        ensure!(
-            new_property_value_id_references_with_same_owner_flag_set
-                .is_subset(entity_property_id_references_with_same_owner_flag_set),
-            Error::<T>::AllProvidedPropertyValueIdsMustBeReferencesWithSameOwnerFlagSet
-        );
-        Ok(())
-    }
-
-    /// Ensure provided actor can create entities of current `Class`
-    pub fn ensure_can_create_entities(
-        class_permissions: &ClassPermissions<T::CuratorGroupId>,
-        account_id: &T::AccountId,
-        actor: &Actor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
-    ) -> Result<(), Error<T>> {
-        let can_create = match &actor {
-            Actor::Lead => {
-                // Ensure lead authorization performed succesfully
-                ensure_lead_auth_success::<T>(account_id)?;
-                true
-            }
-            Actor::Member(member_id) if class_permissions.any_member_status() => {
-                // Ensure member authorization performed succesfully
-                ensure_member_auth_success::<T>(member_id, account_id)?;
-                true
-            }
-            Actor::Curator(curator_group_id, curator_id)
-                if class_permissions.is_maintainer(curator_group_id) =>
-            {
-                // Authorize curator, performing all checks to ensure curator can act
-                CuratorGroup::<T>::perform_curator_in_group_auth(
-                    curator_id,
-                    curator_group_id,
-                    account_id,
-                )?;
-                true
-            }
-            _ => false,
-        };
-        ensure!(can_create, Error::<T>::ActorCanNotCreateEntities);
-        Ok(())
-    }
-
-    /// Ensure all provided `new_property_value_references_with_same_owner_flag_set` are valid
-    fn ensure_are_valid_references_with_same_owner_flag_set(
-        new_property_value_references_with_same_owner_flag_set: InputValuesForExistingProperties<T>,
-        new_controller: &EntityController<T::MemberId>,
-    ) -> Result<(), Error<T>> {
-        for updated_value_for_existing_property in
-            new_property_value_references_with_same_owner_flag_set.values()
-        {
-            let (property, value) = updated_value_for_existing_property.unzip();
-
-            // Perform all required checks to ensure provided property values are valid references
-            Property::<T::ClassId>::ensure_property_value_is_valid_reference(
-                &property,
-                value,
-                new_controller,
-            )?;
-        }
-        Ok(())
-    }
-
-    /// Used to update entity_property_values with parameters provided.
-    /// Returns updated `entity_property_values`, if update performed
-    pub fn make_updated_property_value_references_with_same_owner_flag_set(
-        unused_property_id_references_with_same_owner_flag_set: BTreeSet<PropertyId>,
-        entity_property_values: &BTreeMap<PropertyId, StoredPropertyValueOf<T>>,
-        new_property_value_references_with_same_owner_flag_set: &BTreeMap<
-            PropertyId,
-            StoredPropertyValueOf<T>,
-        >,
-    ) -> Option<BTreeMap<PropertyId, StoredPropertyValueOf<T>>> {
-        // Used to check if update performed
-        let mut entity_property_values_updated = entity_property_values.clone();
-
-        for (property_id, new_property_value_reference_with_same_owner_flag_set) in
-            new_property_value_references_with_same_owner_flag_set
-        {
-            // Update entity_property_values map at property_id with new_property_value_reference_with_same_owner_flag_set
-            entity_property_values_updated.insert(
-                *property_id,
-                new_property_value_reference_with_same_owner_flag_set.to_owned(),
-            );
-        }
-
-        // Throw away old non required property value references with same owner flag set
-        // and replace them with Default ones
-        for unused_property_id_reference_with_same_owner_flag_set in
-            unused_property_id_references_with_same_owner_flag_set
-        {
-            entity_property_values_updated.insert(
-                unused_property_id_reference_with_same_owner_flag_set,
-                StoredPropertyValue::default(),
-            );
-        }
-
-        if *entity_property_values != entity_property_values_updated {
-            Some(entity_property_values_updated)
-        } else {
-            None
-        }
-    }
-
-    /// Update InboundReferenceCounter, based on previously calculated entities_inbound_rcs_delta, for each Entity involved
-    pub fn update_entities_rcs(
-        entities_inbound_rcs_delta: &Option<ReferenceCounterSideEffects<T>>,
-    ) {
-        if let Some(entities_inbound_rcs_delta) = entities_inbound_rcs_delta {
-            entities_inbound_rcs_delta.update_entities_rcs();
-        }
-    }
-
-    /// Retrieve `property_ids`, that are not in `property_values`
-    pub fn compute_unused_property_ids(
-        property_values: &BTreeMap<PropertyId, InputPropertyValue<T>>,
-        property_ids: &BTreeSet<PropertyId>,
-    ) -> BTreeSet<PropertyId> {
-        let property_value_indices: BTreeSet<PropertyId> =
-            property_values.keys().cloned().collect();
-
-        property_ids
-            .difference(&property_value_indices)
-            .copied()
-            .collect()
-    }
-
-    /// Used to compute old unique hashes, that should be substituted with new ones.
-    pub fn compute_old_unique_hashes(
-        new_output_property_values: &BTreeMap<PropertyId, StoredPropertyValueOf<T>>,
-        entity_values: &BTreeMap<PropertyId, StoredPropertyValueOf<T>>,
-    ) -> BTreeMap<PropertyId, T::Hash> {
-        entity_values
-            .iter()
-            .filter(|(property_id, _)| new_output_property_values.contains_key(property_id))
-            .map(|(&property_id, property_value)| {
-                (
-                    property_id,
-                    property_value.compute_unique_hash::<T>(property_id),
-                )
-            })
-            .collect()
-    }
-
-    /// Perform checks to ensure all required `property_values` under provided `unused_schema_property_ids` provided
-    pub fn ensure_all_required_properties_provided(
-        class_properties: &[Property<T::ClassId>],
-        unused_schema_property_ids: &BTreeSet<PropertyId>,
-    ) -> Result<(), Error<T>> {
-        for &unused_schema_property_id in unused_schema_property_ids {
-            let class_property = &class_properties
-                .get(unused_schema_property_id as usize)
-                .ok_or(Error::<T>::ClassPropertyNotFound)?;
-
-            // All required property values should be provided
-            ensure!(
-                !class_property.required,
-                Error::<T>::MissingRequiredProperty
-            );
-        }
-        Ok(())
-    }
-
-    /// Validate all values, provided in `values_for_existing_properties`, against the type of its `Property`
-    /// and check any additional constraints
-    pub fn ensure_property_values_are_valid(
-        entity_controller: &EntityController<T::MemberId>,
-        values_for_existing_properties: &InputValuesForExistingProperties<T>,
-    ) -> Result<(), Error<T>> {
-        for value_for_existing_property in values_for_existing_properties.values() {
-            let (property, value) = value_for_existing_property.unzip();
-
-            // Validate new InputPropertyValue against the type of this Property and check any additional constraints
-            Property::<T::ClassId>::ensure_property_value_to_update_is_valid(
-                property,
-                value,
-                entity_controller,
-            )?;
-        }
-
-        Ok(())
-    }
-
-    /// Ensure all provided `new_property_values` are already exist in `entity_property_values` map
-    pub fn ensure_all_property_values_are_already_added(
-        entity_property_values: &BTreeMap<PropertyId, StoredPropertyValueOf<T>>,
-        new_property_values: &BTreeMap<PropertyId, InputPropertyValue<T>>,
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            new_property_values
-                .keys()
-                .all(|key| entity_property_values.contains_key(key)),
-            Error::<T>::UnknownEntityPropertyId
-        );
-        Ok(())
-    }
-
-    /// Ensure `new_values_for_existing_properties` are accessible for actor with given `access_level`
-    pub fn ensure_all_property_values_are_unlocked_from(
-        new_values_for_existing_properties: &InputValuesForExistingProperties<T>,
-        access_level: EntityAccessLevel,
-    ) -> Result<(), Error<T>> {
-        for value_for_new_property in new_values_for_existing_properties.values() {
-            // Ensure Property is unlocked from Actor with given EntityAccessLevel
-            value_for_new_property
-                .get_property()
-                .ensure_unlocked_from::<T>(access_level)?;
-        }
-        Ok(())
-    }
-
-    /// Filter `new_property_values` identical to `entity_property_values`.
-    /// Return only `new_property_values`, that are not in `entity_property_values`
-    pub fn try_filter_identical_property_values(
-        entity_property_values: &BTreeMap<PropertyId, StoredPropertyValueOf<T>>,
-        new_property_values: BTreeMap<PropertyId, InputPropertyValue<T>>,
-    ) -> BTreeMap<PropertyId, InputPropertyValue<T>> {
-        new_property_values
-            .into_iter()
-            .filter(|(id, new_property_value)| {
-                if let Some(entity_property_value) = entity_property_values.get(id) {
-                    StoredPropertyValue::<T::Hash, T::EntityId, T::Nonce>::from(
-                        new_property_value.to_owned(),
-                    ) != *entity_property_value
-                } else {
-                    true
-                }
-            })
-            .collect()
-    }
-
-    /// Update existing `entity_property_values` with `new_property_values`.
-    /// if update performed, returns updated entity property values
-    pub fn make_updated_property_values(
-        entity_property_values: &BTreeMap<PropertyId, StoredPropertyValueOf<T>>,
-        new_output_property_values: &BTreeMap<PropertyId, StoredPropertyValueOf<T>>,
-    ) -> Option<BTreeMap<PropertyId, StoredPropertyValueOf<T>>> {
-        // Used to check if updated performed
-        let mut entity_property_values_updated = entity_property_values.to_owned();
-
-        new_output_property_values
-            .iter()
-            .for_each(|(id, new_property_value)| {
-                if let Some(entity_property_value) = entity_property_values_updated.get_mut(&id) {
-                    entity_property_value.update(new_property_value.to_owned());
-                }
-            });
-
-        if entity_property_values_updated != *entity_property_values {
-            Some(entity_property_values_updated)
-        } else {
-            None
-        }
-    }
-
-    /// Insert `InputValue` into `VecStoredPropertyValue` at `index_in_property_vector`.
-    /// Returns `VecStoredPropertyValue` wrapped in `StoredPropertyValue`
-    pub fn insert_at_index_in_property_vector(
-        mut property_value_vector: VecStoredPropertyValue<T::Hash, T::EntityId, T::Nonce>,
-        index_in_property_vector: VecMaxLength,
-        value: InputValue<T>,
-    ) -> StoredPropertyValueOf<T> {
-        property_value_vector.insert_at(index_in_property_vector, value.into());
-        StoredPropertyValue::Vector(property_value_vector)
-    }
-
-    /// Remove `InputValue` at `index_in_property_vector` in `VecInputPropertyValue`.
-    /// Returns `VecInputPropertyValue` wrapped in `InputPropertyValue`
-    pub fn remove_at_index_in_property_vector(
-        mut property_value_vector: VecStoredPropertyValue<T::Hash, T::EntityId, T::Nonce>,
-        index_in_property_vector: VecMaxLength,
-    ) -> StoredPropertyValueOf<T> {
-        property_value_vector.remove_at(index_in_property_vector);
-        StoredPropertyValue::Vector(property_value_vector)
-    }
-
-    /// Clear `VecStoredPropertyValue`.
-    /// Returns empty `VecStoredPropertyValue` wrapped in `StoredPropertyValue`
-    pub fn clear_property_vector(
-        mut property_value_vector: VecStoredPropertyValue<T::Hash, T::EntityId, T::Nonce>,
-    ) -> StoredPropertyValueOf<T> {
-        property_value_vector.clear();
-        StoredPropertyValue::Vector(property_value_vector)
-    }
-
-    /// Insert `InputPropertyValue` into `entity_property_values` mapping at `in_class_schema_property_id`.
-    /// Returns updated `entity_property_values`
-    pub fn insert_at_in_class_schema_property_id(
-        mut entity_property_values: BTreeMap<PropertyId, StoredPropertyValueOf<T>>,
-        in_class_schema_property_id: PropertyId,
-        property_value: StoredPropertyValueOf<T>,
-    ) -> BTreeMap<PropertyId, StoredPropertyValueOf<T>> {
-        entity_property_values.insert(in_class_schema_property_id, property_value);
-        entity_property_values
-    }
-
-    /// Ensure `Class` under given id exists, return corresponding one
-    pub fn ensure_known_class_id(class_id: T::ClassId) -> Result<ClassOf<T>, Error<T>> {
-        ensure!(
-            <ClassById<T>>::contains_key(class_id),
-            Error::<T>::ClassNotFound
-        );
-        Ok(Self::class_by_id(class_id))
-    }
-
-    /// Ensure `Entity` under given id exists, return corresponding one
-    pub fn ensure_known_entity_id(entity_id: T::EntityId) -> Result<EntityOf<T>, Error<T>> {
-        ensure!(
-            <EntityById<T>>::contains_key(entity_id),
-            Error::<T>::EntityNotFound
-        );
-        Ok(Self::entity_by_id(entity_id))
-    }
-
-    /// Ensure `CuratorGroup` under given id exists
-    pub fn ensure_curator_group_under_given_id_exists(
-        curator_group_id: &T::CuratorGroupId,
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            <CuratorGroupById<T>>::contains_key(curator_group_id),
-            Error::<T>::CuratorGroupDoesNotExist
-        );
-        Ok(())
-    }
-
-    /// Ensure `CuratorGroup` under given id exists, return corresponding one
-    pub fn ensure_curator_group_exists(
-        curator_group_id: &T::CuratorGroupId,
-    ) -> Result<CuratorGroup<T>, Error<T>> {
-        Self::ensure_curator_group_under_given_id_exists(curator_group_id)?;
-        Ok(Self::curator_group_by_id(curator_group_id))
-    }
-
-    /// Ensure `MaxNumberOfMaintainersPerClass` constraint satisfied
-    pub fn ensure_maintainers_limit_not_reached(
-        curator_groups: &BTreeSet<T::CuratorGroupId>,
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            curator_groups.len() < T::MaxNumberOfMaintainersPerClass::get() as usize,
-            Error::<T>::ClassMaintainersLimitReached
-        );
-        Ok(())
-    }
-
-    /// Ensure all `CuratorGroup`'s under given ids exist
-    pub fn ensure_curator_groups_exist(
-        curator_groups: &BTreeSet<T::CuratorGroupId>,
-    ) -> Result<(), Error<T>> {
-        for curator_group in curator_groups {
-            // Ensure CuratorGroup under given id exists
-            Self::ensure_curator_group_exists(curator_group)?;
-        }
-        Ok(())
-    }
-
-    /// Perform security checks to ensure provided `class_maintainers` are valid
-    pub fn ensure_class_maintainers_are_valid(
-        class_maintainers: &BTreeSet<T::CuratorGroupId>,
-    ) -> Result<(), Error<T>> {
-        // Ensure max number of maintainers per Class constraint satisfied
-        ensure!(
-            class_maintainers.len() <= T::MaxNumberOfMaintainersPerClass::get() as usize,
-            Error::<T>::ClassMaintainersLimitReached
-        );
-
-        // Ensure all curator groups provided are already exist in runtime
-        Self::ensure_curator_groups_exist(class_maintainers)?;
-        Ok(())
-    }
-
-    /// Ensure new `Schema` is not empty
-    pub fn ensure_non_empty_schema(
-        existing_properties: &BTreeSet<PropertyId>,
-        new_properties: &[Property<T::ClassId>],
-    ) -> Result<(), Error<T>> {
-        // Schema is empty if both existing_properties and new_properties are empty
-        let non_empty_schema = !existing_properties.is_empty() || !new_properties.is_empty();
-        ensure!(non_empty_schema, Error::<T>::NoPropertiesInClassSchema);
-        Ok(())
-    }
-
-    /// Ensure `ClassNameLengthConstraint` conditions satisfied
-    pub fn ensure_class_name_is_valid(text: &[u8]) -> Result<(), Error<T>> {
-        T::ClassNameLengthConstraint::get().ensure_valid(
-            text.len(),
-            Error::<T>::ClassNameTooShort,
-            Error::<T>::ClassNameTooLong,
-        )
-    }
-
-    /// Ensure `ClassDescriptionLengthConstraint` conditions satisfied
-    pub fn ensure_class_description_is_valid(text: &[u8]) -> Result<(), Error<T>> {
-        T::ClassDescriptionLengthConstraint::get().ensure_valid(
-            text.len(),
-            Error::<T>::ClassDescriptionTooShort,
-            Error::<T>::ClassDescriptionTooLong,
-        )
-    }
-
-    /// Ensure `MaxNumberOfClasses` constraint satisfied
-    pub fn ensure_class_limit_not_reached() -> Result<(), Error<T>> {
-        ensure!(
-            (<ClassById<T>>::iter().count() as MaxNumber) < T::MaxNumberOfClasses::get(),
-            Error::<T>::ClassLimitReached
-        );
-        Ok(())
-    }
-
-    /// Ensure `MaxNumberOfEntitiesPerClass` constraint satisfied
-    pub fn ensure_valid_number_of_entities_per_class(
-        maximum_entities_count: T::EntityId,
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            maximum_entities_count <= T::MaxNumberOfEntitiesPerClass::get(),
-            Error::<T>::EntitiesNumberPerClassConstraintViolated
-        );
-        Ok(())
-    }
-
-    /// Ensure `IndividualEntitiesCreationLimit` constraint satisfied
-    pub fn ensure_valid_number_of_class_entities_per_actor_constraint(
-        number_of_class_entities_per_actor: T::EntityId,
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            number_of_class_entities_per_actor <= T::IndividualEntitiesCreationLimit::get(),
-            Error::<T>::NumberOfClassEntitiesPerActorConstraintViolated
-        );
-        Ok(())
-    }
-
-    /// Ensure all entities creation limits, defined for a given `Class`, are valid
-    pub fn ensure_entities_creation_limits_are_valid(
-        maximum_entities_count: T::EntityId,
-        default_entity_creation_voucher_upper_bound: T::EntityId,
-    ) -> Result<(), Error<T>> {
-        // Ensure default_entity_creation_voucher_upper_bound does not exceed default_entity_creation_voucher_upper_bound
-        ensure!(
-            default_entity_creation_voucher_upper_bound <= maximum_entities_count,
-            Error::<T>::PerControllerEntitiesCreationLimitExceedsOverallLimit
-        );
-
-        // Ensure maximum_entities_count does not exceed MaxNumberOfEntitiesPerClass limit
-        Self::ensure_valid_number_of_entities_per_class(maximum_entities_count)?;
-
-        // Ensure default_entity_creation_voucher_upper_bound constraint does not exceed IndividualEntitiesCreationLimit
-        Self::ensure_valid_number_of_class_entities_per_actor_constraint(
-            default_entity_creation_voucher_upper_bound,
-        )
-    }
-
-    /// Ensure maximum number of operations during atomic batching constraint satisfied
-    pub fn ensure_number_of_operations_during_atomic_batching_limit_not_reached(
-        operations: &[OperationType<T>],
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            operations.len() <= T::MaxNumberOfOperationsDuringAtomicBatching::get() as usize,
-            Error::<T>::NumberOfOperationsDuringAtomicBatchingLimitReached
-        );
-        Ok(())
-    }
-
-    /// Complete all checks to ensure each `Property` is valid
-    pub fn ensure_all_properties_are_valid(
-        new_properties: &[Property<T::ClassId>],
-    ) -> Result<(), Error<T>> {
-        for new_property in new_properties.iter() {
-            // Ensure PropertyNameLengthConstraint satisfied
-            new_property.ensure_name_is_valid()?;
-
-            // Ensure PropertyDescriptionLengthConstraint satisfied
-            new_property.ensure_description_is_valid()?;
-
-            // Ensure Type specific constraints satisfied
-            new_property.ensure_property_type_size_is_valid()?;
-
-            // Ensure refers to existing class_id, if If Property Type is Reference,
-            Self::ensure_property_type_reference_is_valid(new_property)?;
-        }
-        Ok(())
-    }
-
-    /// Ensure refers to existing `class_id`, if If `Property` `Type` is `Reference`,
-    pub fn ensure_property_type_reference_is_valid(
-        property: &Property<T::ClassId>,
-    ) -> Result<(), Error<T>> {
-        let has_unknown_reference =
-            if let Type::Reference(other_class_id, _) = property.property_type.get_inner_type() {
-                !<ClassById<T>>::contains_key(other_class_id)
-            } else {
-                false
-            };
-
-        ensure!(
-            !has_unknown_reference,
-            Error::<T>::ClassSchemaRefersUnknownClass
-        );
-
-        Ok(())
-    }
-
-    /// Ensure all `Property` names are  unique within `Class`
-    pub fn ensure_all_property_names_are_unique(
-        class_properties: &[Property<T::ClassId>],
-        new_properties: &[Property<T::ClassId>],
-    ) -> Result<(), Error<T>> {
-        // Used to ensure all property names are unique within class
-        let mut unique_prop_names = BTreeSet::new();
-
-        for property in class_properties.iter() {
-            unique_prop_names.insert(property.name.to_owned());
-        }
-
-        for new_property in new_properties {
-            // Ensure name of a new property is unique within its class.
-            ensure!(
-                !unique_prop_names.contains(&new_property.name),
-                Error::<T>::PropertyNameNotUniqueInAClass
-            );
-
-            unique_prop_names.insert(new_property.name.to_owned());
-        }
-
-        Ok(())
-    }
-
-    /// Ensure provided indices of `existing_properties`  are valid indices of `Class` properties
-    pub fn ensure_schema_properties_are_valid_indices(
-        existing_properties: &BTreeSet<PropertyId>,
-        class_properties: &[Property<T::ClassId>],
-    ) -> Result<(), Error<T>> {
-        let has_unknown_properties = existing_properties
-            .iter()
-            .any(|&prop_id| prop_id >= class_properties.len() as PropertyId);
-        ensure!(
-            !has_unknown_properties,
-            Error::<T>::ClassSchemaRefersUnknownPropertyIndex
-        );
-        Ok(())
-    }
-
-    /// Create new `Schema` from existing and new property ids
-    pub fn create_class_schema(
-        existing_properties: BTreeSet<PropertyId>,
-        class_properties: &[Property<T::ClassId>],
-        new_properties: &[Property<T::ClassId>],
-    ) -> Schema {
-        // Calcualate new property ids
-        let properties = new_properties
-            .iter()
-            .enumerate()
-            .map(|(i, _)| (class_properties.len() + i) as PropertyId)
-            // Concatenate them with existing ones
-            .chain(existing_properties.into_iter())
-            .collect();
-
-        Schema::new(properties)
-    }
-
-    /// Update existing `Class` properties with new ones provided, return updated ones
-    pub fn make_updated_class_properties(
-        class_properties: Vec<Property<T::ClassId>>,
-        new_properties: Vec<Property<T::ClassId>>,
-    ) -> Vec<Property<T::ClassId>> {
-        class_properties
-            .into_iter()
-            .chain(new_properties.into_iter())
-            .collect()
-    }
-}
-
-impl<T: Trait> Module<T> {
-    pub fn set_initial_ids_to_one() {
-        <NextEntityId<T>>::put(T::EntityId::one());
-        <NextClassId<T>>::put(T::ClassId::one());
-        <NextCuratorGroupId<T>>::put(T::CuratorGroupId::one());
-    }
-}
-
-decl_event!(
-    pub enum Event<T>
-    where
-        CuratorGroupId = <T as ActorAuthenticator>::CuratorGroupId,
-        CuratorId = <T as ActorAuthenticator>::CuratorId,
-        ClassId = <T as Trait>::ClassId,
-        EntityId = <T as Trait>::EntityId,
-        EntityController = EntityController<<T as ActorAuthenticator>::MemberId>,
-        EntityCreationVoucher = EntityCreationVoucher<T>,
-        Status = bool,
-        Actor = Actor<
-            <T as ActorAuthenticator>::CuratorGroupId,
-            <T as ActorAuthenticator>::CuratorId,
-            <T as ActorAuthenticator>::MemberId,
-        >,
-        Nonce = <T as Trait>::Nonce,
-        SideEffects = Option<ReferenceCounterSideEffects<T>>,
-        SideEffect = Option<(<T as Trait>::EntityId, EntityReferenceCounterSideEffect)>,
-        FailedAt = u32,
-    {
-        CuratorGroupAdded(CuratorGroupId),
-        CuratorGroupRemoved(CuratorGroupId),
-        CuratorGroupStatusSet(CuratorGroupId, Status),
-        CuratorAdded(CuratorGroupId, CuratorId),
-        CuratorRemoved(CuratorGroupId, CuratorId),
-        MaintainerAdded(ClassId, CuratorGroupId),
-        MaintainerRemoved(ClassId, CuratorGroupId),
-        EntityCreationVoucherUpdated(EntityController, EntityCreationVoucher),
-        EntityCreationVoucherCreated(EntityController, EntityCreationVoucher),
-        ClassCreated(ClassId),
-        ClassPermissionsUpdated(ClassId),
-        ClassSchemaAdded(ClassId, SchemaId),
-        ClassSchemaStatusUpdated(ClassId, SchemaId, Status),
-        EntityPermissionsUpdated(EntityId),
-        EntityCreated(Actor, EntityId),
-        EntityRemoved(Actor, EntityId),
-        EntitySchemaSupportAdded(Actor, EntityId, SchemaId, SideEffects),
-        EntityPropertyValuesUpdated(Actor, EntityId, SideEffects),
-        VectorCleared(Actor, EntityId, PropertyId, SideEffects),
-        RemovedAtVectorIndex(Actor, EntityId, PropertyId, VecMaxLength, Nonce, SideEffect),
-        InsertedAtVectorIndex(Actor, EntityId, PropertyId, VecMaxLength, Nonce, SideEffect),
-        EntityOwnershipTransfered(EntityId, EntityController, SideEffects),
-        TransactionCompleted(Actor),
-        TransactionFailed(Actor, FailedAt),
-    }
-);

+ 0 - 1041
runtime-modules/content-directory/src/mock.rs

@@ -1,1041 +0,0 @@
-#![cfg(test)]
-
-use crate::InputValidationLengthConstraint;
-use crate::*;
-use core::iter::FromIterator;
-use frame_support::traits::{OnFinalize, OnInitialize};
-pub use frame_support::{
-    assert_err, assert_ok, impl_outer_event, impl_outer_origin, parameter_types,
-};
-use sp_core::H256;
-use sp_runtime::{
-    testing::Header,
-    traits::{BlakeTwo256, IdentityLookup},
-    Perbill,
-};
-use std::cell::RefCell;
-
-/// Runtime Types
-
-pub type ClassId = <Runtime as Trait>::ClassId;
-pub type EntityId = <Runtime as Trait>::EntityId;
-pub type Nonce = <Runtime as Trait>::Nonce;
-pub type Hashed = <Runtime as system::Trait>::Hash;
-
-pub type CuratorId = <Runtime as ActorAuthenticator>::CuratorId;
-pub type CuratorGroupId = <Runtime as ActorAuthenticator>::CuratorGroupId;
-pub type MemberId = <Runtime as ActorAuthenticator>::MemberId;
-
-/// Origins
-
-pub const LEAD_ORIGIN: u64 = 1;
-
-pub const FIRST_CURATOR_ORIGIN: u64 = 2;
-pub const SECOND_CURATOR_ORIGIN: u64 = 3;
-
-pub const FIRST_MEMBER_ORIGIN: u64 = 4;
-pub const SECOND_MEMBER_ORIGIN: u64 = 5;
-pub const UNKNOWN_ORIGIN: u64 = 7777;
-
-/// Runtime Id's
-
-pub const FIRST_CURATOR_ID: CuratorId = 1;
-pub const SECOND_CURATOR_ID: CuratorId = 2;
-
-pub const FIRST_CURATOR_GROUP_ID: CuratorGroupId = 1;
-pub const SECOND_CURATOR_GROUP_ID: CuratorGroupId = 2;
-
-pub const FIRST_MEMBER_ID: MemberId = 1;
-pub const SECOND_MEMBER_ID: MemberId = 2;
-
-pub const FIRST_CLASS_ID: ClassId = 1;
-pub const SECOND_CLASS_ID: ClassId = 2;
-
-pub const FIRST_ENTITY_ID: EntityId = 1;
-pub const SECOND_ENTITY_ID: EntityId = 2;
-pub const THIRD_ENTITY_ID: EntityId = 3;
-
-pub const UNKNOWN_CLASS_ID: ClassId = 111;
-pub const UNKNOWN_ENTITY_ID: EntityId = 222;
-pub const UNKNOWN_PROPERTY_ID: PropertyId = 333;
-pub const UNKNOWN_SCHEMA_ID: SchemaId = 444;
-
-pub const UNKNOWN_CURATOR_GROUP_ID: CuratorGroupId = 555;
-pub const UNKNOWN_CURATOR_ID: CuratorGroupId = 555;
-pub const UNKNOWN_MEMBER_ID: CuratorGroupId = 777;
-
-pub const FIRST_SCHEMA_ID: SchemaId = 0;
-pub const SECOND_SCHEMA_ID: SchemaId = 1;
-
-pub const FIRST_PROPERTY_ID: SchemaId = 0;
-pub const SECOND_PROPERTY_ID: SchemaId = 1;
-
-impl_outer_origin! {
-    pub enum Origin for Runtime {}
-}
-
-// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
-#[derive(Clone, Default, PartialEq, Eq, Debug)]
-pub struct Runtime;
-parameter_types! {
-    pub const BlockHashCount: u64 = 250;
-    pub const MaximumBlockWeight: u32 = 1024;
-    pub const MaximumBlockLength: u32 = 2 * 1024;
-    pub const AvailableBlockRatio: Perbill = Perbill::one();
-    pub const MinimumPeriod: u64 = 5;
-}
-
-thread_local! {
-    static PROPERTY_NAME_CONSTRAINT: RefCell<InputValidationLengthConstraint> = RefCell::new(InputValidationLengthConstraint::default());
-    static PROPERTY_DESCRIPTION_CONSTRAINT: RefCell<InputValidationLengthConstraint> = RefCell::new(InputValidationLengthConstraint::default());
-    static CLASS_NAME_CONSTRAINT: RefCell<InputValidationLengthConstraint> = RefCell::new(InputValidationLengthConstraint::default());
-    static CLASS_DESCRIPTION_CONSTRAINT: RefCell<InputValidationLengthConstraint> = RefCell::new(InputValidationLengthConstraint::default());
-    static MAX_NUMBER_OF_CLASSES: RefCell<MaxNumber> = RefCell::new(0);
-    static MAX_NUMBER_OF_MAINTAINERS_PER_CLASS: RefCell<MaxNumber> = RefCell::new(0);
-    static MAX_NUMBER_OF_SCHEMAS_PER_CLASS: RefCell<MaxNumber> = RefCell::new(0);
-    static MAX_NUMBER_OF_PROPERTIES_PER_CLASS: RefCell<MaxNumber> = RefCell::new(0);
-    static MAX_NUMBER_OF_ENTITIES_PER_CLASS: RefCell<EntityId> = RefCell::new(0);
-    static MAX_NUMBER_OF_CURATORS_PER_GROUP: RefCell<MaxNumber> = RefCell::new(0);
-    static MAX_NUMBER_OF_OPERATIONS_DURING_ATOMIC_BATCHING: RefCell<MaxNumber> = RefCell::new(0);
-    static VEC_MAX_LENGTH_CONSTRAINT: RefCell<VecMaxLength> = RefCell::new(0);
-    static TEXT_MAX_LENGTH_CONSTRAINT: RefCell<TextMaxLength> = RefCell::new(0);
-    static HASHED_TEXT_MAX_LENGTH_CONSTRAINT: RefCell<HashedTextMaxLength> = RefCell::new(Some(0));
-    static INDIVIDUAL_ENTITIES_CREATION_LIMIT: RefCell<EntityId> = RefCell::new(0);
-}
-
-pub struct PropertyNameLengthConstraint;
-impl Get<InputValidationLengthConstraint> for PropertyNameLengthConstraint {
-    fn get() -> InputValidationLengthConstraint {
-        PROPERTY_NAME_CONSTRAINT.with(|v| *v.borrow())
-    }
-}
-
-pub struct PropertyDescriptionLengthConstraint;
-impl Get<InputValidationLengthConstraint> for PropertyDescriptionLengthConstraint {
-    fn get() -> InputValidationLengthConstraint {
-        PROPERTY_DESCRIPTION_CONSTRAINT.with(|v| *v.borrow())
-    }
-}
-
-pub struct ClassNameLengthConstraint;
-impl Get<InputValidationLengthConstraint> for ClassNameLengthConstraint {
-    fn get() -> InputValidationLengthConstraint {
-        CLASS_NAME_CONSTRAINT.with(|v| *v.borrow())
-    }
-}
-
-pub struct ClassDescriptionLengthConstraint;
-impl Get<InputValidationLengthConstraint> for ClassDescriptionLengthConstraint {
-    fn get() -> InputValidationLengthConstraint {
-        CLASS_DESCRIPTION_CONSTRAINT.with(|v| *v.borrow())
-    }
-}
-
-pub struct MaxNumberOfClasses;
-impl Get<MaxNumber> for MaxNumberOfClasses {
-    fn get() -> MaxNumber {
-        MAX_NUMBER_OF_CLASSES.with(|v| *v.borrow())
-    }
-}
-
-pub struct MaxNumberOfMaintainersPerClass;
-impl Get<MaxNumber> for MaxNumberOfMaintainersPerClass {
-    fn get() -> MaxNumber {
-        MAX_NUMBER_OF_MAINTAINERS_PER_CLASS.with(|v| *v.borrow())
-    }
-}
-
-pub struct MaxNumberOfCuratorsPerGroup;
-impl Get<MaxNumber> for MaxNumberOfCuratorsPerGroup {
-    fn get() -> MaxNumber {
-        MAX_NUMBER_OF_CURATORS_PER_GROUP.with(|v| *v.borrow())
-    }
-}
-
-pub struct MaxNumberOfSchemasPerClass;
-impl Get<MaxNumber> for MaxNumberOfSchemasPerClass {
-    fn get() -> MaxNumber {
-        MAX_NUMBER_OF_SCHEMAS_PER_CLASS.with(|v| *v.borrow())
-    }
-}
-
-pub struct MaxNumberOfPropertiesPerSchema;
-impl Get<MaxNumber> for MaxNumberOfPropertiesPerSchema {
-    fn get() -> MaxNumber {
-        MAX_NUMBER_OF_PROPERTIES_PER_CLASS.with(|v| *v.borrow())
-    }
-}
-
-pub struct MaxNumberOfOperationsDuringAtomicBatching;
-impl Get<MaxNumber> for MaxNumberOfOperationsDuringAtomicBatching {
-    fn get() -> MaxNumber {
-        MAX_NUMBER_OF_OPERATIONS_DURING_ATOMIC_BATCHING.with(|v| *v.borrow())
-    }
-}
-
-pub struct VecMaxLengthConstraint;
-impl Get<VecMaxLength> for VecMaxLengthConstraint {
-    fn get() -> VecMaxLength {
-        VEC_MAX_LENGTH_CONSTRAINT.with(|v| *v.borrow())
-    }
-}
-
-pub struct TextMaxLengthConstraint;
-impl Get<TextMaxLength> for TextMaxLengthConstraint {
-    fn get() -> TextMaxLength {
-        TEXT_MAX_LENGTH_CONSTRAINT.with(|v| *v.borrow())
-    }
-}
-
-pub struct HashedTextMaxLengthConstraint;
-impl Get<HashedTextMaxLength> for HashedTextMaxLengthConstraint {
-    fn get() -> HashedTextMaxLength {
-        HASHED_TEXT_MAX_LENGTH_CONSTRAINT.with(|v| *v.borrow())
-    }
-}
-
-pub struct MaxNumberOfEntitiesPerClass;
-impl Get<EntityId> for MaxNumberOfEntitiesPerClass {
-    fn get() -> EntityId {
-        MAX_NUMBER_OF_ENTITIES_PER_CLASS.with(|v| *v.borrow())
-    }
-}
-
-pub struct IndividualEntitiesCreationLimit;
-impl Get<EntityId> for IndividualEntitiesCreationLimit {
-    fn get() -> EntityId {
-        INDIVIDUAL_ENTITIES_CREATION_LIMIT.with(|v| *v.borrow())
-    }
-}
-
-impl system::Trait for Runtime {
-    type BaseCallFilter = ();
-    type Origin = Origin;
-    type Call = ();
-    type Index = u64;
-    type BlockNumber = u64;
-    type Hash = H256;
-    type Hashing = BlakeTwo256;
-    type AccountId = u64;
-    type Lookup = IdentityLookup<Self::AccountId>;
-    type Header = Header;
-    type Event = TestEvent;
-    type BlockHashCount = BlockHashCount;
-    type MaximumBlockWeight = MaximumBlockWeight;
-    type DbWeight = ();
-    type BlockExecutionWeight = ();
-    type ExtrinsicBaseWeight = ();
-    type MaximumExtrinsicWeight = ();
-    type MaximumBlockLength = MaximumBlockLength;
-    type AvailableBlockRatio = AvailableBlockRatio;
-    type Version = ();
-    type ModuleToIndex = ();
-    type AccountData = ();
-    type OnNewAccount = ();
-    type OnKilledAccount = ();
-}
-
-mod test_events {
-    pub use crate::Event;
-}
-
-impl_outer_event! {
-    pub enum TestEvent for Runtime {
-        test_events<T>,
-        system<T>,
-    }
-}
-
-impl Trait for Runtime {
-    type Event = TestEvent;
-    type Nonce = u64;
-    type ClassId = u64;
-    type EntityId = u64;
-    type PropertyNameLengthConstraint = PropertyNameLengthConstraint;
-    type PropertyDescriptionLengthConstraint = PropertyDescriptionLengthConstraint;
-    type ClassNameLengthConstraint = ClassNameLengthConstraint;
-    type ClassDescriptionLengthConstraint = ClassDescriptionLengthConstraint;
-    type MaxNumberOfClasses = MaxNumberOfClasses;
-    type MaxNumberOfMaintainersPerClass = MaxNumberOfMaintainersPerClass;
-    type MaxNumberOfSchemasPerClass = MaxNumberOfSchemasPerClass;
-    type MaxNumberOfPropertiesPerSchema = MaxNumberOfPropertiesPerSchema;
-    type MaxNumberOfEntitiesPerClass = MaxNumberOfEntitiesPerClass;
-    type MaxNumberOfCuratorsPerGroup = MaxNumberOfCuratorsPerGroup;
-    type MaxNumberOfOperationsDuringAtomicBatching = MaxNumberOfOperationsDuringAtomicBatching;
-    type VecMaxLengthConstraint = VecMaxLengthConstraint;
-    type TextMaxLengthConstraint = TextMaxLengthConstraint;
-    type HashedTextMaxLengthConstraint = HashedTextMaxLengthConstraint;
-    type IndividualEntitiesCreationLimit = IndividualEntitiesCreationLimit;
-}
-
-impl ActorAuthenticator for Runtime {
-    type CuratorId = u64;
-    type MemberId = u64;
-    type CuratorGroupId = u64;
-
-    // Consider lazy_static crate?
-
-    fn is_lead(account_id: &Self::AccountId) -> bool {
-        let lead_account_id = ensure_signed(Origin::signed(LEAD_ORIGIN)).unwrap();
-        *account_id == lead_account_id
-    }
-
-    fn is_curator(curator_id: &Self::CuratorId, account_id: &Self::AccountId) -> bool {
-        let first_curator_account_id = ensure_signed(Origin::signed(FIRST_CURATOR_ORIGIN)).unwrap();
-        let second_curator_account_id =
-            ensure_signed(Origin::signed(SECOND_CURATOR_ORIGIN)).unwrap();
-        (first_curator_account_id == *account_id && FIRST_CURATOR_ID == *curator_id)
-            || (second_curator_account_id == *account_id && SECOND_CURATOR_ID == *curator_id)
-    }
-
-    fn is_member(member_id: &Self::MemberId, account_id: &Self::AccountId) -> bool {
-        let unknown_member_account_id = ensure_signed(Origin::signed(UNKNOWN_ORIGIN)).unwrap();
-        *member_id < MaxNumberOfEntitiesPerClass::get() && unknown_member_account_id != *account_id
-    }
-}
-
-pub struct ExtBuilder {
-    property_name_constraint: InputValidationLengthConstraint,
-    property_description_constraint: InputValidationLengthConstraint,
-    class_name_constraint: InputValidationLengthConstraint,
-    class_description_constraint: InputValidationLengthConstraint,
-    max_number_of_classes: MaxNumber,
-    max_number_of_maintainers_per_class: MaxNumber,
-    max_number_of_schemas_per_class: MaxNumber,
-    max_number_of_properties_per_class: MaxNumber,
-    max_number_of_entities_per_class: EntityId,
-    max_number_of_curators_per_group: MaxNumber,
-    max_number_of_operations_during_atomic_batching: MaxNumber,
-    vec_max_length_constraint: VecMaxLength,
-    text_max_length_constraint: TextMaxLength,
-    hashed_text_max_length_constraint: HashedTextMaxLength,
-    individual_entities_creation_limit: EntityId,
-}
-
-impl Default for ExtBuilder {
-    fn default() -> Self {
-        Self {
-            property_name_constraint: InputValidationLengthConstraint::new(1, 49),
-            property_description_constraint: InputValidationLengthConstraint::new(1, 500),
-            class_name_constraint: InputValidationLengthConstraint::new(1, 49),
-            class_description_constraint: InputValidationLengthConstraint::new(1, 500),
-            max_number_of_classes: 100,
-            max_number_of_maintainers_per_class: 10,
-            max_number_of_schemas_per_class: 20,
-            max_number_of_properties_per_class: 40,
-            max_number_of_entities_per_class: 400,
-            max_number_of_curators_per_group: 50,
-            max_number_of_operations_during_atomic_batching: 500,
-            vec_max_length_constraint: 200,
-            text_max_length_constraint: 5000,
-            hashed_text_max_length_constraint: Some(25000),
-            individual_entities_creation_limit: 50,
-        }
-    }
-}
-
-impl ExtBuilder {
-    pub fn set_associated_consts(&self) {
-        PROPERTY_NAME_CONSTRAINT.with(|v| *v.borrow_mut() = self.property_name_constraint);
-        PROPERTY_DESCRIPTION_CONSTRAINT
-            .with(|v| *v.borrow_mut() = self.property_description_constraint);
-        CLASS_NAME_CONSTRAINT.with(|v| *v.borrow_mut() = self.class_name_constraint);
-        CLASS_DESCRIPTION_CONSTRAINT.with(|v| *v.borrow_mut() = self.class_description_constraint);
-        MAX_NUMBER_OF_CLASSES.with(|v| *v.borrow_mut() = self.max_number_of_classes);
-        MAX_NUMBER_OF_MAINTAINERS_PER_CLASS
-            .with(|v| *v.borrow_mut() = self.max_number_of_maintainers_per_class);
-        MAX_NUMBER_OF_SCHEMAS_PER_CLASS
-            .with(|v| *v.borrow_mut() = self.max_number_of_schemas_per_class);
-        MAX_NUMBER_OF_PROPERTIES_PER_CLASS
-            .with(|v| *v.borrow_mut() = self.max_number_of_properties_per_class);
-        MAX_NUMBER_OF_ENTITIES_PER_CLASS
-            .with(|v| *v.borrow_mut() = self.max_number_of_entities_per_class);
-        MAX_NUMBER_OF_CURATORS_PER_GROUP
-            .with(|v| *v.borrow_mut() = self.max_number_of_curators_per_group);
-        MAX_NUMBER_OF_OPERATIONS_DURING_ATOMIC_BATCHING
-            .with(|v| *v.borrow_mut() = self.max_number_of_operations_during_atomic_batching);
-        VEC_MAX_LENGTH_CONSTRAINT.with(|v| *v.borrow_mut() = self.vec_max_length_constraint);
-        TEXT_MAX_LENGTH_CONSTRAINT.with(|v| *v.borrow_mut() = self.text_max_length_constraint);
-        HASHED_TEXT_MAX_LENGTH_CONSTRAINT
-            .with(|v| *v.borrow_mut() = self.hashed_text_max_length_constraint);
-        INDIVIDUAL_ENTITIES_CREATION_LIMIT
-            .with(|v| *v.borrow_mut() = self.individual_entities_creation_limit);
-    }
-
-    pub fn build(self, config: GenesisConfig<Runtime>) -> sp_io::TestExternalities {
-        self.set_associated_consts();
-        let mut t = system::GenesisConfig::default()
-            .build_storage::<Runtime>()
-            .unwrap();
-        config.assimilate_storage(&mut t).unwrap();
-        t.into()
-    }
-}
-
-// This function basically just builds a genesis storage key/value store according to
-// our desired mockup.
-
-fn default_content_directory_genesis_config() -> GenesisConfig<Runtime> {
-    GenesisConfig {
-        class_by_id: vec![],
-        entity_by_id: vec![],
-        curator_group_by_id: vec![],
-        next_class_id: 1,
-        next_entity_id: 1,
-        next_curator_group_id: 1,
-    }
-}
-
-pub fn with_test_externalities<R, F: FnOnce() -> R>(f: F) -> R {
-    let default_genesis_config = default_content_directory_genesis_config();
-    /*
-        Events are not emitted on block 0.
-        So any dispatchable calls made during genesis block formation will have no events emitted.
-        https://substrate.dev/recipes/2-appetizers/4-events.html
-    */
-    let func = || {
-        run_to_block(1);
-        f()
-    };
-
-    ExtBuilder::default()
-        .build(default_genesis_config)
-        .execute_with(func)
-}
-
-pub fn generate_text(len: usize) -> Vec<u8> {
-    vec![b'x'; len]
-}
-
-impl<ClassId: Default + BaseArithmetic + Clone + Copy> Property<ClassId> {
-    pub fn required(mut self) -> Self {
-        self.required = true;
-        self
-    }
-
-    pub fn unique(mut self) -> Self {
-        self.unique = true;
-        self
-    }
-}
-
-// Events
-
-type RawTestEvent = RawEvent<
-    CuratorGroupId,
-    CuratorId,
-    ClassId,
-    EntityId,
-    EntityController<MemberId>,
-    EntityCreationVoucher<Runtime>,
-    bool,
-    Actor<CuratorGroupId, CuratorId, MemberId>,
-    Nonce,
-    Option<ReferenceCounterSideEffects<Runtime>>,
-    Option<(EntityId, EntityReferenceCounterSideEffect)>,
-    u32,
->;
-
-pub fn get_test_event(raw_event: RawTestEvent) -> TestEvent {
-    TestEvent::test_events(raw_event)
-}
-
-pub fn assert_event(tested_event: TestEvent, number_of_events_after_call: usize) {
-    // Ensure  runtime events length is equal to expected number of events after call
-    assert_eq!(System::events().len(), number_of_events_after_call);
-
-    // Ensure  last emitted event is equal to expected one
-    assert!(matches!(
-            System::events()
-                .iter()
-                .last(),
-            Some(last_event) if last_event.event == tested_event
-    ));
-}
-
-pub fn assert_failure(
-    call_result: DispatchResult,
-    expected_error: Error<Runtime>,
-    number_of_events_before_call: usize,
-) {
-    // Ensure  call result is equal to expected error
-    assert_err!(call_result, expected_error);
-
-    // Ensure  no other events emitted after call
-    assert_eq!(System::events().len(), number_of_events_before_call);
-}
-
-// Curator groups
-
-pub fn next_curator_group_id() -> CuratorGroupId {
-    TestModule::next_curator_group_id()
-}
-
-pub fn add_curator_group(lead_origin: u64) -> DispatchResult {
-    TestModule::add_curator_group(Origin::signed(lead_origin))
-}
-
-pub fn remove_curator_group(lead_origin: u64, curator_group_id: CuratorGroupId) -> DispatchResult {
-    TestModule::remove_curator_group(Origin::signed(lead_origin), curator_group_id)
-}
-
-pub fn add_curator_to_group(
-    lead_origin: u64,
-    curator_group_id: CuratorGroupId,
-    curator_id: CuratorId,
-) -> DispatchResult {
-    TestModule::add_curator_to_group(Origin::signed(lead_origin), curator_group_id, curator_id)
-}
-
-pub fn remove_curator_from_group(
-    lead_origin: u64,
-    curator_group_id: CuratorGroupId,
-    curator_id: CuratorId,
-) -> DispatchResult {
-    TestModule::remove_curator_from_group(Origin::signed(lead_origin), curator_group_id, curator_id)
-}
-
-pub fn set_curator_group_status(
-    lead_origin: u64,
-    curator_group_id: CuratorGroupId,
-    is_active: bool,
-) -> DispatchResult {
-    TestModule::set_curator_group_status(Origin::signed(lead_origin), curator_group_id, is_active)
-}
-
-pub fn curator_group_by_id(curator_group_id: CuratorGroupId) -> CuratorGroup<Runtime> {
-    TestModule::curator_group_by_id(curator_group_id)
-}
-
-pub fn curator_group_exists(curator_group_id: CuratorGroupId) -> bool {
-    CuratorGroupById::<Runtime>::contains_key(curator_group_id)
-}
-
-// Classes
-
-pub enum ClassType {
-    Valid,
-    NameTooLong,
-    NameTooShort,
-    DescriptionTooLong,
-    DescriptionTooShort,
-    InvalidMaximumEntitiesCount,
-    InvalidDefaultVoucherUpperBound,
-    DefaultVoucherUpperBoundExceedsMaximumEntitiesCount,
-    MaintainersLimitReached,
-    CuratorGroupDoesNotExist,
-}
-
-pub fn create_simple_class(lead_origin: u64, class_type: ClassType) -> DispatchResult {
-    let mut class = create_class_with_default_permissions();
-    match class_type {
-        ClassType::Valid => (),
-        ClassType::NameTooShort => {
-            class.set_name(generate_text(
-                ClassNameLengthConstraint::get().min() as usize - 1,
-            ));
-        }
-        ClassType::NameTooLong => {
-            class.set_name(generate_text(
-                ClassNameLengthConstraint::get().max() as usize + 1,
-            ));
-        }
-        ClassType::DescriptionTooLong => {
-            class.set_description(generate_text(
-                ClassDescriptionLengthConstraint::get().max() as usize + 1,
-            ));
-        }
-        ClassType::DescriptionTooShort => {
-            class.set_description(generate_text(
-                ClassDescriptionLengthConstraint::get().min() as usize - 1,
-            ));
-        }
-        ClassType::InvalidMaximumEntitiesCount => {
-            class.set_maximum_entities_count(MaxNumberOfEntitiesPerClass::get() + 1);
-        }
-        ClassType::InvalidDefaultVoucherUpperBound => {
-            class.set_default_entity_creation_voucher_upper_bound(
-                IndividualEntitiesCreationLimit::get() + 1,
-            );
-        }
-        ClassType::DefaultVoucherUpperBoundExceedsMaximumEntitiesCount => {
-            class.set_maximum_entities_count(5);
-
-            class.set_maximum_entities_count(3);
-        }
-        ClassType::MaintainersLimitReached => {
-            let mut maintainers = BTreeSet::new();
-            for curator_group_id in 1..=(MaxNumberOfMaintainersPerClass::get() + 1) {
-                maintainers.insert(curator_group_id as CuratorGroupId);
-            }
-            class.get_permissions_mut().set_maintainers(maintainers);
-        }
-        ClassType::CuratorGroupDoesNotExist => {
-            let maintainers = BTreeSet::from_iter(vec![UNKNOWN_CURATOR_GROUP_ID].into_iter());
-            class.get_permissions_mut().set_maintainers(maintainers);
-        }
-    };
-    TestModule::create_class(
-        Origin::signed(lead_origin),
-        class.get_name().to_owned(),
-        class.get_description().to_owned(),
-        class.get_permissions_ref().to_owned(),
-        class.get_maximum_entities_count(),
-        class.get_default_entity_creation_voucher_upper_bound(),
-    )
-}
-
-pub fn create_class_with_default_permissions() -> Class<EntityId, ClassId, CuratorGroupId> {
-    Class::new(
-        ClassPermissions::default(),
-        generate_text(ClassNameLengthConstraint::get().max() as usize),
-        generate_text(ClassDescriptionLengthConstraint::get().max() as usize),
-        MaxNumberOfEntitiesPerClass::get(),
-        IndividualEntitiesCreationLimit::get(),
-    )
-}
-
-pub fn add_maintainer_to_class(
-    lead_origin: u64,
-    class_id: ClassId,
-    curator_group_id: CuratorGroupId,
-) -> DispatchResult {
-    TestModule::add_maintainer_to_class(Origin::signed(lead_origin), class_id, curator_group_id)
-}
-
-pub fn remove_maintainer_from_class(
-    lead_origin: u64,
-    class_id: ClassId,
-    curator_group_id: CuratorGroupId,
-) -> DispatchResult {
-    TestModule::remove_maintainer_from_class(
-        Origin::signed(lead_origin),
-        class_id,
-        curator_group_id,
-    )
-}
-
-pub fn update_class_permissions(
-    lead_origin: u64,
-    class_id: ClassId,
-    updated_any_member: Option<bool>,
-    updated_entity_creation_blocked: Option<bool>,
-    updated_all_entity_property_values_locked: Option<bool>,
-    updated_maintainers: Option<BTreeSet<CuratorGroupId>>,
-) -> DispatchResult {
-    TestModule::update_class_permissions(
-        Origin::signed(lead_origin),
-        class_id,
-        updated_any_member,
-        updated_entity_creation_blocked,
-        updated_all_entity_property_values_locked,
-        updated_maintainers,
-    )
-}
-
-pub fn add_class_schema(
-    lead_origin: u64,
-    class_id: ClassId,
-    existing_properties: BTreeSet<PropertyId>,
-    new_properties: Vec<Property<ClassId>>,
-) -> DispatchResult {
-    TestModule::add_class_schema(
-        Origin::signed(lead_origin),
-        class_id,
-        existing_properties,
-        new_properties,
-    )
-}
-
-pub fn update_class_schema_status(
-    lead_origin: u64,
-    class_id: ClassId,
-    schema_id: SchemaId,
-    status: bool,
-) -> DispatchResult {
-    TestModule::update_class_schema_status(Origin::signed(lead_origin), class_id, schema_id, status)
-}
-
-pub fn next_class_id() -> ClassId {
-    TestModule::next_class_id()
-}
-
-pub fn class_by_id(class_id: ClassId) -> Class<EntityId, ClassId, CuratorGroupId> {
-    TestModule::class_by_id(class_id)
-}
-
-pub fn class_exists(class_id: ClassId) -> bool {
-    ClassById::<Runtime>::contains_key(class_id)
-}
-
-// Vouchers
-
-pub fn update_entity_creation_voucher(
-    lead_origin: u64,
-    class_id: ClassId,
-    controller: EntityController<MemberId>,
-    maximum_entities_count: EntityId,
-) -> DispatchResult {
-    TestModule::update_entity_creation_voucher(
-        Origin::signed(lead_origin),
-        class_id,
-        controller,
-        maximum_entities_count,
-    )
-}
-
-pub fn entity_creation_vouchers(
-    class_id: ClassId,
-    entity_controller: &EntityController<MemberId>,
-) -> EntityCreationVoucher<Runtime> {
-    TestModule::entity_creation_vouchers(class_id, entity_controller)
-}
-
-pub fn entity_creation_voucher_exists(
-    class_id: ClassId,
-    entity_controller: &EntityController<MemberId>,
-) -> bool {
-    EntityCreationVouchers::<Runtime>::contains_key(class_id, entity_controller)
-}
-
-// Entities
-
-pub fn entity_exists(entity_id: EntityId) -> bool {
-    EntityById::<Runtime>::contains_key(entity_id)
-}
-
-pub fn entity_by_id(entity_id: EntityId) -> Entity<ClassId, MemberId, Hashed, EntityId, Nonce> {
-    TestModule::entity_by_id(entity_id)
-}
-
-pub fn next_entity_id() -> EntityId {
-    TestModule::next_entity_id()
-}
-
-pub fn create_entity(
-    origin: u64,
-    class_id: ClassId,
-    actor: Actor<CuratorGroupId, CuratorId, MemberId>,
-) -> DispatchResult {
-    TestModule::create_entity(Origin::signed(origin), class_id, actor)
-}
-
-pub fn remove_entity(
-    origin: u64,
-    actor: Actor<CuratorGroupId, CuratorId, MemberId>,
-    entity_id: EntityId,
-) -> DispatchResult {
-    TestModule::remove_entity(Origin::signed(origin), actor, entity_id)
-}
-
-pub fn update_entity_permissions(
-    lead_origin: u64,
-    entity_id: EntityId,
-    updated_frozen: Option<bool>,
-    updated_referenceable: Option<bool>,
-) -> DispatchResult {
-    TestModule::update_entity_permissions(
-        Origin::signed(lead_origin),
-        entity_id,
-        updated_frozen,
-        updated_referenceable,
-    )
-}
-
-pub fn add_schema_support_to_entity(
-    origin: u64,
-    actor: Actor<CuratorGroupId, CuratorId, MemberId>,
-    entity_id: EntityId,
-    schema_id: SchemaId,
-    new_property_values: BTreeMap<PropertyId, InputPropertyValue<Runtime>>,
-) -> DispatchResult {
-    TestModule::add_schema_support_to_entity(
-        Origin::signed(origin),
-        actor,
-        entity_id,
-        schema_id,
-        new_property_values,
-    )
-}
-
-pub fn update_entity_property_values(
-    origin: u64,
-    actor: Actor<CuratorGroupId, CuratorId, MemberId>,
-    entity_id: EntityId,
-    new_property_values: BTreeMap<PropertyId, InputPropertyValue<Runtime>>,
-) -> DispatchResult {
-    TestModule::update_entity_property_values(
-        Origin::signed(origin),
-        actor,
-        entity_id,
-        new_property_values,
-    )
-}
-
-pub fn clear_entity_property_vector(
-    origin: u64,
-    actor: Actor<CuratorGroupId, CuratorId, MemberId>,
-    entity_id: EntityId,
-    in_class_schema_property_id: PropertyId,
-) -> DispatchResult {
-    TestModule::clear_entity_property_vector(
-        Origin::signed(origin),
-        actor,
-        entity_id,
-        in_class_schema_property_id,
-    )
-}
-
-pub fn insert_at_entity_property_vector(
-    origin: u64,
-    actor: Actor<CuratorGroupId, CuratorId, MemberId>,
-    entity_id: EntityId,
-    in_class_schema_property_id: PropertyId,
-    index_in_property_vector: VecMaxLength,
-    property_value: InputValue<Runtime>,
-    nonce: Nonce,
-) -> DispatchResult {
-    TestModule::insert_at_entity_property_vector(
-        Origin::signed(origin),
-        actor,
-        entity_id,
-        in_class_schema_property_id,
-        index_in_property_vector,
-        property_value,
-        nonce,
-    )
-}
-
-pub fn remove_at_entity_property_vector(
-    origin: u64,
-    actor: Actor<CuratorGroupId, CuratorId, MemberId>,
-    entity_id: EntityId,
-    in_class_schema_property_id: PropertyId,
-    index_in_property_vector: VecMaxLength,
-    nonce: Nonce,
-) -> DispatchResult {
-    TestModule::remove_at_entity_property_vector(
-        Origin::signed(origin),
-        actor,
-        entity_id,
-        in_class_schema_property_id,
-        index_in_property_vector,
-        nonce,
-    )
-}
-
-pub fn transfer_entity_ownership(
-    origin: u64,
-    entity_id: EntityId,
-    new_controller: EntityController<MemberId>,
-    new_property_value_references_with_same_owner_flag_set: BTreeMap<
-        PropertyId,
-        InputPropertyValue<Runtime>,
-    >,
-) -> DispatchResult {
-    TestModule::transfer_entity_ownership(
-        Origin::signed(origin),
-        entity_id,
-        new_controller,
-        new_property_value_references_with_same_owner_flag_set,
-    )
-}
-
-// Transaction
-
-pub fn transaction(
-    origin: u64,
-    actor: Actor<CuratorGroupId, CuratorId, MemberId>,
-    operations: Vec<OperationType<Runtime>>,
-) -> DispatchResult {
-    TestModule::transaction(Origin::signed(origin), actor, operations)
-}
-
-pub enum InvalidPropertyType {
-    NameTooLong,
-    NameTooShort,
-    DescriptionTooLong,
-    DescriptionTooShort,
-    TextIsTooLong,
-    TextHashIsTooLong,
-    VecIsTooLong,
-}
-
-impl Property<ClassId> {
-    pub fn default_with_name(name_len: usize) -> Self {
-        let name = generate_text(name_len);
-        let description = generate_text(PropertyDescriptionLengthConstraint::get().min() as usize);
-        Self {
-            name,
-            description,
-            ..Property::<ClassId>::default()
-        }
-    }
-
-    pub fn with_name_and_type(
-        name_len: usize,
-        property_type: PropertyType<ClassId>,
-        required: bool,
-        unique: bool,
-    ) -> Self {
-        let name = generate_text(name_len);
-        let description = generate_text(PropertyDescriptionLengthConstraint::get().min() as usize);
-        Self {
-            name,
-            description,
-            property_type,
-            required,
-            unique,
-            ..Property::<ClassId>::default()
-        }
-    }
-
-    pub fn invalid(invalid_property_type: InvalidPropertyType) -> Property<ClassId> {
-        let mut default_property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().min() as usize,
-        );
-        match invalid_property_type {
-            InvalidPropertyType::NameTooLong => {
-                default_property.name =
-                    generate_text(PropertyNameLengthConstraint::get().max() as usize + 1);
-            }
-            InvalidPropertyType::NameTooShort => {
-                default_property.name =
-                    generate_text(PropertyNameLengthConstraint::get().min() as usize - 1);
-            }
-            InvalidPropertyType::DescriptionTooLong => {
-                default_property.description =
-                    generate_text(PropertyDescriptionLengthConstraint::get().max() as usize + 1);
-            }
-            InvalidPropertyType::DescriptionTooShort => {
-                default_property.description =
-                    generate_text(PropertyDescriptionLengthConstraint::get().min() as usize - 1);
-            }
-            InvalidPropertyType::TextIsTooLong => {
-                default_property.property_type =
-                    PropertyType::<ClassId>::single_text(TextMaxLengthConstraint::get() + 1);
-            }
-            InvalidPropertyType::TextHashIsTooLong => {
-                if let Some(hashed_text_max_len) = HashedTextMaxLengthConstraint::get() {
-                    default_property.property_type =
-                        PropertyType::<ClassId>::single_text_hash(Some(hashed_text_max_len + 1));
-                }
-            }
-            InvalidPropertyType::VecIsTooLong => {
-                default_property.property_type = PropertyType::<ClassId>::vec_reference(
-                    FIRST_CLASS_ID,
-                    true,
-                    VecMaxLengthConstraint::get() + 1,
-                );
-            }
-        };
-        default_property
-    }
-}
-
-impl PropertyType<ClassId> {
-    pub fn vec_reference(
-        class_id: ClassId,
-        same_controller: bool,
-        max_length: VecMaxLength,
-    ) -> PropertyType<ClassId> {
-        let vec_type = Type::<ClassId>::Reference(class_id, same_controller);
-        let vec_reference = VecPropertyType::<ClassId>::new(vec_type, max_length);
-        PropertyType::<ClassId>::Vector(vec_reference)
-    }
-
-    pub fn vec_text(
-        text_max_len: TextMaxLength,
-        vec_max_length: VecMaxLength,
-    ) -> PropertyType<ClassId> {
-        let vec_type = Type::<ClassId>::Text(text_max_len);
-        let vec_text = VecPropertyType::<ClassId>::new(vec_type, vec_max_length);
-        PropertyType::<ClassId>::Vector(vec_text)
-    }
-
-    pub fn single_text(text_max_len: TextMaxLength) -> PropertyType<ClassId> {
-        let text_type = Type::<ClassId>::Text(text_max_len);
-        PropertyType::<ClassId>::Single(text_type)
-    }
-
-    pub fn single_text_hash(text_hash_max_len: HashedTextMaxLength) -> PropertyType<ClassId> {
-        let text_type = Type::<ClassId>::Hash(text_hash_max_len);
-        PropertyType::<ClassId>::Single(text_type)
-    }
-
-    pub fn vec_text_hash(
-        text_hash_max_len: HashedTextMaxLength,
-        vec_max_length: VecMaxLength,
-    ) -> PropertyType<ClassId> {
-        let vec_type = Type::<ClassId>::Hash(text_hash_max_len);
-        let vec_text_hash = VecPropertyType::<ClassId>::new(vec_type, vec_max_length);
-        PropertyType::<ClassId>::Vector(vec_text_hash)
-    }
-}
-
-impl<T: Trait> InputPropertyValue<T> {
-    pub fn vec_reference(entity_ids: Vec<EntityId>) -> InputPropertyValue<Runtime> {
-        let vec_value = VecInputValue::<Runtime>::Reference(entity_ids);
-        InputPropertyValue::<Runtime>::Vector(vec_value)
-    }
-
-    pub fn vec_text(texts: Vec<Vec<u8>>) -> InputPropertyValue<Runtime> {
-        let vec_value = VecInputValue::<Runtime>::Text(texts);
-        InputPropertyValue::<Runtime>::Vector(vec_value)
-    }
-
-    pub fn vec_text_to_hash(texts: Vec<Vec<u8>>) -> InputPropertyValue<Runtime> {
-        let vec_value = VecInputValue::<Runtime>::TextToHash(texts);
-        InputPropertyValue::<Runtime>::Vector(vec_value)
-    }
-
-    pub fn single_text(text_len: TextMaxLength) -> InputPropertyValue<Runtime> {
-        let text_value = InputValue::<Runtime>::Text(generate_text(text_len as usize));
-        InputPropertyValue::<Runtime>::Single(text_value)
-    }
-
-    pub fn single_text_to_hash(text_len: TextMaxLength) -> InputPropertyValue<Runtime> {
-        let text_value = InputValue::<Runtime>::TextToHash(generate_text(text_len as usize));
-        InputPropertyValue::<Runtime>::Single(text_value)
-    }
-}
-
-impl From<InboundReferenceCounter> for EntityReferenceCounterSideEffect {
-    fn from(inbound_rc: InboundReferenceCounter) -> Self {
-        Self {
-            total: inbound_rc.total as i32,
-            same_owner: inbound_rc.same_owner as i32,
-        }
-    }
-}
-
-impl EntityReferenceCounterSideEffect {
-    pub fn new(total: i32, same_owner: i32) -> Self {
-        Self { total, same_owner }
-    }
-}
-
-impl PropertyLockingPolicy {
-    pub fn new(is_locked_from_maintainer: bool, is_locked_from_controller: bool) -> Self {
-        Self {
-            is_locked_from_maintainer,
-            is_locked_from_controller,
-        }
-    }
-}
-
-// Assign back to type variables so we can make dispatched calls of these modules later.
-pub type System = system::Module<Runtime>;
-pub type TestModule = Module<Runtime>;
-
-// Recommendation from Parity on testing on_finalize
-// https://substrate.dev/docs/en/next/development/module/tests
-pub fn run_to_block(n: u64) {
-    while System::block_number() < n {
-        <System as OnFinalize<u64>>::on_finalize(System::block_number());
-        <TestModule as OnFinalize<u64>>::on_finalize(System::block_number());
-        System::set_block_number(System::block_number() + 1);
-        <System as OnInitialize<u64>>::on_initialize(System::block_number());
-        <TestModule as OnInitialize<u64>>::on_initialize(System::block_number());
-    }
-}

+ 0 - 141
runtime-modules/content-directory/src/operations.rs

@@ -1,141 +0,0 @@
-use crate::{Error, InputPropertyValue, InputValue, PropertyId, SchemaId, Trait, VecInputValue};
-use codec::{Decode, Encode};
-use sp_std::collections::btree_map::BTreeMap;
-use sp_std::prelude::*;
-
-/// Parametrized entity property value
-#[derive(Encode, Decode, Eq, PartialEq, Clone)]
-pub enum ParametrizedPropertyValue<T: Trait> {
-    /// Same fields as normal InputPropertyValue
-    InputPropertyValue(InputPropertyValue<T>),
-
-    /// This is the index of an operation creating an entity in the transaction/batch operations
-    InternalEntityJustAdded(u32), // should really be usize but it doesn't have Encode/Decode support
-
-    /// Vector of mix of Entities already existing and just added in a recent operation
-    InternalEntityVec(Vec<ParameterizedEntity<T>>),
-}
-
-/// Parametrized entity
-#[derive(Encode, Decode, Eq, PartialEq, Clone)]
-pub enum ParameterizedEntity<T: Trait> {
-    InternalEntityJustAdded(u32),
-    ExistingEntity(T::EntityId),
-}
-
-/// Parametrized class property value
-#[derive(Encode, Decode, Eq, PartialEq, Clone)]
-pub struct ParametrizedClassPropertyValue<T: Trait> {
-    /// Index is into properties vector of class.
-    pub in_class_index: PropertyId,
-
-    /// InputValue of property with index `in_class_index` in a given class.
-    pub value: ParametrizedPropertyValue<T>,
-}
-
-/// Operation, that represents `Entity` creation
-#[derive(Encode, Decode, Eq, PartialEq, Clone)]
-pub struct CreateEntityOperation<T: Trait> {
-    /// Class of an Entity
-    pub class_id: T::ClassId,
-}
-
-/// Operation, that represents property values update
-#[derive(Encode, Decode, Eq, PartialEq, Clone)]
-pub struct UpdatePropertyValuesOperation<T: Trait> {
-    /// Entity id to perfrom operation
-    pub entity_id: ParameterizedEntity<T>,
-    /// Property values, that should be updated
-    pub new_parametrized_property_values: Vec<ParametrizedClassPropertyValue<T>>,
-}
-
-/// Operation, that represents adding `Entity` `Schema` support
-#[derive(Encode, Decode, Eq, PartialEq, Clone)]
-pub struct AddSchemaSupportToEntityOperation<T: Trait> {
-    /// Entity id to perfrom operation
-    pub entity_id: ParameterizedEntity<T>,
-    /// Schema id defined on `Class` level to be added to the `Entity`
-    pub schema_id: SchemaId,
-    /// Property values, that should be added for the underlying schema_id
-    pub parametrized_property_values: Vec<ParametrizedClassPropertyValue<T>>,
-}
-
-/// The type of operation performed
-#[derive(Encode, Decode, Eq, PartialEq, Clone)]
-pub enum OperationType<T: Trait> {
-    CreateEntity(CreateEntityOperation<T>),
-    UpdatePropertyValues(UpdatePropertyValuesOperation<T>),
-    AddSchemaSupportToEntity(AddSchemaSupportToEntityOperation<T>),
-}
-
-impl<T: Trait> core::fmt::Debug for OperationType<T> {
-    fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
-        write!(formatter, "OperationType {:?}", self)
-    }
-}
-
-/// Retrieve entity_id of parametrized `Entity`
-pub fn parametrized_entity_to_entity_id<T: Trait>(
-    created_entities: &BTreeMap<usize, T::EntityId>,
-    entity: ParameterizedEntity<T>,
-) -> Result<T::EntityId, Error<T>> {
-    match entity {
-        ParameterizedEntity::ExistingEntity(entity_id) => Ok(entity_id),
-        ParameterizedEntity::InternalEntityJustAdded(op_index_u32) => {
-            let op_index = op_index_u32 as usize;
-            Ok(*created_entities
-                .get(&op_index)
-                .ok_or(Error::<T>::EntityNotCreatedByOperation)?)
-        }
-    }
-}
-
-/// Convert parametrized property values into property values
-pub fn parametrized_property_values_to_property_values<T: Trait>(
-    created_entities: &BTreeMap<usize, T::EntityId>,
-    parametrized_property_values: Vec<ParametrizedClassPropertyValue<T>>,
-) -> Result<BTreeMap<PropertyId, InputPropertyValue<T>>, Error<T>> {
-    let mut class_property_values = BTreeMap::new();
-
-    for parametrized_class_property_value in parametrized_property_values.into_iter() {
-        let property_value = match parametrized_class_property_value.value {
-            ParametrizedPropertyValue::InputPropertyValue(value) => value,
-            ParametrizedPropertyValue::InternalEntityJustAdded(
-                entity_created_in_operation_index,
-            ) => {
-                // Verify that referenced entity was indeed created created
-                let op_index = entity_created_in_operation_index as usize;
-                let entity_id = created_entities
-                    .get(&op_index)
-                    .ok_or(Error::<T>::EntityNotCreatedByOperation)?;
-                InputPropertyValue::Single(InputValue::Reference(*entity_id))
-            }
-            ParametrizedPropertyValue::InternalEntityVec(parametrized_entities) => {
-                let mut entities: Vec<T::EntityId> = vec![];
-
-                for parametrized_entity in parametrized_entities.into_iter() {
-                    match parametrized_entity {
-                        ParameterizedEntity::ExistingEntity(id) => entities.push(id),
-                        ParameterizedEntity::InternalEntityJustAdded(
-                            entity_created_in_operation_index,
-                        ) => {
-                            let op_index = entity_created_in_operation_index as usize;
-                            let entity_id = created_entities
-                                .get(&op_index)
-                                .ok_or(Error::<T>::EntityNotCreatedByOperation)?;
-                            entities.push(*entity_id);
-                        }
-                    }
-                }
-                InputPropertyValue::Vector(VecInputValue::Reference(entities))
-            }
-        };
-
-        class_property_values.insert(
-            parametrized_class_property_value.in_class_index,
-            property_value,
-        );
-    }
-
-    Ok(class_property_values)
-}

+ 0 - 107
runtime-modules/content-directory/src/permissions/class.rs

@@ -1,107 +0,0 @@
-use super::*;
-
-/// Permissions for an instance of a `Class` in the versioned store.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, Default)]
-pub struct ClassPermissions<CuratorGroupId: Ord + Default> {
-    /// For this permission, the individual member is allowed to create the entity and become controller.
-    any_member: bool,
-
-    /// Whether to prevent everyone from creating an entity.
-    ///
-    /// This could be useful in order to quickly, and possibly temporarily, block new entity creation, without
-    /// having to tear down `can_create_entities`.
-    entity_creation_blocked: bool,
-
-    /// Whether to prevent everyone from updating entity properties.
-    ///
-    /// This could be useful in order to quickly, and probably temporarily, block any editing of entities,
-    /// rather than for example having to set, and later clear.
-    all_entity_property_values_locked: bool,
-
-    /// Current class maintainer curator groups
-    maintainers: BTreeSet<CuratorGroupId>,
-}
-
-impl<CuratorGroupId: Ord + Default> ClassPermissions<CuratorGroupId> {
-    /// Retieve `all_entity_property_values_locked` status
-    pub fn all_entity_property_values_locked(&self) -> bool {
-        self.all_entity_property_values_locked
-    }
-
-    /// Retieve `any_member` status
-    pub fn any_member_status(&self) -> bool {
-        self.any_member
-    }
-
-    /// Check if given `curator_group_id` is maintainer of current `Class`
-    pub fn is_maintainer(&self, curator_group_id: &CuratorGroupId) -> bool {
-        self.maintainers.contains(curator_group_id)
-    }
-
-    /// Get `Class` maintainers by reference
-    pub fn get_maintainers(&self) -> &BTreeSet<CuratorGroupId> {
-        &self.maintainers
-    }
-
-    /// Get `Class` maintainers by mutable reference
-    pub fn get_maintainers_mut(&mut self) -> &mut BTreeSet<CuratorGroupId> {
-        &mut self.maintainers
-    }
-
-    /// Set `entity_creation_blocked` flag, as provided
-    pub fn set_entity_creation_blocked(&mut self, entity_creation_blocked: bool) {
-        self.entity_creation_blocked = entity_creation_blocked
-    }
-
-    /// Set `all_entity_property_values_locked` flag, as provided
-    pub fn set_all_entity_property_values_locked(
-        &mut self,
-        all_entity_property_values_locked: bool,
-    ) {
-        self.all_entity_property_values_locked = all_entity_property_values_locked
-    }
-
-    /// Set `any_member` flag, as provided
-    pub fn set_any_member_status(&mut self, any_member: bool) {
-        self.any_member = any_member;
-    }
-
-    /// Update `maintainers` set with provided one
-    pub fn set_maintainers(&mut self, maintainers: BTreeSet<CuratorGroupId>) {
-        self.maintainers = maintainers
-    }
-
-    /// Ensure entities creation is not blocked on `Class` level
-    pub fn ensure_entity_creation_not_blocked<T: Trait>(&self) -> Result<(), Error<T>> {
-        ensure!(
-            !self.entity_creation_blocked,
-            Error::<T>::EntitiesCreationBlocked
-        );
-        Ok(())
-    }
-
-    /// Ensure maintainer, associated with given `curator_group_id` is already added to `maintainers` set
-    pub fn ensure_maintainer_exists<T: Trait>(
-        &self,
-        curator_group_id: &CuratorGroupId,
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            self.maintainers.contains(curator_group_id),
-            Error::<T>::MaintainerDoesNotExist
-        );
-        Ok(())
-    }
-
-    /// Ensure maintainer, associated with given `curator_group_id` is not yet added to `maintainers` set
-    pub fn ensure_maintainer_does_not_exist<T: Trait>(
-        &self,
-        curator_group_id: &CuratorGroupId,
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            !self.maintainers.contains(curator_group_id),
-            Error::<T>::MaintainerAlreadyExists
-        );
-        Ok(())
-    }
-}

+ 0 - 175
runtime-modules/content-directory/src/permissions/entity.rs

@@ -1,175 +0,0 @@
-use super::*;
-
-/// Owner of an `Entity`.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
-pub enum EntityController<MemberId: Default + PartialEq + Clone + Copy> {
-    Maintainers,
-    Member(MemberId),
-    Lead,
-}
-
-impl<MemberId: Default + PartialEq + Clone + Copy> EntityController<MemberId> {
-    /// Create `EntityController` enum representation, using provided `Actor`
-    pub fn from_actor<T: Trait>(actor: &Actor<T::CuratorGroupId, T::CuratorId, MemberId>) -> Self {
-        match &actor {
-            Actor::Lead => Self::Lead,
-            Actor::Member(member_id) => Self::Member(*member_id),
-            Actor::Curator(_, _) => Self::Maintainers,
-        }
-    }
-}
-
-impl<MemberId: Default + PartialEq + Clone + Copy> Default for EntityController<MemberId> {
-    fn default() -> Self {
-        Self::Lead
-    }
-}
-
-/// Permissions for a given entity.
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
-#[derive(Encode, Decode, Clone, PartialEq, Eq)]
-pub struct EntityPermissions<MemberId: Default + PartialEq + Clone + Copy> {
-    /// Current controller, which is initially set based on who created entity
-    pub controller: EntityController<MemberId>,
-
-    /// Forbid groups to mutate any property value.
-    /// Can be useful to use in concert with some curation censorship policy
-    pub frozen: bool,
-
-    /// Prevent from being referenced by any entity (including self-references).
-    /// Can be useful to use in concert with some curation censorship policy,
-    /// e.g. to block content from being included in some public playlist.
-    pub referenceable: bool,
-}
-
-impl<MemberId: Default + PartialEq + Clone + Copy> Default for EntityPermissions<MemberId> {
-    fn default() -> Self {
-        Self {
-            controller: EntityController::<MemberId>::default(),
-            frozen: false,
-            referenceable: true,
-        }
-    }
-}
-
-impl<MemberId: Default + PartialEq + Clone + Copy> EntityPermissions<MemberId> {
-    /// Create an instance of `EntityPermissions` with `EntityController` equal to provided one
-    pub fn default_with_controller(controller: EntityController<MemberId>) -> Self {
-        Self {
-            controller,
-            ..EntityPermissions::default()
-        }
-    }
-
-    /// Set current `controller` as provided
-    pub fn set_conroller(&mut self, controller: EntityController<MemberId>) {
-        self.controller = controller
-    }
-
-    /// Check if inner `controller` is equal to the provided one
-    pub fn controller_is_equal_to(
-        &self,
-        new_entity_controller: &EntityController<MemberId>,
-    ) -> bool {
-        self.controller == *new_entity_controller
-    }
-
-    /// Set `frozen` flag as provided
-    pub fn set_frozen(&mut self, frozen: bool) {
-        self.frozen = frozen
-    }
-
-    /// Set `referenceable` flag as provided
-    pub fn set_referencable(&mut self, referenceable: bool) {
-        self.referenceable = referenceable;
-    }
-
-    /// Retrieve `referenceable` flag
-    pub fn is_referancable(&self) -> bool {
-        self.referenceable
-    }
-
-    /// Get current `controller` by reference
-    pub fn get_controller(&self) -> &EntityController<MemberId> {
-        &self.controller
-    }
-
-    /// Ensure actor with given `EntityAccessLevel` can remove entity
-    pub fn ensure_group_can_remove_entity<T: Trait>(
-        access_level: EntityAccessLevel,
-    ) -> Result<(), Error<T>> {
-        match access_level {
-            EntityAccessLevel::EntityController => Ok(()),
-            EntityAccessLevel::EntityControllerAndMaintainer => Ok(()),
-            _ => Err(Error::<T>::EntityRemovalAccessDenied),
-        }
-    }
-
-    /// Ensure provided new_entity_controller is not equal to current one
-    pub fn ensure_controllers_are_not_equal<T: Trait>(
-        &self,
-        new_entity_controller: &EntityController<MemberId>,
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            !self.controller_is_equal_to(new_entity_controller),
-            Error::<T>::ProvidedEntityControllerIsEqualToTheCurrentOne
-        );
-        Ok(())
-    }
-}
-
-/// Type, derived from dispatchable call, identifies the caller
-#[derive(Encode, Decode, Eq, PartialEq, Ord, PartialOrd, Clone, Copy)]
-pub enum EntityAccessLevel {
-    /// Caller identified as the entity maintainer
-    EntityMaintainer,
-
-    /// Caller identified as the entity controller
-    EntityController,
-
-    /// Caller, that can act as controller and maintainer simultaneously
-    /// (can be useful, when controller and maintainer have features, that do not intersect)
-    EntityControllerAndMaintainer,
-}
-
-impl EntityAccessLevel {
-    /// Derives the `EntityAccessLevel` for the actor, attempting to act.
-    pub fn derive<T: Trait>(
-        account_id: &T::AccountId,
-        entity_permissions: &EntityPermissions<T::MemberId>,
-        class_permissions: &ClassPermissions<T::CuratorGroupId>,
-        actor: &Actor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
-    ) -> Result<Self, Error<T>> {
-        let controller = EntityController::<T::MemberId>::from_actor::<T>(actor);
-        match actor {
-            Actor::Lead if entity_permissions.controller_is_equal_to(&controller) => {
-                // Ensure lead authorization performed succesfully
-                ensure_lead_auth_success::<T>(account_id).map(|_| Self::EntityController)
-            }
-            Actor::Member(member_id) if entity_permissions.controller_is_equal_to(&controller) => {
-                // Ensure member authorization performed succesfully
-                ensure_member_auth_success::<T>(member_id, account_id)
-                    .map(|_| Self::EntityController)
-            }
-            Actor::Curator(curator_group_id, curator_id) => {
-                // Authorize curator, performing all checks to ensure curator can act
-                CuratorGroup::<T>::perform_curator_in_group_auth(
-                    curator_id,
-                    curator_group_id,
-                    account_id,
-                )?;
-                match (
-                    entity_permissions.controller_is_equal_to(&controller),
-                    class_permissions.is_maintainer(curator_group_id),
-                ) {
-                    (true, true) => Ok(Self::EntityControllerAndMaintainer),
-                    (false, true) => Ok(Self::EntityMaintainer),
-                    // Curator cannot be controller, but not maintainer simultaneously
-                    _ => Err(Error::<T>::EntityAccessDenied),
-                }
-            }
-            _ => Err(Error::<T>::EntityAccessDenied),
-        }
-    }
-}

+ 0 - 56
runtime-modules/content-directory/src/permissions/entity_creation_voucher.rs

@@ -1,56 +0,0 @@
-use super::*;
-
-/// A voucher for `Entity` creation
-#[derive(Encode, Decode, Clone, Copy, Debug, PartialEq, Eq)]
-pub struct EntityCreationVoucher<T: Trait> {
-    /// How many are allowed in total
-    pub maximum_entities_count: T::EntityId,
-
-    /// How many have currently been created
-    pub entities_created: T::EntityId,
-}
-
-impl<T: Trait> Default for EntityCreationVoucher<T> {
-    fn default() -> Self {
-        Self {
-            maximum_entities_count: T::EntityId::zero(),
-            entities_created: T::EntityId::zero(),
-        }
-    }
-}
-
-impl<T: Trait> EntityCreationVoucher<T> {
-    /// Create a new instance of `EntityCreationVoucher` with specified limit
-    pub fn new(maximum_entities_count: T::EntityId) -> Self {
-        Self {
-            maximum_entities_count,
-            entities_created: T::EntityId::zero(),
-        }
-    }
-
-    /// Set new `maximum_entities_count` limit
-    pub fn set_maximum_entities_count(&mut self, maximum_entities_count: T::EntityId) {
-        self.maximum_entities_count = maximum_entities_count
-    }
-
-    /// Increase `entities_created` by 1
-    pub fn increment_created_entities_count(&mut self) {
-        self.entities_created += T::EntityId::one();
-    }
-
-    /// Decrease `entities_created` by 1
-    pub fn decrement_created_entities_count(&mut self) {
-        self.entities_created -= T::EntityId::one();
-    }
-
-    /// Check if `entities_created` is less than `maximum_entities_count` limit set to this `EntityCreationVoucher`
-    pub fn limit_not_reached(&self) -> bool {
-        self.entities_created < self.maximum_entities_count
-    }
-
-    /// Ensure voucher limit not reached
-    pub fn ensure_voucher_limit_not_reached(&self) -> Result<(), Error<T>> {
-        ensure!(self.limit_not_reached(), Error::<T>::VoucherLimitReached);
-        Ok(())
-    }
-}

+ 0 - 91
runtime-modules/content-directory/src/schema.rs

@@ -1,91 +0,0 @@
-mod convert;
-mod input;
-mod output;
-mod property;
-
-pub use convert::*;
-pub use input::*;
-pub use output::*;
-pub use property::*;
-
-pub use crate::{permissions::EntityAccessLevel, *};
-pub use codec::{Decode, Encode};
-use core::ops::Deref;
-#[cfg(feature = "std")]
-pub use serde::{Deserialize, Serialize};
-
-/// Type identificator for schema id
-pub type SchemaId = u16;
-
-/// A schema defines what properties describe an entity
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
-#[derive(Encode, Decode, Clone, PartialEq, Eq)]
-pub struct Schema {
-    /// Indices into properties vector for the corresponding class.
-    properties: BTreeSet<PropertyId>,
-    /// If schema can be added to an entity
-    is_active: bool,
-}
-
-impl Default for Schema {
-    fn default() -> Self {
-        Self {
-            properties: BTreeSet::new(),
-            // Default schema status
-            is_active: true,
-        }
-    }
-}
-
-impl Schema {
-    /// Create new schema with provided properties
-    pub fn new(properties: BTreeSet<PropertyId>) -> Self {
-        Self {
-            properties,
-            // Default schema status
-            is_active: true,
-        }
-    }
-
-    /// If `Schema` can be added to an entity
-    pub fn is_active(&self) -> bool {
-        self.is_active
-    }
-
-    /// Ensure schema in `active` status
-    pub fn ensure_is_active<T: Trait>(&self) -> Result<(), Error<T>> {
-        ensure!(self.is_active, Error::<T>::ClassSchemaNotActive);
-        Ok(())
-    }
-
-    /// Get `Schema` `properties` by reference
-    pub fn get_properties(&self) -> &BTreeSet<PropertyId> {
-        &self.properties
-    }
-
-    /// Ensure keys of provided `property_values` are valid indices of current `Schema`
-    pub fn ensure_has_properties<T: Trait>(
-        &self,
-        property_values: &BTreeMap<PropertyId, InputPropertyValue<T>>,
-    ) -> Result<(), Error<T>> {
-        let property_value_indices: BTreeSet<PropertyId> =
-            property_values.keys().cloned().collect();
-
-        ensure!(
-            property_value_indices.is_subset(&self.properties),
-            Error::<T>::SchemaDoesNotContainProvidedPropertyId
-        );
-
-        Ok(())
-    }
-
-    /// Get `Schema` `properties` by mutable reference
-    pub fn get_properties_mut(&mut self) -> &mut BTreeSet<PropertyId> {
-        &mut self.properties
-    }
-
-    /// Set `Schema`'s `is_active` flag as provided
-    pub fn set_status(&mut self, is_active: bool) {
-        self.is_active = is_active;
-    }
-}

+ 0 - 62
runtime-modules/content-directory/src/schema/convert.rs

@@ -1,62 +0,0 @@
-use super::*;
-use sp_runtime::traits::Hash;
-
-impl<T: Trait> From<InputPropertyValue<T>> for StoredPropertyValueOf<T> {
-    fn from(input_property_value: InputPropertyValue<T>) -> Self {
-        match input_property_value {
-            InputPropertyValue::Single(input_value) => {
-                StoredPropertyValue::Single(input_value.into())
-            }
-            InputPropertyValue::Vector(vector_input_value) => {
-                let vec_output_property_value =
-                    VecStoredPropertyValue::new(vector_input_value.into(), T::Nonce::default());
-                StoredPropertyValue::Vector(vec_output_property_value)
-            }
-        }
-    }
-}
-
-impl<T: Trait> From<InputValue<T>> for StoredValue<T::Hash, T::EntityId> {
-    fn from(input_value: InputValue<T>) -> Self {
-        match input_value {
-            InputValue::Bool(value) => StoredValue::Bool(value),
-            InputValue::Uint16(value) => StoredValue::Uint16(value),
-            InputValue::Uint32(value) => StoredValue::Uint32(value),
-            InputValue::Uint64(value) => StoredValue::Uint64(value),
-            InputValue::Int16(value) => StoredValue::Int16(value),
-            InputValue::Int32(value) => StoredValue::Int32(value),
-            InputValue::Int64(value) => StoredValue::Int64(value),
-            InputValue::Text(value) => StoredValue::Text(value),
-
-            InputValue::TextToHash(value) => {
-                let hash_value = value.using_encoded(<T as system::Trait>::Hashing::hash);
-                StoredValue::Hash(hash_value)
-            }
-            InputValue::Reference(value) => StoredValue::Reference(value),
-        }
-    }
-}
-
-impl<T: Trait> From<VecInputValue<T>> for VecStoredValue<T::Hash, T::EntityId> {
-    fn from(vec_input_value: VecInputValue<T>) -> Self {
-        match vec_input_value {
-            VecInputValue::Bool(vec_value) => VecStoredValue::Bool(vec_value),
-            VecInputValue::Uint16(vec_value) => VecStoredValue::Uint16(vec_value),
-            VecInputValue::Uint32(vec_value) => VecStoredValue::Uint32(vec_value),
-            VecInputValue::Uint64(vec_value) => VecStoredValue::Uint64(vec_value),
-            VecInputValue::Int16(vec_value) => VecStoredValue::Int16(vec_value),
-            VecInputValue::Int32(vec_value) => VecStoredValue::Int32(vec_value),
-            VecInputValue::Int64(vec_value) => VecStoredValue::Int64(vec_value),
-            VecInputValue::Text(vec_value) => VecStoredValue::Text(vec_value),
-
-            VecInputValue::TextToHash(vec_value) => {
-                let hash_vec_value: Vec<_> = vec_value
-                    .into_iter()
-                    .map(|value| value.using_encoded(<T as system::Trait>::Hashing::hash))
-                    .collect();
-                VecStoredValue::Hash(hash_vec_value)
-            }
-            VecInputValue::Reference(value) => VecStoredValue::Reference(value),
-        }
-    }
-}

+ 0 - 137
runtime-modules/content-directory/src/schema/input.rs

@@ -1,137 +0,0 @@
-use super::*;
-
-/// Enum, representing either `SingleInputPropertyValue` or `VecInputPropertyValue`
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Clone, PartialEq, Eq)]
-pub enum InputPropertyValue<T: Trait> {
-    Single(InputValue<T>),
-    Vector(VecInputValue<T>),
-}
-
-impl<T: Trait> core::fmt::Debug for InputPropertyValue<T> {
-    fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
-        write!(formatter, "InputPropertyValue {:?}", self)
-    }
-}
-
-impl<T: Trait> InputPropertyValue<T> {
-    pub fn as_single_value(&self) -> Option<&InputValue<T>> {
-        if let InputPropertyValue::Single(single_value) = self {
-            Some(single_value)
-        } else {
-            None
-        }
-    }
-
-    pub fn as_vec_value(&self) -> Option<&VecInputValue<T>> {
-        if let InputPropertyValue::Vector(vec_value) = self {
-            Some(vec_value)
-        } else {
-            None
-        }
-    }
-
-    pub fn as_vec_value_mut(&mut self) -> Option<&mut VecInputValue<T>> {
-        if let InputPropertyValue::Vector(vec_value) = self {
-            Some(vec_value)
-        } else {
-            None
-        }
-    }
-
-    /// Retrieve all involved `entity_id`'s, if current `InputPropertyValue` is reference
-    pub fn get_involved_entities(&self) -> Option<Vec<T::EntityId>> {
-        match self {
-            InputPropertyValue::Single(single_property_value) => {
-                if let Some(entity_id) = single_property_value.get_involved_entity() {
-                    Some(vec![entity_id])
-                } else {
-                    None
-                }
-            }
-            InputPropertyValue::Vector(vector_property_value) => {
-                vector_property_value.get_involved_entities()
-            }
-        }
-    }
-}
-
-impl<T: Trait> Default for InputPropertyValue<T> {
-    fn default() -> Self {
-        InputPropertyValue::Single(InputValue::default())
-    }
-}
-
-/// InputValue enum representation, related to corresponding `SingleInputPropertyValue` structure
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Clone, PartialEq, Eq)]
-pub enum InputValue<T: Trait> {
-    Bool(bool),
-    Uint16(u16),
-    Uint32(u32),
-    Uint64(u64),
-    Int16(i16),
-    Int32(i32),
-    Int64(i64),
-    Text(Vec<u8>),
-    // Used to pass text value, which respective hash should be stored
-    TextToHash(Vec<u8>),
-    Reference(T::EntityId),
-}
-
-impl<T: Trait> core::fmt::Debug for InputValue<T> {
-    fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> sp_std::fmt::Result {
-        write!(formatter, "InputValue {:?}", self)
-    }
-}
-
-impl<T: Trait> Default for InputValue<T> {
-    fn default() -> InputValue<T> {
-        Self::Bool(false)
-    }
-}
-
-impl<T: Trait> InputValue<T> {
-    /// Retrieve involved `entity_id`, if current `InputValue` is reference
-    pub fn get_involved_entity(&self) -> Option<T::EntityId> {
-        if let InputValue::Reference(entity_id) = self {
-            Some(*entity_id)
-        } else {
-            None
-        }
-    }
-}
-
-/// Vector value enum representation
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
-#[derive(Encode, Decode, Clone, PartialEq, Eq)]
-pub enum VecInputValue<T: Trait> {
-    Bool(Vec<bool>),
-    Uint16(Vec<u16>),
-    Uint32(Vec<u32>),
-    Uint64(Vec<u64>),
-    Int16(Vec<i16>),
-    Int32(Vec<i32>),
-    Int64(Vec<i64>),
-    // Used to pass text vec value, which respective hashes should be stored
-    TextToHash(Vec<Vec<u8>>),
-    Text(Vec<Vec<u8>>),
-    Reference(Vec<T::EntityId>),
-}
-
-impl<T: Trait> Default for VecInputValue<T> {
-    fn default() -> Self {
-        Self::Bool(vec![])
-    }
-}
-
-impl<T: Trait> VecInputValue<T> {
-    /// Retrieve all involved `entity_id`'s, if current `VecInputValue` is reference
-    pub fn get_involved_entities(&self) -> Option<Vec<T::EntityId>> {
-        if let Self::Reference(entity_ids) = self {
-            Some(entity_ids.to_owned())
-        } else {
-            None
-        }
-    }
-}

+ 0 - 348
runtime-modules/content-directory/src/schema/output.rs

@@ -1,348 +0,0 @@
-use super::*;
-use sp_runtime::traits::Hash;
-
-/// Enum, representing either `StoredValue` or `VecStoredPropertyValue`
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
-#[derive(Encode, Decode, Clone, PartialEq, Eq)]
-pub enum StoredPropertyValue<
-    Hashed: Default + Clone + Codec,
-    EntityId: Default + Clone + Copy + Codec,
-    Nonce: Default + BaseArithmetic + Clone + Copy,
-> {
-    Single(StoredValue<Hashed, EntityId>),
-    Vector(VecStoredPropertyValue<Hashed, EntityId, Nonce>),
-}
-
-impl<
-        Hashed: Default + Clone + Codec,
-        EntityId: Default + Clone + Copy + Codec,
-        Nonce: Default + BaseArithmetic + Clone + Copy,
-    > StoredPropertyValue<Hashed, EntityId, Nonce>
-{
-    /// Returns single property value by reference if `StoredPropertyValue` is Single
-    pub fn as_single_value(&self) -> Option<&StoredValue<Hashed, EntityId>> {
-        if let StoredPropertyValue::Single(single_value) = self {
-            Some(single_value)
-        } else {
-            None
-        }
-    }
-
-    /// Returns vector property value by reference if `StoredPropertyValue` is Single
-    pub fn as_vec_property_value(
-        &self,
-    ) -> Option<&VecStoredPropertyValue<Hashed, EntityId, Nonce>> {
-        if let StoredPropertyValue::Vector(vec_property_value) = self {
-            Some(vec_property_value)
-        } else {
-            None
-        }
-    }
-
-    /// Returns vector property value by mutable reference if `StoredPropertyValue` is Single
-    pub fn as_vec_property_value_mut(
-        &mut self,
-    ) -> Option<&mut VecStoredPropertyValue<Hashed, EntityId, Nonce>> {
-        if let StoredPropertyValue::Vector(vec_property_value) = self {
-            Some(vec_property_value)
-        } else {
-            None
-        }
-    }
-
-    /// Update `Self` with provided `StoredPropertyValue`
-    pub fn update(&mut self, mut new_value: Self) {
-        if let (Some(vec_property_value), Some(new_vec_property_value)) = (
-            self.as_vec_property_value_mut(),
-            new_value.as_vec_property_value_mut(),
-        ) {
-            new_vec_property_value.nonce = vec_property_value.nonce;
-        }
-        *self = new_value
-    }
-
-    /// Retrieve all involved `entity_id`'s, if current `StoredPropertyValue` is reference
-    pub fn get_involved_entities(&self) -> Option<Vec<EntityId>> {
-        match self {
-            StoredPropertyValue::Single(single_property_value) => {
-                if let Some(entity_id) = single_property_value.get_involved_entity() {
-                    Some(vec![entity_id])
-                } else {
-                    None
-                }
-            }
-            StoredPropertyValue::Vector(vector_property_value) => vector_property_value
-                .get_vec_value_ref()
-                .get_involved_entities(),
-        }
-    }
-
-    /// Compute hash from unique property value and its respective property_id
-    pub fn compute_unique_hash<T: Trait>(&self, property_id: PropertyId) -> T::Hash {
-        match self {
-            StoredPropertyValue::Single(output_value) => {
-                (property_id, output_value).using_encoded(<T as system::Trait>::Hashing::hash)
-            }
-            StoredPropertyValue::Vector(vector_output_value) => {
-                vector_output_value.compute_unique_hash::<T>(property_id)
-            }
-        }
-    }
-}
-
-impl<
-        Hashed: Default + Clone + Codec,
-        EntityId: Default + Clone + Copy + Codec,
-        Nonce: Default + BaseArithmetic + Clone + Copy,
-    > Default for StoredPropertyValue<Hashed, EntityId, Nonce>
-{
-    fn default() -> Self {
-        StoredPropertyValue::Single(StoredValue::default())
-    }
-}
-
-/// StoredValue enum representation, related to corresponding `SingleStoredPropertyValue` structure
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
-#[derive(Encode, Decode, Clone, PartialEq, PartialOrd, Ord, Eq)]
-pub enum StoredValue<Hashed: Default + Clone + Codec, EntityId: Default + Clone + Copy + Codec> {
-    Bool(bool),
-    Uint16(u16),
-    Uint32(u32),
-    Uint64(u64),
-    Int16(i16),
-    Int32(i32),
-    Int64(i64),
-    Text(Vec<u8>),
-    Hash(Hashed),
-    Reference(EntityId),
-}
-
-impl<Hashed: Default + Clone + Codec, EntityId: Default + Clone + Copy + Codec> Default
-    for StoredValue<Hashed, EntityId>
-{
-    fn default() -> StoredValue<Hashed, EntityId> {
-        Self::Bool(false)
-    }
-}
-
-impl<Hashed: Default + Clone + Codec, EntityId: Default + Clone + Copy + Codec>
-    StoredValue<Hashed, EntityId>
-{
-    /// Retrieve involved `entity_id`, if current `StoredValue` is reference
-    pub fn get_involved_entity(&self) -> Option<EntityId> {
-        if let StoredValue::Reference(entity_id) = self {
-            Some(*entity_id)
-        } else {
-            None
-        }
-    }
-}
-
-/// Consists of `VecStoredPropertyValue` enum representation and `nonce`, used to avoid vector data race update conditions
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
-#[derive(Encode, Decode, Default, Clone, PartialEq, Eq)]
-pub struct VecStoredPropertyValue<
-    Hashed: Default + Clone + Codec,
-    EntityId: Default + Clone + Copy + Codec,
-    Nonce: Default + BaseArithmetic + Clone + Copy,
-> {
-    vec_value: VecStoredValue<Hashed, EntityId>,
-    nonce: Nonce,
-}
-
-impl<
-        Hashed: Default + Clone + Codec,
-        EntityId: Default + Clone + Copy + Codec,
-        Nonce: Default + BaseArithmetic + Clone + Copy,
-    > VecStoredPropertyValue<Hashed, EntityId, Nonce>
-{
-    /// Compute hash from unique vec property value and its respective property_id
-    pub fn compute_unique_hash<T: Trait>(&self, property_id: PropertyId) -> T::Hash {
-        // Do not hash nonce
-        (property_id, &self.vec_value).using_encoded(<T as system::Trait>::Hashing::hash)
-    }
-
-    /// Increase nonce by 1
-    fn increment_nonce(&mut self) -> Nonce {
-        self.nonce += Nonce::one();
-        self.nonce
-    }
-
-    /// Create new `VecStoredPropertyValue` from `vec value` provided and `nonce`
-    pub fn new(vec_value: VecStoredValue<Hashed, EntityId>, nonce: Nonce) -> Self {
-        Self { vec_value, nonce }
-    }
-
-    /// Retrieve `VecStoredValue`
-    pub fn get_vec_value(self) -> VecStoredValue<Hashed, EntityId> {
-        self.vec_value
-    }
-
-    /// Retrieve `VecStoredValue` by reference
-    pub fn get_vec_value_ref(&self) -> &VecStoredValue<Hashed, EntityId> {
-        &self.vec_value
-    }
-
-    fn len(&self) -> usize {
-        match &self.vec_value {
-            VecStoredValue::Bool(vec) => vec.len(),
-            VecStoredValue::Uint16(vec) => vec.len(),
-            VecStoredValue::Uint32(vec) => vec.len(),
-            VecStoredValue::Uint64(vec) => vec.len(),
-            VecStoredValue::Int16(vec) => vec.len(),
-            VecStoredValue::Int32(vec) => vec.len(),
-            VecStoredValue::Int64(vec) => vec.len(),
-            VecStoredValue::Text(vec) => vec.len(),
-            VecStoredValue::Hash(vec) => vec.len(),
-            VecStoredValue::Reference(vec) => vec.len(),
-        }
-    }
-
-    /// Clear current `vec_value`
-    pub fn clear(&mut self) {
-        match &mut self.vec_value {
-            VecStoredValue::Bool(vec) => *vec = vec![],
-            VecStoredValue::Uint16(vec) => *vec = vec![],
-            VecStoredValue::Uint32(vec) => *vec = vec![],
-            VecStoredValue::Uint64(vec) => *vec = vec![],
-            VecStoredValue::Int16(vec) => *vec = vec![],
-            VecStoredValue::Int32(vec) => *vec = vec![],
-            VecStoredValue::Int64(vec) => *vec = vec![],
-            VecStoredValue::Text(vec) => *vec = vec![],
-            VecStoredValue::Hash(vec) => *vec = vec![],
-            VecStoredValue::Reference(vec) => *vec = vec![],
-        }
-    }
-
-    /// Perform removal at given `index_in_property_vec`, increment `nonce`
-    pub fn remove_at(&mut self, index_in_property_vec: VecMaxLength) {
-        fn remove_at_checked<T>(vec: &mut Vec<T>, index_in_property_vec: VecMaxLength) {
-            if (index_in_property_vec as usize) < vec.len() {
-                vec.remove(index_in_property_vec as usize);
-            }
-        }
-
-        match &mut self.vec_value {
-            VecStoredValue::Bool(vec) => remove_at_checked(vec, index_in_property_vec),
-            VecStoredValue::Uint16(vec) => remove_at_checked(vec, index_in_property_vec),
-            VecStoredValue::Uint32(vec) => remove_at_checked(vec, index_in_property_vec),
-            VecStoredValue::Uint64(vec) => remove_at_checked(vec, index_in_property_vec),
-            VecStoredValue::Int16(vec) => remove_at_checked(vec, index_in_property_vec),
-            VecStoredValue::Int32(vec) => remove_at_checked(vec, index_in_property_vec),
-            VecStoredValue::Int64(vec) => remove_at_checked(vec, index_in_property_vec),
-            VecStoredValue::Text(vec) => remove_at_checked(vec, index_in_property_vec),
-            VecStoredValue::Hash(vec) => remove_at_checked(vec, index_in_property_vec),
-            VecStoredValue::Reference(vec) => remove_at_checked(vec, index_in_property_vec),
-        }
-
-        self.increment_nonce();
-    }
-
-    /// Insert provided `StoredValue` at given `index_in_property_vec`, increment `nonce`
-    pub fn insert_at(
-        &mut self,
-        index_in_property_vec: VecMaxLength,
-        single_value: StoredValue<Hashed, EntityId>,
-    ) {
-        fn insert_at<T>(vec: &mut Vec<T>, index_in_property_vec: VecMaxLength, value: T) {
-            if (index_in_property_vec as usize) < vec.len() {
-                vec.insert(index_in_property_vec as usize, value);
-            }
-        }
-
-        match (&mut self.vec_value, single_value) {
-            (VecStoredValue::Bool(vec), StoredValue::Bool(value)) => {
-                insert_at(vec, index_in_property_vec, value)
-            }
-            (VecStoredValue::Uint16(vec), StoredValue::Uint16(value)) => {
-                insert_at(vec, index_in_property_vec, value)
-            }
-            (VecStoredValue::Uint32(vec), StoredValue::Uint32(value)) => {
-                insert_at(vec, index_in_property_vec, value)
-            }
-            (VecStoredValue::Uint64(vec), StoredValue::Uint64(value)) => {
-                insert_at(vec, index_in_property_vec, value)
-            }
-            (VecStoredValue::Int16(vec), StoredValue::Int16(value)) => {
-                insert_at(vec, index_in_property_vec, value)
-            }
-            (VecStoredValue::Int32(vec), StoredValue::Int32(value)) => {
-                insert_at(vec, index_in_property_vec, value)
-            }
-            (VecStoredValue::Int64(vec), StoredValue::Int64(value)) => {
-                insert_at(vec, index_in_property_vec, value)
-            }
-
-            // Match by move, when https://github.com/rust-lang/rust/issues/68354 stableize
-            (VecStoredValue::Text(vec), StoredValue::Text(ref value)) => {
-                insert_at(vec, index_in_property_vec, value.to_owned())
-            }
-            (VecStoredValue::Reference(vec), StoredValue::Reference(value)) => {
-                insert_at(vec, index_in_property_vec, value)
-            }
-            _ => return,
-        }
-
-        self.increment_nonce();
-    }
-
-    /// Ensure `VecStoredPropertyValue` nonce is equal to the provided one.
-    /// Used to to avoid possible data races, when performing vector specific operations
-    pub fn ensure_nonce_equality<T: Trait>(&self, new_nonce: Nonce) -> Result<(), Error<T>> {
-        ensure!(
-            self.nonce == new_nonce,
-            Error::<T>::PropertyValueVecNoncesDoesNotMatch
-        );
-        Ok(())
-    }
-
-    /// Ensure, provided `index_in_property_vec` is valid index of `VecStoredValue`
-    pub fn ensure_index_in_property_vector_is_valid<T: Trait>(
-        &self,
-        index_in_property_vec: VecMaxLength,
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            (index_in_property_vec as usize) <= self.len(),
-            Error::<T>::EntityPropertyValueVectorIndexIsOutOfRange
-        );
-
-        Ok(())
-    }
-}
-
-/// Vector value enum representation, related to corresponding `VecStoredPropertyValue` structure
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
-#[derive(Encode, Decode, Clone, PartialEq, Eq, PartialOrd, Ord)]
-pub enum VecStoredValue<Hashed: Default + Clone + Codec, EntityId: Default + Clone + Copy + Codec> {
-    Bool(Vec<bool>),
-    Uint16(Vec<u16>),
-    Uint32(Vec<u32>),
-    Uint64(Vec<u64>),
-    Int16(Vec<i16>),
-    Int32(Vec<i32>),
-    Int64(Vec<i64>),
-    Hash(Vec<Hashed>),
-    Text(Vec<Vec<u8>>),
-    Reference(Vec<EntityId>),
-}
-
-impl<Hashed: Default + Clone + Codec, EntityId: Default + Clone + Copy + Codec> Default
-    for VecStoredValue<Hashed, EntityId>
-{
-    fn default() -> Self {
-        Self::Bool(vec![])
-    }
-}
-
-impl<Hashed: Default + Clone + Codec, EntityId: Default + Clone + Copy + Codec>
-    VecStoredValue<Hashed, EntityId>
-{
-    /// Retrieve all involved `entity_id`'s, if current `VecStoredValue` is reference
-    pub fn get_involved_entities(&self) -> Option<Vec<EntityId>> {
-        if let Self::Reference(entity_ids) = self {
-            Some(entity_ids.to_owned())
-        } else {
-            None
-        }
-    }
-}

+ 0 - 634
runtime-modules/content-directory/src/schema/property.rs

@@ -1,634 +0,0 @@
-use super::*;
-
-/// Type identificator for property id
-pub type PropertyId = u16;
-
-/// Type representing max length of vector property type
-pub type VecMaxLength = u16;
-
-/// Type representing max length of text property type
-pub type TextMaxLength = u16;
-
-/// Type representing optional max length of text property type, that will be subsequently hashed
-pub type HashedTextMaxLength = Option<u16>;
-
-/// Used to force property values to only reference entities, owned by the same controller
-type SameController = bool;
-
-/// Locking policy, representing `Property` locking status for both controller and maintainer
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Default, Decode, Clone, Copy, PartialEq, Eq, Debug)]
-pub struct PropertyLockingPolicy {
-    /// If property is locked from maintainer
-    pub is_locked_from_maintainer: bool,
-    /// If property is locked from controller
-    pub is_locked_from_controller: bool,
-}
-
-/// Enum, used for `PropertyType` representation
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, Debug)]
-pub enum Type<ClassId: Default + BaseArithmetic + Clone + Copy> {
-    Bool,
-    Uint16,
-    Uint32,
-    Uint64,
-    Int16,
-    Int32,
-    Int64,
-    /// Max length of text item.
-    Text(TextMaxLength),
-    Hash(HashedTextMaxLength),
-    /// Can reference only specific class id entities
-    Reference(ClassId, SameController),
-}
-
-impl<ClassId: Default + BaseArithmetic + Clone + Copy> Default for Type<ClassId> {
-    fn default() -> Self {
-        Self::Bool
-    }
-}
-
-impl<ClassId: Default + BaseArithmetic + Clone + Copy> Type<ClassId> {
-    /// Ensure `Type` specific `TextMaxLengthConstraint` or `HashedTextMaxLengthConstraint` satisfied
-    pub fn ensure_property_type_size_is_valid<T: Trait>(&self) -> Result<(), Error<T>> {
-        if let Type::Text(text_max_len) = self {
-            ensure!(
-                *text_max_len <= T::TextMaxLengthConstraint::get(),
-                Error::<T>::TextPropertyTooLong
-            );
-        }
-
-        if let Type::Hash(hashed_text_max_len) = self {
-            ensure!(
-                *hashed_text_max_len <= T::HashedTextMaxLengthConstraint::get(),
-                Error::<T>::HashedTextPropertyTooLong
-            );
-        }
-
-        Ok(())
-    }
-}
-
-/// Vector property type representation
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Clone, Default, Copy, PartialEq, Eq, Debug)]
-pub struct VecPropertyType<ClassId: Default + BaseArithmetic + Clone + Copy> {
-    vec_type: Type<ClassId>,
-    /// Max length of vector, corresponding to a given type
-    max_length: VecMaxLength,
-}
-
-impl<ClassId: Default + BaseArithmetic + Clone + Copy> VecPropertyType<ClassId> {
-    /// Create new `VecPropertyType` from provided `type` and `max_length`
-    pub fn new(vec_type: Type<ClassId>, max_length: VecMaxLength) -> Self {
-        Self {
-            vec_type,
-            max_length,
-        }
-    }
-
-    /// Ensure `Type` specific `TextMaxLengthConstraint` & `VecMaxLengthConstraint` satisfied
-    fn ensure_property_type_size_is_valid<T: Trait>(&self) -> Result<(), Error<T>> {
-        // Ensure Type specific TextMaxLengthConstraint or HashedTextMaxLengthConstraint satisfied
-        self.vec_type.ensure_property_type_size_is_valid()?;
-
-        ensure!(
-            self.max_length <= T::VecMaxLengthConstraint::get(),
-            Error::<T>::VecPropertyTooLong
-        );
-        Ok(())
-    }
-
-    fn get_vec_type(&self) -> &Type<ClassId> {
-        &self.vec_type
-    }
-
-    fn get_max_len(&self) -> VecMaxLength {
-        self.max_length
-    }
-}
-
-/// Enum, representing either `Type` or `VecPropertyType`
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, Debug)]
-pub enum PropertyType<ClassId: Default + BaseArithmetic + Clone + Copy> {
-    Single(Type<ClassId>),
-    Vector(VecPropertyType<ClassId>),
-}
-
-impl<ClassId: Default + BaseArithmetic + Clone + Copy> Default for PropertyType<ClassId> {
-    fn default() -> Self {
-        Self::Single(Type::default())
-    }
-}
-
-impl<ClassId: Default + BaseArithmetic + Clone + Copy> PropertyType<ClassId> {
-    fn as_single_value_type(&self) -> Option<&Type<ClassId>> {
-        if let PropertyType::Single(single_value_property_type) = self {
-            Some(single_value_property_type)
-        } else {
-            None
-        }
-    }
-
-    pub fn as_vec_type(&self) -> Option<&VecPropertyType<ClassId>> {
-        if let PropertyType::Vector(vec_value_property_type) = self {
-            Some(vec_value_property_type)
-        } else {
-            None
-        }
-    }
-
-    /// Get inner type of `PropertyType` enum wrapper
-    pub fn get_inner_type(&self) -> &Type<ClassId> {
-        match self {
-            PropertyType::Single(single_property_type) => single_property_type,
-            PropertyType::Vector(vec_property_type) => vec_property_type.get_vec_type(),
-        }
-    }
-
-    /// Retrives `same_controller` flag.
-    /// Always returns false if `Type` is not a reference,
-    pub fn same_controller_status(&self) -> SameController {
-        if let Type::Reference(_, same_controller) = self.get_inner_type() {
-            *same_controller
-        } else {
-            false
-        }
-    }
-}
-
-/// `Property` representation, related to a given `Class`
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-#[derive(Encode, Decode, Clone, Debug, PartialEq, Eq)]
-pub struct Property<ClassId: Default + BaseArithmetic + Clone + Copy> {
-    /// The type of `Property`
-    pub property_type: PropertyType<ClassId>,
-    /// If property value can be skipped, when adding entity schema support
-    pub required: bool,
-    /// Used to enforce uniquness of a property across all entities that have this property
-    pub unique: bool,
-    /// Property name
-    pub name: Vec<u8>,
-    /// Property description
-    pub description: Vec<u8>,
-    /// Locking policy, representing `Property` locking status for both controller and maintainer
-    pub locking_policy: PropertyLockingPolicy,
-}
-
-impl<ClassId: Default + BaseArithmetic + Clone + Copy> Default for Property<ClassId> {
-    fn default() -> Self {
-        Self {
-            property_type: PropertyType::<ClassId>::default(),
-            required: false,
-            unique: false,
-            name: vec![],
-            description: vec![],
-            locking_policy: PropertyLockingPolicy::default(),
-        }
-    }
-}
-
-impl<ClassId: Default + BaseArithmetic + Clone + Copy> Property<ClassId> {
-    /// Check if property is locked from actor with provided `EntityAccessLevel`
-    pub fn is_locked_from(&self, access_level: EntityAccessLevel) -> bool {
-        let is_locked_from_controller = self.locking_policy.is_locked_from_controller;
-        let is_locked_from_maintainer = self.locking_policy.is_locked_from_maintainer;
-        match access_level {
-            EntityAccessLevel::EntityControllerAndMaintainer => {
-                is_locked_from_controller && is_locked_from_maintainer
-            }
-            EntityAccessLevel::EntityController => is_locked_from_controller,
-            EntityAccessLevel::EntityMaintainer => is_locked_from_maintainer,
-        }
-    }
-
-    /// Ensure `Property` is unlocked from `Actor` with given `EntityAccessLevel`
-    pub fn ensure_unlocked_from<T: Trait>(
-        &self,
-        access_level: EntityAccessLevel,
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            !self.is_locked_from(access_level),
-            Error::<T>::ClassPropertyTypeLockedForGivenActor
-        );
-        Ok(())
-    }
-
-    /// Validate new `InputPropertyValue` against the type of this `Property`
-    /// and check any additional constraints
-    pub fn ensure_property_value_to_update_is_valid<T: Trait>(
-        property: &Property<T::ClassId>,
-        value: &InputPropertyValue<T>,
-        current_entity_controller: &EntityController<T::MemberId>,
-    ) -> Result<(), Error<T>> {
-        // Ensure provided InputPropertyValue matches its Type
-        property.ensure_property_value_matches_its_type(value)?;
-
-        // Perform all required checks to ensure provided InputPropertyValue is valid, when current PropertyType is Reference
-        Self::ensure_property_value_is_valid_reference(
-            &property,
-            value,
-            current_entity_controller,
-        )?;
-
-        // Ensure text property does not exceed its max length
-        property.validate_max_len_if_text_property(value)?;
-
-        // Ensure vector property does not exceed its max length
-        property.validate_max_len_if_vec_property(value)?;
-        Ok(())
-    }
-
-    /// Ensure property vector length after value inserted is valid
-    fn validate_property_vector_length_after_value_insert<T: Trait, V>(
-        vec: &[V],
-        max_len: VecMaxLength,
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            vec.len() < max_len as usize,
-            Error::<T>::EntityPropertyValueVectorIsTooLong
-        );
-        Ok(())
-    }
-
-    /// Ensure `SingleInputPropertyValue` type is equal to the `VecInputPropertyValue` type
-    /// and check all constraints
-    pub fn ensure_property_value_can_be_inserted_at_property_vector<T: Trait>(
-        property: &Property<T::ClassId>,
-        single_value: &InputValue<T>,
-        vec_value: &VecStoredPropertyValue<T::Hash, T::EntityId, T::Nonce>,
-        index_in_property_vec: VecMaxLength,
-        current_entity_controller: &EntityController<T::MemberId>,
-    ) -> Result<(), Error<T>> {
-        // Ensure, provided index_in_property_vec is valid index of VecInputValue
-        vec_value.ensure_index_in_property_vector_is_valid(index_in_property_vec)?;
-
-        let property_type_vec = property
-            .property_type
-            .as_vec_type()
-            .ok_or(Error::<T>::PropertyValueTypeDoesNotMatchInternalVectorType)?;
-
-        let max_vec_len = property_type_vec.get_max_len();
-
-        match (
-            single_value,
-            vec_value.get_vec_value_ref(),
-            property_type_vec.get_vec_type(),
-        ) {
-            // Single values
-            (InputValue::Bool(_), VecStoredValue::Bool(vec), Type::Bool) => {
-                Self::validate_property_vector_length_after_value_insert::<T, bool>(
-                    vec,
-                    max_vec_len,
-                )
-            }
-            (InputValue::Uint16(_), VecStoredValue::Uint16(vec), Type::Uint16) => {
-                Self::validate_property_vector_length_after_value_insert::<T, u16>(vec, max_vec_len)
-            }
-            (InputValue::Uint32(_), VecStoredValue::Uint32(vec), Type::Uint32) => {
-                Self::validate_property_vector_length_after_value_insert::<T, u32>(vec, max_vec_len)
-            }
-            (InputValue::Uint64(_), VecStoredValue::Uint64(vec), Type::Uint64) => {
-                Self::validate_property_vector_length_after_value_insert::<T, u64>(vec, max_vec_len)
-            }
-            (InputValue::Int16(_), VecStoredValue::Int16(vec), Type::Int16) => {
-                Self::validate_property_vector_length_after_value_insert::<T, i16>(vec, max_vec_len)
-            }
-            (InputValue::Int32(_), VecStoredValue::Int32(vec), Type::Int32) => {
-                Self::validate_property_vector_length_after_value_insert::<T, i32>(vec, max_vec_len)
-            }
-            (InputValue::Int64(_), VecStoredValue::Int64(vec), Type::Int64) => {
-                Self::validate_property_vector_length_after_value_insert::<T, i64>(vec, max_vec_len)
-            }
-            (InputValue::Text(text_item), VecStoredValue::Text(vec), Type::Text(text_max_len)) => {
-                Self::validate_max_len_of_text(text_item, *text_max_len)?;
-                Self::validate_property_vector_length_after_value_insert::<T, Vec<u8>>(
-                    vec,
-                    max_vec_len,
-                )
-            }
-            (
-                InputValue::TextToHash(text_item),
-                VecStoredValue::Hash(vec),
-                Type::Hash(text_max_len),
-            ) => {
-                if let Some(text_max_len) = text_max_len {
-                    Self::validate_max_len_of_text_to_be_hashed(text_item, *text_max_len)?;
-                }
-                Self::validate_property_vector_length_after_value_insert::<T, T::Hash>(
-                    vec,
-                    max_vec_len,
-                )
-            }
-            (
-                InputValue::Reference(entity_id),
-                VecStoredValue::Reference(vec),
-                Type::Reference(class_id, same_controller_status),
-            ) => {
-                // Ensure class_id of Entity under provided entity_id references Entity,
-                // which class_id is equal to class_id, declared in corresponding PropertyType
-                // Retrieve corresponding Entity
-                let entity =
-                    Self::ensure_referenced_entity_match_its_class::<T>(*entity_id, *class_id)?;
-                // Ensure Entity can be referenced.
-                Self::ensure_entity_can_be_referenced(
-                    entity,
-                    *same_controller_status,
-                    current_entity_controller,
-                )?;
-                Self::validate_property_vector_length_after_value_insert::<T, T::EntityId>(
-                    vec,
-                    max_vec_len,
-                )
-            }
-            _ => Err(Error::<T>::PropertyValueTypeDoesNotMatchInternalVectorType),
-        }
-    }
-
-    /// Ensure text property does not exceed its max len
-    pub fn validate_max_len_if_text_property<T: Trait>(
-        &self,
-        value: &InputPropertyValue<T>,
-    ) -> Result<(), Error<T>> {
-        let single_value = value.as_single_value();
-
-        match (single_value, &self.property_type.as_single_value_type()) {
-            (Some(InputValue::Text(text)), Some(Type::Text(text_max_len))) => {
-                Self::validate_max_len_of_text(text, *text_max_len)
-            }
-            (
-                Some(InputValue::TextToHash(text_to_be_hashed)),
-                Some(Type::Hash(Some(text_to_be_hashed_max_len))),
-            ) => Self::validate_max_len_of_text_to_be_hashed(
-                text_to_be_hashed,
-                *text_to_be_hashed_max_len,
-            ),
-            _ => Ok(()),
-        }
-    }
-
-    fn validate_max_len_of_text<T: Trait>(
-        text: &[u8],
-        text_max_len: TextMaxLength,
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            text.len() <= text_max_len as usize,
-            Error::<T>::TextPropertyTooLong
-        );
-        Ok(())
-    }
-
-    fn validate_max_len_of_text_to_be_hashed<T: Trait>(
-        text_to_be_hashed: &[u8],
-        text_to_be_hashed_max_len: u16,
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            text_to_be_hashed.len() <= text_to_be_hashed_max_len as usize,
-            Error::<T>::HashedTextPropertyTooLong
-        );
-        Ok(())
-    }
-
-    fn validate_vec_len<V, T: Trait>(vec: &[V], max_len: VecMaxLength) -> Result<(), Error<T>> {
-        ensure!(
-            vec.len() <= max_len as usize,
-            Error::<T>::VecPropertyTooLong
-        );
-        Ok(())
-    }
-
-    /// Ensure `VecInputValue` does not exceed its max len
-    pub fn validate_max_len_if_vec_property<T: Trait>(
-        &self,
-        value: &InputPropertyValue<T>,
-    ) -> Result<(), Error<T>> {
-        let (vec_value, vec_property_type) = if let (Some(vec_value), Some(vec_property_type)) =
-            (value.as_vec_value(), self.property_type.as_vec_type())
-        {
-            (vec_value, vec_property_type)
-        } else {
-            return Ok(());
-        };
-
-        let max_len = vec_property_type.get_max_len();
-
-        match vec_value {
-            VecInputValue::Bool(vec) => Self::validate_vec_len(vec, max_len),
-            VecInputValue::Uint16(vec) => Self::validate_vec_len(vec, max_len),
-            VecInputValue::Uint32(vec) => Self::validate_vec_len(vec, max_len),
-            VecInputValue::Uint64(vec) => Self::validate_vec_len(vec, max_len),
-            VecInputValue::Int16(vec) => Self::validate_vec_len(vec, max_len),
-            VecInputValue::Int32(vec) => Self::validate_vec_len(vec, max_len),
-            VecInputValue::Int64(vec) => Self::validate_vec_len(vec, max_len),
-            VecInputValue::TextToHash(vec) => {
-                Self::validate_vec_len(vec, max_len)?;
-                if let Type::Hash(Some(text_to_be_hashed_max_len)) =
-                    vec_property_type.get_vec_type()
-                {
-                    for text_to_be_hashed_item in vec.iter() {
-                        Self::validate_max_len_of_text_to_be_hashed(
-                            text_to_be_hashed_item,
-                            *text_to_be_hashed_max_len,
-                        )?;
-                    }
-                }
-                Ok(())
-            }
-            VecInputValue::Text(vec) => {
-                Self::validate_vec_len(vec, max_len)?;
-                if let Type::Text(text_max_len) = vec_property_type.get_vec_type() {
-                    for text_item in vec.iter() {
-                        Self::validate_max_len_of_text(text_item, *text_max_len)?;
-                    }
-                }
-                Ok(())
-            }
-            VecInputValue::Reference(vec) => Self::validate_vec_len(vec, max_len),
-        }
-    }
-
-    /// Ensure provided `InputPropertyValue` matches its `Type`
-    pub fn ensure_property_value_matches_its_type<T: Trait>(
-        &self,
-        value: &InputPropertyValue<T>,
-    ) -> Result<(), Error<T>> {
-        ensure!(
-            self.does_prop_value_match_type(value),
-            Error::<T>::PropertyValueDoNotMatchType
-        );
-        Ok(())
-    }
-
-    /// Check if provided `InputPropertyValue` matches its `Type`
-    pub fn does_prop_value_match_type<T: Trait>(&self, value: &InputPropertyValue<T>) -> bool {
-        // A non required property can be updated to Bool(false):
-        if !self.required && *value == InputPropertyValue::default() {
-            return true;
-        }
-        match (value, &self.property_type) {
-            (
-                InputPropertyValue::Single(single_property_value),
-                PropertyType::Single(ref single_property_type),
-            ) => matches!((single_property_value, single_property_type.deref()),
-                (InputValue::Bool(_), Type::Bool)
-                | (InputValue::Uint16(_), Type::Uint16)
-                | (InputValue::Uint32(_), Type::Uint32)
-                | (InputValue::Uint64(_), Type::Uint64)
-                | (InputValue::Int16(_), Type::Int16)
-                | (InputValue::Int32(_), Type::Int32)
-                | (InputValue::Int64(_), Type::Int64)
-                | (InputValue::Text(_), Type::Text(_))
-                | (InputValue::TextToHash(_), Type::Hash(_))
-                | (InputValue::Reference(_), Type::Reference(_, _))),
-            (
-                InputPropertyValue::Vector(vec_value),
-                PropertyType::Vector(ref vec_property_type),
-            ) => matches!((vec_value, vec_property_type.get_vec_type()),
-                (VecInputValue::Bool(_), Type::Bool)
-                | (VecInputValue::Uint16(_), Type::Uint16)
-                | (VecInputValue::Uint32(_), Type::Uint32)
-                | (VecInputValue::Uint64(_), Type::Uint64)
-                | (VecInputValue::Int16(_), Type::Int16)
-                | (VecInputValue::Int32(_), Type::Int32)
-                | (VecInputValue::Int64(_), Type::Int64)
-                | (VecInputValue::Text(_), Type::Text(_))
-                | (VecInputValue::TextToHash(_), Type::Hash(_))
-                | (VecInputValue::Reference(_), Type::Reference(_, _))),
-            _ => false,
-        }
-    }
-
-    /// Perform all required checks to ensure provided `InputPropertyValue` is valid,
-    /// when current `PropertyType` is `Reference`
-    pub fn ensure_property_value_is_valid_reference<T: Trait>(
-        property: &Property<T::ClassId>,
-        value: &InputPropertyValue<T>,
-        current_entity_controller: &EntityController<T::MemberId>,
-    ) -> Result<(), Error<T>> {
-        match (value, &property.property_type) {
-            (
-                InputPropertyValue::Single(single_property_value),
-                PropertyType::Single(single_property_type),
-            ) => {
-                if let (
-                    InputValue::Reference(entity_id),
-                    Type::Reference(class_id, same_controller_status),
-                ) = (single_property_value, single_property_type.deref())
-                {
-                    // Ensure class_id of Entity under provided entity_id references Entity,
-                    // which class_id is equal to class_id, declared in corresponding PropertyType
-                    // Retrieve corresponding Entity
-                    let entity =
-                        Self::ensure_referenced_entity_match_its_class::<T>(*entity_id, *class_id)?;
-
-                    // Ensure Entity can be referenced.
-                    Self::ensure_entity_can_be_referenced(
-                        entity,
-                        *same_controller_status,
-                        current_entity_controller,
-                    )?;
-                }
-            }
-            (InputPropertyValue::Vector(vec_value), PropertyType::Vector(vec_property_type)) => {
-                if let (
-                    VecInputValue::Reference(entity_ids),
-                    Type::Reference(class_id, same_controller_status),
-                ) = (vec_value, vec_property_type.get_vec_type())
-                {
-                    for entity_id in entity_ids.iter() {
-                        // Ensure class_id of Entity under provided entity_id references Entity,
-                        // which class_id is equal to class_id, declared in corresponding PropertyType
-                        // Retrieve corresponding Entity
-                        let entity = Self::ensure_referenced_entity_match_its_class::<T>(
-                            *entity_id, *class_id,
-                        )?;
-
-                        // Ensure Entity can be referenced.
-                        Self::ensure_entity_can_be_referenced(
-                            entity,
-                            *same_controller_status,
-                            current_entity_controller,
-                        )?;
-                    }
-                }
-            }
-            _ => (),
-        }
-        Ok(())
-    }
-
-    /// Ensure `class_id` of `Entity` under provided `entity_id` references `Entity`, which `class_id` is equal to `class_id`,
-    /// declared in corresponding `PropertyType`.
-    /// Returns  corresponding `Entity` instance
-    pub fn ensure_referenced_entity_match_its_class<T: Trait>(
-        entity_id: T::EntityId,
-        class_id: T::ClassId,
-    ) -> Result<EntityOf<T>, Error<T>> {
-        // Ensure Entity under given id exists
-        let entity = Module::<T>::ensure_known_entity_id(entity_id)?;
-
-        ensure!(
-            class_id == entity.get_class_id(),
-            Error::<T>::ReferencedEntityDoesNotMatchItsClass
-        );
-        Ok(entity)
-    }
-
-    /// Ensure `Entity` can be referenced.
-    pub fn ensure_entity_can_be_referenced<T: Trait>(
-        entity: EntityOf<T>,
-        same_controller_status: bool,
-        current_entity_controller: &EntityController<T::MemberId>,
-    ) -> Result<(), Error<T>> {
-        let entity_permissions = entity.get_permissions();
-
-        // Ensure Entity is referencable
-        ensure!(
-            entity_permissions.is_referancable(),
-            Error::<T>::EntityCanNotBeReferenced
-        );
-
-        if same_controller_status {
-            // Ensure Entity controller is equal to the provided one
-            ensure!(
-                entity_permissions.controller_is_equal_to(current_entity_controller),
-                Error::<T>::SameControllerConstraintViolation
-            );
-        }
-        Ok(())
-    }
-
-    /// Ensure `PropertyNameLengthConstraint` satisfied
-    pub fn ensure_name_is_valid<T: Trait>(&self) -> Result<(), Error<T>> {
-        T::PropertyNameLengthConstraint::get().ensure_valid(
-            self.name.len(),
-            Error::<T>::PropertyNameTooShort,
-            Error::<T>::PropertyNameTooLong,
-        )
-    }
-
-    /// Ensure `PropertyDescriptionLengthConstraint` satisfied
-    pub fn ensure_description_is_valid<T: Trait>(&self) -> Result<(), Error<T>> {
-        T::PropertyDescriptionLengthConstraint::get().ensure_valid(
-            self.description.len(),
-            Error::<T>::PropertyDescriptionTooShort,
-            Error::<T>::PropertyDescriptionTooLong,
-        )
-    }
-
-    /// Ensure `Type` specific constraints satisfied
-    pub fn ensure_property_type_size_is_valid<T: Trait>(&self) -> Result<(), Error<T>> {
-        match &self.property_type {
-            PropertyType::Single(single_property_type) => {
-                // Ensure Type specific TextMaxLengthConstraint satisfied
-                single_property_type.ensure_property_type_size_is_valid()
-            }
-            PropertyType::Vector(vec_property_type) => {
-                // Ensure Type specific TextMaxLengthConstraint & VecMaxLengthConstraint satisfied
-                vec_property_type.ensure_property_type_size_is_valid()
-            }
-        }
-    }
-}

+ 0 - 350
runtime-modules/content-directory/src/tests.rs

@@ -1,350 +0,0 @@
-mod add_class_schema;
-mod add_curator_group;
-mod add_curator_to_group;
-mod add_maintainer_to_class;
-mod add_schema_support_to_entity;
-mod clear_entity_property_vector;
-mod create_class;
-mod create_entity;
-mod insert_at_entity_property_vector;
-mod remove_at_entity_property_vector;
-mod remove_curator_from_group;
-mod remove_curator_group;
-mod remove_entity;
-mod remove_maintainer_from_class;
-mod set_curator_group_status;
-mod transaction;
-mod transfer_entity_ownership;
-mod update_class_permissions;
-mod update_class_schema_status;
-mod update_entity_creation_voucher;
-mod update_entity_permissions;
-mod update_entity_property_values;
-
-use super::*;
-use crate::mock::*;
-use core::iter::FromIterator;
-
-pub fn add_entity_schemas_support() -> (
-    Entity<ClassId, MemberId, Hashed, EntityId, Nonce>,
-    Entity<ClassId, MemberId, Hashed, EntityId, Nonce>,
-) {
-    // Create first class with default permissions
-    assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-    // Create second class with default permissions
-    assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-    let actor = Actor::Lead;
-
-    // Create first entity
-    assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.to_owned()));
-
-    // Create second entity
-    assert_ok!(create_entity(
-        LEAD_ORIGIN,
-        SECOND_CLASS_ID,
-        actor.to_owned()
-    ));
-
-    // Create first property
-    let first_property =
-        Property::<ClassId>::default_with_name(PropertyNameLengthConstraint::get().max() as usize);
-
-    // Create second property
-    let second_property_type = PropertyType::<ClassId>::vec_reference(SECOND_CLASS_ID, true, 5);
-
-    let second_property = Property::<ClassId>::with_name_and_type(
-        (PropertyNameLengthConstraint::get().max() - 1) as usize,
-        second_property_type,
-        true,
-        false,
-    );
-
-    // Add first Schema to the first Class
-    assert_ok!(add_class_schema(
-        LEAD_ORIGIN,
-        FIRST_CLASS_ID,
-        BTreeSet::new(),
-        vec![first_property]
-    ));
-
-    // Add second Schema to the first Class
-    assert_ok!(add_class_schema(
-        LEAD_ORIGIN,
-        FIRST_CLASS_ID,
-        BTreeSet::new(),
-        vec![second_property]
-    ));
-
-    // Runtime state before tested call
-
-    // Events number before tested calls
-    let number_of_events_before_calls = System::events().len();
-
-    // Used to ensure schema support added succesfully
-    let mut first_entity = entity_by_id(FIRST_ENTITY_ID);
-
-    // Used to ensure reference counter updated succesfully
-    let mut second_entity = entity_by_id(SECOND_ENTITY_ID);
-
-    let mut first_schema_property_values = BTreeMap::new();
-    first_schema_property_values.insert(FIRST_PROPERTY_ID, InputPropertyValue::default());
-
-    // Add first schema support to the first entity
-    assert_ok!(add_schema_support_to_entity(
-        LEAD_ORIGIN,
-        actor.to_owned(),
-        FIRST_ENTITY_ID,
-        FIRST_SCHEMA_ID,
-        first_schema_property_values.clone()
-    ));
-
-    let mut second_schema_property_values = BTreeMap::new();
-    let second_schema_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![
-        SECOND_ENTITY_ID,
-        SECOND_ENTITY_ID,
-        SECOND_ENTITY_ID,
-    ]);
-
-    second_schema_property_values.insert(SECOND_PROPERTY_ID, second_schema_property_value);
-
-    // Add second schema support to the first entity
-    assert_ok!(add_schema_support_to_entity(
-        LEAD_ORIGIN,
-        actor.to_owned(),
-        FIRST_ENTITY_ID,
-        SECOND_SCHEMA_ID,
-        second_schema_property_values.clone()
-    ));
-
-    // Update supported schemas set and properties of first entity
-    *first_entity.get_supported_schemas_mut() =
-        BTreeSet::from_iter(vec![FIRST_SCHEMA_ID, SECOND_SCHEMA_ID].into_iter());
-
-    first_schema_property_values.append(&mut second_schema_property_values);
-
-    first_entity.set_values(TestModule::make_output_property_values(
-        first_schema_property_values,
-    ));
-
-    // Update reference counter of second entity
-    let inbound_rc = InboundReferenceCounter::new(3, true);
-    *second_entity.get_reference_counter_mut() = inbound_rc.clone();
-
-    // Create side-effect
-    let side_effect: EntityReferenceCounterSideEffect = inbound_rc.into();
-    let mut side_effects = ReferenceCounterSideEffects::default();
-    side_effects.insert(SECOND_ENTITY_ID, side_effect);
-
-    let entity_schema_support_added_event = get_test_event(RawEvent::EntitySchemaSupportAdded(
-        actor,
-        FIRST_ENTITY_ID,
-        SECOND_SCHEMA_ID,
-        Some(side_effects),
-    ));
-
-    // Last event checked
-    assert_event(
-        entity_schema_support_added_event,
-        number_of_events_before_calls + 2,
-    );
-
-    (first_entity, second_entity)
-}
-
-pub enum EntityAccessStateFailureType {
-    EntityNotFound,
-    LeadAuthFailed,
-    MemberAuthFailed,
-    CuratorAuthFailed,
-    CuratorNotFoundInCuratorGroup,
-    EntityAccessDenied,
-    PropertyValuesLocked,
-}
-
-pub fn emulate_entity_access_state_for_failure_case(
-    entity_access_level_failure_type: EntityAccessStateFailureType,
-) -> Actor<CuratorGroupId, CuratorId, MemberId> {
-    // Create class with default permissions
-    assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-    match entity_access_level_failure_type {
-        EntityAccessStateFailureType::EntityNotFound => Actor::Lead,
-        EntityAccessStateFailureType::LeadAuthFailed => {
-            let actor = Actor::Lead;
-
-            // Create entity
-            assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-            actor
-        }
-        EntityAccessStateFailureType::MemberAuthFailed => {
-            // Update class permissions to force any member be available to create entities
-            assert_ok!(update_class_permissions(
-                LEAD_ORIGIN,
-                FIRST_CLASS_ID,
-                Some(true),
-                None,
-                None,
-                None
-            ));
-
-            let actor = Actor::Member(FIRST_MEMBER_ID);
-
-            // Create entity
-            assert_ok!(create_entity(
-                FIRST_MEMBER_ORIGIN,
-                FIRST_CLASS_ID,
-                actor.clone()
-            ));
-            actor
-        }
-        EntityAccessStateFailureType::CuratorAuthFailed => {
-            // Add curator group
-            assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-            // Add curator to group
-            assert_ok!(add_curator_to_group(
-                LEAD_ORIGIN,
-                FIRST_CURATOR_GROUP_ID,
-                FIRST_CURATOR_ID,
-            ));
-
-            // Add curator group as class maintainer
-            assert_ok!(add_maintainer_to_class(
-                LEAD_ORIGIN,
-                FIRST_CLASS_ID,
-                FIRST_CURATOR_GROUP_ID
-            ));
-
-            // Make curator group active
-            assert_ok!(set_curator_group_status(
-                LEAD_ORIGIN,
-                FIRST_CURATOR_GROUP_ID,
-                true
-            ));
-
-            let actor = Actor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID);
-
-            // Create Entity
-            assert_ok!(create_entity(
-                FIRST_CURATOR_ORIGIN,
-                FIRST_CLASS_ID,
-                actor.clone()
-            ));
-
-            actor
-        }
-        EntityAccessStateFailureType::CuratorNotFoundInCuratorGroup => {
-            // Add curator group
-            assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-            // Add curator to group
-            assert_ok!(add_curator_to_group(
-                LEAD_ORIGIN,
-                FIRST_CURATOR_GROUP_ID,
-                FIRST_CURATOR_ID,
-            ));
-
-            // Make curator group active
-            assert_ok!(set_curator_group_status(
-                LEAD_ORIGIN,
-                FIRST_CURATOR_GROUP_ID,
-                true
-            ));
-
-            // Add curator group as class maintainer
-            assert_ok!(add_maintainer_to_class(
-                LEAD_ORIGIN,
-                FIRST_CLASS_ID,
-                FIRST_CURATOR_GROUP_ID
-            ));
-
-            // Create entity
-            assert_ok!(create_entity(
-                FIRST_CURATOR_ORIGIN,
-                FIRST_CLASS_ID,
-                Actor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID)
-            ));
-
-            Actor::Curator(FIRST_CURATOR_GROUP_ID, SECOND_CURATOR_ID)
-        }
-        EntityAccessStateFailureType::EntityAccessDenied => {
-            // Update class permissions to force any member be available to create entities
-            assert_ok!(update_class_permissions(
-                LEAD_ORIGIN,
-                FIRST_CLASS_ID,
-                Some(true),
-                None,
-                None,
-                None
-            ));
-
-            // Create entity
-            assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, Actor::Lead));
-
-            Actor::Member(SECOND_MEMBER_ID)
-        }
-        EntityAccessStateFailureType::PropertyValuesLocked => {
-            // Update class permissions to force lock all entity property values from update being performed
-            assert_ok!(update_class_permissions(
-                LEAD_ORIGIN,
-                FIRST_CLASS_ID,
-                None,
-                None,
-                Some(true),
-                None
-            ));
-
-            // Create entity
-            assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, Actor::Lead));
-
-            Actor::Lead
-        }
-    }
-}
-
-///  Create class reference schema
-pub fn add_unique_class_reference_schema() {
-    // Create property
-    let property_type =
-        PropertyType::<ClassId>::vec_reference(FIRST_CLASS_ID, true, VecMaxLengthConstraint::get());
-
-    let property = Property::<ClassId>::with_name_and_type(
-        (PropertyNameLengthConstraint::get().max() - 1) as usize,
-        property_type,
-        true,
-        true,
-    );
-
-    // Add Schema to the Class
-    assert_ok!(add_class_schema(
-        LEAD_ORIGIN,
-        FIRST_CLASS_ID,
-        BTreeSet::new(),
-        vec![property]
-    ));
-}
-
-///  Create class reference schema and add corresponding schema support to the Entity
-pub fn add_unique_class_reference_schema_and_entity_schema_support(
-    actor: &Actor<CuratorGroupId, CuratorId, MemberId>,
-    origin: u64,
-) {
-    add_unique_class_reference_schema();
-
-    let schema_property_value =
-        InputPropertyValue::<Runtime>::vec_reference(vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID]);
-
-    let mut schema_property_values = BTreeMap::new();
-    schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-    // Add schema support to the entity
-    assert_ok!(add_schema_support_to_entity(
-        origin,
-        actor.to_owned(),
-        FIRST_ENTITY_ID,
-        FIRST_SCHEMA_ID,
-        schema_property_values
-    ));
-}

+ 0 - 507
runtime-modules/content-directory/src/tests/add_class_schema.rs

@@ -1,507 +0,0 @@
-use super::*;
-
-#[test]
-fn add_class_schema_success() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        // Events number before tested calls
-        let number_of_events_before_call = System::events().len();
-
-        let first_property =
-            Property::default_with_name(PropertyNameLengthConstraint::get().max() as usize);
-
-        let second_property =
-            Property::default_with_name((PropertyNameLengthConstraint::get().max() - 1) as usize);
-
-        // Add first class schema
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![first_property.clone()]
-        ));
-
-        // Add second class schema
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::from_iter(vec![FIRST_PROPERTY_ID].into_iter()),
-            vec![second_property.clone()]
-        ));
-
-        // Runtime tested state after call
-
-        // Ensure class schemas added succesfully
-        let mut class = create_class_with_default_permissions();
-
-        class.set_properties(vec![first_property, second_property]);
-        *class.get_schemas_mut() = vec![
-            Schema::new(BTreeSet::from_iter(vec![FIRST_PROPERTY_ID].into_iter())),
-            Schema::new(BTreeSet::from_iter(
-                vec![FIRST_PROPERTY_ID, SECOND_PROPERTY_ID].into_iter(),
-            )),
-        ];
-
-        assert_eq!(class_by_id(FIRST_CLASS_ID), class);
-
-        let class_schema_added_event =
-            get_test_event(RawEvent::ClassSchemaAdded(FIRST_CLASS_ID, SECOND_SCHEMA_ID));
-
-        // Last event checked
-        assert_event(class_schema_added_event, number_of_events_before_call + 2);
-    })
-}
-
-#[test]
-fn add_class_schema_lead_auth_failied() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        // Events number before tested calls
-        let number_of_events_before_call = System::events().len();
-
-        let property =
-            Property::default_with_name(PropertyNameLengthConstraint::get().max() as usize);
-
-        // Make an attempt to add class schema under non lead origin
-        let add_class_schema_result = add_class_schema(
-            FIRST_MEMBER_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property],
-        );
-
-        // Failure checked
-        assert_failure(
-            add_class_schema_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_class_schema_class_does_not_exist() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested calls
-        let number_of_events_before_call = System::events().len();
-
-        let property =
-            Property::default_with_name(PropertyNameLengthConstraint::get().max() as usize);
-
-        // Make an attempt to add class schema to class, which does not exist in runtime
-        let add_class_schema_result = add_class_schema(
-            LEAD_ORIGIN,
-            UNKNOWN_CLASS_ID,
-            BTreeSet::new(),
-            vec![property],
-        );
-
-        // Failure checked
-        assert_failure(
-            add_class_schema_result,
-            Error::<Runtime>::ClassNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_class_schema_limit_reached() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        // Events number before tested calls
-        let number_of_events_before_call = System::events().len();
-
-        let mut number_of_schemas_added = 0;
-
-        // Add schemas to the class until MaxNumberOfSchemasPerClass limit reached
-        let add_class_schema_result = loop {
-            // property name must be unique
-            let property = Property::default_with_name(
-                PropertyNameLengthConstraint::get().max() as usize - number_of_schemas_added,
-            );
-
-            // Add class schema
-            let add_class_schema_result =
-                add_class_schema(LEAD_ORIGIN, FIRST_CLASS_ID, BTreeSet::new(), vec![property]);
-
-            if add_class_schema_result.is_err() {
-                break add_class_schema_result;
-            } else {
-                number_of_schemas_added += 1;
-            }
-        };
-
-        // Ensure number of schemas added is equal to MaxNumberOfSchemasPerClass
-        assert_eq!(
-            number_of_schemas_added,
-            MaxNumberOfSchemasPerClass::get() as usize
-        );
-
-        // Failure checked
-        assert_failure(
-            add_class_schema_result,
-            Error::<Runtime>::ClassSchemasLimitReached,
-            number_of_events_before_call + number_of_schemas_added,
-        );
-    })
-}
-
-#[test]
-fn add_class_schema_no_props_in_schema() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        // Events number before tested calls
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to add class schema with both empty existing and new properties
-        let add_class_schema_result =
-            add_class_schema(LEAD_ORIGIN, FIRST_CLASS_ID, BTreeSet::new(), vec![]);
-
-        // Failure checked
-        assert_failure(
-            add_class_schema_result,
-            Error::<Runtime>::NoPropertiesInClassSchema,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_class_schema_properties_limit_reached() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        // Events number before tested calls
-        let number_of_events_before_call = System::events().len();
-
-        // Add properties to Vec until it exceed MaxNumberOfPropertiesPerSchema runtime constraint
-        let properties = (1..=MaxNumberOfPropertiesPerSchema::get() + 1)
-            .into_iter()
-            .map(|property_id| {
-                // property name must be unique
-                let name_len = PropertyNameLengthConstraint::get().max() as u32 - property_id;
-                Property::default_with_name(name_len as usize)
-            })
-            .collect();
-
-        // Make an attempt to add class schema, providing properties, which total number exceeds MaxNumberOfPropertiesPerSchema limit
-        let add_class_schema_result =
-            add_class_schema(LEAD_ORIGIN, FIRST_CLASS_ID, BTreeSet::new(), properties);
-
-        // Failure checked
-        assert_failure(
-            add_class_schema_result,
-            Error::<Runtime>::SchemaPropertiesLimitReached,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_class_schema_prop_name_not_unique() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        let first_property =
-            Property::default_with_name(PropertyNameLengthConstraint::get().max() as usize);
-
-        let second_property =
-            Property::default_with_name((PropertyNameLengthConstraint::get().max()) as usize);
-
-        // Add first class schema
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![first_property]
-        ));
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to add second class schema with the same name
-        let add_class_schema_result = add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::from_iter(vec![FIRST_PROPERTY_ID].into_iter()),
-            vec![second_property],
-        );
-
-        // Failure checked
-        assert_failure(
-            add_class_schema_result,
-            Error::<Runtime>::PropertyNameNotUniqueInAClass,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_class_schema_refers_invalid_property_index() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        // Events number before tested calls
-        let number_of_events_before_call = System::events().len();
-
-        let property =
-            Property::default_with_name(PropertyNameLengthConstraint::get().max() as usize);
-
-        // Make an attempt to add class schema, providing existing property index, which corresponding property does not added yet
-        let add_class_schema_result = add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::from_iter(vec![UNKNOWN_PROPERTY_ID].into_iter()),
-            vec![property],
-        );
-
-        // Failure checked
-        assert_failure(
-            add_class_schema_result,
-            Error::<Runtime>::ClassSchemaRefersUnknownPropertyIndex,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_class_schema_property_name_too_long() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        // Events number before tested calls
-        let number_of_events_before_call = System::events().len();
-
-        let property = Property::<ClassId>::invalid(InvalidPropertyType::NameTooLong);
-
-        // Make an attempt to add class schema, providing property with name, which length exceeds PropertyNameLengthConstraint
-        let add_class_schema_result =
-            add_class_schema(LEAD_ORIGIN, FIRST_CLASS_ID, BTreeSet::new(), vec![property]);
-
-        // Failure checked
-        assert_failure(
-            add_class_schema_result,
-            Error::<Runtime>::PropertyNameTooLong,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_class_schema_property_name_too_short() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        // Events number before tested calls
-        let number_of_events_before_call = System::events().len();
-
-        let property = Property::<ClassId>::invalid(InvalidPropertyType::NameTooShort);
-
-        // Make an attempt to add class schema, providing property with name, which length is less than min value of PropertyNameLengthConstraint
-        let add_class_schema_result =
-            add_class_schema(LEAD_ORIGIN, FIRST_CLASS_ID, BTreeSet::new(), vec![property]);
-
-        // Failure checked
-        assert_failure(
-            add_class_schema_result,
-            Error::<Runtime>::PropertyNameTooShort,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_class_schema_property_description_too_long() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        // Events number before tested calls
-        let number_of_events_before_call = System::events().len();
-
-        let property = Property::<ClassId>::invalid(InvalidPropertyType::DescriptionTooLong);
-
-        // Make an attempt to add class schema, providing property with description, which length exceeds PropertyDescriptionLengthConstraint
-        let add_class_schema_result =
-            add_class_schema(LEAD_ORIGIN, FIRST_CLASS_ID, BTreeSet::new(), vec![property]);
-
-        // Failure checked
-        assert_failure(
-            add_class_schema_result,
-            Error::<Runtime>::PropertyDescriptionTooLong,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_class_schema_property_description_too_short() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        // Events number before tested calls
-        let number_of_events_before_call = System::events().len();
-
-        let property = Property::<ClassId>::invalid(InvalidPropertyType::DescriptionTooShort);
-
-        // Make an attempt to add class schema, providing property with description, which length is less than min value of PropertyDescriptionLengthConstraint
-        let add_class_schema_result =
-            add_class_schema(LEAD_ORIGIN, FIRST_CLASS_ID, BTreeSet::new(), vec![property]);
-
-        // Failure checked
-        assert_failure(
-            add_class_schema_result,
-            Error::<Runtime>::PropertyDescriptionTooShort,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_class_schema_text_property_is_too_long() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        // Events number before tested calls
-        let number_of_events_before_call = System::events().len();
-
-        let property = Property::<ClassId>::invalid(InvalidPropertyType::TextIsTooLong);
-
-        // Make an attempt to add class schema, providing property with Text type, which TextMaxLength exceeds corresponding TextMaxLengthConstraint
-        let add_class_schema_result =
-            add_class_schema(LEAD_ORIGIN, FIRST_CLASS_ID, BTreeSet::new(), vec![property]);
-
-        // Failure checked
-        assert_failure(
-            add_class_schema_result,
-            Error::<Runtime>::TextPropertyTooLong,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_class_schema_text_hash_property_is_too_long() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        // Events number before tested calls
-        let number_of_events_before_call = System::events().len();
-
-        let property = Property::<ClassId>::invalid(InvalidPropertyType::TextHashIsTooLong);
-
-        // Make an attempt to add class schema, providing property with Hash type,
-        // which HashedTextMaxLength exceeds corresponding HashedTextMaxLengthConstraint
-        let add_class_schema_result =
-            add_class_schema(LEAD_ORIGIN, FIRST_CLASS_ID, BTreeSet::new(), vec![property]);
-
-        // Failure checked
-        assert_failure(
-            add_class_schema_result,
-            Error::<Runtime>::HashedTextPropertyTooLong,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_class_schema_property_vec_property_is_too_long() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        // Events number before tested calls
-        let number_of_events_before_call = System::events().len();
-
-        let property = Property::<ClassId>::invalid(InvalidPropertyType::VecIsTooLong);
-
-        // Make an attempt to add class schema, providing Vector property, which VecMaxLength exceeds corresponding VecMaxLengthConstraint
-        let add_class_schema_result =
-            add_class_schema(LEAD_ORIGIN, FIRST_CLASS_ID, BTreeSet::new(), vec![property]);
-
-        // Failure checked
-        assert_failure(
-            add_class_schema_result,
-            Error::<Runtime>::VecPropertyTooLong,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_class_schema_property_refers_unknown_class() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        // Events number before tested calls
-        let number_of_events_before_call = System::events().len();
-
-        let reference_vec_type = PropertyType::<ClassId>::vec_reference(
-            UNKNOWN_CLASS_ID,
-            true,
-            VecMaxLengthConstraint::get(),
-        );
-        let property = Property::<ClassId>::with_name_and_type(1, reference_vec_type, true, true);
-
-        // Make an attempt to add class schema, providing property with Type::Reference, which refers to unknown ClassId
-        let add_class_schema_result =
-            add_class_schema(LEAD_ORIGIN, FIRST_CLASS_ID, BTreeSet::new(), vec![property]);
-
-        // Failure checked
-        assert_failure(
-            add_class_schema_result,
-            Error::<Runtime>::ClassSchemaRefersUnknownClass,
-            number_of_events_before_call,
-        );
-    })
-}

+ 0 - 59
runtime-modules/content-directory/src/tests/add_curator_group.rs

@@ -1,59 +0,0 @@
-use super::*;
-
-///Root Origin
-
-#[test]
-fn add_curator_group_success() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        assert_eq!(next_curator_group_id(), FIRST_CURATOR_GROUP_ID);
-        assert!(!curator_group_exists(FIRST_CURATOR_GROUP_ID));
-
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Runtime tested state after call
-
-        // Ensure new curator group exists and equal to default one right after creation
-        let curator_group = CuratorGroup::default();
-        assert_eq!(curator_group_by_id(FIRST_CURATOR_GROUP_ID), curator_group);
-
-        // Overall curator groups counter after curator group creation creation checked
-        assert_eq!(next_curator_group_id(), SECOND_CURATOR_GROUP_ID);
-
-        assert!(curator_group_exists(FIRST_CURATOR_GROUP_ID));
-
-        let curator_group_created_event =
-            get_test_event(RawEvent::CuratorGroupAdded(FIRST_CURATOR_GROUP_ID));
-
-        // Event checked
-        assert_event(
-            curator_group_created_event,
-            number_of_events_before_call + 1,
-        );
-    })
-}
-
-#[test]
-fn add_curator_group_lead_auth_failed() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // An attemt to add curator group from non lead origin
-        let add_curator_group_result = add_curator_group(FIRST_MEMBER_ORIGIN);
-
-        // Failure checked
-        assert_failure(
-            add_curator_group_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}

+ 0 - 162
runtime-modules/content-directory/src/tests/add_curator_to_group.rs

@@ -1,162 +0,0 @@
-use super::*;
-
-#[test]
-fn add_curator_to_group_success() {
-    with_test_externalities(|| {
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Add curator to group
-        assert_ok!(add_curator_to_group(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            FIRST_CURATOR_ID
-        ));
-
-        // Runtime tested state after call
-
-        // Ensure curator added to group
-        let mut curator_group = CuratorGroup::default();
-        curator_group.get_curators_mut().insert(FIRST_CURATOR_ID);
-        assert_eq!(curator_group_by_id(FIRST_CURATOR_GROUP_ID), curator_group);
-
-        let curator_group_curator_added_event = get_test_event(RawEvent::CuratorAdded(
-            FIRST_CURATOR_GROUP_ID,
-            FIRST_CURATOR_ID,
-        ));
-
-        // Event checked
-        assert_event(
-            curator_group_curator_added_event,
-            number_of_events_before_call + 1,
-        );
-    })
-}
-
-#[test]
-fn add_curator_to_group_lead_auth_failed() {
-    with_test_externalities(|| {
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to add curator to group from non lead origin
-        let add_curator_to_group_result = add_curator_to_group(
-            FIRST_MEMBER_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            FIRST_CURATOR_ID,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_curator_to_group_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_curator_to_non_existent_group() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to add curator to group that does not exist
-        let add_curator_to_group_result =
-            add_curator_to_group(LEAD_ORIGIN, UNKNOWN_CURATOR_GROUP_ID, FIRST_CURATOR_ID);
-
-        // Failure checked
-        assert_failure(
-            add_curator_to_group_result,
-            Error::<Runtime>::CuratorGroupDoesNotExist,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_curator_to_group_already_a_member_of_given_curator_group() {
-    with_test_externalities(|| {
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Add curator to group
-        assert_ok!(add_curator_to_group(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            FIRST_CURATOR_ID
-        ));
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to add curator, which is already a member of given curator group.
-        let add_curator_to_group_result =
-            add_curator_to_group(LEAD_ORIGIN, FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID);
-
-        // Failure checked
-        assert_failure(
-            add_curator_to_group_result,
-            Error::<Runtime>::CuratorIsAlreadyAMemberOfGivenCuratorGroup,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_curator_to_group_curators_limit_reached() {
-    with_test_externalities(|| {
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut number_of_curators_added = 0;
-
-        // Adding curators to the same group until limit reached
-        let add_curator_to_group_result = loop {
-            // Add curator to group
-            let add_curator_to_group_result = add_curator_to_group(
-                LEAD_ORIGIN,
-                FIRST_CURATOR_GROUP_ID,
-                number_of_curators_added,
-            );
-
-            if add_curator_to_group_result.is_err() {
-                break add_curator_to_group_result;
-            } else {
-                number_of_curators_added += 1;
-            }
-        };
-
-        // Ensure number of curators added is equal to the MaxNumberOfCuratorsPerGroup runtime limit
-        assert_eq!(
-            number_of_curators_added as u32,
-            MaxNumberOfCuratorsPerGroup::get()
-        );
-
-        // Failure checked
-        assert_failure(
-            add_curator_to_group_result,
-            Error::<Runtime>::CuratorsPerGroupLimitReached,
-            number_of_events_before_call + number_of_curators_added as usize,
-        );
-    })
-}

+ 0 - 195
runtime-modules/content-directory/src/tests/add_maintainer_to_class.rs

@@ -1,195 +0,0 @@
-use super::*;
-
-#[test]
-fn add_maintainer_to_class_success() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        assert_ok!(add_maintainer_to_class(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            FIRST_CURATOR_GROUP_ID
-        ));
-
-        // Runtime tested state after call
-
-        // Ensure curator_group added as class maintainer
-        let mut class = create_class_with_default_permissions();
-        class
-            .get_permissions_mut()
-            .get_maintainers_mut()
-            .insert(FIRST_CURATOR_GROUP_ID);
-        assert_eq!(class_by_id(FIRST_CLASS_ID), class);
-
-        let maintainer_added_event = get_test_event(RawEvent::MaintainerAdded(
-            FIRST_CLASS_ID,
-            FIRST_CURATOR_GROUP_ID,
-        ));
-
-        // Event checked
-        assert_event(maintainer_added_event, number_of_events_before_call + 1);
-    })
-}
-
-#[test]
-fn add_maintainer_to_class_lead_auth_failed() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to add maintainer to class from non lead origin
-        let add_maintainer_result =
-            add_maintainer_to_class(SECOND_MEMBER_ORIGIN, FIRST_CLASS_ID, FIRST_CURATOR_GROUP_ID);
-
-        // Failure checked
-        assert_failure(
-            add_maintainer_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_non_existent_maintainer_to_class() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to add non existent maintainer curator group to class
-        let add_maintainer_result =
-            add_maintainer_to_class(LEAD_ORIGIN, FIRST_CLASS_ID, UNKNOWN_CURATOR_GROUP_ID);
-
-        // Failure checked
-        assert_failure(
-            add_maintainer_result,
-            Error::<Runtime>::CuratorGroupDoesNotExist,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_maintainer_to_non_existent_class() {
-    with_test_externalities(|| {
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to add maintainer to non existent class
-        let add_maintainer_result =
-            add_maintainer_to_class(LEAD_ORIGIN, UNKNOWN_CLASS_ID, FIRST_CURATOR_GROUP_ID);
-
-        // Failure checked
-        assert_failure(
-            add_maintainer_result,
-            Error::<Runtime>::ClassNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_maintainer_to_class_limit_reached() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Add curator groups to runtime storage, that will be used to be added as class maintainers
-        for _ in 0..=MaxNumberOfMaintainersPerClass::get() {
-            assert_ok!(add_curator_group(LEAD_ORIGIN));
-        }
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut number_of_maintainers_added_to_class = 0_usize;
-
-        // Adding curator group maintainers to the same class until limit reached
-        let add_maintainer_result = loop {
-            let curator_group_id = (number_of_maintainers_added_to_class + 1) as CuratorGroupId;
-
-            let add_maintainer_result =
-                add_maintainer_to_class(LEAD_ORIGIN, FIRST_CLASS_ID, curator_group_id);
-
-            if add_maintainer_result.is_err() {
-                break add_maintainer_result;
-            } else {
-                number_of_maintainers_added_to_class += 1;
-            }
-        };
-
-        // Ensure number of maintainers added to the class is equal to MaxNumberOfMaintainersPerClass constraint defined on class level
-        assert_eq!(
-            number_of_maintainers_added_to_class,
-            MaxNumberOfMaintainersPerClass::get() as usize
-        );
-
-        // Failure checked
-        assert_failure(
-            add_maintainer_result,
-            Error::<Runtime>::ClassMaintainersLimitReached,
-            number_of_events_before_call + number_of_maintainers_added_to_class,
-        );
-    })
-}
-
-#[test]
-fn add_maintainer_that_is_already_exist() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Add maintainer
-        assert_ok!(add_maintainer_to_class(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            FIRST_CURATOR_GROUP_ID
-        ));
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to add curator group maintainer, that is already added to given class maintainers set
-        let add_maintainer_result =
-            add_maintainer_to_class(LEAD_ORIGIN, FIRST_CLASS_ID, FIRST_CURATOR_GROUP_ID);
-
-        // Failure checked
-        assert_failure(
-            add_maintainer_result,
-            Error::<Runtime>::MaintainerAlreadyExists,
-            number_of_events_before_call,
-        );
-    })
-}

+ 0 - 1458
runtime-modules/content-directory/src/tests/add_schema_support_to_entity.rs

@@ -1,1458 +0,0 @@
-use super::*;
-
-#[test]
-fn add_schema_support_to_entity_success() {
-    with_test_externalities(|| {
-        // Add entity schemas support
-        let (first_entity, second_entity) = add_entity_schemas_support();
-
-        // Ensure supported schemas set and properties of first entity updated succesfully
-        assert_eq!(first_entity, entity_by_id(FIRST_ENTITY_ID));
-
-        // Ensure reference counter of second entity updated succesfully
-        assert_eq!(second_entity, entity_by_id(SECOND_ENTITY_ID));
-    })
-}
-
-#[test]
-fn add_schema_support_to_non_existent_entity() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::EntityNotFound,
-        );
-
-        // Create property
-        let property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().max() as usize,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, InputPropertyValue::default());
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to add schema support to non existent Entity
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::EntityNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_lead_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::LeadAuthFailed,
-        );
-
-        // Create property
-        let property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().max() as usize,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, InputPropertyValue::default());
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to add schema support under non lead origin
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            UNKNOWN_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_member_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::MemberAuthFailed,
-        );
-
-        // Create property
-        let property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().max() as usize,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, InputPropertyValue::default());
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to add schema support to entity using unknown origin and member actor
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            UNKNOWN_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::MemberAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_curator_group_is_not_active() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorAuthFailed,
-        );
-
-        // Make curator group inactive to block it from any entity operations
-        assert_ok!(set_curator_group_status(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            false
-        ));
-
-        // Create property
-        let property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().max() as usize,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, InputPropertyValue::default());
-
-        // Make an attempt to add schema support to entity using curator group, which is not active as actor
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            FIRST_CURATOR_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::CuratorGroupIsNotActive,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_curator_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorAuthFailed,
-        );
-
-        // Create property
-        let property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().max() as usize,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, InputPropertyValue::default());
-
-        // Make an attempt to add schema support to entity under unknown origin and curator actor,
-        // which corresponding group is current entity controller
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            UNKNOWN_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::CuratorAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_curator_not_found_in_curator_group() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorNotFoundInCuratorGroup,
-        );
-
-        // Create property
-        let property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().max() as usize,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, InputPropertyValue::default());
-
-        // Make an attempt to add schema support to entity, using actor in group,
-        // which curator id was not added to corresponding group set
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            SECOND_CURATOR_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::CuratorIsNotAMemberOfGivenCuratorGroup,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_access_denied() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::EntityAccessDenied,
-        );
-
-        // Create property
-        let property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().max() as usize,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, InputPropertyValue::default());
-
-        // Make an attempt to add schema support to entity, using origin,
-        // which corresponding actor is neither entity maintainer, nor controller.
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            SECOND_MEMBER_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::EntityAccessDenied,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_to_entity_schema_does_not_exist() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, InputPropertyValue::default());
-
-        // Make an attempt to add schema support to entity, providing schema_id,
-        // which corresponding Schema does not exist on Class level
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::UnknownClassSchemaId,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_to_entity_class_property_not_found() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create property
-        let property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().max() as usize,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(SECOND_PROPERTY_ID, InputPropertyValue::default());
-
-        // Make an attempt to add schema support to Entity, providing property value under property_id,
-        // which does not not yet added to corresponding Class properties
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::ClassPropertyNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_already_added_to_the_entity() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create property
-        let property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().max() as usize,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, InputPropertyValue::default());
-
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.clone(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values.clone(),
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to add schema support to entity, providing schema_id,
-        // which was already added to the Entity
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::SchemaAlreadyAddedToTheEntity,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_already_contains_given_property_id() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create first property
-        let first_property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().max() as usize,
-        );
-
-        // Add first Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![first_property]
-        ));
-
-        // Create second property
-        let second_property_type =
-            PropertyType::<ClassId>::single_text(TextMaxLengthConstraint::get());
-        let second_property = Property::<ClassId>::with_name_and_type(
-            PropertyNameLengthConstraint::get().max() as usize - 1,
-            second_property_type,
-            true,
-            false,
-        );
-
-        // Add second Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::from_iter(vec![FIRST_PROPERTY_ID].into_iter()),
-            vec![second_property]
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, InputPropertyValue::default());
-
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.clone(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values.clone(),
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        schema_property_values.insert(
-            SECOND_PROPERTY_ID,
-            InputPropertyValue::<Runtime>::single_text(TextMaxLengthConstraint::get()),
-        );
-
-        // Make an attempt to add schema support to entity, providing Schema property_values,
-        // some of which were already added to this Entity
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            SECOND_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::EntityAlreadyContainsGivenPropertyId,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_is_not_active() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create property
-        let property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().max() as usize,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Make Class Schema inactive
-        assert_ok!(update_class_schema_status(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            FIRST_SCHEMA_ID,
-            false
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, InputPropertyValue::default());
-
-        // Make an attempt to add schema support to Entity, providing schema id,
-        // which corresponding class Schema is not active
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::ClassSchemaNotActive,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_does_not_contain_provided_property_id() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create first property
-        let first_property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().max() as usize,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![first_property]
-        ));
-
-        // Create second property
-        let second_property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().max() as usize - 1,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![second_property]
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(SECOND_PROPERTY_ID, InputPropertyValue::default());
-
-        // Make an attempt to add schema support to Entity, providing property values, which are not a members of
-        // provided Schema
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::SchemaDoesNotContainProvidedPropertyId,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_missing_required_property() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create first property
-        let first_property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().max() as usize,
-        );
-
-        // Create second property
-        let second_property_type =
-            PropertyType::<ClassId>::single_text(TextMaxLengthConstraint::get());
-        let second_property = Property::<ClassId>::with_name_and_type(
-            PropertyNameLengthConstraint::get().max() as usize - 1,
-            second_property_type,
-            true,
-            false,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![first_property, second_property]
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, InputPropertyValue::default());
-
-        // Make an attempt to add schema support to Entity, do not providing some of required property values
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::MissingRequiredProperty,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_dont_match_type() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create property
-        let property_type = PropertyType::<ClassId>::single_text(TextMaxLengthConstraint::get());
-        let property = Property::<ClassId>::with_name_and_type(
-            PropertyNameLengthConstraint::get().max() as usize - 1,
-            property_type,
-            true,
-            false,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, InputPropertyValue::default());
-
-        // Make an attempt to add schema support to Entity, providing property values, some of which do not match
-        // Class level Property Type
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::PropertyValueDoNotMatchType,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_referenced_entity_does_not_match_class() {
-    with_test_externalities(|| {
-        // Create first class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create second class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create first entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.to_owned()));
-
-        // Create second entity
-        assert_ok!(create_entity(
-            LEAD_ORIGIN,
-            SECOND_CLASS_ID,
-            actor.to_owned()
-        ));
-
-        // Create property
-        let property_type = PropertyType::<ClassId>::vec_reference(FIRST_CLASS_ID, true, 5);
-
-        let property = Property::<ClassId>::with_name_and_type(
-            (PropertyNameLengthConstraint::get().max() - 1) as usize,
-            property_type,
-            true,
-            false,
-        );
-
-        // Add Schema to the first Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_property_values = BTreeMap::new();
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![SECOND_ENTITY_ID, SECOND_ENTITY_ID]);
-
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Make an attempt to add schema support to the Entity, when provided schema property value(s) refer(s) Entity, which Class
-        // does not match the class in corresponding Class Property
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::ReferencedEntityDoesNotMatchItsClass,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_referenced_entity_does_not_exist() {
-    with_test_externalities(|| {
-        // Create first class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create second class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.to_owned()));
-
-        // Create property
-        let property_type = PropertyType::<ClassId>::vec_reference(SECOND_CLASS_ID, true, 5);
-
-        let property = Property::<ClassId>::with_name_and_type(
-            (PropertyNameLengthConstraint::get().max() - 1) as usize,
-            property_type,
-            true,
-            false,
-        );
-
-        // Add Schema to the first Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_property_values = BTreeMap::new();
-        let schema_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![
-            UNKNOWN_ENTITY_ID,
-            UNKNOWN_ENTITY_ID,
-        ]);
-
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Make an attempt to add schema support to the first entity, if provided property value(s) refer(s) to another Entity,
-        // which does not exist in runtime
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::EntityNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_entity_can_not_be_referenced() {
-    with_test_externalities(|| {
-        // Create first class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create first entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.to_owned()));
-
-        // Create second entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.to_owned()));
-
-        // Update second entity permissions to forbid it from being referencable
-        assert_ok!(update_entity_permissions(
-            LEAD_ORIGIN,
-            SECOND_ENTITY_ID,
-            None,
-            Some(false)
-        ));
-
-        // Create property
-        let property_type = PropertyType::<ClassId>::vec_reference(FIRST_CLASS_ID, true, 5);
-
-        let property = Property::<ClassId>::with_name_and_type(
-            (PropertyNameLengthConstraint::get().max() - 1) as usize,
-            property_type,
-            true,
-            false,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_property_values = BTreeMap::new();
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![SECOND_ENTITY_ID, SECOND_ENTITY_ID]);
-
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Make an attempt to add schema support to the first entity, when provided schema property value(s)
-        // refer(s) to Entity which can not be referenced
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::EntityCanNotBeReferenced,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_same_controller_constraint_violation() {
-    with_test_externalities(|| {
-        // Create first class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Update class permissions to force any member be available to create Entities
-        assert_ok!(update_class_permissions(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            Some(true),
-            None,
-            None,
-            None
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create first entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.to_owned()));
-
-        // Create second entity
-        assert_ok!(create_entity(
-            FIRST_MEMBER_ORIGIN,
-            FIRST_CLASS_ID,
-            Actor::Member(FIRST_MEMBER_ID)
-        ));
-
-        // Create property
-        let property_type = PropertyType::<ClassId>::vec_reference(FIRST_CLASS_ID, true, 5);
-
-        let property = Property::<ClassId>::with_name_and_type(
-            (PropertyNameLengthConstraint::get().max() - 1) as usize,
-            property_type,
-            true,
-            false,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_property_values = BTreeMap::new();
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![SECOND_ENTITY_ID, SECOND_ENTITY_ID]);
-
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Make an attempt to add schema support to the first entity, providing reference property value(s) in case,
-        // when corresponding Entity can only be referenced from Entity with the same controller.
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::SameControllerConstraintViolation,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_text_property_is_too_long() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.to_owned()));
-
-        // Create text property
-        let property_type = PropertyType::<ClassId>::single_text(TextMaxLengthConstraint::get());
-
-        let property = Property::<ClassId>::with_name_and_type(
-            PropertyNameLengthConstraint::get().max() as usize,
-            property_type,
-            true,
-            false,
-        );
-
-        // Add Schema to the first Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_property_values = BTreeMap::new();
-
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::single_text(TextMaxLengthConstraint::get() + 1);
-
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Make an attempt to add schema support to the entity, providing text property value(s), which
-        // length exceeds TextMaxLengthConstraint.
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::TextPropertyTooLong,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_text_hash_property_is_too_long() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.to_owned()));
-
-        let hashed_text_max_length_constraint = HashedTextMaxLengthConstraint::get();
-
-        // Create hash property
-        let property_type =
-            PropertyType::<ClassId>::single_text_hash(hashed_text_max_length_constraint);
-
-        let property = Property::<ClassId>::with_name_and_type(
-            PropertyNameLengthConstraint::get().max() as usize,
-            property_type,
-            true,
-            false,
-        );
-
-        // Add Schema to the first Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_property_values = BTreeMap::new();
-
-        let schema_property_value = InputPropertyValue::<Runtime>::single_text_to_hash(
-            hashed_text_max_length_constraint.unwrap() + 1,
-        );
-
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Make an attempt to add schema support to the entity, providing text property value(s), which
-        // length exceeds HashedTextMaxLengthConstraint.
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::HashedTextPropertyTooLong,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_vec_property_is_too_long() {
-    with_test_externalities(|| {
-        // Create first class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create second class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create first entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.to_owned()));
-
-        // Create second entity
-        assert_ok!(create_entity(
-            LEAD_ORIGIN,
-            SECOND_CLASS_ID,
-            actor.to_owned()
-        ));
-
-        // Create vec property
-        let property_type = PropertyType::<ClassId>::vec_reference(
-            SECOND_CLASS_ID,
-            true,
-            VecMaxLengthConstraint::get(),
-        );
-
-        let property = Property::<ClassId>::with_name_and_type(
-            (PropertyNameLengthConstraint::get().max() - 1) as usize,
-            property_type,
-            true,
-            false,
-        );
-
-        // Add Schema to the first Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_property_values = BTreeMap::new();
-        let schema_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![
-                SECOND_ENTITY_ID;
-                VecMaxLengthConstraint::get() as usize + 1
-            ]);
-
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Make an attempt to add schema support to the Entity, providing vector property value(s), which
-        // length exceeds VecMaxLengthConstraint.
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::VecPropertyTooLong,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_property_should_be_unique() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create first entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.to_owned()));
-
-        // Create second entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.to_owned()));
-
-        let property_type = PropertyType::<ClassId>::single_text(TextMaxLengthConstraint::get());
-
-        // Create text property
-
-        let property = Property::<ClassId>::with_name_and_type(
-            PropertyNameLengthConstraint::get().max() as usize,
-            property_type,
-            true,
-            true,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let mut schema_property_values = BTreeMap::new();
-
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::single_text(TextMaxLengthConstraint::get());
-
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add Entity Schema support to the first Entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.to_owned(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values.clone(),
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to add schema support to the Entity, providing property values, which respective Class properties have
-        // unique flag set and same property values under same property_ids were already added to any Entity of this Class
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            SECOND_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::PropertyValueShouldBeUnique,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn add_schema_support_properties_should_be_unique() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create first entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.to_owned()));
-
-        // Create second entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.to_owned()));
-
-        // Create third entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.to_owned()));
-
-        let property_type = PropertyType::<ClassId>::single_text(TextMaxLengthConstraint::get());
-
-        // Create text property
-
-        let property = Property::<ClassId>::with_name_and_type(
-            PropertyNameLengthConstraint::get().max() as usize,
-            property_type,
-            true,
-            true,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let mut first_schema_property_values = BTreeMap::new();
-
-        let first_schema_property_value =
-            InputPropertyValue::<Runtime>::single_text(TextMaxLengthConstraint::get());
-
-        first_schema_property_values.insert(FIRST_PROPERTY_ID, first_schema_property_value);
-
-        // Add Entity Schema support to the first Entity (property unique on the Class level added)
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.to_owned(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            first_schema_property_values.clone(),
-        ));
-
-        let mut second_schema_property_values = BTreeMap::new();
-
-        let second_schema_property_value =
-            InputPropertyValue::<Runtime>::single_text(TextMaxLengthConstraint::get() - 1);
-
-        second_schema_property_values.insert(FIRST_PROPERTY_ID, second_schema_property_value);
-
-        // Add Entity Schema support to the second Entity (property unique on the Class level added)
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.to_owned(),
-            SECOND_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            second_schema_property_values,
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to add schema support to the Entity, providing property values, which respective Class properties have
-        // unique flag set and same property values under same property_ids were already added to any Entity of this Class
-        let add_schema_support_to_entity_result = add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            THIRD_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            first_schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            add_schema_support_to_entity_result,
-            Error::<Runtime>::PropertyValueShouldBeUnique,
-            number_of_events_before_call,
-        );
-    })
-}

+ 0 - 557
runtime-modules/content-directory/src/tests/clear_entity_property_vector.rs

@@ -1,557 +0,0 @@
-use super::*;
-
-#[test]
-fn clear_entity_property_vector_success() {
-    with_test_externalities(|| {
-        let actor = Actor::Lead;
-
-        // Add entity schemas support
-        let (mut first_entity, mut second_entity) = add_entity_schemas_support();
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_calls = System::events().len();
-
-        // Clear property_vector under given `entity_id` & `in_class_schema_property_id`
-        assert_ok!(clear_entity_property_vector(
-            LEAD_ORIGIN,
-            actor.clone(),
-            FIRST_ENTITY_ID,
-            SECOND_PROPERTY_ID
-        ));
-
-        // Runtime tested state after call
-
-        // Ensure first entity properties updated succesfully
-        if let Some(second_schema_old_property_value) = first_entity
-            .get_values_mut()
-            .get_mut(&SECOND_PROPERTY_ID)
-            .and_then(|property_value| property_value.as_vec_property_value_mut())
-        {
-            second_schema_old_property_value.clear();
-        }
-
-        assert_eq!(first_entity, entity_by_id(FIRST_ENTITY_ID));
-
-        // Ensure reference counter of second entity updated succesfully
-        let inbound_rc = InboundReferenceCounter::new(0, true);
-        *second_entity.get_reference_counter_mut() = inbound_rc.clone();
-
-        assert_eq!(second_entity, entity_by_id(SECOND_ENTITY_ID));
-
-        // Create side-effect
-        let side_effect = EntityReferenceCounterSideEffect::new(-3, -3);
-        let mut side_effects = ReferenceCounterSideEffects::default();
-        side_effects.insert(SECOND_ENTITY_ID, side_effect);
-
-        let entity_property_vector_cleared_event = get_test_event(RawEvent::VectorCleared(
-            actor,
-            FIRST_ENTITY_ID,
-            SECOND_PROPERTY_ID,
-            Some(side_effects),
-        ));
-
-        // Last event checked
-        assert_event(
-            entity_property_vector_cleared_event,
-            number_of_events_before_calls + 1,
-        );
-    })
-}
-
-#[test]
-fn clear_entity_property_vector_entity_not_found() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::EntityNotFound,
-        );
-
-        // Create class reference schema
-        add_unique_class_reference_schema();
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to clear property_vector under given `entity_id` & `in_class_schema_property_id`
-        // in case when corresponding Entity does not exist
-        let clear_entity_property_vector_result =
-            clear_entity_property_vector(LEAD_ORIGIN, actor, FIRST_ENTITY_ID, FIRST_PROPERTY_ID);
-
-        // Failure checked
-        assert_failure(
-            clear_entity_property_vector_result,
-            Error::<Runtime>::EntityNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn clear_entity_property_vector_lead_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::LeadAuthFailed,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to clear property_vector under given `entity_id` & `in_class_schema_property_id`
-        // using unknown origin and lead actor
-        let clear_entity_property_vector_result = clear_entity_property_vector(
-            UNKNOWN_ORIGIN,
-            actor.clone(),
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-        );
-
-        // Failure checked
-        assert_failure(
-            clear_entity_property_vector_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn clear_entity_property_vector_member_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::MemberAuthFailed,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, FIRST_MEMBER_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to clear property_vector under given `entity_id` & `in_class_schema_property_id`
-        // using unknown origin an member actor
-        let clear_entity_property_vector_result = clear_entity_property_vector(
-            UNKNOWN_ORIGIN,
-            actor.clone(),
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-        );
-
-        // Failure checked
-        assert_failure(
-            clear_entity_property_vector_result,
-            Error::<Runtime>::MemberAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn clear_entity_property_vector_curator_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorAuthFailed,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, FIRST_CURATOR_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to clear property_vector under given `entity_id` & `in_class_schema_property_id`
-        // using unknown origin and curator actor
-        let clear_entity_property_vector_result =
-            clear_entity_property_vector(UNKNOWN_ORIGIN, actor, FIRST_ENTITY_ID, FIRST_PROPERTY_ID);
-
-        // Failure checked
-        assert_failure(
-            clear_entity_property_vector_result,
-            Error::<Runtime>::CuratorAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn clear_entity_property_vector_curator_group_is_not_active() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorAuthFailed,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, FIRST_CURATOR_ORIGIN);
-
-        // Make curator group inactive to block it from any entity operations
-        assert_ok!(set_curator_group_status(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            false
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to clear property_vector under given `entity_id` & `in_class_schema_property_id`
-        // using curator group, which is not active as actor
-        let clear_entity_property_vector_result = clear_entity_property_vector(
-            FIRST_CURATOR_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-        );
-
-        // Failure checked
-        assert_failure(
-            clear_entity_property_vector_result,
-            Error::<Runtime>::CuratorGroupIsNotActive,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn clear_entity_property_vector_curator_not_found_in_curator_group() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorNotFoundInCuratorGroup,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(
-            &Actor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
-            FIRST_CURATOR_ORIGIN,
-        );
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to clear property_vector under given `entity_id` & `in_class_schema_property_id`
-        // using actor in group, which curator id was not added to corresponding group set
-        let clear_entity_property_vector_result = clear_entity_property_vector(
-            SECOND_CURATOR_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-        );
-
-        // Failure checked
-        assert_failure(
-            clear_entity_property_vector_result,
-            Error::<Runtime>::CuratorIsNotAMemberOfGivenCuratorGroup,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn clear_entity_property_vector_entity_access_denied() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::EntityAccessDenied,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&Actor::Lead, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to clear property_vector under given `entity_id` & `in_class_schema_property_id`
-        // using origin, which corresponding actor is neither entity maintainer, nor controller.
-        let clear_entity_property_vector_result = clear_entity_property_vector(
-            SECOND_CURATOR_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-        );
-
-        // Failure checked
-        assert_failure(
-            clear_entity_property_vector_result,
-            Error::<Runtime>::EntityAccessDenied,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn clear_entity_property_vector_values_locked_on_class_level() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::PropertyValuesLocked,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&Actor::Lead, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to clear property_vector under given `entity_id` & `in_class_schema_property_id`
-        // in the case, when all property values were locked on Class level
-        let clear_entity_property_vector_result =
-            clear_entity_property_vector(LEAD_ORIGIN, actor, FIRST_ENTITY_ID, FIRST_PROPERTY_ID);
-
-        // Failure checked
-        assert_failure(
-            clear_entity_property_vector_result,
-            Error::<Runtime>::AllPropertiesWereLockedOnClassLevel,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn clear_entity_property_vector_class_property_not_found() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to clear property_vector under given `entity_id` & `in_class_schema_property_id`
-        // in the case, when Property under corresponding PropertyId was not found on Class level
-        let clear_entity_property_vector_result =
-            clear_entity_property_vector(LEAD_ORIGIN, actor, FIRST_ENTITY_ID, FIRST_PROPERTY_ID);
-
-        // Failure checked
-        assert_failure(
-            clear_entity_property_vector_result,
-            Error::<Runtime>::ClassPropertyNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn clear_entity_property_vector_is_locked_for_given_actor() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create property
-        let property_type = PropertyType::<ClassId>::vec_reference(FIRST_CLASS_ID, true, 5);
-
-        let mut property = Property::<ClassId>::with_name_and_type(
-            (PropertyNameLengthConstraint::get().max() - 1) as usize,
-            property_type,
-            true,
-            false,
-        );
-
-        property.locking_policy = PropertyLockingPolicy::new(false, true);
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.clone(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to clear property_vector under given `entity_id` & `in_class_schema_property_id` under lead origin,
-        // which is current Entity controller, in the case, when corresponding class Property was locked from controller on Class level
-        let clear_entity_property_vector_result =
-            clear_entity_property_vector(LEAD_ORIGIN, actor, FIRST_ENTITY_ID, FIRST_PROPERTY_ID);
-
-        // Failure checked
-        assert_failure(
-            clear_entity_property_vector_result,
-            Error::<Runtime>::ClassPropertyTypeLockedForGivenActor,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn clear_entity_property_vector_unknown_entity_property_id() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create class reference schema
-        add_unique_class_reference_schema();
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to clear property_vector under given `entity_id` & `in_class_schema_property_id`
-        // in the case, when property value was not added to current Entity values yet.
-        let clear_entity_property_vector_result =
-            clear_entity_property_vector(LEAD_ORIGIN, actor, FIRST_ENTITY_ID, FIRST_PROPERTY_ID);
-
-        // Failure checked
-        assert_failure(
-            clear_entity_property_vector_result,
-            Error::<Runtime>::UnknownEntityPropertyId,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn clear_entity_property_vector_value_under_given_index_is_not_a_vector() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create property
-        let property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().max() as usize,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, InputPropertyValue::default());
-
-        // Add schema support to the entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.clone(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to clear property_vector under given `entity_id` & `in_class_schema_property_id`
-        // in the case, when entity property value corresponding to a given in_class_schema_property_id is not a vector.
-        let clear_entity_property_vector_result =
-            clear_entity_property_vector(LEAD_ORIGIN, actor, FIRST_ENTITY_ID, FIRST_PROPERTY_ID);
-
-        // Failure checked
-        assert_failure(
-            clear_entity_property_vector_result,
-            Error::<Runtime>::PropertyValueUnderGivenIndexIsNotAVector,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn clear_entity_property_vector_property_should_be_unique() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create first Entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create unique class reference schema and add corresponding schema support to the first Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Create second Entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create blank vec reference
-        let schema_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the second Entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.to_owned(),
-            SECOND_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to clear property_vector under given `entity_id` & `in_class_schema_property_id`
-        // in case, when the same blank required & unique property value vector already added to another Entity of this Class.
-        let clear_entity_property_vector_result =
-            clear_entity_property_vector(LEAD_ORIGIN, actor, FIRST_ENTITY_ID, FIRST_PROPERTY_ID);
-
-        // Failure checked
-        assert_failure(
-            clear_entity_property_vector_result,
-            Error::<Runtime>::PropertyValueShouldBeUnique,
-            number_of_events_before_call,
-        );
-    })
-}

+ 0 - 275
runtime-modules/content-directory/src/tests/create_class.rs

@@ -1,275 +0,0 @@
-use super::*;
-
-#[test]
-fn create_class_success() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        assert_eq!(next_class_id(), FIRST_CLASS_ID);
-        assert!(!class_exists(FIRST_CLASS_ID));
-
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state after call
-
-        // Ensure class under given if is equal to default one
-        let default_class = create_class_with_default_permissions();
-        assert_eq!(class_by_id(FIRST_CLASS_ID), default_class);
-
-        let class_created_event = get_test_event(RawEvent::ClassCreated(FIRST_CLASS_ID));
-
-        // Event checked
-        assert_event(class_created_event, number_of_events_before_call + 1);
-    })
-}
-
-#[test]
-fn create_class_lead_auth_failed() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // An attempt to create class with non lead origin
-        let create_class_result = create_simple_class(FIRST_MEMBER_ORIGIN, ClassType::Valid);
-
-        // Failure checked
-        assert_failure(
-            create_class_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_class_limit_reached() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut number_of_classes_created = 0;
-
-        // Creating classes before limit reached
-        let create_class_result = loop {
-            let create_class_result = create_simple_class(LEAD_ORIGIN, ClassType::Valid);
-            if create_class_result.is_err() {
-                break create_class_result;
-            } else {
-                number_of_classes_created += 1;
-            }
-        };
-
-        // Ensure number of classes created is equal to MaxNumberOfClasses runtime constraint
-        assert_eq!(
-            number_of_classes_created,
-            MaxNumberOfClasses::get() as usize
-        );
-
-        // Failure checked
-        assert_failure(
-            create_class_result,
-            Error::<Runtime>::ClassLimitReached,
-            number_of_events_before_call + number_of_classes_created,
-        );
-    })
-}
-
-#[test]
-fn create_class_name_is_too_long() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // An attempt to create class with invalid name
-        let create_class_result = create_simple_class(LEAD_ORIGIN, ClassType::NameTooLong);
-
-        // Failure checked
-        assert_failure(
-            create_class_result,
-            Error::<Runtime>::ClassNameTooLong,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_class_name_is_too_short() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // An attempt to create class with invalid name
-        let create_class_result = create_simple_class(LEAD_ORIGIN, ClassType::NameTooShort);
-
-        // Failure checked
-        assert_failure(
-            create_class_result,
-            Error::<Runtime>::ClassNameTooShort,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_class_description_is_too_long() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // An attempt to create class with invalid description
-        let create_class_result = create_simple_class(LEAD_ORIGIN, ClassType::DescriptionTooLong);
-
-        // Failure checked
-        assert_failure(
-            create_class_result,
-            Error::<Runtime>::ClassDescriptionTooLong,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_class_description_is_too_short() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // An attempt to create class with invalid description
-        let create_class_result = create_simple_class(LEAD_ORIGIN, ClassType::DescriptionTooShort);
-
-        // Failure checked
-        assert_failure(
-            create_class_result,
-            Error::<Runtime>::ClassDescriptionTooShort,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_class_invalid_maximum_entities_count() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // An attempt to create class with invalid maximum entities count value
-        let create_class_result =
-            create_simple_class(LEAD_ORIGIN, ClassType::InvalidMaximumEntitiesCount);
-
-        // Failure checked
-        assert_failure(
-            create_class_result,
-            Error::<Runtime>::EntitiesNumberPerClassConstraintViolated,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_class_invalid_default_voucher_upper_bound() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // An attempt to create class with invalid default voucher upper bound value
-        let create_class_result =
-            create_simple_class(LEAD_ORIGIN, ClassType::InvalidDefaultVoucherUpperBound);
-
-        // Failure checked
-        assert_failure(
-            create_class_result,
-            Error::<Runtime>::NumberOfClassEntitiesPerActorConstraintViolated,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_class_per_controller_creation_limit_exceeds_overall_limit() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // An attempt to create class with per controller creation limit that exceeds overall entities creation limit
-        let create_class_result = create_simple_class(
-            LEAD_ORIGIN,
-            ClassType::DefaultVoucherUpperBoundExceedsMaximumEntitiesCount,
-        );
-
-        // Failure checked
-        assert_failure(
-            create_class_result,
-            Error::<Runtime>::PerControllerEntitiesCreationLimitExceedsOverallLimit,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_class_maintainers_limit_reached() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Add curator groups to runtime
-        for _ in 1..=MaxNumberOfMaintainersPerClass::get() {
-            assert_ok!(add_curator_group(LEAD_ORIGIN));
-        }
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // An attempt to create class with number of maintainers that exceeds runtime limit
-        let create_class_result =
-            create_simple_class(LEAD_ORIGIN, ClassType::MaintainersLimitReached);
-
-        // Failure checked
-        assert_failure(
-            create_class_result,
-            Error::<Runtime>::ClassMaintainersLimitReached,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_class_curator_group_does_not_exist() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // An attempt to create class with curator group maintainer, which does not exist in runtime
-        let create_class_result =
-            create_simple_class(LEAD_ORIGIN, ClassType::CuratorGroupDoesNotExist);
-
-        // Failure checked
-        assert_failure(
-            create_class_result,
-            Error::<Runtime>::CuratorGroupDoesNotExist,
-            number_of_events_before_call,
-        );
-    })
-}

+ 0 - 446
runtime-modules/content-directory/src/tests/create_entity.rs

@@ -1,446 +0,0 @@
-use super::*;
-
-#[test]
-fn create_entity_success() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Update class permissions to force any member be available to create entities
-        assert_ok!(update_class_permissions(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            Some(true),
-            None,
-            None,
-            None
-        ));
-
-        // Runtime state before tested call
-
-        assert_eq!(next_entity_id(), FIRST_ENTITY_ID);
-        assert!(!entity_exists(FIRST_ENTITY_ID));
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let actor = Actor::Member(FIRST_MEMBER_ID);
-
-        // Create entity
-        assert_ok!(create_entity(
-            FIRST_MEMBER_ORIGIN,
-            FIRST_CLASS_ID,
-            actor.clone()
-        ));
-
-        // Runtime tested state after call
-
-        // Ensure Class `current_number_of_entities` value updated succesfully
-        let mut class = create_class_with_default_permissions();
-        class.get_permissions_mut().set_any_member_status(true);
-        class.increment_entities_count();
-
-        assert_eq!(class_by_id(FIRST_CLASS_ID), class);
-
-        // Ensure  entity creation voucher with `default_entity_creation_voucher_upper_bound` for given entity controller created succesfully.
-        let mut entity_voucher =
-            EntityCreationVoucher::new(class.get_default_entity_creation_voucher_upper_bound());
-        entity_voucher.increment_created_entities_count();
-
-        let entity_controller = EntityController::<MemberId>::from_actor::<Runtime>(&actor);
-
-        assert_eq!(
-            entity_creation_vouchers(FIRST_CLASS_ID, &entity_controller),
-            entity_voucher,
-        );
-
-        // Ensure new entity created
-        let entity = Entity::<ClassId, MemberId, Hashed, EntityId, Nonce>::new(
-            entity_controller,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            BTreeMap::new(),
-        );
-
-        assert_eq!(entity_by_id(FIRST_ENTITY_ID), entity);
-
-        // Ensure `NextEntityId` storage value updated
-        assert_eq!(next_entity_id(), SECOND_ENTITY_ID);
-
-        let entity_created_event =
-            get_test_event(RawEvent::EntityCreated(actor, next_entity_id() - 1));
-
-        // Last event checked
-        assert_event(entity_created_event, number_of_events_before_call + 1);
-    })
-}
-
-#[test]
-fn create_entity_of_non_existent_class() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let actor = Actor::Lead;
-
-        // Make an attempt to create Entity of non existent Class
-        let create_entity_result = create_entity(LEAD_ORIGIN, UNKNOWN_CLASS_ID, actor);
-
-        // Failure checked
-        assert_failure(
-            create_entity_result,
-            Error::<Runtime>::ClassNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_entity_creation_limit_reached() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Update class permissions to force any member be available to create entities
-        assert_ok!(update_class_permissions(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            Some(true),
-            None,
-            None,
-            None
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut number_of_entities_created = 0;
-
-        // Create entities of the same Class entities limit per class reached
-        let create_entity_result = loop {
-            let create_entity_result = create_entity(
-                number_of_entities_created,
-                FIRST_CLASS_ID,
-                Actor::Member(number_of_entities_created),
-            );
-            if create_entity_result.is_err() {
-                break create_entity_result;
-            } else {
-                number_of_entities_created += 1;
-            }
-        };
-
-        // Runtime tested state after call
-
-        // Ensure number of entities created is equal to MaxNumberOfEntitiesPerClass runtime constraint.
-        assert_eq!(
-            number_of_entities_created,
-            MaxNumberOfEntitiesPerClass::get()
-        );
-
-        // Failure checked
-        assert_failure(
-            create_entity_result,
-            Error::<Runtime>::NumberOfEntitiesPerClassLimitReached,
-            number_of_events_before_call + number_of_entities_created as usize,
-        );
-    })
-}
-
-#[test]
-fn create_entity_creation_blocked_on_class_level() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Update class permissions to block entity creation on class level
-        assert_ok!(update_class_permissions(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            None,
-            Some(true),
-            None,
-            None
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let actor = Actor::Lead;
-
-        // Make an attempt to create Entity, when entiti creation was previously blocked on class level
-        let create_entity_result = create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor);
-
-        // Runtime tested state after call
-
-        // Failure checked
-        assert_failure(
-            create_entity_result,
-            Error::<Runtime>::EntitiesCreationBlocked,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_entity_lead_auth_failed() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let actor = Actor::Lead;
-
-        // Make an attempt to authorize as Lead under non lead origin
-        let create_entity_result = create_entity(FIRST_MEMBER_ORIGIN, FIRST_CLASS_ID, actor);
-
-        // Failure checked
-        assert_failure(
-            create_entity_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_entity_member_auth_failed() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Update class permissions to force any member be available to create entities
-        assert_ok!(update_class_permissions(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            Some(true),
-            None,
-            None,
-            None
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let actor = Actor::Member(UNKNOWN_MEMBER_ID);
-
-        // Make an attempt to authorize under non existent member id
-        let create_entity_result = create_entity(UNKNOWN_ORIGIN, FIRST_CLASS_ID, actor);
-
-        // Failure checked
-        assert_failure(
-            create_entity_result,
-            Error::<Runtime>::MemberAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_entity_actor_can_not_create_entities() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let actor = Actor::Member(UNKNOWN_MEMBER_ID);
-
-        // Make an attempt to create entity, authorizing as member in case, when members are not permitted to create entities on class level
-        let create_entity_result = create_entity(UNKNOWN_ORIGIN, FIRST_CLASS_ID, actor);
-
-        // Failure checked
-        assert_failure(
-            create_entity_result,
-            Error::<Runtime>::ActorCanNotCreateEntities,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_entity_unknown_curator_id() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Make curator group active
-        assert_ok!(set_curator_group_status(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            true
-        ));
-
-        // Add curator group as class maintainer
-        assert_ok!(add_maintainer_to_class(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            FIRST_CURATOR_GROUP_ID
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let actor = Actor::Curator(FIRST_CURATOR_GROUP_ID, UNKNOWN_CURATOR_ID);
-
-        // Make an attempt to create entity, authorizing as curator in group,
-        // in case, when provided curator id wasn`t added to respective curator group set
-        let create_entity_result = create_entity(FIRST_CURATOR_ORIGIN, FIRST_CLASS_ID, actor);
-
-        // Failure checked
-        assert_failure(
-            create_entity_result,
-            Error::<Runtime>::CuratorAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_entity_curator_group_is_not_active() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Add curator to group
-        assert_ok!(add_curator_to_group(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            FIRST_CURATOR_ID,
-        ));
-
-        // Add curator group as class maintainer
-        assert_ok!(add_maintainer_to_class(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            FIRST_CURATOR_GROUP_ID
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let actor = Actor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID);
-
-        // Make an attempt to create entity, authorizing as curator in group, in case, when
-        // corresponding curator group is not active. (default status of curator group right after creation)
-        let create_entity_result = create_entity(FIRST_CURATOR_ORIGIN, FIRST_CLASS_ID, actor);
-
-        // Failure checked
-        assert_failure(
-            create_entity_result,
-            Error::<Runtime>::CuratorGroupIsNotActive,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_entity_curator_not_found_in_curator_group() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Make curator group active
-        assert_ok!(set_curator_group_status(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            true
-        ));
-
-        // Add curator group as class maintainer
-        assert_ok!(add_maintainer_to_class(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            FIRST_CURATOR_GROUP_ID
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let actor = Actor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID);
-
-        // Make an attempt to create entity, authorizing as curator in group, in case, when
-        // curator was not added to corresponding curator group.
-        let create_entity_result = create_entity(FIRST_CURATOR_ORIGIN, FIRST_CLASS_ID, actor);
-
-        // Failure checked
-        assert_failure(
-            create_entity_result,
-            Error::<Runtime>::CuratorIsNotAMemberOfGivenCuratorGroup,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_entity_voucher_limit_reached() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let actor = Actor::Lead;
-
-        let mut number_of_entities_created = 0;
-
-        // Create entities until individual creation limit reached
-        let create_entity_result = loop {
-            let create_entity_result = create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone());
-            if create_entity_result.is_err() {
-                break create_entity_result;
-            } else {
-                number_of_entities_created += 1;
-            }
-        };
-
-        // Ensure number of entities created is equal to IndividualEntitiesCreationLimit runtime constraint.
-        assert_eq!(
-            number_of_entities_created,
-            IndividualEntitiesCreationLimit::get()
-        );
-
-        // Failure checked
-        assert_failure(
-            create_entity_result,
-            Error::<Runtime>::VoucherLimitReached,
-            number_of_events_before_call + number_of_entities_created as usize,
-        );
-    })
-}

+ 0 - 1271
runtime-modules/content-directory/src/tests/insert_at_entity_property_vector.rs

@@ -1,1271 +0,0 @@
-use super::*;
-
-#[test]
-fn insert_at_entity_property_vector_success() {
-    with_test_externalities(|| {
-        let actor = Actor::Lead;
-
-        // Add entity schemas support
-        let (mut first_entity, mut second_entity) = add_entity_schemas_support();
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_calls = System::events().len();
-
-        // Insert `InputValue` at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id`
-        let nonce = 0;
-        let index_in_property_vector = 1;
-        let input_value = InputValue::Reference(SECOND_ENTITY_ID);
-
-        assert_ok!(insert_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor.clone(),
-            FIRST_ENTITY_ID,
-            SECOND_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce
-        ));
-
-        // Runtime tested state after call
-
-        // Ensure first entity properties updated succesfully
-        if let Some(second_schema_old_property_value) = first_entity
-            .get_values_mut()
-            .get_mut(&SECOND_PROPERTY_ID)
-            .and_then(|property_value| property_value.as_vec_property_value_mut())
-        {
-            second_schema_old_property_value.insert_at(
-                index_in_property_vector,
-                StoredValue::Reference(SECOND_ENTITY_ID),
-            );
-        }
-
-        assert_eq!(first_entity, entity_by_id(FIRST_ENTITY_ID));
-
-        // Ensure reference counter of second entity updated succesfully
-        let inbound_rc = InboundReferenceCounter::new(4, true);
-        *second_entity.get_reference_counter_mut() = inbound_rc;
-
-        assert_eq!(second_entity, entity_by_id(SECOND_ENTITY_ID));
-
-        // Create side-effect
-        let side_effect = EntityReferenceCounterSideEffect::new(1, 1);
-
-        let inserted_at_vector_index_event = get_test_event(RawEvent::InsertedAtVectorIndex(
-            actor,
-            FIRST_ENTITY_ID,
-            SECOND_PROPERTY_ID,
-            index_in_property_vector,
-            nonce + 1,
-            Some((SECOND_ENTITY_ID, side_effect)),
-        ));
-
-        // Last event checked
-        assert_event(
-            inserted_at_vector_index_event,
-            number_of_events_before_calls + 1,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_entity_not_found() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::EntityNotFound,
-        );
-
-        // Create class reference schema
-        add_unique_class_reference_schema();
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 1;
-        let input_value = InputValue::Reference(FIRST_ENTITY_ID);
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id` in case when corresponding Entity does not exist
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor.clone(),
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::EntityNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_lead_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::LeadAuthFailed,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 1;
-        let input_value = InputValue::Reference(FIRST_ENTITY_ID);
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id` using unknown origin and lead actor
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            UNKNOWN_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_member_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::MemberAuthFailed,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-        let input_value = InputValue::Reference(FIRST_ENTITY_ID);
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id` using unknown origin and member actor
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            UNKNOWN_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::MemberAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_curator_group_is_not_active() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorAuthFailed,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, FIRST_CURATOR_ORIGIN);
-
-        // Make curator group inactive to block it from any entity operations
-        assert_ok!(set_curator_group_status(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            false
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-        let input_value = InputValue::Reference(FIRST_ENTITY_ID);
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id` using curator group, which is not active as actor
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            FIRST_CURATOR_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::CuratorGroupIsNotActive,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_curator_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorAuthFailed,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(
-            &Actor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
-            FIRST_CURATOR_ORIGIN,
-        );
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-        let input_value = InputValue::Reference(FIRST_ENTITY_ID);
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id` using unknown origin and curator actor
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            UNKNOWN_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::CuratorAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_curator_not_found_in_curator_group() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorNotFoundInCuratorGroup,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(
-            &Actor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
-            FIRST_CURATOR_ORIGIN,
-        );
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-        let input_value = InputValue::Reference(FIRST_ENTITY_ID);
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id`,
-        // using actor in group, which curator id was not added to corresponding group set
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            SECOND_CURATOR_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::CuratorIsNotAMemberOfGivenCuratorGroup,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_access_denied() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::EntityAccessDenied,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&Actor::Lead, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-        let input_value = InputValue::Reference(FIRST_ENTITY_ID);
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id`,
-        // using origin, which corresponding actor is neither entity maintainer, nor controller.
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            SECOND_CURATOR_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::EntityAccessDenied,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_values_locked_on_class_level() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::PropertyValuesLocked,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&Actor::Lead, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-        let input_value = InputValue::Reference(FIRST_ENTITY_ID);
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id`,
-        // in the case, when all property values were locked on Class level.
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::AllPropertiesWereLockedOnClassLevel,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_class_property_not_found() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-        let input_value = InputValue::Reference(FIRST_ENTITY_ID);
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id`,
-        // in the case, when Property under corresponding PropertyId was not found on Class level.
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::ClassPropertyNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_is_locked_for_given_actor() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create property
-        let property_type = PropertyType::<ClassId>::vec_reference(FIRST_CLASS_ID, true, 5);
-
-        let mut property = Property::<ClassId>::with_name_and_type(
-            (PropertyNameLengthConstraint::get().max() - 1) as usize,
-            property_type,
-            true,
-            false,
-        );
-
-        property.locking_policy = PropertyLockingPolicy::new(false, true);
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.clone(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-        let input_value = InputValue::Reference(FIRST_ENTITY_ID);
-
-        // Make an attempt to remove value at given `index_in_property_vector`
-        // from `VecStoredPropertyValue` under `in_class_schema_property_id`,
-        // under lead origin, which is current Entity controller, in the case,
-        // when corresponding class Property was locked from controller on Class level
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::ClassPropertyTypeLockedForGivenActor,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_unknown_entity_property_id() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create class reference schema
-        add_unique_class_reference_schema();
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-        let input_value = InputValue::Reference(FIRST_ENTITY_ID);
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id`,
-        // in the case, when property value was not added to current Entity values yet.
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::UnknownEntityPropertyId,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_value_under_given_index_is_not_a_vector() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create property
-        let property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().max() as usize,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, InputPropertyValue::default());
-
-        // Add schema support to the entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.clone(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-        let input_value = InputValue::Reference(FIRST_ENTITY_ID);
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id`,
-        // in the case, when entity property value corresponding to a given in_class_schema_property_id is not a vector.
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::PropertyValueUnderGivenIndexIsNotAVector,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_nonces_does_not_match() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 1;
-        let index_in_property_vector = 0;
-        let input_value = InputValue::Reference(FIRST_ENTITY_ID);
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id`,
-        // providing nonce that does not corresponding property value vector one.
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::PropertyValueVecNoncesDoesNotMatch,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_index_is_out_of_range() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create class reference schema
-        add_unique_class_reference_schema();
-
-        let entity_ids = vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID];
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(entity_ids.clone());
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.to_owned(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id` in case,
-        // when provided index_in_property_vector is out of range of the related vector
-        let nonce = 0;
-        let index_in_property_vector = entity_ids.len() as u16 + 1;
-        let input_value = InputValue::Reference(FIRST_ENTITY_ID);
-
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::EntityPropertyValueVectorIndexIsOutOfRange,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_is_too_long() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create class reference schema
-        add_unique_class_reference_schema();
-
-        let entity_ids = vec![FIRST_ENTITY_ID; VecMaxLengthConstraint::get() as usize];
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(entity_ids.clone());
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.to_owned(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id` in case,
-        // when corresponding property_vector can not contain more values
-        let nonce = 0;
-        let index_in_property_vector = 1;
-        let input_value = InputValue::Reference(FIRST_ENTITY_ID);
-
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::EntityPropertyValueVectorIsTooLong,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_text_prop_is_too_long() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create property
-        let property_type = PropertyType::<ClassId>::vec_text(
-            TextMaxLengthConstraint::get(),
-            VecMaxLengthConstraint::get(),
-        );
-
-        let property = Property::<ClassId>::with_name_and_type(
-            (PropertyNameLengthConstraint::get().max() - 1) as usize,
-            property_type,
-            true,
-            false,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let schema_property_value = InputPropertyValue::<Runtime>::vec_text(vec![]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.to_owned(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id` in case,
-        // when corresponding property text value is too long
-        let nonce = 0;
-        let index_in_property_vector = 0;
-        let input_value =
-            InputValue::Text(generate_text(TextMaxLengthConstraint::get() as usize + 1));
-
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::TextPropertyTooLong,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_hashed_text_prop_is_too_long() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let hashed_text_max_length_constraint = HashedTextMaxLengthConstraint::get();
-
-        // Create vec text hash property
-        let property_type = PropertyType::<ClassId>::vec_text_hash(
-            hashed_text_max_length_constraint,
-            VecMaxLengthConstraint::get(),
-        );
-
-        let property = Property::<ClassId>::with_name_and_type(
-            PropertyNameLengthConstraint::get().max() as usize,
-            property_type,
-            true,
-            false,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let schema_property_value = InputPropertyValue::<Runtime>::vec_text_to_hash(vec![]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.to_owned(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id` in case,
-        // when corresponding property text to hash value is too long
-        let nonce = 0;
-        let index_in_property_vector = 0;
-        let input_value = InputValue::TextToHash(generate_text(
-            hashed_text_max_length_constraint.unwrap() as usize + 1,
-        ));
-
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::HashedTextPropertyTooLong,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_prop_type_does_not_match_internal_vec_property() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create property
-        let property_type = PropertyType::<ClassId>::vec_text(
-            TextMaxLengthConstraint::get(),
-            VecMaxLengthConstraint::get(),
-        );
-
-        let property = Property::<ClassId>::with_name_and_type(
-            (PropertyNameLengthConstraint::get().max() - 1) as usize,
-            property_type,
-            true,
-            false,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let schema_property_value = InputPropertyValue::<Runtime>::vec_text(vec![]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.to_owned(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id` in case,
-        // when corresponding property type does not match internal vector property type
-        let nonce = 0;
-        let index_in_property_vector = 0;
-        let input_value = InputValue::default();
-
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::PropertyValueTypeDoesNotMatchInternalVectorType,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_referenced_entity_not_found() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id` in case,
-        // when corresponding input_value referes to unknown Entity
-        let nonce = 0;
-        let index_in_property_vector = 0;
-        let input_value = InputValue::Reference(SECOND_ENTITY_ID);
-
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::EntityNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_entity_can_not_be_referenced() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create first Entity of first Class
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create class reference schema and add corresponding schema support to the first Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Create second Entity of first Class
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Update second entity permissions to forbid it from being referencable
-        assert_ok!(update_entity_permissions(
-            LEAD_ORIGIN,
-            SECOND_ENTITY_ID,
-            None,
-            Some(false)
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id` in case,
-        // when corresponding Entity can not be referenced
-        let nonce = 0;
-        let index_in_property_vector = 0;
-        let input_value = InputValue::Reference(SECOND_ENTITY_ID);
-
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::EntityCanNotBeReferenced,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_same_controller_constraint_violation() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Update class permissions to force any member be available to create Entities
-        assert_ok!(update_class_permissions(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            Some(true),
-            None,
-            None,
-            None
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create first Entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create class reference schema and add corresponding schema support to the first  Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Create second Entity
-        assert_ok!(create_entity(
-            FIRST_MEMBER_ORIGIN,
-            FIRST_CLASS_ID,
-            Actor::Member(FIRST_MEMBER_ID)
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id` in case,
-        // when corresponding Entity can only be referenced from Entity with the same controller.
-        let nonce = 0;
-        let index_in_property_vector = 0;
-        let input_value = InputValue::Reference(SECOND_ENTITY_ID);
-
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::SameControllerConstraintViolation,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn insert_at_entity_property_vector_property_should_be_unique() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create first Entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create unique class reference schema and add corresponding schema support to the first Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Create second Entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create vec reference
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![FIRST_ENTITY_ID]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the second Entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.to_owned(),
-            SECOND_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to insert value at given `index_in_property_vector`
-        // into `VecStoredPropertyValue` under `in_class_schema_property_id` in case,
-        // when in result we`ll get required & unique property value vector,
-        // which is already added to another Entity of this Class.
-        let nonce = 0;
-        let index_in_property_vector = 0;
-        let input_value = InputValue::Reference(FIRST_ENTITY_ID);
-
-        let insert_at_entity_property_vector_result = insert_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            SECOND_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            input_value,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            insert_at_entity_property_vector_result,
-            Error::<Runtime>::PropertyValueShouldBeUnique,
-            number_of_events_before_call,
-        );
-    })
-}

+ 0 - 776
runtime-modules/content-directory/src/tests/remove_at_entity_property_vector.rs

@@ -1,776 +0,0 @@
-use super::*;
-
-#[test]
-fn remove_at_entity_property_vector_success() {
-    with_test_externalities(|| {
-        let actor = Actor::Lead;
-
-        // Add entity schemas support
-        let (mut first_entity, mut second_entity) = add_entity_schemas_support();
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_calls = System::events().len();
-
-        // Remove value at given `index_in_property_vector`
-        // from `PropertyValueVec` under in_class_schema_property_id
-        let nonce = 0;
-        let index_in_property_vector = 0;
-
-        assert_ok!(remove_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor.clone(),
-            FIRST_ENTITY_ID,
-            SECOND_PROPERTY_ID,
-            index_in_property_vector,
-            nonce
-        ));
-
-        // Runtime tested state after call
-
-        // Ensure first entity properties updated succesfully
-        if let Some(second_schema_old_property_value) = first_entity
-            .get_values_mut()
-            .get_mut(&SECOND_PROPERTY_ID)
-            .and_then(|property_value| property_value.as_vec_property_value_mut())
-        {
-            second_schema_old_property_value.remove_at(index_in_property_vector);
-        }
-
-        assert_eq!(first_entity, entity_by_id(FIRST_ENTITY_ID));
-
-        // Ensure reference counter of second entity updated succesfully
-        let inbound_rc = InboundReferenceCounter::new(2, true);
-        *second_entity.get_reference_counter_mut() = inbound_rc;
-
-        assert_eq!(second_entity, entity_by_id(SECOND_ENTITY_ID));
-
-        // Create side-effect
-        let side_effect = EntityReferenceCounterSideEffect::new(-1, -1);
-
-        let removed_at_vector_index_event = get_test_event(RawEvent::RemovedAtVectorIndex(
-            actor,
-            FIRST_ENTITY_ID,
-            SECOND_PROPERTY_ID,
-            index_in_property_vector,
-            nonce + 1,
-            Some((SECOND_ENTITY_ID, side_effect)),
-        ));
-
-        // Last event checked
-        assert_event(
-            removed_at_vector_index_event,
-            number_of_events_before_calls + 1,
-        );
-    })
-}
-
-#[test]
-fn remove_at_entity_property_vector_entity_not_found() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::EntityNotFound,
-        );
-
-        // Create class reference schema
-        add_unique_class_reference_schema();
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-
-        // Make an attempt to remove value at given `index_in_property_vector`
-        // from `PropertyValueVec` under `in_class_schema_property_id` in case when corresponding Entity does not exist
-        let remove_at_entity_property_vector_result = remove_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            remove_at_entity_property_vector_result,
-            Error::<Runtime>::EntityNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_at_entity_property_vector_lead_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::LeadAuthFailed,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-
-        // Make an attempt to remove value at given `index_in_property_vector`
-        // from `PropertyValueVec` under `in_class_schema_property_id` using unknown origin and lead actor
-        let remove_at_entity_property_vector_result = remove_at_entity_property_vector(
-            UNKNOWN_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            remove_at_entity_property_vector_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_at_entity_property_vector_member_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::MemberAuthFailed,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-
-        // Make an attempt to remove value at given `index_in_property_vector`
-        // from `PropertyValueVec` under `in_class_schema_property_id` using unknown origin and member actor
-        let remove_at_entity_property_vector_result = remove_at_entity_property_vector(
-            UNKNOWN_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            remove_at_entity_property_vector_result,
-            Error::<Runtime>::MemberAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_at_entity_property_vector_curator_group_is_not_active() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorAuthFailed,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, FIRST_CURATOR_ORIGIN);
-
-        // Make curator group inactive to block it from any entity operations
-        assert_ok!(set_curator_group_status(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            false
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-
-        // Make an attempt to remove value at given `index_in_property_vector`
-        // from `PropertyValueVec` under `in_class_schema_property_id` using curator group, which is not active as actor
-        let remove_at_entity_property_vector_result = remove_at_entity_property_vector(
-            FIRST_CURATOR_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            remove_at_entity_property_vector_result,
-            Error::<Runtime>::CuratorGroupIsNotActive,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_at_entity_property_vector_curator_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorAuthFailed,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, FIRST_CURATOR_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-
-        // Make an attempt to remove value at given `index_in_property_vector`
-        // from `PropertyValueVec` under `in_class_schema_property_id` using unknown origin and curator actor
-        let remove_at_entity_property_vector_result = remove_at_entity_property_vector(
-            UNKNOWN_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            remove_at_entity_property_vector_result,
-            Error::<Runtime>::CuratorAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_at_entity_property_vector_curator_not_found_in_curator_group() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorNotFoundInCuratorGroup,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(
-            &Actor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
-            FIRST_CURATOR_ORIGIN,
-        );
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-
-        // Make an attempt to remove value at given `index_in_property_vector`
-        // from `PropertyValueVec` under `in_class_schema_property_id`,
-        // using actor in group, which curator id was not added to corresponding group set
-        let remove_at_entity_property_vector_result = remove_at_entity_property_vector(
-            SECOND_CURATOR_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            remove_at_entity_property_vector_result,
-            Error::<Runtime>::CuratorIsNotAMemberOfGivenCuratorGroup,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_at_entity_property_vector_access_denied() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::EntityAccessDenied,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&Actor::Lead, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-
-        // Make an attempt to remove value at given `index_in_property_vector`
-        // from `PropertyValueVec` under `in_class_schema_property_id`,
-        // using origin, which corresponding actor is neither entity maintainer, nor controller.
-        let remove_at_entity_property_vector_result = remove_at_entity_property_vector(
-            SECOND_CURATOR_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            remove_at_entity_property_vector_result,
-            Error::<Runtime>::EntityAccessDenied,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_at_entity_property_vector_values_locked_on_class_level() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::PropertyValuesLocked,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&Actor::Lead, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-
-        // Make an attempt to remove value at given `index_in_property_vector`
-        // from `PropertyValueVec` under `in_class_schema_property_id`,
-        // in the case, when all property values were locked on Class level.
-        let remove_at_entity_property_vector_result = remove_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            remove_at_entity_property_vector_result,
-            Error::<Runtime>::AllPropertiesWereLockedOnClassLevel,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_at_entity_property_vector_class_property_not_found() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-
-        // Make an attempt to remove value at given `index_in_property_vector`
-        // from `PropertyValueVec` under `in_class_schema_property_id`,
-        // in the case, when Property under corresponding PropertyId was not found on Class level.
-        let remove_at_entity_property_vector_result = remove_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            remove_at_entity_property_vector_result,
-            Error::<Runtime>::ClassPropertyNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_at_entity_property_vector_is_locked_for_given_actor() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create property
-        let property_type = PropertyType::<ClassId>::vec_reference(FIRST_CLASS_ID, true, 5);
-
-        let mut property = Property::<ClassId>::with_name_and_type(
-            (PropertyNameLengthConstraint::get().max() - 1) as usize,
-            property_type,
-            true,
-            false,
-        );
-
-        property.locking_policy = PropertyLockingPolicy::new(false, true);
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.clone(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-
-        // Make an attempt to remove value at given `index_in_property_vector`
-        // from `PropertyValueVec` under `in_class_schema_property_id`,
-        // under lead origin, which is current Entity controller, in the case,
-        // when corresponding class Property was locked from controller on Class level
-        let remove_at_entity_property_vector_result = remove_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            remove_at_entity_property_vector_result,
-            Error::<Runtime>::ClassPropertyTypeLockedForGivenActor,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_at_entity_property_vector_unknown_entity_property_id() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create class reference schema
-        add_unique_class_reference_schema();
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-
-        // Make an attempt to remove value at given `index_in_property_vector`
-        // from `PropertyValueVec` under `in_class_schema_property_id`,
-        // in the case, when property value was not added to current Entity values yet.
-        let remove_at_entity_property_vector_result = remove_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            remove_at_entity_property_vector_result,
-            Error::<Runtime>::UnknownEntityPropertyId,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_at_entity_property_vector_value_under_given_index_is_not_a_vector() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create property
-        let property = Property::<ClassId>::default_with_name(
-            PropertyNameLengthConstraint::get().max() as usize,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, InputPropertyValue::default());
-
-        // Add schema support to the entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.clone(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-
-        // Make an attempt to remove value at given `index_in_property_vector`
-        // from `PropertyValueVec` under `in_class_schema_property_id`,
-        // in the case, when entity property value corresponding to a given in_class_schema_property_id is not a vector.
-        let remove_at_entity_property_vector_result = remove_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            remove_at_entity_property_vector_result,
-            Error::<Runtime>::PropertyValueUnderGivenIndexIsNotAVector,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_at_entity_property_vector_nonces_does_not_match() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&Actor::Lead, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 1;
-        let index_in_property_vector = 0;
-
-        // Make an attempt to remove value at given `index_in_property_vector`
-        // from `PropertyValueVec` under `in_class_schema_property_id`,
-        // providing nonce that does not corresponding property value vector one.
-        let remove_at_entity_property_vector_result = remove_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            remove_at_entity_property_vector_result,
-            Error::<Runtime>::PropertyValueVecNoncesDoesNotMatch,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_at_entity_property_vector_index_is_out_of_range() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create class reference schema
-        add_unique_class_reference_schema();
-
-        let entity_ids = vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID];
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(entity_ids.clone());
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.to_owned(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to remove value at given `index_in_property_vector`
-        // from `PropertyValueVec` under `in_class_schema_property_id` in case,
-        // when provided index_in_property_vector is out of range of the related vector
-        let nonce = 0;
-        let index_in_property_vector = entity_ids.len() as u16 + 1;
-
-        let remove_at_entity_property_vector_result = remove_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            remove_at_entity_property_vector_result,
-            Error::<Runtime>::EntityPropertyValueVectorIndexIsOutOfRange,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_at_entity_property_vector_property_should_be_unique() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create first Entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create unique class reference schema and add corresponding schema support to the first Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Create second Entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create vec reference
-        let schema_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![
-            FIRST_ENTITY_ID,
-            FIRST_ENTITY_ID,
-            FIRST_ENTITY_ID,
-        ]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the second Entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.to_owned(),
-            SECOND_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let nonce = 0;
-        let index_in_property_vector = 0;
-
-        // Make an attempt to remove value at given `index_in_property_vector`
-        // from `PropertyValueVec` under `in_class_schema_property_id` in case,
-        // when in result we`ll get required & unique property value vector,
-        // which is already added to another Entity of this Class.
-        let remove_at_entity_property_vector_result = remove_at_entity_property_vector(
-            LEAD_ORIGIN,
-            actor,
-            SECOND_ENTITY_ID,
-            FIRST_PROPERTY_ID,
-            index_in_property_vector,
-            nonce,
-        );
-
-        // Failure checked
-        assert_failure(
-            remove_at_entity_property_vector_result,
-            Error::<Runtime>::PropertyValueShouldBeUnique,
-            number_of_events_before_call,
-        );
-    })
-}

+ 0 - 131
runtime-modules/content-directory/src/tests/remove_curator_from_group.rs

@@ -1,131 +0,0 @@
-use super::*;
-
-#[test]
-fn remove_curator_from_group_success() {
-    with_test_externalities(|| {
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Add first curator to group
-        assert_ok!(add_curator_to_group(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            FIRST_CURATOR_ID
-        ));
-        // Add second curator to group
-        assert_ok!(add_curator_to_group(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            SECOND_CURATOR_ID
-        ));
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Remove first curator from group
-        assert_ok!(remove_curator_from_group(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            FIRST_CURATOR_ID
-        ));
-
-        // Runtime tested state after call
-
-        // Ensure group contains only second curator
-        let mut curator_group = CuratorGroup::default();
-        curator_group.get_curators_mut().insert(SECOND_CURATOR_ID);
-        assert_eq!(curator_group_by_id(FIRST_CURATOR_GROUP_ID), curator_group);
-
-        let curator_group_curator_removed_event = get_test_event(RawEvent::CuratorRemoved(
-            FIRST_CURATOR_GROUP_ID,
-            FIRST_CURATOR_ID,
-        ));
-
-        // Event checked
-        assert_event(
-            curator_group_curator_removed_event,
-            number_of_events_before_call + 1,
-        );
-    })
-}
-
-#[test]
-fn remove_curator_from_group_lead_auth_failed() {
-    with_test_externalities(|| {
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Add curator to group
-        assert_ok!(add_curator_to_group(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            FIRST_CURATOR_ID
-        ));
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to remove curator from group using non lead origin
-        let remove_curator_from_group_result = remove_curator_from_group(
-            FIRST_MEMBER_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            FIRST_CURATOR_ID,
-        );
-
-        // Failure checked
-        assert_failure(
-            remove_curator_from_group_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_curator_from_group_curator_is_not_a_member() {
-    with_test_externalities(|| {
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to remove curator that does not added to the provided curator group
-        let remove_curator_from_group_result =
-            remove_curator_from_group(LEAD_ORIGIN, FIRST_CURATOR_GROUP_ID, UNKNOWN_CURATOR_ID);
-
-        // Failure checked
-        assert_failure(
-            remove_curator_from_group_result,
-            Error::<Runtime>::CuratorIsNotAMemberOfGivenCuratorGroup,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_curator_from_non_existent_group() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to remove curator from group using non lead origin
-        let remove_curator_from_group_result =
-            remove_curator_from_group(LEAD_ORIGIN, UNKNOWN_CURATOR_GROUP_ID, FIRST_CURATOR_ID);
-
-        // Failure checked
-        assert_failure(
-            remove_curator_from_group_result,
-            Error::<Runtime>::CuratorGroupDoesNotExist,
-            number_of_events_before_call,
-        );
-    })
-}

+ 0 - 110
runtime-modules/content-directory/src/tests/remove_curator_group.rs

@@ -1,110 +0,0 @@
-use super::*;
-
-#[test]
-fn remove_curator_group_success() {
-    with_test_externalities(|| {
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        assert_ok!(remove_curator_group(LEAD_ORIGIN, FIRST_CURATOR_GROUP_ID));
-
-        // Runtime tested state after call
-
-        assert_eq!(next_curator_group_id(), SECOND_CURATOR_GROUP_ID);
-
-        // Ensure curator group removed
-        assert!(!curator_group_exists(FIRST_CURATOR_GROUP_ID));
-
-        let curator_group_removed_event =
-            get_test_event(RawEvent::CuratorGroupRemoved(FIRST_CURATOR_GROUP_ID));
-
-        // Event checked
-        assert_event(
-            curator_group_removed_event,
-            number_of_events_before_call + 1,
-        );
-    })
-}
-
-#[test]
-fn remove_curator_group_lead_auth_failed() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // An attemt to remove curator group from non lead origin
-        let remove_curator_group_result =
-            remove_curator_group(FIRST_MEMBER_ORIGIN, FIRST_CURATOR_GROUP_ID);
-
-        // Failure checked
-        assert_failure(
-            remove_curator_group_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_non_existent_curator_group() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // An attemt to remove non existent curator group
-        let remove_curator_group_result =
-            remove_curator_group(LEAD_ORIGIN, UNKNOWN_CURATOR_GROUP_ID);
-
-        // Failure checked
-        assert_failure(
-            remove_curator_group_result,
-            Error::<Runtime>::CuratorGroupDoesNotExist,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn curator_group_removal_forbidden() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Create class
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Add curator group as class maintainer
-        assert_ok!(add_maintainer_to_class(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            FIRST_CURATOR_GROUP_ID
-        ));
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // An attemt to remove curator group, that have classes maintained
-        let remove_curator_group_result = remove_curator_group(LEAD_ORIGIN, FIRST_CURATOR_ID);
-
-        // Failure checked
-        assert_failure(
-            remove_curator_group_result,
-            Error::<Runtime>::CuratorGroupRemovalForbidden,
-            number_of_events_before_call,
-        );
-    })
-}

+ 0 - 302
runtime-modules/content-directory/src/tests/remove_entity.rs

@@ -1,302 +0,0 @@
-use super::*;
-
-#[test]
-fn remove_entity_success() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Remove entity
-        assert_ok!(remove_entity(LEAD_ORIGIN, actor.clone(), FIRST_ENTITY_ID));
-
-        // Runtime tested state after call
-
-        // Ensure entity under corresponding id was succesfully removed from runtime storage
-        assert!(!entity_exists(FIRST_ENTITY_ID));
-
-        // Ensure number of entities_created under respective entity creation voucher decremented succesfully.
-        let entity_voucher = EntityCreationVoucher::new(IndividualEntitiesCreationLimit::get());
-
-        let entity_controller = EntityController::<MemberId>::from_actor::<Runtime>(&actor);
-
-        assert_eq!(
-            entity_creation_vouchers(FIRST_CLASS_ID, &entity_controller),
-            entity_voucher,
-        );
-
-        let entity_removed_event =
-            get_test_event(RawEvent::EntityRemoved(actor, next_entity_id() - 1));
-
-        // Last event checked
-        assert_event(entity_removed_event, number_of_events_before_call + 1);
-    })
-}
-
-#[test]
-fn remove_non_existent_entity() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::EntityNotFound,
-        );
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to remove Entity, which does not exist in runtime
-        let remove_entity_result = remove_entity(LEAD_ORIGIN, actor, UNKNOWN_ENTITY_ID);
-
-        // Failure checked
-        assert_failure(
-            remove_entity_result,
-            Error::<Runtime>::EntityNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_entity_lead_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::LeadAuthFailed,
-        );
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to remove entity under non lead origin
-        let remove_entity_result = remove_entity(UNKNOWN_ORIGIN, actor, FIRST_ENTITY_ID);
-
-        // Failure checked
-        assert_failure(
-            remove_entity_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_entity_member_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::MemberAuthFailed,
-        );
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to remove entity using unknown origin and member actor, which is current Entity controller
-        let remove_entity_result = remove_entity(UNKNOWN_ORIGIN, actor, FIRST_ENTITY_ID);
-
-        // Failure checked
-        assert_failure(
-            remove_entity_result,
-            Error::<Runtime>::MemberAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn create_entity_curator_group_is_not_active() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorAuthFailed,
-        );
-
-        // Make curator group inactive to block it from any entity operations
-        assert_ok!(set_curator_group_status(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            false
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to remove entity using curator group, which is not active as actor
-        let remove_entity_result = remove_entity(FIRST_CURATOR_ORIGIN, actor, FIRST_ENTITY_ID);
-
-        // Failure checked
-        assert_failure(
-            remove_entity_result,
-            Error::<Runtime>::CuratorGroupIsNotActive,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_entity_curator_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorAuthFailed,
-        );
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to remove entity under unknown origin and curator actor, which corresponding group is current entity controller
-        let remove_entity_result = remove_entity(UNKNOWN_ORIGIN, actor, FIRST_ENTITY_ID);
-
-        // Failure checked
-        assert_failure(
-            remove_entity_result,
-            Error::<Runtime>::CuratorAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_entity_curator_not_found_in_curator_group() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorNotFoundInCuratorGroup,
-        );
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to remove entity, using actor in group,
-        // which curator id was not added to corresponding group set
-        let remove_entity_result = remove_entity(SECOND_CURATOR_ORIGIN, actor, FIRST_ENTITY_ID);
-
-        // Failure checked
-        assert_failure(
-            remove_entity_result,
-            Error::<Runtime>::CuratorIsNotAMemberOfGivenCuratorGroup,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_entity_access_denied() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::EntityAccessDenied,
-        );
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to remove entity, using origin, which corresponding actor is neither entity maintainer, nor controller.
-        let remove_entity_result = remove_entity(SECOND_MEMBER_ORIGIN, actor, FIRST_ENTITY_ID);
-
-        // Failure checked
-        assert_failure(
-            remove_entity_result,
-            Error::<Runtime>::EntityAccessDenied,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_entity_removal_access_denied() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Add curator to group
-        assert_ok!(add_curator_to_group(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            FIRST_CURATOR_ID,
-        ));
-
-        // Make curator group active
-        assert_ok!(set_curator_group_status(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            true
-        ));
-
-        // Add curator group as class maintainer
-        assert_ok!(add_maintainer_to_class(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            FIRST_CURATOR_GROUP_ID
-        ));
-
-        // Runtime state before tested call
-
-        let actor = Actor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID);
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, Actor::Lead));
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to remove entity, using origin, which corresponding actor is not an entity controller
-        let remove_entity_result = remove_entity(FIRST_CURATOR_ORIGIN, actor, FIRST_ENTITY_ID);
-
-        // Failure checked
-        assert_failure(
-            remove_entity_result,
-            Error::<Runtime>::EntityRemovalAccessDenied,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_entity_rc_does_not_equal_to_zero() {
-    with_test_externalities(|| {
-        let actor = Actor::Lead;
-
-        // Create class, two corresponding entities and force first entity have schema support with property value referencing second entity
-        add_entity_schemas_support();
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to remove entity, which rc does not equal to zero
-        let remove_entity_result = remove_entity(LEAD_ORIGIN, actor, SECOND_ENTITY_ID);
-
-        // Failure checked
-        assert_failure(
-            remove_entity_result,
-            Error::<Runtime>::EntityRcDoesNotEqualToZero,
-            number_of_events_before_call,
-        );
-
-        // Remove first entity, which have property values referencing second one.
-        assert_ok!(remove_entity(LEAD_ORIGIN, actor, FIRST_ENTITY_ID));
-
-        // Succesfully perform second entity removal
-        assert_ok!(remove_entity(LEAD_ORIGIN, actor, SECOND_ENTITY_ID));
-    })
-}

+ 0 - 147
runtime-modules/content-directory/src/tests/remove_maintainer_from_class.rs

@@ -1,147 +0,0 @@
-use super::*;
-
-#[test]
-fn remove_maintainer_from_class_success() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Add first curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Add second curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Add first maintainer to class
-        assert_ok!(add_maintainer_to_class(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            FIRST_CURATOR_GROUP_ID
-        ));
-
-        // Add second maintainer to class
-        assert_ok!(add_maintainer_to_class(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            SECOND_CURATOR_GROUP_ID
-        ));
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Remove first maintainer from class
-        assert_ok!(remove_maintainer_from_class(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            FIRST_CURATOR_GROUP_ID
-        ));
-
-        // Runtime tested state after call
-
-        // Ensure curator_group removed from class maintainers set
-        let mut class = create_class_with_default_permissions();
-        class
-            .get_permissions_mut()
-            .get_maintainers_mut()
-            .insert(SECOND_CURATOR_GROUP_ID);
-        assert_eq!(class_by_id(FIRST_CLASS_ID), class);
-
-        let maintainer_removed_event = get_test_event(RawEvent::MaintainerRemoved(
-            FIRST_CLASS_ID,
-            FIRST_CURATOR_GROUP_ID,
-        ));
-
-        // Event checked
-        assert_event(maintainer_removed_event, number_of_events_before_call + 1);
-    })
-}
-
-#[test]
-fn remove_maintainer_from_class_lead_auth_failed() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Add maintainer to class
-        assert_ok!(add_maintainer_to_class(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            FIRST_CURATOR_GROUP_ID
-        ));
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to remove maintainer from class under non lead origin
-        let remove_maintainer_from_class_result = remove_maintainer_from_class(
-            FIRST_MEMBER_ORIGIN,
-            FIRST_CLASS_ID,
-            FIRST_CURATOR_GROUP_ID,
-        );
-
-        // Failure checked
-        assert_failure(
-            remove_maintainer_from_class_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_maintainer_from_non_existent_class() {
-    with_test_externalities(|| {
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to remove maintainer from non existent class
-        let remove_maintainer_from_class_result =
-            remove_maintainer_from_class(LEAD_ORIGIN, UNKNOWN_CLASS_ID, FIRST_CURATOR_GROUP_ID);
-
-        // Failure checked
-        assert_failure(
-            remove_maintainer_from_class_result,
-            Error::<Runtime>::ClassNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn remove_maintainer_that_was_not_added_to_class_maintainers_set() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to remove curator group maintainer, that was not added to corresponding class maintainers set yet
-        let remove_maintainer_from_class_result =
-            remove_maintainer_from_class(LEAD_ORIGIN, FIRST_CLASS_ID, UNKNOWN_CURATOR_GROUP_ID);
-
-        // Failure checked
-        assert_failure(
-            remove_maintainer_from_class_result,
-            Error::<Runtime>::MaintainerDoesNotExist,
-            number_of_events_before_call,
-        );
-    })
-}

+ 0 - 84
runtime-modules/content-directory/src/tests/set_curator_group_status.rs

@@ -1,84 +0,0 @@
-use super::*;
-
-#[test]
-fn set_curator_group_status_success() {
-    with_test_externalities(|| {
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Change curator group status
-        assert_ok!(set_curator_group_status(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            true
-        ));
-
-        // Runtime tested state after call
-
-        // Ensure curator group status changed
-        let mut curator_group = CuratorGroup::default();
-        curator_group.set_status(true);
-        assert_eq!(curator_group_by_id(FIRST_CURATOR_GROUP_ID), curator_group);
-
-        let curator_group_status_set_event = get_test_event(RawEvent::CuratorGroupStatusSet(
-            FIRST_CURATOR_GROUP_ID,
-            true,
-        ));
-
-        // Event checked
-        assert_event(
-            curator_group_status_set_event,
-            number_of_events_before_call + 1,
-        );
-    })
-}
-
-#[test]
-fn set_curator_group_status_lead_auth_failed() {
-    with_test_externalities(|| {
-        // Add curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // An attemt to change curator group status from non lead origin
-        let set_curator_group_status_result =
-            set_curator_group_status(FIRST_MEMBER_ORIGIN, FIRST_CURATOR_GROUP_ID, true);
-
-        // Failure checked
-        assert_failure(
-            set_curator_group_status_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn set_curator_group_status_for_non_existent_curator_group() {
-    with_test_externalities(|| {
-        // Runtime tested state before call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // An attemt to change curator group status for non existent curator group
-        let set_curator_group_status_result =
-            set_curator_group_status(LEAD_ORIGIN, FIRST_CURATOR_GROUP_ID, true);
-
-        // Failure checked
-        assert_failure(
-            set_curator_group_status_result,
-            Error::<Runtime>::CuratorGroupDoesNotExist,
-            number_of_events_before_call,
-        );
-    })
-}

+ 0 - 155
runtime-modules/content-directory/src/tests/transaction.rs

@@ -1,155 +0,0 @@
-use super::*;
-
-#[test]
-fn transaction_success() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create single reference property
-        let property_type_reference = Type::Reference(FIRST_CLASS_ID, true);
-        let property = Property::<ClassId>::with_name_and_type(
-            PropertyNameLengthConstraint::get().max() as usize,
-            PropertyType::Single(property_type_reference),
-            true,
-            false,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let operations = vec![
-            OperationType::CreateEntity(CreateEntityOperation {
-                class_id: FIRST_CLASS_ID,
-            }),
-            OperationType::AddSchemaSupportToEntity(AddSchemaSupportToEntityOperation {
-                entity_id: ParameterizedEntity::InternalEntityJustAdded(0), // index 0 (prior operation)
-                schema_id: 0,
-                parametrized_property_values: vec![ParametrizedClassPropertyValue {
-                    in_class_index: 0,
-                    value: ParametrizedPropertyValue::InternalEntityJustAdded(0),
-                }],
-            }),
-            OperationType::CreateEntity(CreateEntityOperation {
-                class_id: FIRST_CLASS_ID,
-            }),
-            OperationType::UpdatePropertyValues(UpdatePropertyValuesOperation {
-                entity_id: ParameterizedEntity::InternalEntityJustAdded(0), // index 0 (prior operation)
-                new_parametrized_property_values: vec![ParametrizedClassPropertyValue {
-                    in_class_index: 0,
-                    value: ParametrizedPropertyValue::InternalEntityJustAdded(2),
-                }],
-            }),
-        ];
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_calls = System::events().len();
-
-        let actor = Actor::Lead;
-
-        // Number of operations to be performed
-        let operations_count = operations.len();
-
-        // Complete transaction
-        assert_ok!(transaction(LEAD_ORIGIN, actor.clone(), operations));
-
-        // Runtime tested state after call
-
-        let transaction_completed_event = get_test_event(RawEvent::TransactionCompleted(actor));
-
-        // Last event checked
-        assert_event(
-            transaction_completed_event,
-            number_of_events_before_calls + operations_count + 1,
-        );
-    })
-}
-
-#[test]
-fn transaction_limit_reached() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let operation = OperationType::CreateEntity(CreateEntityOperation {
-            class_id: FIRST_CLASS_ID,
-        });
-
-        let operations =
-            vec![operation; MaxNumberOfOperationsDuringAtomicBatching::get() as usize + 1];
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let actor = Actor::Lead;
-
-        // Make an attempt to complete transaction with operations, which total number exceeds MaxNumberOfOperationsDuringAtomicBatching runtime constraint
-        let transaction_result = transaction(LEAD_ORIGIN, actor, operations);
-
-        // Failure checked
-        assert_failure(
-            transaction_result,
-            Error::<Runtime>::NumberOfOperationsDuringAtomicBatchingLimitReached,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn transaction_failed() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let operation = OperationType::CreateEntity(CreateEntityOperation {
-            class_id: FIRST_CLASS_ID,
-        });
-
-        let failed_operation = OperationType::CreateEntity(CreateEntityOperation {
-            class_id: UNKNOWN_CLASS_ID,
-        });
-
-        let operations = vec![
-            operation.clone(),
-            operation.clone(),
-            failed_operation,
-            operation,
-        ];
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let actor = Actor::Lead;
-
-        // Make an attempt to complete transaction with CreateEntity operation, when provided class_id does not exist on runtime level
-        let transaction_result = transaction(LEAD_ORIGIN, actor, operations.clone());
-
-        let failed_operation_index = 2;
-
-        // Failure checked
-
-        // Ensure  call result is equal to expected error
-        assert_err!(transaction_result, Error::<Runtime>::ClassNotFound);
-
-        let transaction_failed_event =
-            get_test_event(RawEvent::TransactionFailed(actor, failed_operation_index));
-
-        // Last event checked
-        assert_event(
-            transaction_failed_event,
-            // two operations succeded and one TransactionFailed event
-            number_of_events_before_call + operations[..failed_operation_index as usize].len() + 1,
-        );
-    })
-}

+ 0 - 738
runtime-modules/content-directory/src/tests/transfer_entity_ownership.rs

@@ -1,738 +0,0 @@
-use super::*;
-
-#[test]
-fn transfer_entity_ownership_success() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_calls = System::events().len();
-
-        // Used to ensure controller changed succesfully
-        let mut entity = entity_by_id(FIRST_ENTITY_ID);
-
-        let new_controller = EntityController::Member(FIRST_MEMBER_ID);
-
-        // Ensure Entity controller set to EntityController::Lead
-        assert!(entity
-            .get_permissions_ref()
-            .controller_is_equal_to(&EntityController::Lead));
-
-        // Transfer entity ownership to new controller
-        assert_ok!(transfer_entity_ownership(
-            LEAD_ORIGIN,
-            FIRST_ENTITY_ID,
-            new_controller.clone(),
-            // Given entity does not have property references with same_owner flag set
-            BTreeMap::new()
-        ));
-
-        // Runtime tested state after call
-
-        // Ensure Entity controller changed to the new_controller
-        entity
-            .get_permissions_mut()
-            .set_conroller(new_controller.clone());
-
-        assert!(entity
-            .get_permissions_ref()
-            .controller_is_equal_to(&new_controller));
-
-        let entity_ownership_transfered_event = get_test_event(
-            RawEvent::EntityOwnershipTransfered(FIRST_ENTITY_ID, new_controller, None),
-        );
-
-        // Last event checked
-        assert_event(
-            entity_ownership_transfered_event,
-            number_of_events_before_calls + 1,
-        );
-    })
-}
-
-#[test]
-fn transfer_entity_ownership_lead_auth_failed() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let new_controller = EntityController::Member(FIRST_MEMBER_ID);
-
-        // Make an attempt to transfer entity ownership to new controller under non lead origin
-        let transfer_entity_ownership_result = transfer_entity_ownership(
-            UNKNOWN_ORIGIN,
-            FIRST_ENTITY_ID,
-            new_controller,
-            // Given entity does not have property references with same_owner flag set
-            BTreeMap::new(),
-        );
-
-        // Failure checked
-        assert_failure(
-            transfer_entity_ownership_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn transfer_entity_ownership_entity_not_found() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let new_controller = EntityController::Member(FIRST_MEMBER_ID);
-
-        // Make an attempt to transfer entity ownership of non existent Entity
-        let transfer_entity_ownership_result = transfer_entity_ownership(
-            LEAD_ORIGIN,
-            FIRST_ENTITY_ID,
-            new_controller,
-            // Given entity does not have property references with same_owner flag set
-            BTreeMap::new(),
-        );
-
-        // Failure checked
-        assert_failure(
-            transfer_entity_ownership_result,
-            Error::<Runtime>::EntityNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn transfer_entity_ownership_provided_entity_controller_is_equal_to_the_current_one() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let new_controller = EntityController::Lead;
-
-        // Make an attempt to transfer entity ownership, providing new Entity controller, which is equal to the current one
-        let transfer_entity_ownership_result = transfer_entity_ownership(
-            LEAD_ORIGIN,
-            FIRST_ENTITY_ID,
-            new_controller,
-            // Given entity does not have property references with same_owner flag set
-            BTreeMap::new(),
-        );
-
-        // Failure checked
-        assert_failure(
-            transfer_entity_ownership_result,
-            Error::<Runtime>::ProvidedEntityControllerIsEqualToTheCurrentOne,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn transfer_entity_ownership_inbound_same_owner_rc_does_not_equal_to_zero() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        add_unique_class_reference_schema();
-
-        let actor = Actor::Lead;
-
-        // Create first entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create second entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the second Entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            SECOND_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let new_controller = EntityController::Member(FIRST_MEMBER_ID);
-
-        // Make an attempt to transfer ownership of Entity, which is referenced by property values
-        // of another entities with same owner flag set
-        let transfer_entity_ownership_result = transfer_entity_ownership(
-            LEAD_ORIGIN,
-            FIRST_ENTITY_ID,
-            new_controller,
-            // Given entity does not have property references with same_owner flag set
-            BTreeMap::new(),
-        );
-
-        // Failure checked
-        assert_failure(
-            transfer_entity_ownership_result,
-            Error::<Runtime>::EntityInboundSameOwnerRcDoesNotEqualToZero,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn transfer_entity_ownership_provided_property_value_ids_must_be_references_with_same_owner_flag_set(
-) {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        add_unique_class_reference_schema();
-
-        // Update class permissions to force any member be available to create Entities
-        assert_ok!(update_class_permissions(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            Some(true),
-            None,
-            None,
-            None
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create first entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create second entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![SECOND_ENTITY_ID, SECOND_ENTITY_ID]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the second Entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Create third entity
-        assert_ok!(create_entity(
-            FIRST_MEMBER_ORIGIN,
-            FIRST_CLASS_ID,
-            Actor::Member(FIRST_MEMBER_ID)
-        ));
-
-        let new_controller = EntityController::Member(FIRST_MEMBER_ID);
-
-        let schema_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![
-            THIRD_ENTITY_ID,
-            THIRD_ENTITY_ID,
-            THIRD_ENTITY_ID,
-        ]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(SECOND_PROPERTY_ID, schema_property_value);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to transfer ownership of Entity, providing new property value references with same owner flag set,
-        // which respective property ids are not references with same owner flag set on Class Property level
-        let transfer_entity_ownership_result = transfer_entity_ownership(
-            LEAD_ORIGIN,
-            FIRST_ENTITY_ID,
-            new_controller,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            transfer_entity_ownership_result,
-            Error::<Runtime>::AllProvidedPropertyValueIdsMustBeReferencesWithSameOwnerFlagSet,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn transfer_entity_ownership_provided_new_property_value_referencing_entity_that_can_not_be_referenced(
-) {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        add_unique_class_reference_schema();
-
-        // Update class permissions to force any member be available to create Entities
-        assert_ok!(update_class_permissions(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            Some(true),
-            None,
-            None,
-            None
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create first entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create second entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![SECOND_ENTITY_ID, SECOND_ENTITY_ID]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the second Entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Create third entity
-        assert_ok!(create_entity(
-            FIRST_MEMBER_ORIGIN,
-            FIRST_CLASS_ID,
-            Actor::Member(FIRST_MEMBER_ID)
-        ));
-
-        // Update third entity permissions to forbid it from being referencable
-        assert_ok!(update_entity_permissions(
-            LEAD_ORIGIN,
-            THIRD_ENTITY_ID,
-            None,
-            Some(false)
-        ));
-
-        let new_controller = EntityController::Member(FIRST_MEMBER_ID);
-
-        let schema_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![
-            THIRD_ENTITY_ID,
-            THIRD_ENTITY_ID,
-            THIRD_ENTITY_ID,
-        ]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to transfer ownership of Entity, providing new property value reference(s) with same owner flag set,
-        // which refer(s) Entity, that can not be referenced
-        let transfer_entity_ownership_result = transfer_entity_ownership(
-            LEAD_ORIGIN,
-            FIRST_ENTITY_ID,
-            new_controller,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            transfer_entity_ownership_result,
-            Error::<Runtime>::EntityCanNotBeReferenced,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn transfer_entity_ownership_provided_new_property_value_referencing_non_existent_entity() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        add_unique_class_reference_schema();
-
-        let actor = Actor::Lead;
-
-        // Create first entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create second entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![SECOND_ENTITY_ID, SECOND_ENTITY_ID]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the second Entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        let new_controller = EntityController::Member(FIRST_MEMBER_ID);
-
-        let schema_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![
-            THIRD_ENTITY_ID,
-            THIRD_ENTITY_ID,
-            THIRD_ENTITY_ID,
-        ]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to transfer ownership of Entity, providing new property value reference(s) with same owner flag set,
-        // which refer(s) to Entity that does not exist
-        let transfer_entity_ownership_result = transfer_entity_ownership(
-            LEAD_ORIGIN,
-            FIRST_ENTITY_ID,
-            new_controller,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            transfer_entity_ownership_result,
-            Error::<Runtime>::EntityNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn transfer_entity_ownership_provided_new_property_value_referencing_entity_controlled_by_another_actor(
-) {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        add_unique_class_reference_schema();
-
-        // Update class permissions to force any member be available to create Entities
-        assert_ok!(update_class_permissions(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            Some(true),
-            None,
-            None,
-            None
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create first entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create second entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![SECOND_ENTITY_ID, SECOND_ENTITY_ID]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the second Entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.to_owned(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Create third entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor));
-
-        let new_controller = EntityController::Member(FIRST_MEMBER_ID);
-
-        let schema_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![
-            THIRD_ENTITY_ID,
-            THIRD_ENTITY_ID,
-            THIRD_ENTITY_ID,
-        ]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to transfer ownership of Entity, providing new property value reference(s) with same owner flag set,
-        // which refer(s) Entity, controlled by another actor
-        let transfer_entity_ownership_result = transfer_entity_ownership(
-            LEAD_ORIGIN,
-            FIRST_ENTITY_ID,
-            new_controller,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            transfer_entity_ownership_result,
-            Error::<Runtime>::SameControllerConstraintViolation,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn transfer_entity_ownership_required_property_was_not_provided() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        add_unique_class_reference_schema();
-
-        // Update class permissions to force any member be available to create Entities
-        assert_ok!(update_class_permissions(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            Some(true),
-            None,
-            None,
-            None
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create first entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create second entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![SECOND_ENTITY_ID, SECOND_ENTITY_ID]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the second Entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Create third entity
-        assert_ok!(create_entity(
-            FIRST_MEMBER_ORIGIN,
-            FIRST_CLASS_ID,
-            Actor::Member(FIRST_MEMBER_ID)
-        ));
-
-        let new_controller = EntityController::Member(FIRST_MEMBER_ID);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to transfer ownership of Entity without providing required
-        // new property value references with same owner flag set
-        let transfer_entity_ownership_result = transfer_entity_ownership(
-            LEAD_ORIGIN,
-            FIRST_ENTITY_ID,
-            new_controller,
-            BTreeMap::new(),
-        );
-
-        // Failure checked
-        assert_failure(
-            transfer_entity_ownership_result,
-            Error::<Runtime>::MissingRequiredProperty,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn transfer_entity_ownership_unique_constraint_violation() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create unique reference property with same_controller flag set
-        let property_type = PropertyType::<ClassId>::vec_reference(
-            FIRST_CLASS_ID,
-            true,
-            VecMaxLengthConstraint::get(),
-        );
-
-        let property = Property::<ClassId>::with_name_and_type(
-            PropertyNameLengthConstraint::get().max() as usize,
-            property_type,
-            true,
-            true,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        // Update class permissions to force any member be available to create Entities
-        assert_ok!(update_class_permissions(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            Some(true),
-            None,
-            None,
-            None
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create first entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create second entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let first_schema_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![SECOND_ENTITY_ID, SECOND_ENTITY_ID]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, first_schema_property_value);
-
-        // Add schema support to the first Entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.to_owned(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        let second_schema_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![
-            SECOND_ENTITY_ID,
-            SECOND_ENTITY_ID,
-            SECOND_ENTITY_ID,
-        ]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, second_schema_property_value);
-
-        // Add schema support to the second Entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor,
-            SECOND_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Create third entity
-        assert_ok!(create_entity(
-            FIRST_MEMBER_ORIGIN,
-            FIRST_CLASS_ID,
-            Actor::Member(FIRST_MEMBER_ID)
-        ));
-
-        let new_controller = EntityController::Member(FIRST_MEMBER_ID);
-
-        let schema_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![
-            THIRD_ENTITY_ID,
-            THIRD_ENTITY_ID,
-            THIRD_ENTITY_ID,
-        ]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        assert_ok!(transfer_entity_ownership(
-            LEAD_ORIGIN,
-            FIRST_ENTITY_ID,
-            new_controller.clone(),
-            schema_property_values.clone(),
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to transfer ownership of Entity, providing new property value reference(s)
-        // with same owner flag set, which are identical to thouse, are already added to the another Entity of this Class,
-        // though should be unique on Class Property level
-        let transfer_entity_ownership_result = transfer_entity_ownership(
-            LEAD_ORIGIN,
-            SECOND_ENTITY_ID,
-            new_controller,
-            schema_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            transfer_entity_ownership_result,
-            Error::<Runtime>::PropertyValueShouldBeUnique,
-            number_of_events_before_call,
-        );
-    })
-}

+ 0 - 227
runtime-modules/content-directory/src/tests/update_class_permissions.rs

@@ -1,227 +0,0 @@
-use super::*;
-
-#[test]
-fn update_class_permissions_success() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Add first curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Add second curator group
-        assert_ok!(add_curator_group(LEAD_ORIGIN));
-
-        // Runtime tested state before call
-
-        let mut class_permissions = ClassPermissions::default();
-
-        // Ensure class permissions of newly created Class are equal to default ones
-
-        assert_eq!(
-            class_by_id(FIRST_CLASS_ID).get_permissions(),
-            class_permissions
-        );
-
-        // Ensure curator groups maintain no classes.
-
-        assert_eq!(
-            curator_group_by_id(FIRST_CURATOR_GROUP_ID).get_number_of_classes_maintained(),
-            0
-        );
-
-        assert_eq!(
-            curator_group_by_id(SECOND_CURATOR_GROUP_ID).get_number_of_classes_maintained(),
-            0
-        );
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut maintainers =
-            BTreeSet::from_iter(vec![FIRST_CURATOR_GROUP_ID, SECOND_CURATOR_GROUP_ID]);
-
-        // Update class permissions
-        assert_ok!(update_class_permissions(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            None,
-            Some(true),
-            None,
-            Some(maintainers.clone())
-        ));
-
-        // Runtime tested state after call
-
-        // Ensure class permissions updated succesfully
-
-        *class_permissions.get_maintainers_mut() = maintainers;
-        class_permissions.set_entity_creation_blocked(true);
-
-        assert_eq!(
-            class_by_id(FIRST_CLASS_ID).get_permissions(),
-            class_permissions
-        );
-
-        let class_permissions_updated_event =
-            get_test_event(RawEvent::ClassPermissionsUpdated(FIRST_CLASS_ID));
-
-        // Ensure number of classes maintained by curator groups updated succesfully.
-
-        assert_eq!(
-            curator_group_by_id(FIRST_CURATOR_GROUP_ID).get_number_of_classes_maintained(),
-            1
-        );
-
-        assert_eq!(
-            curator_group_by_id(SECOND_CURATOR_GROUP_ID).get_number_of_classes_maintained(),
-            1
-        );
-
-        maintainers = BTreeSet::from_iter(vec![SECOND_CURATOR_GROUP_ID]);
-
-        // Update class permissions
-        assert_ok!(update_class_permissions(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            None,
-            Some(true),
-            None,
-            Some(maintainers.clone())
-        ));
-
-        // Ensure number of classes maintained by curator groups updated succesfully.
-
-        assert_eq!(
-            curator_group_by_id(FIRST_CURATOR_GROUP_ID).get_number_of_classes_maintained(),
-            0
-        );
-
-        assert_eq!(
-            curator_group_by_id(SECOND_CURATOR_GROUP_ID).get_number_of_classes_maintained(),
-            1
-        );
-
-        // Event checked
-        assert_event(
-            class_permissions_updated_event,
-            number_of_events_before_call + 2,
-        );
-    })
-}
-
-#[test]
-fn update_class_permissions_lead_auth_failed() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to update class permissions under non lead origin
-        let update_class_permissions_result = update_class_permissions(
-            FIRST_MEMBER_ORIGIN,
-            FIRST_CLASS_ID,
-            None,
-            Some(true),
-            None,
-            None,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_class_permissions_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_class_permissions_of_non_existent_class() {
-    with_test_externalities(|| {
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to update class permissions of non existent class
-        let update_class_permissions_result =
-            update_class_permissions(LEAD_ORIGIN, FIRST_CLASS_ID, None, Some(true), None, None);
-
-        // Failure checked
-        assert_failure(
-            update_class_permissions_result,
-            Error::<Runtime>::ClassNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_class_permissions_curator_group_does_not_exist() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let maintainers = BTreeSet::from_iter(vec![UNKNOWN_CURATOR_GROUP_ID]);
-
-        // Make an attempt to update class permissions, providing curator group maintainers which aren`t exist in runtime yet
-        let update_class_permissions_result = update_class_permissions(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            None,
-            Some(true),
-            None,
-            Some(maintainers),
-        );
-
-        // Failure checked
-        assert_failure(
-            update_class_permissions_result,
-            Error::<Runtime>::CuratorGroupDoesNotExist,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_class_permissions_maintainers_limit_reached() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Add curator groups, which total number exceeds MaxNumberOfMaintainersPerClass runtime limit
-        // and initialize class maintainers set with their respective ids
-        let mut maintainers = BTreeSet::new();
-        (1..=(MaxNumberOfMaintainersPerClass::get() + 1))
-            .into_iter()
-            .for_each(|curator_group_id| {
-                assert_ok!(add_curator_group(LEAD_ORIGIN));
-                maintainers.insert(curator_group_id as CuratorGroupId);
-            });
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to update class permissions, providing curator group maintainers,
-        // which total number exceeds MaxNumberOfMaintainersPerClass runtime limit
-        let update_class_permissions_result = update_class_permissions(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            None,
-            Some(true),
-            None,
-            Some(maintainers),
-        );
-
-        // Failure checked
-        assert_failure(
-            update_class_permissions_result,
-            Error::<Runtime>::ClassMaintainersLimitReached,
-            number_of_events_before_call,
-        );
-    })
-}

+ 0 - 145
runtime-modules/content-directory/src/tests/update_class_schema_status.rs

@@ -1,145 +0,0 @@
-use super::*;
-
-#[test]
-fn update_class_schema_status_success() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        let property =
-            Property::default_with_name(PropertyNameLengthConstraint::get().max() as usize);
-
-        // Add class schema (default class schema active flag set true)
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property.clone()]
-        ));
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        assert_ok!(update_class_schema_status(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            FIRST_SCHEMA_ID,
-            false
-        ));
-
-        // Runtime tested state after call
-
-        // Ensure class schema status updated succesfully
-        let mut class = create_class_with_default_permissions();
-        let mut schema = Schema::new(BTreeSet::from_iter(vec![FIRST_PROPERTY_ID].into_iter()));
-
-        schema.set_status(false);
-        class.set_properties(vec![property]);
-        *class.get_schemas_mut() = vec![schema];
-
-        assert_eq!(class_by_id(FIRST_CLASS_ID), class);
-
-        let class_schema_status_updated_event = get_test_event(RawEvent::ClassSchemaStatusUpdated(
-            FIRST_CLASS_ID,
-            FIRST_SCHEMA_ID,
-            false,
-        ));
-
-        // Last event checked
-        assert_event(
-            class_schema_status_updated_event,
-            number_of_events_before_call + 1,
-        );
-    })
-}
-
-#[test]
-fn update_class_schema_status_lead_auth_failed() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        let property =
-            Property::default_with_name(PropertyNameLengthConstraint::get().max() as usize);
-
-        // Add class schema (default class schema active flag set true)
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // make an attempt to update class schema status under non lead origin
-        let update_class_schema_status_result =
-            update_class_schema_status(FIRST_MEMBER_ORIGIN, FIRST_CLASS_ID, FIRST_SCHEMA_ID, false);
-
-        // Failure checked
-        assert_failure(
-            update_class_schema_status_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_class_schema_status_of_non_existent_class() {
-    with_test_externalities(|| {
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to update class schema status of non existent class
-        let update_class_schema_status_result =
-            update_class_schema_status(LEAD_ORIGIN, UNKNOWN_CLASS_ID, FIRST_SCHEMA_ID, false);
-
-        // Failure checked
-        assert_failure(
-            update_class_schema_status_result,
-            Error::<Runtime>::ClassNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_class_schema_status_for_non_existent_schema() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime tested state before call
-
-        let property =
-            Property::default_with_name(PropertyNameLengthConstraint::get().max() as usize);
-
-        // Add class schema (default class schema active flag set true)
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to update  status of Schema, which does not exist in this Class yet.
-        let update_class_schema_status_result =
-            update_class_schema_status(LEAD_ORIGIN, FIRST_CLASS_ID, UNKNOWN_SCHEMA_ID, false);
-
-        // Failure checked
-        assert_failure(
-            update_class_schema_status_result,
-            Error::<Runtime>::UnknownClassSchemaId,
-            number_of_events_before_call,
-        );
-    })
-}

+ 0 - 197
runtime-modules/content-directory/src/tests/update_entity_creation_voucher.rs

@@ -1,197 +0,0 @@
-use super::*;
-
-#[test]
-fn create_entity_creation_voucher_success() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime state before tested call
-
-        let entity_controller = EntityController::Member(FIRST_MEMBER_ID);
-        assert!(!entity_creation_voucher_exists(
-            FIRST_CLASS_ID,
-            &entity_controller
-        ));
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Create entities creation voucher for chosen controller
-        assert_ok!(update_entity_creation_voucher(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            entity_controller.clone(),
-            IndividualEntitiesCreationLimit::get()
-        ));
-
-        // Runtime tested state after call
-
-        // Ensure entity creation voucher for chosen controller created succesfully
-        let entity_voucher = EntityCreationVoucher::new(IndividualEntitiesCreationLimit::get());
-
-        assert_eq!(
-            entity_creation_vouchers(FIRST_CLASS_ID, &entity_controller),
-            entity_voucher,
-        );
-
-        let entity_creation_voucher_created_event = get_test_event(
-            RawEvent::EntityCreationVoucherCreated(entity_controller, entity_voucher),
-        );
-
-        // Last event checked
-        assert_event(
-            entity_creation_voucher_created_event,
-            number_of_events_before_call + 1,
-        );
-    })
-}
-
-#[test]
-fn update_entity_creation_voucher_success() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Member(FIRST_MEMBER_ID);
-
-        // Update class permissions to force any member be available to create entities
-        assert_ok!(update_class_permissions(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            Some(true),
-            None,
-            None,
-            None
-        ));
-
-        let entity_controller = EntityController::<MemberId>::from_actor::<Runtime>(&actor);
-
-        // Create entity
-        assert_ok!(create_entity(FIRST_MEMBER_ORIGIN, FIRST_CLASS_ID, actor));
-
-        // Runtime state before tested call
-
-        let mut entity_creation_voucher =
-            entity_creation_vouchers(FIRST_CLASS_ID, &entity_controller);
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Update entities creation voucher for chosen controller
-        let new_maximum_entities_count = entity_creation_voucher.maximum_entities_count - 1;
-        assert_ok!(update_entity_creation_voucher(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            entity_controller.clone(),
-            new_maximum_entities_count
-        ));
-
-        // Runtime tested state after call
-
-        // Ensure  entity creation voucher for chosen controller updated succesfully
-        entity_creation_voucher.set_maximum_entities_count(new_maximum_entities_count);
-        assert_eq!(
-            entity_creation_vouchers(FIRST_CLASS_ID, &entity_controller),
-            entity_creation_voucher
-        );
-
-        let entity_creation_voucher_created_event = get_test_event(
-            RawEvent::EntityCreationVoucherUpdated(entity_controller, entity_creation_voucher),
-        );
-
-        // Last event checked
-        assert_event(
-            entity_creation_voucher_created_event,
-            number_of_events_before_call + 1,
-        );
-    })
-}
-
-#[test]
-fn update_entity_creation_voucher_lead_auth_failed() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime state before tested call
-
-        let entity_controller = EntityController::Member(FIRST_MEMBER_ID);
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to create entities creation voucher for chosen controller under non lead origin
-        let update_entity_creation_voucher_result = update_entity_creation_voucher(
-            FIRST_MEMBER_ORIGIN,
-            FIRST_CLASS_ID,
-            entity_controller,
-            IndividualEntitiesCreationLimit::get(),
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_creation_voucher_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_creation_voucher_class_does_not_exist() {
-    with_test_externalities(|| {
-        // Runtime state before tested call
-
-        let entity_controller = EntityController::Member(FIRST_MEMBER_ID);
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to create entities creation voucher for chosen controller and non existent class
-        let update_entity_creation_voucher_result = update_entity_creation_voucher(
-            LEAD_ORIGIN,
-            UNKNOWN_CLASS_ID,
-            entity_controller,
-            IndividualEntitiesCreationLimit::get(),
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_creation_voucher_result,
-            Error::<Runtime>::ClassNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_creation_voucher_individual_creation_limit_exceed() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime state before tested call
-
-        let entity_controller = EntityController::Member(FIRST_MEMBER_ID);
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to create entities creation voucher for chosen controller with maximum_entities_count
-        // value that exceeds IndividualEntitiesCreationLimit
-        let update_entity_creation_voucher_result = update_entity_creation_voucher(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            entity_controller,
-            IndividualEntitiesCreationLimit::get() + 1,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_creation_voucher_result,
-            Error::<Runtime>::NumberOfClassEntitiesPerActorConstraintViolated,
-            number_of_events_before_call,
-        );
-    })
-}

+ 0 - 104
runtime-modules/content-directory/src/tests/update_entity_permissions.rs

@@ -1,104 +0,0 @@
-use super::*;
-
-#[test]
-fn update_entity_permissions_success() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor));
-
-        // Runtime state before tested call
-
-        // Ensure entity permissions of newly created Entity are equal to default ones.
-        let mut entity_permissions = EntityPermissions::default();
-        assert_eq!(
-            entity_by_id(FIRST_ENTITY_ID).get_permissions(),
-            entity_permissions
-        );
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Update entity permissions for chosen entity
-        assert_ok!(update_entity_permissions(
-            LEAD_ORIGIN,
-            FIRST_ENTITY_ID,
-            None,
-            Some(false)
-        ));
-
-        // Runtime tested state after call
-
-        entity_permissions.set_referencable(false);
-        assert_eq!(
-            entity_by_id(FIRST_ENTITY_ID).get_permissions(),
-            entity_permissions
-        );
-
-        let entity_permissions_updated_event =
-            get_test_event(RawEvent::EntityPermissionsUpdated(FIRST_ENTITY_ID));
-
-        // Last event checked
-        assert_event(
-            entity_permissions_updated_event,
-            number_of_events_before_call + 1,
-        );
-    })
-}
-
-#[test]
-fn update_entity_permissions_lead_auth_failed() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to update entity permissions for chosen entity under non lead origin
-        let update_entity_permissions_result =
-            update_entity_permissions(FIRST_MEMBER_ORIGIN, FIRST_ENTITY_ID, None, Some(false));
-
-        // Failure checked
-        assert_failure(
-            update_entity_permissions_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_permissions_of_non_existent_entity() {
-    with_test_externalities(|| {
-        // Create simple class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        // Make an attempt to update entity permissions for chosen entity under non lead origin
-        let update_entity_permissions_result =
-            update_entity_permissions(LEAD_ORIGIN, UNKNOWN_ENTITY_ID, None, Some(false));
-
-        // Failure checked
-        assert_failure(
-            update_entity_permissions_result,
-            Error::<Runtime>::EntityNotFound,
-            number_of_events_before_call,
-        );
-    })
-}

+ 0 - 1025
runtime-modules/content-directory/src/tests/update_entity_property_values.rs

@@ -1,1025 +0,0 @@
-use super::*;
-
-#[test]
-fn update_entity_property_values_success() {
-    with_test_externalities(|| {
-        let actor = Actor::Lead;
-
-        // Add entity schemas support
-        let (mut first_entity, mut second_entity) = add_entity_schemas_support();
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_calls = System::events().len();
-
-        let mut second_schema_new_property_values = BTreeMap::new();
-        let second_schema_new_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![SECOND_ENTITY_ID, SECOND_ENTITY_ID]);
-
-        second_schema_new_property_values
-            .insert(SECOND_PROPERTY_ID, second_schema_new_property_value.clone());
-
-        // Update entity property values
-        assert_ok!(update_entity_property_values(
-            LEAD_ORIGIN,
-            actor.clone(),
-            FIRST_ENTITY_ID,
-            second_schema_new_property_values
-        ));
-
-        // Runtime tested state after call
-
-        // Ensure first entity properties updated succesfully
-        if let Some(second_schema_old_property_value) =
-            first_entity.get_values_mut().get_mut(&SECOND_PROPERTY_ID)
-        {
-            second_schema_old_property_value.update(second_schema_new_property_value.into());
-        }
-
-        assert_eq!(first_entity, entity_by_id(FIRST_ENTITY_ID));
-
-        // Ensure reference counter of second entity updated succesfully
-        let inbound_rc = InboundReferenceCounter::new(2, true);
-        *second_entity.get_reference_counter_mut() = inbound_rc;
-
-        assert_eq!(second_entity, entity_by_id(SECOND_ENTITY_ID));
-
-        // Create side-effect
-        let side_effect = EntityReferenceCounterSideEffect::atomic(true, DeltaMode::Decrement);
-        let mut side_effects = ReferenceCounterSideEffects::default();
-        side_effects.insert(SECOND_ENTITY_ID, side_effect);
-
-        let entity_property_values_updated_event = get_test_event(
-            RawEvent::EntityPropertyValuesUpdated(actor, FIRST_ENTITY_ID, Some(side_effects)),
-        );
-
-        // Last event checked
-        assert_event(
-            entity_property_values_updated_event,
-            number_of_events_before_calls + 1,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_entity_not_found() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::EntityNotFound,
-        );
-
-        // Create class reference schema
-        add_unique_class_reference_schema();
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID]);
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values in case when corresponding Entity does not exist
-        let update_entity_property_values_result = update_entity_property_values(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::EntityNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_lead_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::LeadAuthFailed,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID]);
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values using unknown origin and lead actor
-        let update_entity_property_values_result = update_entity_property_values(
-            UNKNOWN_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::LeadAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_member_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::MemberAuthFailed,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID]);
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values using unknown origin and member actor
-        let update_entity_property_values_result = update_entity_property_values(
-            UNKNOWN_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::MemberAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_curator_group_is_not_active() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorAuthFailed,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(
-            &Actor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
-            FIRST_CURATOR_ORIGIN,
-        );
-
-        // Make curator group inactive to block it from any entity operations
-        assert_ok!(set_curator_group_status(
-            LEAD_ORIGIN,
-            FIRST_CURATOR_GROUP_ID,
-            false
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID]);
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values using curator group, which is not active as actor
-        let update_entity_property_values_result = update_entity_property_values(
-            FIRST_CURATOR_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::CuratorGroupIsNotActive,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_curator_auth_failed() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorAuthFailed,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(
-            &Actor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
-            FIRST_CURATOR_ORIGIN,
-        );
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID]);
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values using unknown origin and curator actor
-        let update_entity_property_values_result = update_entity_property_values(
-            UNKNOWN_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::CuratorAuthFailed,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_curator_not_found_in_curator_group() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::CuratorNotFoundInCuratorGroup,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(
-            &Actor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
-            FIRST_CURATOR_ORIGIN,
-        );
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID]);
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values using actor in group, which curator id was not added to corresponding group set
-        let update_entity_property_values_result = update_entity_property_values(
-            SECOND_CURATOR_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::CuratorIsNotAMemberOfGivenCuratorGroup,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_entity_access_denied() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::EntityAccessDenied,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&Actor::Lead, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID]);
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values using actor in group,
-        // using origin, which corresponding actor is neither entity maintainer, nor controller.
-        let update_entity_property_values_result = update_entity_property_values(
-            SECOND_CURATOR_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::EntityAccessDenied,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_locked_on_class_level() {
-    with_test_externalities(|| {
-        let actor = emulate_entity_access_state_for_failure_case(
-            EntityAccessStateFailureType::PropertyValuesLocked,
-        );
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&Actor::Lead, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID]);
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values using actor in group,
-        // in the case, when all property values were locked on Class level.
-        let update_entity_property_values_result = update_entity_property_values(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::AllPropertiesWereLockedOnClassLevel,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_is_locked_for_given_actor() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create property
-        let property_type = PropertyType::<ClassId>::vec_reference(FIRST_CLASS_ID, true, 5);
-
-        let mut property = Property::<ClassId>::with_name_and_type(
-            (PropertyNameLengthConstraint::get().max() - 1) as usize,
-            property_type,
-            true,
-            false,
-        );
-
-        property.locking_policy = PropertyLockingPolicy::new(false, true);
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create second entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let schema_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![
-            FIRST_ENTITY_ID,
-            FIRST_ENTITY_ID,
-            FIRST_ENTITY_ID,
-        ]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.clone(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID]);
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values
-        // under lead origin, which is current Entity controller, in the case,
-        // when corresponding class Property was locked from controller on Class level
-        let update_entity_property_values_result = update_entity_property_values(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::ClassPropertyTypeLockedForGivenActor,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_unknown_entity_property_id() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID]);
-
-        schema_new_property_values.insert(SECOND_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values in the case, when Property
-        // under corresponding property id was not added to the current Entity yet
-        let update_entity_property_values_result = update_entity_property_values(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::UnknownEntityPropertyId,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_prop_value_do_not_match_type() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value = InputPropertyValue::<Runtime>::default();
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values in the case, providing property values,
-        // some of which do not match Class level Property Type
-        let update_entity_property_values_result = update_entity_property_values(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::PropertyValueDoNotMatchType,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_vec_prop_is_too_long() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![
-                FIRST_ENTITY_ID;
-                VecMaxLengthConstraint::get() as usize + 1
-            ]);
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values providing vector property value(s), which
-        // length exceeds VecMaxLengthConstraint.
-        let update_entity_property_values_result = update_entity_property_values(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::VecPropertyTooLong,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_text_prop_is_too_long() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.to_owned()));
-
-        // Create text property
-        let property_type = PropertyType::<ClassId>::single_text(TextMaxLengthConstraint::get());
-
-        let property = Property::<ClassId>::with_name_and_type(
-            PropertyNameLengthConstraint::get().max() as usize,
-            property_type,
-            true,
-            false,
-        );
-
-        // Add Schema to the Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let mut schema_property_values = BTreeMap::new();
-
-        let schema_property_value =
-            InputPropertyValue::<Runtime>::single_text(TextMaxLengthConstraint::get());
-
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.to_owned(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value =
-            InputPropertyValue::<Runtime>::single_text(TextMaxLengthConstraint::get() + 1);
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values providing text property value(s), which
-        // length exceeds TextMaxLengthConstraint.
-        let update_entity_property_values_result = update_entity_property_values(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::TextPropertyTooLong,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_hashed_text_prop_is_too_long() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.to_owned()));
-
-        let hashed_text_max_length_constraint = HashedTextMaxLengthConstraint::get();
-
-        // Create hash property
-        let property_type =
-            PropertyType::<ClassId>::single_text_hash(hashed_text_max_length_constraint);
-
-        let property = Property::<ClassId>::with_name_and_type(
-            PropertyNameLengthConstraint::get().max() as usize,
-            property_type,
-            true,
-            false,
-        );
-
-        // Add Schema to the first Class
-        assert_ok!(add_class_schema(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            BTreeSet::new(),
-            vec![property]
-        ));
-
-        let mut schema_property_values = BTreeMap::new();
-
-        let schema_property_value = InputPropertyValue::<Runtime>::single_text_to_hash(
-            hashed_text_max_length_constraint.unwrap(),
-        );
-
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.clone(),
-            FIRST_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values,
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value = InputPropertyValue::<Runtime>::single_text_to_hash(
-            hashed_text_max_length_constraint.unwrap() + 1,
-        );
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values providing text to hash property value(s), which
-        // length exceeds length exceeds HashedTextMaxLengthConstraint.
-        let update_entity_property_values_result = update_entity_property_values(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::HashedTextPropertyTooLong,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_referenced_entity_not_found() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create class reference schema and add corresponding schema support to the Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![
-                SECOND_ENTITY_ID;
-                VecMaxLengthConstraint::get() as usize
-            ]);
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values, providing new property value(s),
-        // some of which refer(s) to another Entity, which does not exist in runtime
-        let update_entity_property_values_result = update_entity_property_values(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::EntityNotFound,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_referenced_entity_does_not_match_its_class() {
-    with_test_externalities(|| {
-        // Create first class
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Create second class
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create first entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create class reference schema and add corresponding schema support to the first Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Create second entity
-        assert_ok!(create_entity(LEAD_ORIGIN, SECOND_CLASS_ID, actor.clone()));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![
-                SECOND_ENTITY_ID;
-                VecMaxLengthConstraint::get() as usize
-            ]);
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values, when provided schema new property value(s)
-        // refer(s) Entity, which Class does not match the class in corresponding Class Property
-        let update_entity_property_values_result = update_entity_property_values(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::ReferencedEntityDoesNotMatchItsClass,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_entity_can_not_be_referenced() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create first Entity of first Class
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create class reference schema and add corresponding schema support to the first Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Create second Entity of first Class
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Update second entity permissions to forbid it from being referencable
-        assert_ok!(update_entity_permissions(
-            LEAD_ORIGIN,
-            SECOND_ENTITY_ID,
-            None,
-            Some(false)
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![
-                SECOND_ENTITY_ID;
-                VecMaxLengthConstraint::get() as usize
-            ]);
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values, when provided schema new property value(s)
-        // refer(s) to Entity which can not be referenced
-        let update_entity_property_values_result = update_entity_property_values(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::EntityCanNotBeReferenced,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_same_controller_constraint_violation() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        // Update class permissions to force any member be available to create Entities
-        assert_ok!(update_class_permissions(
-            LEAD_ORIGIN,
-            FIRST_CLASS_ID,
-            Some(true),
-            None,
-            None,
-            None
-        ));
-
-        let actor = Actor::Lead;
-
-        // Create first Entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create class reference schema and add corresponding schema support to the first  Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Create second Entity
-        assert_ok!(create_entity(
-            FIRST_MEMBER_ORIGIN,
-            FIRST_CLASS_ID,
-            Actor::Member(FIRST_MEMBER_ID)
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![
-                SECOND_ENTITY_ID;
-                VecMaxLengthConstraint::get() as usize
-            ]);
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values, providing new reference property value(s) in case,
-        // when corresponding Entity can only be referenced from Entity with the same controller.
-        let update_entity_property_values_result = update_entity_property_values(
-            LEAD_ORIGIN,
-            actor,
-            FIRST_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::SameControllerConstraintViolation,
-            number_of_events_before_call,
-        );
-    })
-}
-
-#[test]
-fn update_entity_property_values_property_should_be_unique() {
-    with_test_externalities(|| {
-        // Create class with default permissions
-        assert_ok!(create_simple_class(LEAD_ORIGIN, ClassType::Valid));
-
-        let actor = Actor::Lead;
-
-        // Create first Entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        // Create Class reference schema and add corresponding schema support to the first Entity
-        add_unique_class_reference_schema_and_entity_schema_support(&actor, LEAD_ORIGIN);
-
-        // Create second Entity
-        assert_ok!(create_entity(LEAD_ORIGIN, FIRST_CLASS_ID, actor.clone()));
-
-        let schema_property_value = InputPropertyValue::<Runtime>::vec_reference(vec![
-            FIRST_ENTITY_ID,
-            FIRST_ENTITY_ID,
-            FIRST_ENTITY_ID,
-        ]);
-
-        let mut schema_property_values = BTreeMap::new();
-        schema_property_values.insert(FIRST_PROPERTY_ID, schema_property_value);
-
-        // Add schema support to the entity
-        assert_ok!(add_schema_support_to_entity(
-            LEAD_ORIGIN,
-            actor.to_owned(),
-            SECOND_ENTITY_ID,
-            FIRST_SCHEMA_ID,
-            schema_property_values
-        ));
-
-        // Runtime state before tested call
-
-        // Events number before tested call
-        let number_of_events_before_call = System::events().len();
-
-        let mut schema_new_property_values = BTreeMap::new();
-        let schema_new_property_value =
-            InputPropertyValue::<Runtime>::vec_reference(vec![FIRST_ENTITY_ID, FIRST_ENTITY_ID]);
-
-        schema_new_property_values.insert(FIRST_PROPERTY_ID, schema_new_property_value);
-
-        // Make an attempt to update entity property values, providing property value(s), which are identical to thouse,
-        // are already added to the another Entity of this Class, though should be unique on Class Property level
-        let update_entity_property_values_result = update_entity_property_values(
-            LEAD_ORIGIN,
-            actor,
-            SECOND_ENTITY_ID,
-            schema_new_property_values,
-        );
-
-        // Failure checked
-        assert_failure(
-            update_entity_property_values_result,
-            Error::<Runtime>::PropertyValueShouldBeUnique,
-            number_of_events_before_call,
-        );
-    })
-}

+ 2 - 0
runtime-modules/content/Cargo.toml

@@ -12,6 +12,7 @@ system = { package = 'frame-system', default-features = false, git = 'https://gi
 sp-arithmetic = { package = 'sp-arithmetic', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
 codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
 serde = {version = '1.0.101', features = ['derive'], optional = true}
+common = { package = 'pallet-common', default-features = false, path = '../common'}
 
 [dev-dependencies]
 sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
@@ -27,4 +28,5 @@ std = [
 	'sp-arithmetic/std',
 	'codec/std',
 	'serde',
+	'common/std'
 ]

+ 0 - 104
runtime-modules/content/lib.rs

@@ -1,104 +0,0 @@
-// Ensure we're `no_std` when compiling for Wasm.
-#![cfg_attr(not(feature = "std"), no_std)]
-#![recursion_limit = "256"]
-
-use core::hash::Hash;
-use core::ops::AddAssign;
-
-use codec::{Codec, Decode, Encode};
-use frame_support::storage::IterableStorageMap;
-
-use frame_support::{
-    decl_event, decl_module, decl_storage,
-    dispatch::{DispatchError, DispatchResult},
-    ensure,
-    traits::Get,
-    Parameter,
-};
-#[cfg(feature = "std")]
-pub use serde::{Deserialize, Serialize};
-use sp_arithmetic::traits::{BaseArithmetic, One, Zero};
-use sp_runtime::traits::{MaybeSerializeDeserialize, Member};
-use sp_std::borrow::ToOwned;
-use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
-use sp_std::vec;
-use sp_std::vec::Vec;
-use system::ensure_signed;
-
-/// Module configuration trait for this Substrate module.
-pub trait Trait: system::Trait + ActorAuthenticator + Clone {
-    /// The overarching event type.
-    type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
-
-    /// Type of identifier for Videos
-    type VideoId: Parameter
-        + Member
-        + BaseArithmetic
-        + Codec
-        + Default
-        + Copy
-        + Clone
-        + Hash
-        + MaybeSerializeDeserialize
-        + Eq
-        + PartialEq
-        + Ord;
-
-    /// Type of identifier for Channels
-    type ChannelId: Parameter
-        + Member
-        + BaseArithmetic
-        + Codec
-        + Default
-        + Copy
-        + Clone
-        + Hash
-        + MaybeSerializeDeserialize
-        + Eq
-        + PartialEq
-        + Ord;
-
-    // Security/configuration constraints
-
-    /// The maximum number of curators per group constraint
-    type MaxNumberOfCuratorsPerGroup: Get<MaxNumber>;
-}
-
-decl_storage! {
-    trait Store for Module<T: Trait> as Content {
-
-
-    }
-}
-
-decl_module! {
-    pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-        /// Predefined errors
-        type Error = Error<T>;
-
-        /// Initializing events
-        fn deposit_event() = default;
-
-    }
-}
-
-impl<T: Trait> Module<T> {
-
-}
-
-decl_event!(
-    pub enum Event<T>
-    where
-        CuratorGroupId = <T as ActorAuthenticator>::CuratorGroupId,
-        CuratorId = <T as ActorAuthenticator>::CuratorId,
-    {
-
-    }
-);
-
-decl_error! {
-    /// Content directory errors
-    pub enum Error for Module<T: Trait> {
-
-    }
-}

+ 47 - 0
runtime-modules/content/src/errors.rs

@@ -0,0 +1,47 @@
+use crate::*;
+use frame_support::decl_error;
+
+decl_error! {
+    /// Content directory errors
+    pub enum Error for Module<T: Trait> {
+
+        // Curator Management Errors
+        // -------------------------
+
+        /// Curator group can`t be removed
+        CuratorGroupRemovalForbidden,
+
+        /// Curator under provided curator id is not a member of curaror group under given id
+        CuratorIsNotAMemberOfGivenCuratorGroup,
+
+        /// Curator under provided curator id is already a member of curaror group under given id
+        CuratorIsAlreadyAMemberOfGivenCuratorGroup,
+
+        /// Given curator group does not exist
+        CuratorGroupDoesNotExist,
+
+        /// Max number of curators per group limit reached
+        CuratorsPerGroupLimitReached,
+
+        /// Curator group is not active
+        CuratorGroupIsNotActive,
+
+        // Authentication Errors
+        // ---------------------
+
+        /// Origin cannot be made into raw origin
+        OriginCanNotBeMadeIntoRawOrigin,
+
+        /// Lead authentication failed
+        LeadAuthFailed,
+
+        /// Member authentication failed
+        MemberAuthFailed,
+
+        /// Curator authentication failed
+        CuratorAuthFailed,
+
+        /// Expected root or signed origin
+        BadOrigin,
+    }
+}

+ 1140 - 0
runtime-modules/content/src/lib.rs

@@ -0,0 +1,1140 @@
+// Ensure we're `no_std` when compiling for Wasm.
+#![cfg_attr(not(feature = "std"), no_std)]
+#![recursion_limit = "256"]
+
+// #[cfg(test)]
+// mod tests;
+
+mod errors;
+mod permissions;
+
+pub use errors::*;
+pub use permissions::*;
+
+use core::hash::Hash;
+
+use codec::Codec;
+use codec::{Decode, Encode};
+
+use frame_support::{
+    decl_event, decl_module, decl_storage, dispatch::DispatchResult, ensure, traits::Get, Parameter,
+};
+#[cfg(feature = "std")]
+pub use serde::{Deserialize, Serialize};
+use sp_arithmetic::traits::{BaseArithmetic, One, Zero};
+use sp_runtime::traits::{MaybeSerializeDeserialize, Member};
+use sp_std::collections::btree_set::BTreeSet;
+// use sp_std::vec;
+use sp_std::vec::Vec;
+use system::ensure_signed;
+
+pub use common::storage::{ContentParameters as ContentParametersRecord, StorageSystem};
+pub use common::{
+    currency::{BalanceOf, GovernanceCurrency},
+    MembershipTypes, StorageOwnership, Url,
+};
+
+pub(crate) type ContentId<T> = <T as StorageOwnership>::ContentId;
+
+pub(crate) type DataObjectTypeId<T> = <T as StorageOwnership>::DataObjectTypeId;
+
+pub(crate) type ContentParameters<T> = ContentParametersRecord<ContentId<T>, DataObjectTypeId<T>>;
+
+/// Type, used in diffrent numeric constraints representations
+pub type MaxNumber = u32;
+
+/// A numeric identifier trait
+pub trait NumericIdentifier:
+    Parameter
+    + Member
+    + BaseArithmetic
+    + Codec
+    + Default
+    + Copy
+    + Clone
+    + Hash
+    + MaybeSerializeDeserialize
+    + Eq
+    + PartialEq
+    + Ord
+    + Zero
+{
+}
+
+impl NumericIdentifier for u64 {}
+
+/// Module configuration trait for Content Directory Module
+pub trait Trait:
+    system::Trait
+    + ContentActorAuthenticator
+    + Clone
+    + StorageOwnership
+    + MembershipTypes
+    + GovernanceCurrency
+{
+    /// The overarching event type.
+    type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
+
+    /// Channel Transfer Payments Escrow Account seed for ModuleId to compute deterministic AccountId
+    type ChannelOwnershipPaymentEscrowId: Get<[u8; 8]>;
+
+    /// Type of identifier for Videos
+    type VideoId: NumericIdentifier;
+
+    /// Type of identifier for Video Categories
+    type VideoCategoryId: NumericIdentifier;
+
+    /// Type of identifier for Channel Categories
+    type ChannelCategoryId: NumericIdentifier;
+
+    /// Type of identifier for Playlists
+    type PlaylistId: NumericIdentifier;
+
+    /// Type of identifier for Persons
+    type PersonId: NumericIdentifier;
+
+    /// Type of identifier for Channels
+    type SeriesId: NumericIdentifier;
+
+    /// Type of identifier for Channel transfer requests
+    type ChannelOwnershipTransferRequestId: NumericIdentifier;
+
+    /// The maximum number of curators per group constraint
+    type MaxNumberOfCuratorsPerGroup: Get<MaxNumber>;
+
+    // Type that handles asset uploads to storage system
+    type StorageSystem: StorageSystem<Self>;
+}
+
+/// Specifies how a new asset will be provided on creating and updating
+/// Channels, Videos, Series and Person
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
+pub enum NewAsset<ContentParameters> {
+    /// Upload to the storage system
+    Upload(ContentParameters),
+    /// Multiple url strings pointing at an asset
+    Urls(Vec<Url>),
+}
+
+/// The owner of a channel, is the authorized "actor" that can update
+/// or delete or transfer a channel and its contents.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
+pub enum ChannelOwner<MemberId, CuratorGroupId, DAOId> {
+    /// A Member owns the channel
+    Member(MemberId),
+    /// A specific curation group owns the channel
+    CuratorGroup(CuratorGroupId),
+    // Native DAO owns the channel
+    Dao(DAOId),
+}
+
+// Default trait implemented only because its used in a Channel which needs to implement a Default trait
+// since it is a StorageValue.
+impl<MemberId: Default, CuratorGroupId, DAOId> Default
+    for ChannelOwner<MemberId, CuratorGroupId, DAOId>
+{
+    fn default() -> Self {
+        ChannelOwner::Member(MemberId::default())
+    }
+}
+
+/// A category which channels can belong to.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct ChannelCategory {
+    // No runtime information is currently stored for a Category.
+}
+
+/// Information on the category being created.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct ChannelCategoryCreationParameters {
+    /// Metadata for the category.
+    meta: Vec<u8>,
+}
+
+/// Information on the category being updated.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct ChannelCategoryUpdateParameters {
+    // as this is the only field it is not an Option
+    /// Metadata update for the category.
+    new_meta: Vec<u8>,
+}
+
+/// Type representing an owned channel which videos, playlists, and series can belong to.
+/// If a channel is deleted, all videos, playlists and series will also be deleted.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct ChannelRecord<MemberId, CuratorGroupId, DAOId, AccountId, VideoId, PlaylistId, SeriesId>
+{
+    /// The owner of a channel
+    owner: ChannelOwner<MemberId, CuratorGroupId, DAOId>,
+    /// The videos under this channel
+    videos: Vec<VideoId>,
+    /// The playlists under this channel
+    playlists: Vec<PlaylistId>,
+    /// The series under this channel
+    series: Vec<SeriesId>,
+    /// If curators have censored this channel or not
+    is_censored: bool,
+    /// Reward account where revenue is sent if set.
+    reward_account: Option<AccountId>,
+}
+
+// Channel alias type for simplification.
+pub type Channel<T> = ChannelRecord<
+    <T as MembershipTypes>::MemberId,
+    <T as ContentActorAuthenticator>::CuratorGroupId,
+    <T as StorageOwnership>::DAOId,
+    <T as system::Trait>::AccountId,
+    <T as Trait>::VideoId,
+    <T as Trait>::PlaylistId,
+    <T as Trait>::SeriesId,
+>;
+
+/// A request to buy a channel by a new ChannelOwner.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct ChannelOwnershipTransferRequestRecord<
+    ChannelId,
+    MemberId,
+    CuratorGroupId,
+    DAOId,
+    Balance,
+    AccountId,
+> {
+    channel_id: ChannelId,
+    new_owner: ChannelOwner<MemberId, CuratorGroupId, DAOId>,
+    payment: Balance,
+    new_reward_account: Option<AccountId>,
+}
+
+// ChannelOwnershipTransferRequest type alias for simplification.
+pub type ChannelOwnershipTransferRequest<T> = ChannelOwnershipTransferRequestRecord<
+    <T as StorageOwnership>::ChannelId,
+    <T as MembershipTypes>::MemberId,
+    <T as ContentActorAuthenticator>::CuratorGroupId,
+    <T as StorageOwnership>::DAOId,
+    BalanceOf<T>,
+    <T as system::Trait>::AccountId,
+>;
+
+/// Information about channel being created.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
+pub struct ChannelCreationParameters<ContentParameters> {
+    /// Assets referenced by metadata
+    assets: Vec<NewAsset<ContentParameters>>,
+    /// Metadata about the channel.
+    meta: Vec<u8>,
+}
+
+/// Information about channel being updated.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct ChannelUpdateParameters<ContentParameters> {
+    /// Assets referenced by metadata
+    assets: Option<Vec<NewAsset<ContentParameters>>>,
+    /// If set, metadata update for the channel.
+    new_meta: Option<Vec<u8>>,
+}
+
+/// A category that videos can belong to.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct VideoCategory {
+    // No runtime information is currently stored for a Category.
+}
+
+/// Information about the video category being created.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct VideoCategoryCreationParameters {
+    /// Metadata about the video category.
+    meta: Vec<u8>,
+}
+
+/// Information about the video category being updated.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct VideoCategoryUpdateParameters {
+    // Because it is the only field it is not an Option
+    /// Metadata update for the video category.
+    new_meta: Vec<u8>,
+}
+
+/// Information about the video being created.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
+pub struct VideoCreationParameters<ContentParameters> {
+    /// Assets referenced by metadata
+    assets: Vec<NewAsset<ContentParameters>>,
+    /// Metadata for the video.
+    meta: Vec<u8>,
+}
+
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct VideoUpdateParameters<ContentParameters> {
+    /// Assets referenced by metadata
+    assets: Option<Vec<NewAsset<ContentParameters>>>,
+    /// If set, metadata update for the video.
+    new_meta: Option<Vec<u8>>,
+}
+
+/// A video which belongs to a channel. A video may be part of a series or playlist.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct Video<ChannelId, SeriesId> {
+    in_channel: ChannelId,
+    // keep track of which season the video is in if it is an 'episode'
+    // - prevent removing a video if it is in a season (because order is important)
+    in_series: Option<SeriesId>,
+    /// Whether the curators have censored the video or not.
+    is_censored: bool,
+    /// Whether the curators have chosen to feature the video or not.
+    is_featured: bool,
+}
+
+/// Information about the plyalist being created.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct PlaylistCreationParameters {
+    /// Metadata about the playlist.
+    meta: Vec<u8>,
+}
+
+/// Information about the playlist being updated.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct PlaylistUpdateParameters {
+    // It is the only field so its not an Option
+    /// Metadata update for the playlist.
+    new_meta: Vec<u8>,
+}
+
+/// A playlist is an ordered collection of videos.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct Playlist<ChannelId> {
+    /// The channel the playlist belongs to.
+    in_channel: ChannelId,
+}
+
+/// Information about the episode being created or updated.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
+pub enum EpisodeParameters<VideoId, ContentParameters> {
+    /// A new video is being added as the episode.
+    NewVideo(VideoCreationParameters<ContentParameters>),
+    /// An existing video is being made into an episode.
+    ExistingVideo(VideoId),
+}
+
+/// Information about the season being created or updated.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct SeasonParameters<VideoId, ContentParameters> {
+    /// Season assets referenced by metadata
+    assets: Option<Vec<NewAsset<ContentParameters>>>,
+    // ?? It might just be more straighforward to always provide full list of episodes at cost of larger tx.
+    /// If set, updates the episodes of a season. Extends the number of episodes in a season
+    /// when length of new_episodes is greater than previously set. Last elements must all be
+    /// 'Some' in that case.
+    /// Will truncate existing season when length of new_episodes is less than previously set.
+    episodes: Option<Vec<Option<EpisodeParameters<VideoId, ContentParameters>>>>,
+    /// If set, Metadata update for season.
+    meta: Option<Vec<u8>>,
+}
+
+/// Information about the series being created or updated.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct SeriesParameters<VideoId, ContentParameters> {
+    /// Series assets referenced by metadata
+    assets: Option<Vec<NewAsset<ContentParameters>>>,
+    // ?? It might just be more straighforward to always provide full list of seasons at cost of larger tx.
+    /// If set, updates the seasons of a series. Extend a series when length of seasons is
+    /// greater than previoulsy set. Last elements must all be 'Some' in that case.
+    /// Will truncate existing series when length of seasons is less than previously set.
+    seasons: Option<Vec<Option<SeasonParameters<VideoId, ContentParameters>>>>,
+    meta: Option<Vec<u8>>,
+}
+
+/// A season is an ordered list of videos (episodes).
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct Season<VideoId> {
+    episodes: Vec<VideoId>,
+}
+
+/// A series is an ordered list of seasons that belongs to a channel.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct Series<ChannelId, VideoId> {
+    in_channel: ChannelId,
+    seasons: Vec<Season<VideoId>>,
+}
+
+// The actor the caller/origin is trying to act as for Person creation and update and delete calls.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
+pub enum PersonActor<MemberId, CuratorId> {
+    Member(MemberId),
+    Curator(CuratorId),
+}
+
+/// The authorized actor that may update or delete a Person.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
+pub enum PersonController<MemberId> {
+    /// Member controls the person
+    Member(MemberId),
+    /// Any curator controls the person
+    Curators,
+}
+
+// Default trait implemented only because its used in Person which needs to implement a Default trait
+// since it is a StorageValue.
+impl<MemberId: Default> Default for PersonController<MemberId> {
+    fn default() -> Self {
+        PersonController::Member(MemberId::default())
+    }
+}
+
+/// Information for Person being created.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
+pub struct PersonCreationParameters<ContentParameters> {
+    /// Assets referenced by metadata
+    assets: Vec<NewAsset<ContentParameters>>,
+    /// Metadata for person.
+    meta: Vec<u8>,
+}
+
+/// Information for Persion being updated.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct PersonUpdateParameters<ContentParameters> {
+    /// Assets referenced by metadata
+    assets: Option<Vec<NewAsset<ContentParameters>>>,
+    /// Metadata to update person.
+    new_meta: Option<Vec<u8>>,
+}
+
+/// A Person represents a real person that may be associated with a video.
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
+pub struct Person<MemberId> {
+    /// Who can update or delete this person.
+    controlled_by: PersonController<MemberId>,
+}
+
+decl_storage! {
+    trait Store for Module<T: Trait> as Content {
+        pub ChannelById get(fn channel_by_id): map hasher(blake2_128_concat) T::ChannelId => Channel<T>;
+
+        pub ChannelCategoryById get(fn channel_category_by_id): map hasher(blake2_128_concat) T::ChannelCategoryId => ChannelCategory;
+
+        pub VideoById get(fn video_by_id): map hasher(blake2_128_concat) T::VideoId => Video<T::ChannelId, T::SeriesId>;
+
+        pub VideoCategoryById get(fn video_category_by_id): map hasher(blake2_128_concat) T::VideoCategoryId => VideoCategory;
+
+        pub PlaylistById get(fn playlist_by_id): map hasher(blake2_128_concat) T::PlaylistId => Playlist<T::ChannelId>;
+
+        pub SeriesById get(fn series_by_id): map hasher(blake2_128_concat) T::SeriesId => Series<T::ChannelId, T::VideoId>;
+
+        pub PersonById get(fn person_by_id): map hasher(blake2_128_concat) T::PersonId => Person<T::MemberId>;
+
+        pub ChannelOwnershipTransferRequestById get(fn channel_ownership_transfer_request_by_id):
+            map hasher(blake2_128_concat) T::ChannelOwnershipTransferRequestId => ChannelOwnershipTransferRequest<T>;
+
+        pub NextChannelCategoryId get(fn next_channel_category_id) config(): T::ChannelCategoryId;
+
+        pub NextChannelId get(fn next_channel_id) config(): T::ChannelId;
+
+        pub NextVideoCategoryId get(fn next_video_category_id) config(): T::VideoCategoryId;
+
+        pub NextVideoId get(fn next_video_id) config(): T::VideoId;
+
+        pub NextPlaylistId get(fn next_playlist_id) config(): T::PlaylistId;
+
+        pub NextPersonId get(fn next_person_id) config(): T::PersonId;
+
+        pub NextSeriesId get(fn next_series_id) config(): T::SeriesId;
+
+        pub NextChannelOwnershipTransferRequestId get(fn next_channel_transfer_request_id) config(): T::ChannelOwnershipTransferRequestId;
+
+        pub NextCuratorGroupId get(fn next_curator_group_id) config(): T::CuratorGroupId;
+
+        /// Map, representing  CuratorGroupId -> CuratorGroup relation
+        pub CuratorGroupById get(fn curator_group_by_id): map hasher(blake2_128_concat) T::CuratorGroupId => CuratorGroup<T>;
+    }
+}
+
+decl_module! {
+    pub struct Module<T: Trait> for enum Call where origin: T::Origin {
+        /// Predefined errors
+        type Error = Error<T>;
+
+        /// Initializing events
+        fn deposit_event() = default;
+
+        /// Exports const -  max number of curators per group
+        const MaxNumberOfCuratorsPerGroup: MaxNumber = T::MaxNumberOfCuratorsPerGroup::get();
+
+        // ======
+        // Next set of extrinsics can only be invoked by lead.
+        // ======
+
+        /// Add new curator group to runtime storage
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn create_curator_group(
+            origin,
+        ) -> DispatchResult {
+
+            // Ensure given origin is lead
+            ensure_is_lead::<T>(origin)?;
+
+            //
+            // == MUTATION SAFE ==
+            //
+
+            let curator_group_id = Self::next_curator_group_id();
+
+            // Insert empty curator group with `active` parameter set to false
+            <CuratorGroupById<T>>::insert(curator_group_id, CuratorGroup::<T>::default());
+
+            // Increment the next curator curator_group_id:
+            <NextCuratorGroupId<T>>::mutate(|n| *n += T::CuratorGroupId::one());
+
+            // Trigger event
+            Self::deposit_event(RawEvent::CuratorGroupCreated(curator_group_id));
+            Ok(())
+        }
+
+        /// Remove curator group under given `curator_group_id` from runtime storage
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn delete_curator_group(
+            origin,
+            curator_group_id: T::CuratorGroupId,
+        ) -> DispatchResult {
+
+            // Ensure given origin is lead
+            ensure_is_lead::<T>(origin)?;
+
+            // Ensure CuratorGroup under given curator_group_id exists
+            let curator_group = Self::ensure_curator_group_exists(&curator_group_id)?;
+
+            // We should previously ensure that curator_group  owns no channels to be able to remove it
+            curator_group.ensure_curator_group_owns_no_channels()?;
+
+            //
+            // == MUTATION SAFE ==
+            //
+
+
+            // Remove curator group under given curator group id from runtime storage
+            <CuratorGroupById<T>>::remove(curator_group_id);
+
+            // Trigger event
+            Self::deposit_event(RawEvent::CuratorGroupDeleted(curator_group_id));
+            Ok(())
+        }
+
+        /// Set `is_active` status for curator group under given `curator_group_id`
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn set_curator_group_status(
+            origin,
+            curator_group_id: T::CuratorGroupId,
+            is_active: bool,
+        ) -> DispatchResult {
+
+            // Ensure given origin is lead
+            ensure_is_lead::<T>(origin)?;
+
+            // Ensure curator group under provided curator_group_id already exist
+            Self::ensure_curator_group_under_given_id_exists(&curator_group_id)?;
+
+            //
+            // == MUTATION SAFE ==
+            //
+
+            // Set `is_active` status for curator group under given `curator_group_id`
+            <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
+                curator_group.set_status(is_active)
+            });
+
+            // Trigger event
+            Self::deposit_event(RawEvent::CuratorGroupStatusSet(curator_group_id, is_active));
+            Ok(())
+        }
+
+        /// Add curator to curator group under given `curator_group_id`
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn add_curator_to_group(
+            origin,
+            curator_group_id: T::CuratorGroupId,
+            curator_id: T::CuratorId,
+        ) -> DispatchResult {
+
+            // Ensure given origin is lead
+            ensure_is_lead::<T>(origin)?;
+
+            // Ensure curator group under provided curator_group_id already exist, retrieve corresponding one
+            let curator_group = Self::ensure_curator_group_exists(&curator_group_id)?;
+
+            // Ensure max number of curators per group limit not reached yet
+            curator_group.ensure_max_number_of_curators_limit_not_reached()?;
+
+            // Ensure curator under provided curator_id isn`t a CuratorGroup member yet
+            curator_group.ensure_curator_in_group_does_not_exist(&curator_id)?;
+
+            //
+            // == MUTATION SAFE ==
+            //
+
+            // Insert curator_id into curator_group under given curator_group_id
+            <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
+                curator_group.get_curators_mut().insert(curator_id);
+            });
+
+            // Trigger event
+            Self::deposit_event(RawEvent::CuratorAdded(curator_group_id, curator_id));
+            Ok(())
+        }
+
+        /// Remove curator from a given curator group
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn remove_curator_from_group(
+            origin,
+            curator_group_id: T::CuratorGroupId,
+            curator_id: T::CuratorId,
+        ) -> DispatchResult {
+
+            // Ensure given origin is lead
+            ensure_is_lead::<T>(origin)?;
+
+            // Ensure curator group under provided curator_group_id already exist, retrieve corresponding one
+            let curator_group = Self::ensure_curator_group_exists(&curator_group_id)?;
+
+            // Ensure curator under provided curator_id is CuratorGroup member
+            curator_group.ensure_curator_in_group_exists(&curator_id)?;
+
+            //
+            // == MUTATION SAFE ==
+            //
+
+            // Remove curator_id from curator_group under given curator_group_id
+            <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
+                curator_group.get_curators_mut().remove(&curator_id);
+            });
+
+            // Trigger event
+            Self::deposit_event(RawEvent::CuratorRemoved(curator_group_id, curator_id));
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn create_channel(
+            origin,
+            owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
+            params: ChannelCreationParameters<ContentParameters<T>>,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn update_channel(
+            origin,
+            owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
+            channel_id: T::ChannelId,
+            params: ChannelUpdateParameters<ContentParameters<T>>,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn delete_channel(
+            origin,
+            owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
+            channel_id: T::ChannelId,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn request_channel_transfer(
+            origin,
+            new_owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
+            channel_id: T::ChannelId,
+            payment: BalanceOf<T>,
+        ) -> DispatchResult {
+            // requester must be new_owner
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn cancel_channel_transfer_request(
+            origin,
+            request_id: T::ChannelOwnershipTransferRequestId,
+        ) -> DispatchResult {
+            // origin must be original requester (ie. proposed new channel owner)
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn accept_channel_transfer(
+            origin,
+            owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
+            request_id: T::ChannelOwnershipTransferRequestId,
+        ) -> DispatchResult {
+            // only current owner of channel can approve
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn create_video(
+            origin,
+            owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
+            channel_id: T::ChannelId,
+            params: VideoCreationParameters<ContentParameters<T>>,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn update_video(
+            origin,
+            owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
+            video: T::VideoId,
+            params: VideoUpdateParameters<ContentParameters<T>>,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn delete_video(
+            origin,
+            owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
+            video: T::VideoId,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn create_playlist(
+            origin,
+            owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
+            channel_id: T::ChannelId,
+            params: PlaylistCreationParameters,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn update_playlist(
+            origin,
+            owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
+            playlist: T::PlaylistId,
+            params: PlaylistUpdateParameters,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn delete_playlist(
+            origin,
+            owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
+            channel_id: T::ChannelId,
+            playlist: T::PlaylistId,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn set_featured_videos(
+            origin,
+            list: Vec<T::VideoId>
+        ) -> DispatchResult {
+            // can only be set by lead
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn create_video_category(
+            origin,
+            curator: T::CuratorId,
+            params: VideoCategoryCreationParameters,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn update_video_category(
+            origin,
+            curator: T::CuratorId,
+            category: T::VideoCategoryId,
+            params: VideoCategoryUpdateParameters,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn delete_video_category(
+            origin,
+            curator: T::CuratorId,
+            category: T::VideoCategoryId,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn create_channel_category(
+            origin,
+            curator: T::CuratorId,
+            params: ChannelCategoryCreationParameters,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn update_channel_category(
+            origin,
+            curator: T::CuratorId,
+            category: T::ChannelCategoryId,
+            params: ChannelCategoryUpdateParameters,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn delete_channel_category(
+            origin,
+            curator: T::CuratorId,
+            category: T::ChannelCategoryId,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn create_person(
+            origin,
+            actor: PersonActor<T::MemberId, T::CuratorId>,
+            params: PersonCreationParameters<ContentParameters<T>>,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn update_person(
+            origin,
+            actor: PersonActor<T::MemberId, T::CuratorId>,
+            person: T::PersonId,
+            params: PersonUpdateParameters<ContentParameters<T>>,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn delete_person(
+            origin,
+            actor: PersonActor<T::MemberId, T::CuratorId>,
+            person: T::PersonId,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn add_person_to_video(
+            origin,
+            owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
+            video_id: T::VideoId,
+            person: T::PersonId
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn remove_person_from_video(
+            origin,
+            owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
+            video_id: T::VideoId
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn censor_video(
+            origin,
+            curator_id: T::CuratorId,
+            video_id: T::VideoId,
+            rationale: Vec<u8>,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn censor_channel(
+            origin,
+            curator_id: T::CuratorId,
+            channel_id: T::ChannelId,
+            rationale: Vec<u8>,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn uncensor_video(
+            origin,
+            curator_id: T::CuratorId,
+            video_id: T::VideoId,
+            rationale: Vec<u8>
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn uncensor_channel(
+            origin,
+            curator_id: T::CuratorId,
+            channel_id: T::ChannelId,
+            rationale: Vec<u8>,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn create_series(
+            origin,
+            owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
+            channel_id: T::ChannelId,
+            params: SeriesParameters<T::VideoId, ContentParameters<T>>,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn update_series(
+            origin,
+            owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
+            channel_id: T::ChannelId,
+            params: SeriesParameters<T::VideoId, ContentParameters<T>>,
+        ) -> DispatchResult {
+            Ok(())
+        }
+
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn delete_series(
+            origin,
+            owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
+            series: T::SeriesId,
+        ) -> DispatchResult {
+            Ok(())
+        }
+    }
+}
+
+impl<T: Trait> Module<T> {
+    // TODO: make this private again after used in module
+    /// Increment number of channels, maintained by each curator group
+    pub fn increment_number_of_channels_owned_by_curator_groups(
+        curator_group_ids: BTreeSet<T::CuratorGroupId>,
+    ) {
+        curator_group_ids.into_iter().for_each(|curator_group_id| {
+            Self::increment_number_of_channels_owned_by_curator_group(curator_group_id);
+        });
+    }
+
+    // TODO: make this private again after used in module
+    /// Decrement number of channels, maintained by each curator group
+    pub fn decrement_number_of_channels_owned_by_curator_groups(
+        curator_group_ids: BTreeSet<T::CuratorGroupId>,
+    ) {
+        curator_group_ids.into_iter().for_each(|curator_group_id| {
+            Self::decrement_number_of_channels_owned_by_curator_group(curator_group_id);
+        });
+    }
+
+    // TODO: make this private again after used in module
+    /// Increment number of channels, maintained by curator group
+    pub fn increment_number_of_channels_owned_by_curator_group(
+        curator_group_id: T::CuratorGroupId,
+    ) {
+        <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
+            curator_group.increment_number_of_channels_owned_count();
+        });
+    }
+
+    // TODO: make this private again after used in module
+    /// Decrement number of channels, maintained by curator group
+    pub fn decrement_number_of_channels_owned_by_curator_group(
+        curator_group_id: T::CuratorGroupId,
+    ) {
+        <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
+            curator_group.decrement_number_of_channels_owned_count();
+        });
+    }
+
+    /// Ensure `CuratorGroup` under given id exists
+    pub fn ensure_curator_group_under_given_id_exists(
+        curator_group_id: &T::CuratorGroupId,
+    ) -> Result<(), Error<T>> {
+        ensure!(
+            <CuratorGroupById<T>>::contains_key(curator_group_id),
+            Error::<T>::CuratorGroupDoesNotExist
+        );
+        Ok(())
+    }
+
+    /// Ensure `CuratorGroup` under given id exists, return corresponding one
+    pub fn ensure_curator_group_exists(
+        curator_group_id: &T::CuratorGroupId,
+    ) -> Result<CuratorGroup<T>, Error<T>> {
+        Self::ensure_curator_group_under_given_id_exists(curator_group_id)?;
+        Ok(Self::curator_group_by_id(curator_group_id))
+    }
+
+    /// Ensure all `CuratorGroup`'s under given ids exist
+    pub fn ensure_curator_groups_exist(
+        curator_groups: &BTreeSet<T::CuratorGroupId>,
+    ) -> Result<(), Error<T>> {
+        for curator_group in curator_groups {
+            // Ensure CuratorGroup under given id exists
+            Self::ensure_curator_group_exists(curator_group)?;
+        }
+        Ok(())
+    }
+}
+
+// Some initial config for the module on runtime upgrade
+impl<T: Trait> Module<T> {
+    pub fn on_runtime_upgrade() {
+        <NextChannelCategoryId<T>>::put(T::ChannelCategoryId::one());
+        <NextVideoCategoryId<T>>::put(T::VideoCategoryId::one());
+        <NextVideoId<T>>::put(T::VideoId::one());
+        <NextChannelId<T>>::put(T::ChannelId::one());
+        <NextPlaylistId<T>>::put(T::PlaylistId::one());
+        <NextSeriesId<T>>::put(T::SeriesId::one());
+        <NextPersonId<T>>::put(T::PersonId::one());
+        <NextChannelOwnershipTransferRequestId<T>>::put(T::ChannelOwnershipTransferRequestId::one());
+    }
+}
+
+decl_event!(
+    pub enum Event<T>
+    where
+        CuratorGroupId = <T as ContentActorAuthenticator>::CuratorGroupId,
+        CuratorId = <T as ContentActorAuthenticator>::CuratorId,
+        VideoId = <T as Trait>::VideoId,
+        VideoCategoryId = <T as Trait>::VideoCategoryId,
+        ChannelId = <T as StorageOwnership>::ChannelId,
+        MemberId = <T as MembershipTypes>::MemberId,
+        NewAsset = NewAsset<ContentParameters<T>>,
+        ChannelCategoryId = <T as Trait>::ChannelCategoryId,
+        ChannelOwnershipTransferRequestId = <T as Trait>::ChannelOwnershipTransferRequestId,
+        PlaylistId = <T as Trait>::PlaylistId,
+        SeriesId = <T as Trait>::SeriesId,
+        PersonId = <T as Trait>::PersonId,
+        DAOId = <T as StorageOwnership>::DAOId,
+        ChannelOwnershipTransferRequest = ChannelOwnershipTransferRequest<T>,
+        Series = Series<<T as StorageOwnership>::ChannelId, <T as Trait>::VideoId>,
+        ContentParameters = ContentParameters<T>,
+    {
+        // Curators
+        CuratorGroupCreated(CuratorGroupId),
+        CuratorGroupDeleted(CuratorGroupId),
+        CuratorGroupStatusSet(CuratorGroupId, bool /* active status */),
+        CuratorAdded(CuratorGroupId, CuratorId),
+        CuratorRemoved(CuratorGroupId, CuratorId),
+
+        // Channels
+        ChannelCreated(
+            ChannelId,
+            ChannelOwner<MemberId, CuratorGroupId, DAOId>,
+            Vec<NewAsset>,
+            ChannelCreationParameters<ContentParameters>,
+        ),
+        ChannelUpdated(
+            ChannelId,
+            Vec<NewAsset>,
+            ChannelUpdateParameters<ContentParameters>,
+        ),
+        ChannelDeleted(ChannelId),
+
+        ChannelCensored(ChannelId, Vec<u8> /* rationale */),
+        ChannelUncensored(ChannelId, Vec<u8> /* rationale */),
+
+        // Channel Ownership Transfers
+        ChannelOwnershipTransferRequested(
+            ChannelOwnershipTransferRequestId,
+            ChannelOwnershipTransferRequest,
+        ),
+        ChannelOwnershipTransferRequestWithdrawn(ChannelOwnershipTransferRequestId),
+        ChannelOwnershipTransferred(ChannelOwnershipTransferRequestId),
+
+        // Channel Categories
+        ChannelCategoryCreated(ChannelCategoryId, ChannelCategoryCreationParameters),
+        ChannelCategoryUpdated(ChannelCategoryUpdateParameters),
+        ChannelCategoryDeleted(ChannelCategoryId),
+
+        // Videos
+        VideoCategoryCreated(VideoCategoryId, VideoCategoryCreationParameters),
+        VideoCategoryUpdated(VideoCategoryId, VideoCategoryUpdateParameters),
+        VideoCategoryDeleted(VideoCategoryId),
+
+        VideoCreated(
+            VideoId,
+            Vec<NewAsset>,
+            VideoCreationParameters<ContentParameters>,
+        ),
+        VideoUpdated(
+            VideoId,
+            Vec<NewAsset>,
+            VideoUpdateParameters<ContentParameters>,
+        ),
+        VideoDeleted(VideoId),
+
+        VideoCensored(VideoId, Vec<u8> /* rationale */),
+        VideoUncensored(VideoId, Vec<u8> /* rationale */),
+
+        // Featured Videos
+        FeaturedVideosSet(Vec<VideoId>),
+
+        // Video Playlists
+        PlaylistCreated(PlaylistId, PlaylistCreationParameters),
+        PlaylistUpdated(PlaylistId, PlaylistUpdateParameters),
+        PlaylistDeleted(PlaylistId),
+
+        // Series
+        SeriesCreated(
+            SeriesId,
+            Vec<NewAsset>,
+            SeriesParameters<VideoId, ContentParameters>,
+            Series,
+        ),
+        SeriesUpdated(
+            SeriesId,
+            Vec<NewAsset>,
+            SeriesParameters<VideoId, ContentParameters>,
+            Series,
+        ),
+        SeriesDeleted(SeriesId),
+
+        // Persons
+        PersonCreated(
+            PersonId,
+            Vec<NewAsset>,
+            PersonCreationParameters<ContentParameters>,
+        ),
+        PersonUpdated(
+            PersonId,
+            Vec<NewAsset>,
+            PersonUpdateParameters<ContentParameters>,
+        ),
+        PersonDeleted(PersonId),
+    }
+);

+ 16 - 16
runtime-modules/content-directory/src/permissions/curator_group.rs → runtime-modules/content/src/permissions/curator_group.rs

@@ -1,8 +1,8 @@
 use super::*;
 
 /// A group, that consists of `curators` set
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
-#[derive(Encode, Decode, Eq, PartialEq, Clone)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug)]
 pub struct CuratorGroup<T: Trait> {
     /// Curators set, associated with a iven curator group
     curators: BTreeSet<T::CuratorId>,
@@ -10,8 +10,8 @@ pub struct CuratorGroup<T: Trait> {
     /// When `false`, curator in a given group is forbidden to act
     active: bool,
 
-    /// Used to count the number of `Class`(es), given curator group maintains
-    number_of_classes_maintained: u32,
+    /// Used to count the number of Channels, given curator group owns
+    number_of_channels_owned: u32,
 }
 
 impl<T: Trait> Default for CuratorGroup<T> {
@@ -20,7 +20,7 @@ impl<T: Trait> Default for CuratorGroup<T> {
             curators: BTreeSet::new(),
             // default curator group status right after creation
             active: false,
-            number_of_classes_maintained: 0,
+            number_of_channels_owned: 0,
         }
     }
 }
@@ -36,8 +36,8 @@ impl<T: Trait> CuratorGroup<T> {
         self.active
     }
 
-    pub fn get_number_of_classes_maintained(&self) -> u32 {
-        self.number_of_classes_maintained
+    pub fn get_number_of_channels_owned(&self) -> u32 {
+        self.number_of_channels_owned
     }
 
     /// Set `CuratorGroup` status as provided
@@ -55,20 +55,20 @@ impl<T: Trait> CuratorGroup<T> {
         &mut self.curators
     }
 
-    /// Increment number of classes `CuratorGroup` maintains
-    pub fn increment_number_of_classes_maintained_count(&mut self) {
-        self.number_of_classes_maintained += 1;
+    /// Increment number of channels `CuratorGroup` owns
+    pub fn increment_number_of_channels_owned_count(&mut self) {
+        self.number_of_channels_owned += 1;
     }
 
-    /// Decrement number of classes `CuratorGroup` maintains
-    pub fn decrement_number_of_classes_maintained_count(&mut self) {
-        self.number_of_classes_maintained -= 1;
+    /// Decrement number of channels `CuratorGroup` owns
+    pub fn decrement_number_of_channels_owned_count(&mut self) {
+        self.number_of_channels_owned -= 1;
     }
 
-    /// Ensure curator group does not maintain any `Class`
-    pub fn ensure_curator_group_maintains_no_classes(&self) -> Result<(), Error<T>> {
+    /// Ensure curator group does not maintain any `Channel`
+    pub fn ensure_curator_group_owns_no_channels(&self) -> Result<(), Error<T>> {
         ensure!(
-            self.number_of_classes_maintained == 0,
+            self.number_of_channels_owned == 0,
             Error::<T>::CuratorGroupRemovalForbidden
         );
         Ok(())

+ 2 - 20
runtime-modules/content-directory/src/permissions.rs → runtime-modules/content/src/permissions/mod.rs

@@ -1,16 +1,11 @@
-mod class;
 mod curator_group;
-mod entity;
-mod entity_creation_voucher;
 
-pub use class::*;
 pub use curator_group::*;
-pub use entity::*;
-pub use entity_creation_voucher::*;
 
 pub use crate::errors::*;
 use crate::*;
 pub use codec::{Codec, Decode, Encode};
+pub use common::MembershipTypes;
 use core::fmt::Debug;
 use frame_support::{ensure, Parameter};
 #[cfg(feature = "std")]
@@ -19,7 +14,7 @@ use sp_arithmetic::traits::BaseArithmetic;
 use sp_runtime::traits::{MaybeSerializeDeserialize, Member};
 
 /// Model of authentication manager.
-pub trait ActorAuthenticator: system::Trait {
+pub trait ContentActorAuthenticator: system::Trait + MembershipTypes {
     /// Curator identifier
     type CuratorId: Parameter
         + Member
@@ -33,19 +28,6 @@ pub trait ActorAuthenticator: system::Trait {
         + PartialEq
         + Ord;
 
-    /// Member identifier
-    type MemberId: Parameter
-        + Member
-        + BaseArithmetic
-        + Codec
-        + Default
-        + Copy
-        + Clone
-        + MaybeSerializeDeserialize
-        + Eq
-        + PartialEq
-        + Ord;
-
     /// Curator group identifier
     type CuratorGroupId: Parameter
         + Member

+ 2 - 1
runtime-modules/service-discovery/Cargo.toml

@@ -12,6 +12,7 @@ frame-support = { package = 'frame-support', default-features = false, git = 'ht
 system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
 sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
 working-group = { package = 'pallet-working-group', default-features = false, path = '../working-group'}
+common = { package = 'pallet-common', default-features = false, path = '../common'}
 
 [dev-dependencies]
 sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
@@ -23,7 +24,6 @@ stake = { package = 'pallet-stake', default-features = false, path = '../stake'}
 hiring = { package = 'pallet-hiring', default-features = false, path = '../hiring'}
 minting = { package = 'pallet-token-mint', default-features = false, path = '../token-minting'}
 recurringrewards = { package = 'pallet-recurring-reward', default-features = false, path = '../recurring-reward'}
-common = { package = 'pallet-common', default-features = false, path = '../common'}
 
 [features]
 default = ['std']
@@ -35,4 +35,5 @@ std = [
 	'system/std',
 	'sp-runtime/std',
 	'working-group/std',
+	'common/std'
 ]

+ 2 - 3
runtime-modules/service-discovery/src/lib.rs

@@ -23,6 +23,8 @@ mod mock;
 mod tests;
 
 use codec::{Decode, Encode};
+use common::Url;
+
 #[cfg(feature = "std")]
 use serde::{Deserialize, Serialize};
 
@@ -45,9 +47,6 @@ use system::ensure_root;
 /// base58 encoded IPNS identity multihash codec
 pub type IPNSIdentity = Vec<u8>;
 
-/// HTTP Url string to a discovery service endpoint
-pub type Url = Vec<u8>;
-
 // The storage working group instance alias.
 pub(crate) type StorageWorkingGroupInstance = working_group::Instance2;
 

+ 503 - 84
runtime-modules/storage/src/data_directory.rs

@@ -24,8 +24,7 @@
 use codec::{Decode, Encode};
 use frame_support::dispatch::DispatchResult;
 use frame_support::traits::Get;
-use frame_support::{decl_error, decl_event, decl_module, decl_storage, ensure, Parameter};
-use sp_runtime::traits::{MaybeSerialize, Member};
+use frame_support::{decl_error, decl_event, decl_module, decl_storage, ensure};
 use sp_std::collections::btree_map::BTreeMap;
 use sp_std::vec::Vec;
 use system::ensure_root;
@@ -34,11 +33,12 @@ use system::ensure_root;
 use serde::{Deserialize, Serialize};
 
 use common::origin::ActorOriginValidator;
+pub use common::storage::{ContentParameters, StorageObjectOwner};
 pub(crate) use common::BlockAndTime;
 
 use crate::data_object_type_registry;
 use crate::data_object_type_registry::IsActiveDataObjectType;
-use crate::{MemberId, StorageProviderId, StorageWorkingGroup, StorageWorkingGroupInstance};
+use crate::*;
 
 /// The _Data directory_ main _Trait_.
 pub trait Trait:
@@ -47,23 +47,23 @@ pub trait Trait:
     + data_object_type_registry::Trait
     + membership::Trait
     + working_group::Trait<StorageWorkingGroupInstance>
+    + common::MembershipTypes
+    + common::StorageOwnership
 {
     /// _Data directory_ event type.
     type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
 
-    /// Content id.
-    type ContentId: Parameter + Member + MaybeSerialize + Copy + Ord + Default;
-
     /// Provides random storage provider id.
     type StorageProviderHelper: StorageProviderHelper<Self>;
 
-    ///Active data object type validator.
+    /// Active data object type validator.
     type IsActiveDataObjectType: data_object_type_registry::IsActiveDataObjectType<Self>;
 
     /// Validates member id and origin combination.
     type MemberOriginValidator: ActorOriginValidator<Self::Origin, MemberId<Self>, Self::AccountId>;
 
-    type MaxObjectsPerInjection: Get<u32>;
+    /// Default content quota for all actors.
+    type DefaultQuota: Get<Quota>;
 }
 
 decl_error! {
@@ -85,7 +85,31 @@ decl_error! {
         RequireRootOrigin,
 
         /// DataObject Injection Failed. Too Many DataObjects.
-        DataObjectsInjectionExceededLimit
+        DataObjectsInjectionExceededLimit,
+
+        /// Contant uploading failed. Actor quota objects limit exceeded.
+        QuotaObjectsLimitExceeded,
+
+        /// Contant uploading failed. Actor quota size limit exceeded.
+        QuotaSizeLimitExceeded,
+
+        /// Quota size limit upper bound exceeded
+        QuotaSizeLimitUpperBoundExceeded,
+
+        /// Quota objects limit upper bound exceeded
+        QuotaObjectsLimitUpperBoundExceeded,
+
+        /// Contant uploading failed. Actor quota size limit exceeded.
+        GlobalQuotaSizeLimitExceeded,
+
+        /// Contant uploading failed. Actor quota objects limit exceeded.
+        GlobalQuotaObjectsLimitExceeded,
+
+        /// Content uploading blocked.
+        ContentUploadingBlocked,
+
+        /// Provided owner should be equal o the data object owner under given content id
+        OwnersAreNotEqual
     }
 }
 
@@ -112,18 +136,28 @@ impl Default for LiaisonJudgement {
 /// Alias for DataObjectInternal
 pub type DataObject<T> = DataObjectInternal<
     MemberId<T>,
+    ChannelId<T>,
+    DAOId<T>,
     <T as system::Trait>::BlockNumber,
     <T as pallet_timestamp::Trait>::Moment,
-    <T as data_object_type_registry::Trait>::DataObjectTypeId,
+    DataObjectTypeId<T>,
     StorageProviderId<T>,
 >;
 
 /// Manages content ids, type and storage provider decision about it.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(Clone, Encode, Decode, PartialEq, Debug)]
-pub struct DataObjectInternal<MemberId, BlockNumber, Moment, DataObjectTypeId, StorageProviderId> {
+pub struct DataObjectInternal<
+    MemberId,
+    ChannelId,
+    DAOId,
+    BlockNumber,
+    Moment,
+    DataObjectTypeId,
+    StorageProviderId,
+> {
     /// Content owner.
-    pub owner: MemberId,
+    pub owner: StorageObjectOwner<MemberId, ChannelId, DAOId>,
 
     /// Content added at.
     pub added_at: BlockAndTime<BlockNumber, Moment>,
@@ -144,32 +178,118 @@ pub struct DataObjectInternal<MemberId, BlockNumber, Moment, DataObjectTypeId, S
     pub ipfs_content_id: Vec<u8>,
 }
 
+#[derive(Clone, Copy)]
+pub struct Voucher {
+    pub size: u64,
+    pub objects: u64,
+}
+
+/// Uploading quota for StorageObjectOwner
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Clone, Copy, Encode, Decode, PartialEq, Eq, Debug, Default)]
+pub struct Quota {
+    // Total objects size limit per StorageObjectOwner
+    pub size_limit: u64,
+    // Total objects number limit per StorageObjectOwner
+    pub objects_limit: u64,
+    pub size_used: u64,
+    pub objects_used: u64,
+}
+
+impl Quota {
+    /// Create new quota with provided size & objects limits
+    pub const fn new(size_limit: u64, objects_limit: u64) -> Self {
+        Self {
+            size_limit,
+            objects_limit,
+            size_used: 0,
+            objects_used: 0,
+        }
+    }
+
+    /// Calculate free quota
+    pub fn calculate_voucher(&self) -> Voucher {
+        Voucher {
+            size: self.size_limit - self.size_used,
+            objects: self.objects_limit - self.objects_used,
+        }
+    }
+
+    pub fn fill_quota(self, voucher: Voucher) -> Self {
+        Self {
+            size_used: self.size_used + voucher.size,
+            objects_used: self.objects_used + voucher.objects,
+            ..self
+        }
+    }
+
+    pub fn release_quota(self, voucher: Voucher) -> Self {
+        Self {
+            size_used: self.size_used - voucher.size,
+            objects_used: self.objects_used - voucher.objects,
+            ..self
+        }
+    }
+
+    pub fn set_new_size_limit(&mut self, new_size_limit: u64) {
+        self.size_limit = new_size_limit;
+    }
+
+    pub fn set_new_objects_limit(&mut self, new_objects_limit: u64) {
+        self.objects_limit = new_objects_limit;
+    }
+}
+
 /// A map collection of unique DataObjects keyed by the ContentId
-pub type DataObjectsMap<T> = BTreeMap<<T as Trait>::ContentId, DataObject<T>>;
+pub type DataObjectsMap<T> = BTreeMap<ContentId<T>, DataObject<T>>;
 
 decl_storage! {
     trait Store for Module<T: Trait> as DataDirectory {
-        /// List of ids known to the system.
-        pub KnownContentIds get(fn known_content_ids) config(): Vec<T::ContentId> = Vec::new();
 
         /// Maps data objects by their content id.
         pub DataObjectByContentId get(fn data_object_by_content_id) config():
             map hasher(blake2_128_concat) T::ContentId => Option<DataObject<T>>;
+
+        /// Maps storage owner to it`s quota. Created when the first upload by the new actor occured.
+        pub Quotas get(fn quotas) config():
+            map hasher(blake2_128_concat) StorageObjectOwner<MemberId<T>, ChannelId<T>, DAOId<T>> => Quota;
+
+        /// Upper bound for the Quota size limit.
+        pub QuotaSizeLimitUpperBound get(fn quota_size_limit_upper_bound) config(): u64;
+
+        /// Upper bound for the Quota objects number limit.
+        pub QuotaObjectsLimitUpperBound get(fn quota_objects_limit_upper_bound) config(): u64;
+
+        /// Global quota.
+        pub GlobalQuota get(fn global_quota) config(): Quota;
+
+        /// If all new uploads blocked
+        pub UploadingBlocked get(fn uploading_blocked) config(): bool;
     }
 }
 
 decl_event! {
     /// _Data directory_ events
     pub enum Event<T> where
-        <T as Trait>::ContentId,
-        MemberId = MemberId<T>,
-        StorageProviderId = StorageProviderId<T>
+        StorageObjectOwner = StorageObjectOwner<MemberId<T>, ChannelId<T>, DAOId<T>>,
+        StorageProviderId = StorageProviderId<T>,
+        Content = Vec<ContentParameters<ContentId<T>, DataObjectTypeId<T>>>,
+        ContentId = ContentId<T>,
+        ContentIds = Vec<ContentId<T>>,
+        QuotaLimit = u64,
+        UploadingStatus = bool
     {
         /// Emits on adding of the content.
         /// Params:
-        /// - Id of the relationship.
-        /// - Id of the member.
-        ContentAdded(ContentId, MemberId),
+        /// - Content parameters representation.
+        /// - StorageObjectOwner enum.
+        ContentAdded(Content, StorageObjectOwner),
+
+        /// Emits on content removal.
+        /// Params:
+        /// - Content parameters representation.
+        /// - StorageObjectOwner enum.
+        ContentRemoved(ContentIds, StorageObjectOwner),
 
         /// Emits when the storage provider accepts a content.
         /// Params:
@@ -182,6 +302,23 @@ decl_event! {
         /// - Id of the relationship.
         /// - Id of the storage provider.
         ContentRejected(ContentId, StorageProviderId),
+
+        /// Emits when the storage object owner quota size limit update performed.
+        /// Params:
+        /// - StorageObjectOwner enum.
+        /// - quota size limit.
+        StorageObjectOwnerQuotaSizeLimitUpdated(StorageObjectOwner, QuotaLimit),
+
+        /// Emits when the storage object owner quota objects limit update performed.
+        /// Params:
+        /// - StorageObjectOwner enum.
+        /// - quota objects limit.
+        StorageObjectOwnerQuotaObjectsLimitUpdated(StorageObjectOwner, QuotaLimit),
+
+        /// Emits when the content uploading status update performed.
+        /// Params:
+        /// - UploadingStatus bool flag.
+        ContentUploadingStatusUpdated(UploadingStatus),
     }
 }
 
@@ -194,50 +331,119 @@ decl_module! {
         /// Predefined errors.
         type Error = Error<T>;
 
-        /// Maximum objects allowed per inject_data_objects() transaction
-        const MaxObjectsPerInjection: u32 = T::MaxObjectsPerInjection::get();
-
-        /// Adds the content to the system. Member id should match its origin. The created DataObject
+        /// Adds the content to the system. The created DataObject
         /// awaits liaison to accept or reject it.
         #[weight = 10_000_000] // TODO: adjust weight
         pub fn add_content(
             origin,
-            member_id: MemberId<T>,
-            content_id: T::ContentId,
-            type_id: <T as data_object_type_registry::Trait>::DataObjectTypeId,
-            size: u64,
-            ipfs_content_id: Vec<u8>
+            owner: StorageObjectOwner<MemberId<T>, ChannelId<T>, DAOId<T>>,
+            content: Vec<ContentParameters<ContentId<T>, DataObjectTypeId<T>>>
         ) {
-            T::MemberOriginValidator::ensure_actor_origin(
-                origin,
-                member_id,
-            )?;
 
-            ensure!(T::IsActiveDataObjectType::is_active_data_object_type(&type_id),
-                Error::<T>::DataObjectTypeMustBeActive);
+            // Ensure given origin can perform operation under specific storage object owner
+            Self::ensure_storage_object_owner_origin(origin, &owner)?;
+
+            Self::ensure_uploading_is_not_blocked()?;
 
-            ensure!(!<DataObjectByContentId<T>>::contains_key(content_id),
-                Error::<T>::DataObjectAlreadyAdded);
+            Self::ensure_content_is_valid(&content)?;
+
+            let owner_quota = Self::get_quota(&owner);
+
+            // Ensure owner quota constraints satisfied.
+            // Calculate upload voucher
+            let upload_voucher = Self::ensure_owner_quota_constraints_satisfied(owner_quota, &content)?;
+
+            // Ensure global quota constraints satisfied.
+            Self::ensure_global_quota_constraints_satisfied(upload_voucher)?;
 
             let liaison = T::StorageProviderHelper::get_random_storage_provider()?;
 
+            //
+            // == MUTATION SAFE ==
+            //
+
             // Let's create the entry then
-            let data: DataObject<T> = DataObjectInternal {
-                type_id,
-                size,
-                added_at: common::current_block_time::<T>(),
-                owner: member_id,
-                liaison,
-                liaison_judgement: LiaisonJudgement::Pending,
-                ipfs_content_id,
+            Self::upload_content(owner_quota, upload_voucher, liaison, content.clone(), owner.clone());
+
+            Self::deposit_event(RawEvent::ContentAdded(content, owner));
+        }
+
+        /// Remove the content from the system.
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn remove_content(
+            origin,
+            owner: StorageObjectOwner<MemberId<T>, ChannelId<T>, DAOId<T>>,
+            content_ids: Vec<ContentId<T>>
+        ) {
+
+            // Ensure given origin can perform operation under specific storage object owner
+            Self::ensure_storage_object_owner_origin(origin, &owner)?;
+
+            // Ensure content under given content ids can be successfully removed
+            let content = Self::ensure_content_can_be_removed(&content_ids, &owner)?;
+
+            //
+            // == MUTATION SAFE ==
+            //
+
+            // Let's remove a content
+            Self::delete_content(&owner, &content_ids, content);
+
+            Self::deposit_event(RawEvent::ContentRemoved(content_ids, owner));
+        }
+
+        /// Updates storage object owner quota objects limit. Requires leader privileges.
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn update_storage_object_owner_quota_objects_limit(
+            origin,
+            abstract_owner: StorageObjectOwner<MemberId<T>, ChannelId<T>, DAOId<T>>,
+            new_quota_objects_limit: u64
+        ) {
+            <StorageWorkingGroup<T>>::ensure_origin_is_active_leader(origin)?;
+            ensure!(new_quota_objects_limit <= Self::quota_objects_limit_upper_bound(), Error::<T>::QuotaSizeLimitUpperBoundExceeded);
+
+            //
+            // == MUTATION SAFE ==
+            //
+
+            if <Quotas<T>>::contains_key(&abstract_owner) {
+                <Quotas<T>>::mutate(&abstract_owner, |quota| {
+                    quota.set_new_objects_limit(new_quota_objects_limit);
+                });
+            } else {
+                let mut quota = T::DefaultQuota::get();
+                quota.set_new_objects_limit(new_quota_objects_limit);
+                <Quotas<T>>::insert(&abstract_owner, quota);
             };
 
+            Self::deposit_event(RawEvent::StorageObjectOwnerQuotaObjectsLimitUpdated(abstract_owner, new_quota_objects_limit));
+        }
+
+        /// Updates storage object owner quota size limit. Requires leader privileges.
+        #[weight = 10_000_000] // TODO: adjust weight
+        pub fn update_storage_object_owner_quota_size_limit(
+            origin,
+            abstract_owner: StorageObjectOwner<MemberId<T>, ChannelId<T>, DAOId<T>>,
+            new_quota_size_limit: u64
+        ) {
+            <StorageWorkingGroup<T>>::ensure_origin_is_active_leader(origin)?;
+            ensure!(new_quota_size_limit <= Self::quota_size_limit_upper_bound(), Error::<T>::QuotaObjectsLimitUpperBoundExceeded);
+
             //
             // == MUTATION SAFE ==
             //
 
-            <DataObjectByContentId<T>>::insert(&content_id, data);
-            Self::deposit_event(RawEvent::ContentAdded(content_id, member_id));
+            if <Quotas<T>>::contains_key(&abstract_owner) {
+                <Quotas<T>>::mutate(&abstract_owner, |quota| {
+                    quota.set_new_size_limit(new_quota_size_limit);
+                });
+            } else {
+                let mut quota = T::DefaultQuota::get();
+                quota.set_new_size_limit(new_quota_size_limit);
+                <Quotas<T>>::insert(&abstract_owner, quota);
+            };
+
+            Self::deposit_event(RawEvent::StorageObjectOwnerQuotaSizeLimitUpdated(abstract_owner, new_quota_size_limit));
         }
 
         /// Storage provider accepts a content. Requires signed storage provider account and its id.
@@ -254,8 +460,6 @@ decl_module! {
 
             Self::update_content_judgement(&storage_provider_id, content_id, LiaisonJudgement::Accepted)?;
 
-            <KnownContentIds<T>>::mutate(|ids| ids.push(content_id));
-
             Self::deposit_event(RawEvent::ContentAccepted(content_id, storage_provider_id));
         }
 
@@ -275,51 +479,195 @@ decl_module! {
             Self::deposit_event(RawEvent::ContentRejected(content_id, storage_provider_id));
         }
 
-        // Sudo methods
-
-        /// Removes the content id from the list of known content ids. Requires root privileges.
+        /// Locks / unlocks content uploading
         #[weight = 10_000_000] // TODO: adjust weight
-        fn remove_known_content_id(origin, content_id: T::ContentId) {
-            ensure_root(origin)?;
+        fn update_content_uploading_status(origin, is_blocked: bool) {
+            <StorageWorkingGroup<T>>::ensure_origin_is_active_leader(origin)?;
 
             // == MUTATION SAFE ==
 
-            let upd_content_ids: Vec<T::ContentId> = Self::known_content_ids()
-                .into_iter()
-                .filter(|&id| id != content_id)
-                .collect();
-            <KnownContentIds<T>>::put(upd_content_ids);
+            <UploadingBlocked>::put(is_blocked);
+            Self::deposit_event(RawEvent::ContentUploadingStatusUpdated(is_blocked));
         }
+    }
+}
 
-        /// Injects a set of data objects and their corresponding content id into the directory.
-        /// The operation is "silent" - no events will be emitted as objects are added.
-        /// The number of objects that can be added per call is limited to prevent the dispatch
-        /// from causing the block production to fail if it takes too much time to process.
-        /// Existing data objects will be overwritten.
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub(crate) fn inject_data_objects(origin, objects: DataObjectsMap<T>) {
+impl<T: Trait> Module<T> {
+    // Ensure given origin can perform operation under specific storage object owner
+    fn ensure_storage_object_owner_origin(
+        origin: T::Origin,
+        owner: &StorageObjectOwner<MemberId<T>, ChannelId<T>, DAOId<T>>,
+    ) -> DispatchResult {
+        if let StorageObjectOwner::Member(member_id) = owner {
+            T::MemberOriginValidator::ensure_actor_origin(origin, *member_id)?;
+        } else {
             ensure_root(origin)?;
+        };
+        Ok(())
+    }
 
-            // Must provide something to inject
-            ensure!(objects.len() <= T::MaxObjectsPerInjection::get() as usize, Error::<T>::DataObjectsInjectionExceededLimit);
-
-            for (id, object) in objects.into_iter() {
-                // append to known content ids
-                // duplicates will be removed at the end
-                <KnownContentIds<T>>::mutate(|ids| ids.push(id));
-                <DataObjectByContentId<T>>::insert(id, object);
-            }
-
-            // remove duplicate ids
-            <KnownContentIds<T>>::mutate(|ids| {
-                ids.sort();
-                ids.dedup();
-            });
+    // Get owner quota if exists, otherwise return default one.
+    fn get_quota(owner: &StorageObjectOwner<MemberId<T>, ChannelId<T>, DAOId<T>>) -> Quota {
+        if <Quotas<T>>::contains_key(owner) {
+            Self::quotas(owner)
+        } else {
+            T::DefaultQuota::get()
         }
     }
-}
 
-impl<T: Trait> Module<T> {
+    // Ensure content uploading is not blocked
+    fn ensure_uploading_is_not_blocked() -> DispatchResult {
+        ensure!(
+            !Self::uploading_blocked(),
+            Error::<T>::ContentUploadingBlocked
+        );
+        Ok(())
+    }
+
+    // Ensure owner quota constraints satisfied, returns total object length and total size voucher for this upload.
+    fn ensure_owner_quota_constraints_satisfied(
+        owner_quota: Quota,
+        content: &[ContentParameters<T::ContentId, DataObjectTypeId<T>>],
+    ) -> Result<Voucher, Error<T>> {
+        let owner_quota_voucher = owner_quota.calculate_voucher();
+
+        // Ensure total content length is less or equal then available per given owner quota
+        let content_length = content.len() as u64;
+
+        ensure!(
+            owner_quota_voucher.objects >= content_length,
+            Error::<T>::QuotaObjectsLimitExceeded
+        );
+
+        // Ensure total content size is less or equal then available per given owner quota
+        let content_size = content
+            .iter()
+            .fold(0, |total_size, content| total_size + content.size);
+
+        ensure!(
+            owner_quota_voucher.size >= content_size,
+            Error::<T>::QuotaSizeLimitExceeded
+        );
+
+        Ok(Voucher {
+            size: content_size,
+            objects: content_length,
+        })
+    }
+
+    // Ensure content under given content ids can be successfully removed
+    fn ensure_content_can_be_removed(
+        content_ids: &[T::ContentId],
+        owner: &StorageObjectOwner<MemberId<T>, ChannelId<T>, DAOId<T>>,
+    ) -> Result<Vec<DataObject<T>>, Error<T>> {
+        let mut content = Vec::new();
+        for content_id in content_ids {
+            let data_object =
+                Self::data_object_by_content_id(content_id).ok_or(Error::<T>::CidNotFound)?;
+            ensure!(data_object.owner == *owner, Error::<T>::OwnersAreNotEqual);
+            content.push(data_object);
+        }
+
+        Ok(content)
+    }
+
+    fn calculate_content_voucher(content: Vec<DataObject<T>>) -> Voucher {
+        let content_length = content.len() as u64;
+
+        let content_size = content
+            .into_iter()
+            .fold(0, |total_size, content| total_size + content.size);
+
+        Voucher {
+            size: content_size,
+            objects: content_length,
+        }
+    }
+
+    // Ensures global quota constraints satisfied.
+    fn ensure_global_quota_constraints_satisfied(upload_voucher: Voucher) -> DispatchResult {
+        let global_quota_voucher = Self::global_quota().calculate_voucher();
+
+        ensure!(
+            global_quota_voucher.objects >= upload_voucher.objects,
+            Error::<T>::GlobalQuotaObjectsLimitExceeded
+        );
+
+        ensure!(
+            global_quota_voucher.size >= upload_voucher.size,
+            Error::<T>::GlobalQuotaSizeLimitExceeded
+        );
+
+        Ok(())
+    }
+
+    // Complete content upload, update quotas
+    fn upload_content(
+        owner_quota: Quota,
+        upload_voucher: Voucher,
+        liaison: StorageProviderId<T>,
+        multi_content: Vec<ContentParameters<T::ContentId, DataObjectTypeId<T>>>,
+        owner: StorageObjectOwner<MemberId<T>, ChannelId<T>, DAOId<T>>,
+    ) {
+        for content in multi_content {
+            let data: DataObject<T> = DataObjectInternal {
+                type_id: content.type_id,
+                size: content.size,
+                added_at: common::current_block_time::<T>(),
+                owner: owner.clone(),
+                liaison,
+                liaison_judgement: LiaisonJudgement::Pending,
+                ipfs_content_id: content.ipfs_content_id,
+            };
+
+            <DataObjectByContentId<T>>::insert(content.content_id, data);
+        }
+
+        // Updade or create owner quota.
+        <Quotas<T>>::insert(owner, owner_quota.fill_quota(upload_voucher));
+
+        // Update global quota
+        <GlobalQuota>::mutate(|global_quota| global_quota.fill_quota(upload_voucher));
+    }
+
+    // Complete content removal
+    fn delete_content(
+        owner: &StorageObjectOwner<MemberId<T>, ChannelId<T>, DAOId<T>>,
+        content_ids: &[T::ContentId],
+        content: Vec<DataObject<T>>,
+    ) {
+        let removal_voucher = Self::calculate_content_voucher(content);
+
+        for content_id in content_ids {
+            <DataObjectByContentId<T>>::remove(content_id);
+        }
+
+        // Updade owner quota.
+        <Quotas<T>>::mutate(owner, |owner_quota| {
+            owner_quota.release_quota(removal_voucher)
+        });
+
+        // Update global quota
+        <GlobalQuota>::mutate(|global_quota| global_quota.release_quota(removal_voucher));
+    }
+
+    fn ensure_content_is_valid(
+        multi_content: &[ContentParameters<T::ContentId, DataObjectTypeId<T>>],
+    ) -> DispatchResult {
+        for content in multi_content {
+            ensure!(
+                T::IsActiveDataObjectType::is_active_data_object_type(&content.type_id),
+                Error::<T>::DataObjectTypeMustBeActive
+            );
+
+            ensure!(
+                !<DataObjectByContentId<T>>::contains_key(&content.content_id),
+                Error::<T>::DataObjectAlreadyAdded
+            );
+        }
+        Ok(())
+    }
+
     fn update_content_judgement(
         storage_provider_id: &StorageProviderId<T>,
         content_id: T::ContentId,
@@ -368,3 +716,74 @@ impl<T: Trait> ContentIdExists<T> for Module<T> {
         }
     }
 }
+
+impl<T: Trait> common::storage::StorageSystem<T> for Module<T> {
+    fn atomically_add_content(
+        owner: StorageObjectOwner<MemberId<T>, ChannelId<T>, DAOId<T>>,
+        content: Vec<ContentParameters<T::ContentId, DataObjectTypeId<T>>>,
+    ) -> DispatchResult {
+        Self::ensure_content_is_valid(&content)?;
+
+        Self::ensure_uploading_is_not_blocked()?;
+
+        let owner_quota = Self::get_quota(&owner);
+
+        // Ensure owner quota constraints satisfied.
+        // Calculate upload voucher
+        let upload_voucher = Self::ensure_owner_quota_constraints_satisfied(owner_quota, &content)?;
+
+        // Ensure global quota constraints satisfied.
+        Self::ensure_global_quota_constraints_satisfied(upload_voucher)?;
+
+        let liaison = T::StorageProviderHelper::get_random_storage_provider()?;
+
+        //
+        // == MUTATION SAFE ==
+        //
+
+        // Let's create the entry then
+
+        Self::upload_content(owner_quota, upload_voucher, liaison, content, owner);
+        Ok(())
+    }
+
+    fn atomically_remove_content(
+        owner: &StorageObjectOwner<MemberId<T>, ChannelId<T>, DAOId<T>>,
+        content_ids: &[T::ContentId],
+    ) -> DispatchResult {
+        // Ensure content under given content ids can be successfully removed
+        let content = Self::ensure_content_can_be_removed(content_ids, owner)?;
+
+        //
+        // == MUTATION SAFE ==
+        //
+
+        // Let's remove a content
+        Self::delete_content(owner, content_ids, content);
+        Ok(())
+    }
+
+    fn can_add_content(
+        owner: StorageObjectOwner<MemberId<T>, ChannelId<T>, DAOId<T>>,
+        content: Vec<ContentParameters<T::ContentId, DataObjectTypeId<T>>>,
+    ) -> DispatchResult {
+        Self::ensure_uploading_is_not_blocked()?;
+
+        T::StorageProviderHelper::get_random_storage_provider()?;
+        let owner_quota = Self::get_quota(&owner);
+
+        // Ensure owner quota constraints satisfied.
+        Self::ensure_owner_quota_constraints_satisfied(owner_quota, &content)?;
+        Self::ensure_content_is_valid(&content)
+    }
+
+    fn can_remove_content(
+        owner: &StorageObjectOwner<MemberId<T>, ChannelId<T>, DAOId<T>>,
+        content_ids: &[ContentId<T>],
+    ) -> DispatchResult {
+        // Ensure content under given content ids can be successfully removed
+        Self::ensure_content_can_be_removed(content_ids, &owner)?;
+
+        Ok(())
+    }
+}

+ 8 - 5
runtime-modules/storage/src/data_object_storage_registry.rs

@@ -30,7 +30,7 @@ use sp_runtime::traits::{MaybeSerialize, Member};
 use sp_std::vec::Vec;
 
 use crate::data_directory::{self, ContentIdExists};
-use crate::{StorageProviderId, StorageWorkingGroup, StorageWorkingGroupInstance};
+use crate::*;
 
 const DEFAULT_FIRST_RELATIONSHIP_ID: u8 = 1;
 
@@ -79,7 +79,7 @@ decl_error! {
 #[derive(Clone, Encode, Decode, PartialEq, Debug)]
 pub struct DataObjectStorageRelationship<T: Trait> {
     /// Content id.
-    pub content_id: <T as data_directory::Trait>::ContentId,
+    pub content_id: <T as common::StorageOwnership>::ContentId,
 
     /// Storge provider id.
     pub storage_provider_id: StorageProviderId<T>,
@@ -111,7 +111,7 @@ decl_storage! {
 decl_event! {
     /// _Data object storage registry_ events
     pub enum Event<T> where
-        <T as data_directory::Trait>::ContentId,
+        <T as common::StorageOwnership>::ContentId,
         <T as Trait>::DataObjectStorageRelationshipId,
         StorageProviderId = StorageProviderId<T>
     {
@@ -124,9 +124,10 @@ decl_event! {
 
         /// Emits on adding of the data object storage relationship.
         /// Params:
+        /// - Id of the storage provider.
         /// - Id of the relationship.
         /// - Current state of the relationship (True=Active).
-        DataObjectStorageRelationshipReadyUpdated(DataObjectStorageRelationshipId, bool),
+        DataObjectStorageRelationshipReadyUpdated(StorageProviderId, DataObjectStorageRelationshipId, bool),
     }
 }
 
@@ -226,7 +227,9 @@ impl<T: Trait> Module<T> {
         // Update DOSR and fire event.
         <Relationships<T>>::insert(id, dosr);
         Self::deposit_event(RawEvent::DataObjectStorageRelationshipReadyUpdated(
-            id, ready,
+            storage_provider_id,
+            id,
+            ready,
         ));
 
         Ok(())

+ 25 - 29
runtime-modules/storage/src/data_object_type_registry.rs

@@ -22,33 +22,26 @@
 // Do not delete! Cannot be uncommented by default, because of Parity decl_module! issue.
 //#![warn(missing_docs)]
 
-use codec::{Codec, Decode, Encode};
+use codec::{Decode, Encode};
 use frame_support::dispatch::DispatchError;
 use frame_support::weights::Weight;
-use frame_support::{decl_error, decl_event, decl_module, decl_storage, Parameter};
-use sp_arithmetic::traits::BaseArithmetic;
-use sp_runtime::traits::{MaybeSerialize, Member};
+use frame_support::{decl_error, decl_event, decl_module, decl_storage};
 use sp_std::vec::Vec;
 
-use crate::{StorageWorkingGroup, StorageWorkingGroupInstance};
+use crate::{DataObjectTypeId, StorageWorkingGroup, StorageWorkingGroupInstance};
 
 const DEFAULT_TYPE_DESCRIPTION: &str = "Default data object type for audio and video content.";
 const DEFAULT_FIRST_DATA_OBJECT_TYPE_ID: u8 = 1;
 
 /// The _Data object type registry_ main _Trait_.
-pub trait Trait: system::Trait + working_group::Trait<StorageWorkingGroupInstance> {
+pub trait Trait:
+    system::Trait
+    + working_group::Trait<StorageWorkingGroupInstance>
+    + common::MembershipTypes
+    + common::StorageOwnership
+{
     /// _Data object type registry_ event type.
     type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
-
-    /// _Data object type id_ type
-    type DataObjectTypeId: Parameter
-        + Member
-        + BaseArithmetic
-        + Codec
-        + Default
-        + Copy
-        + MaybeSerialize
-        + PartialEq;
 }
 
 decl_error! {
@@ -63,7 +56,7 @@ decl_error! {
 }
 
 /// Contains description and constrains for the data object.
-#[derive(Clone, Encode, Decode, PartialEq, Debug)]
+#[derive(Clone, Encode, Decode, PartialEq, Eq, Debug)]
 pub struct DataObjectType {
     /// Data object description.
     pub description: Vec<u8>,
@@ -85,31 +78,34 @@ decl_storage! {
     trait Store for Module<T: Trait> as DataObjectTypeRegistry {
         /// Data object type ids should start at this value.
         pub FirstDataObjectTypeId get(fn first_data_object_type_id) config(first_data_object_type_id):
-            T::DataObjectTypeId = T::DataObjectTypeId::from(DEFAULT_FIRST_DATA_OBJECT_TYPE_ID);
+            DataObjectTypeId<T> = DataObjectTypeId::<T>::from(DEFAULT_FIRST_DATA_OBJECT_TYPE_ID);
 
         /// Provides id counter for the data object types.
         pub NextDataObjectTypeId get(fn next_data_object_type_id) build(|config: &GenesisConfig<T>|
-            config.first_data_object_type_id): T::DataObjectTypeId = T::DataObjectTypeId::from(DEFAULT_FIRST_DATA_OBJECT_TYPE_ID);
+            config.first_data_object_type_id): DataObjectTypeId<T> = DataObjectTypeId::<T>::from(DEFAULT_FIRST_DATA_OBJECT_TYPE_ID);
 
         /// Mapping of Data object types.
         pub DataObjectTypes get(fn data_object_types): map hasher(blake2_128_concat)
-            T::DataObjectTypeId => Option<DataObjectType>;
+            DataObjectTypeId<T> => Option<DataObjectType>;
     }
 }
 
 decl_event! {
     /// _Data object type registry_ events
     pub enum Event<T> where
-        <T as Trait>::DataObjectTypeId {
+        DataObjectTypeId = DataObjectTypeId<T>
+    {
         /// Emits on the data object type registration.
         /// Params:
+        /// - DataObjectType
         /// - Id of the new data object type.
-        DataObjectTypeRegistered(DataObjectTypeId),
+        DataObjectTypeRegistered(DataObjectType, DataObjectTypeId),
 
         /// Emits on the data object type update.
         /// Params:
         /// - Id of the updated data object type.
-        DataObjectTypeUpdated(DataObjectTypeId),
+        /// - DataObjectType
+        DataObjectTypeUpdated(DataObjectTypeId, DataObjectType),
     }
 }
 
@@ -153,7 +149,7 @@ decl_module! {
             <DataObjectTypes<T>>::insert(new_do_type_id, do_type);
             <NextDataObjectTypeId<T>>::mutate(|n| { *n += T::DataObjectTypeId::from(1); });
 
-            Self::deposit_event(RawEvent::DataObjectTypeRegistered(new_do_type_id));
+            Self::deposit_event(RawEvent::DataObjectTypeRegistered(data_object_type, new_do_type_id));
         }
 
         /// Updates existing data object type. Requires leader privileges.
@@ -172,7 +168,7 @@ decl_module! {
 
             <DataObjectTypes<T>>::insert(id, do_type);
 
-            Self::deposit_event(RawEvent::DataObjectTypeUpdated(id));
+            Self::deposit_event(RawEvent::DataObjectTypeUpdated(id, data_object_type));
         }
 
         /// Activates existing data object type. Requires leader privileges.
@@ -188,9 +184,9 @@ decl_module! {
             // == MUTATION SAFE ==
             //
 
-            <DataObjectTypes<T>>::insert(id, do_type);
+            <DataObjectTypes<T>>::insert(id, do_type.clone());
 
-            Self::deposit_event(RawEvent::DataObjectTypeUpdated(id));
+            Self::deposit_event(RawEvent::DataObjectTypeUpdated(id, do_type));
         }
 
         /// Deactivates existing data object type. Requires leader privileges.
@@ -206,9 +202,9 @@ decl_module! {
             // == MUTATION SAFE ==
             //
 
-            <DataObjectTypes<T>>::insert(id, do_type);
+            <DataObjectTypes<T>>::insert(id, do_type.clone());
 
-            Self::deposit_event(RawEvent::DataObjectTypeUpdated(id));
+            Self::deposit_event(RawEvent::DataObjectTypeUpdated(id, do_type));
         }
     }
 }

+ 13 - 1
runtime-modules/storage/src/lib.rs

@@ -14,7 +14,19 @@ pub type StorageWorkingGroupInstance = working_group::Instance2;
 pub(crate) type StorageWorkingGroup<T> = working_group::Module<T, StorageWorkingGroupInstance>;
 
 // Alias for the member id.
-pub(crate) type MemberId<T> = <T as membership::Trait>::MemberId;
+pub(crate) type MemberId<T> = <T as common::MembershipTypes>::MemberId;
+
+// Alias for the content id.
+pub(crate) type ContentId<T> = <T as common::StorageOwnership>::ContentId;
+
+// Alias for the channel id.
+pub(crate) type ChannelId<T> = <T as common::StorageOwnership>::ChannelId;
+
+// Alias for the dao id.
+pub(crate) type DAOId<T> = <T as common::StorageOwnership>::DAOId;
+
+/// DAO object type id.
+pub(crate) type DataObjectTypeId<T> = <T as common::StorageOwnership>::DataObjectTypeId;
 
 /// Storage provider is a worker from the working group module.
 pub type StorageProviderId<T> = working_group::WorkerId<T>;

+ 83 - 199
runtime-modules/storage/src/tests/data_directory.rs

@@ -1,7 +1,7 @@
 #![cfg(test)]
 
+use common::storage::StorageObjectOwner;
 use frame_support::dispatch::DispatchError;
-use sp_std::collections::btree_map::BTreeMap;
 use system::RawOrigin;
 
 use super::mock::*;
@@ -10,16 +10,26 @@ use super::mock::*;
 fn succeed_adding_content() {
     with_default_mock_builder(|| {
         let sender = 1u64;
-        let member_id = 1u64;
+        let owner = StorageObjectOwner::Member(1u64);
+
+        let first_content_parameters = ContentParameters {
+            content_id: 1,
+            type_id: 1234,
+            size: 0,
+            ipfs_content_id: vec![1, 2, 3, 4],
+        };
+
+        let second_content_parameters = ContentParameters {
+            content_id: 2,
+            type_id: 2,
+            size: 20,
+            ipfs_content_id: vec![1, 2, 7, 9],
+        };
+
+        let multi_content = vec![first_content_parameters, second_content_parameters];
+
         // Register a content with 1234 bytes of type 1, which should be recognized.
-        let res = TestDataDirectory::add_content(
-            Origin::signed(sender),
-            member_id,
-            1,
-            1234,
-            0,
-            vec![1, 3, 3, 7],
-        );
+        let res = TestDataDirectory::add_content(Origin::signed(sender), owner, multi_content);
         assert!(res.is_ok());
     });
 }
@@ -27,16 +37,18 @@ fn succeed_adding_content() {
 #[test]
 fn add_content_fails_with_invalid_origin() {
     with_default_mock_builder(|| {
-        let member_id = 1u64;
+        let owner = StorageObjectOwner::Member(1u64);
+
+        let content_parameters = ContentParameters {
+            content_id: 1,
+            type_id: 1234,
+            size: 0,
+            ipfs_content_id: vec![1, 2, 3, 4],
+        };
+
         // Register a content with 1234 bytes of type 1, which should be recognized.
-        let res = TestDataDirectory::add_content(
-            RawOrigin::Root.into(),
-            member_id,
-            1,
-            1234,
-            0,
-            vec![1, 3, 3, 7],
-        );
+        let res =
+            TestDataDirectory::add_content(RawOrigin::Root.into(), owner, vec![content_parameters]);
         assert_eq!(res, Err(DispatchError::Other("Bad origin")));
     });
 }
@@ -52,24 +64,24 @@ fn accept_and_reject_content_fail_with_invalid_storage_provider() {
         run_to_block(1);
 
         let sender = 1u64;
-        let member_id = 1u64;
-
-        let res = TestDataDirectory::add_content(
-            Origin::signed(sender),
-            member_id,
-            1,
-            1234,
-            0,
-            vec![1, 2, 3, 4],
-        );
+        let owner = StorageObjectOwner::Member(1u64);
+
+        let content_parameters = ContentParameters {
+            content_id: 1,
+            type_id: 1234,
+            size: 0,
+            ipfs_content_id: vec![1, 2, 3, 4],
+        };
+
+        let res =
+            TestDataDirectory::add_content(Origin::signed(sender), owner, vec![content_parameters]);
         assert!(res.is_ok());
 
-        let (content_id, _) = match System::events().last().unwrap().event {
-            MetaEvent::data_directory(data_directory::RawEvent::ContentAdded(
-                content_id,
-                creator,
-            )) => (content_id, creator),
-            _ => (0u64, 0xdeadbeefu64), // invalid value, unlikely to match
+        let content_id = match &System::events().last().unwrap().event {
+            MetaEvent::data_directory(data_directory::RawEvent::ContentAdded(content, _)) => {
+                content[0].content_id
+            }
+            _ => 0u64,
         };
 
         //  invalid data
@@ -102,28 +114,28 @@ fn accept_content_as_liaison() {
         run_to_block(1);
 
         let sender = 1u64;
-        let member_id = 1u64;
-
-        let res = TestDataDirectory::add_content(
-            Origin::signed(sender),
-            member_id,
-            1,
-            1234,
-            0,
-            vec![1, 2, 3, 4],
-        );
+        let owner = StorageObjectOwner::Member(1u64);
+
+        let content_parameters = ContentParameters {
+            content_id: 1,
+            type_id: 1234,
+            size: 0,
+            ipfs_content_id: vec![1, 2, 3, 4],
+        };
+
+        let res =
+            TestDataDirectory::add_content(Origin::signed(sender), owner, vec![content_parameters]);
         assert!(res.is_ok());
 
         // An appropriate event should have been fired.
-        let (content_id, creator) = match System::events().last().unwrap().event {
-            MetaEvent::data_directory(data_directory::RawEvent::ContentAdded(
-                content_id,
-                creator,
-            )) => (content_id, creator),
-            _ => (0u64, 0xdeadbeefu64), // invalid value, unlikely to match
+        let (content_id, creator) = match &System::events().last().unwrap().event {
+            MetaEvent::data_directory(data_directory::RawEvent::ContentAdded(content, creator)) => {
+                (content[0].content_id, creator.clone())
+            }
+            _ => (0u64, StorageObjectOwner::Member(0xdeadbeefu64)), // invalid value, unlikely to match
         };
-        assert_ne!(creator, 0xdeadbeefu64);
-        assert_eq!(creator, sender);
+        assert_ne!(creator, StorageObjectOwner::Member(0xdeadbeefu64));
+        assert_eq!(creator, StorageObjectOwner::Member(sender));
 
         let (storage_provider_account_id, storage_provider_id) = hire_storage_provider();
 
@@ -153,28 +165,28 @@ fn reject_content_as_liaison() {
         run_to_block(1);
 
         let sender = 1u64;
-        let member_id = 1u64;
-
-        let res = TestDataDirectory::add_content(
-            Origin::signed(sender),
-            member_id,
-            1,
-            1234,
-            0,
-            vec![1, 2, 3, 4],
-        );
+        let owner = StorageObjectOwner::Member(1u64);
+
+        let content_parameters = ContentParameters {
+            content_id: 1,
+            type_id: 1234,
+            size: 0,
+            ipfs_content_id: vec![1, 2, 3, 4],
+        };
+
+        let res =
+            TestDataDirectory::add_content(Origin::signed(sender), owner, vec![content_parameters]);
         assert!(res.is_ok());
 
         // An appropriate event should have been fired.
-        let (content_id, creator) = match System::events().last().unwrap().event {
-            MetaEvent::data_directory(data_directory::RawEvent::ContentAdded(
-                content_id,
-                creator,
-            )) => (content_id, creator),
-            _ => (0u64, 0xdeadbeefu64), // invalid value, unlikely to match
+        let (content_id, creator) = match &System::events().last().unwrap().event {
+            MetaEvent::data_directory(data_directory::RawEvent::ContentAdded(content, creator)) => {
+                (content[0].content_id, creator.clone())
+            }
+            _ => (0u64, StorageObjectOwner::Member(0xdeadbeefu64)), // invalid value, unlikely to match
         };
-        assert_ne!(creator, 0xdeadbeefu64);
-        assert_eq!(creator, sender);
+        assert_ne!(creator, StorageObjectOwner::Member(0xdeadbeefu64));
+        assert_eq!(creator, StorageObjectOwner::Member(sender));
 
         let (storage_provider_account_id, storage_provider_id) = hire_storage_provider();
 
@@ -192,131 +204,3 @@ fn reject_content_as_liaison() {
         assert_eq!(res, Ok(()));
     });
 }
-
-#[test]
-fn data_object_injection_works() {
-    with_default_mock_builder(|| {
-        // No objects in directory before injection
-        assert_eq!(TestDataDirectory::known_content_ids(), vec![]);
-
-        // new objects to inject into the directory
-        let mut objects = BTreeMap::new();
-
-        let object = data_directory::DataObjectInternal {
-            type_id: 1,
-            size: 1234,
-            added_at: data_directory::BlockAndTime {
-                block: 10,
-                time: 1024,
-            },
-            owner: 1,
-            liaison: TEST_MOCK_LIAISON_STORAGE_PROVIDER_ID,
-            liaison_judgement: data_directory::LiaisonJudgement::Pending,
-            ipfs_content_id: vec![],
-        };
-
-        let content_id_1 = 1;
-        objects.insert(content_id_1, object.clone());
-
-        let content_id_2 = 2;
-        objects.insert(content_id_2, object.clone());
-
-        let res = TestDataDirectory::inject_data_objects(RawOrigin::Root.into(), objects);
-        assert!(res.is_ok());
-
-        assert_eq!(
-            TestDataDirectory::known_content_ids(),
-            vec![content_id_1, content_id_2]
-        );
-
-        assert_eq!(
-            TestDataDirectory::data_object_by_content_id(content_id_1),
-            Some(object.clone())
-        );
-
-        assert_eq!(
-            TestDataDirectory::data_object_by_content_id(content_id_2),
-            Some(object)
-        );
-    });
-}
-
-#[test]
-fn data_object_injection_overwrites_and_removes_duplicate_ids() {
-    with_default_mock_builder(|| {
-        let sender = 1u64;
-        let member_id = 1u64;
-        let content_id_1 = 1;
-        let content_id_2 = 2;
-
-        // Start with some existing objects in directory which will be
-        // overwritten
-        let res = TestDataDirectory::add_content(
-            Origin::signed(sender),
-            member_id,
-            content_id_1,
-            1,
-            10,
-            vec![8, 8, 8, 8],
-        );
-        assert!(res.is_ok());
-        let res = TestDataDirectory::add_content(
-            Origin::signed(sender),
-            member_id,
-            content_id_2,
-            2,
-            20,
-            vec![9, 9, 9, 9],
-        );
-        assert!(res.is_ok());
-
-        let mut objects = BTreeMap::new();
-
-        let object1 = data_directory::DataObjectInternal {
-            type_id: 1,
-            size: 6666,
-            added_at: data_directory::BlockAndTime {
-                block: 10,
-                time: 1000,
-            },
-            owner: 5,
-            liaison: TEST_MOCK_LIAISON_STORAGE_PROVIDER_ID,
-            liaison_judgement: data_directory::LiaisonJudgement::Pending,
-            ipfs_content_id: vec![5, 6, 7],
-        };
-
-        let object2 = data_directory::DataObjectInternal {
-            type_id: 1,
-            size: 7777,
-            added_at: data_directory::BlockAndTime {
-                block: 20,
-                time: 2000,
-            },
-            owner: 6,
-            liaison: TEST_MOCK_LIAISON_STORAGE_PROVIDER_ID,
-            liaison_judgement: data_directory::LiaisonJudgement::Pending,
-            ipfs_content_id: vec![5, 6, 7],
-        };
-
-        objects.insert(content_id_1, object1.clone());
-        objects.insert(content_id_2, object2.clone());
-
-        let res = TestDataDirectory::inject_data_objects(RawOrigin::Root.into(), objects);
-        assert!(res.is_ok());
-
-        assert_eq!(
-            TestDataDirectory::known_content_ids(),
-            vec![content_id_1, content_id_2]
-        );
-
-        assert_eq!(
-            TestDataDirectory::data_object_by_content_id(content_id_1),
-            Some(object1.clone())
-        );
-
-        assert_eq!(
-            TestDataDirectory::data_object_by_content_id(content_id_2),
-            Some(object2)
-        );
-    });
-}

+ 3 - 1
runtime-modules/storage/src/tests/data_object_storage_registry.rs

@@ -156,7 +156,9 @@ fn test_toggle_ready() {
             System::events().last().unwrap().event,
             MetaEvent::data_object_storage_registry(
                 data_object_storage_registry::RawEvent::DataObjectStorageRelationshipReadyUpdated(
-                    dosr_id, true,
+                    storage_provider_id,
+                    dosr_id,
+                    true,
                 )
             )
         );

+ 12 - 8
runtime-modules/storage/src/tests/data_object_type_registry.rs

@@ -35,7 +35,7 @@ impl SetLeadFixture {
 fn get_last_data_object_type_id() -> u64 {
     let dot_id = match System::events().last().unwrap().event {
         MetaEvent::data_object_type_registry(
-            data_object_type_registry::RawEvent::DataObjectTypeRegistered(dot_id),
+            data_object_type_registry::RawEvent::DataObjectTypeRegistered(_, dot_id),
         ) => dot_id,
         _ => 0xdeadbeefu64, // unlikely value
     };
@@ -242,7 +242,7 @@ fn update_existing() {
         let res = TestDataObjectTypeRegistry::update_data_object_type(
             RawOrigin::Signed(DEFAULT_LEADER_ACCOUNT_ID).into(),
             dot_id,
-            updated3,
+            updated3.clone(),
         );
         assert!(res.is_ok());
         assert_eq!(
@@ -250,7 +250,7 @@ fn update_existing() {
             EventRecord {
                 phase: Phase::Initialization,
                 event: MetaEvent::data_object_type_registry(
-                    data_object_type_registry::RawEvent::DataObjectTypeUpdated(dot_id)
+                    data_object_type_registry::RawEvent::DataObjectTypeUpdated(dot_id, updated3)
                 ),
                 topics: vec![],
             }
@@ -295,7 +295,7 @@ fn activate_existing() {
         };
         let id_res = TestDataObjectTypeRegistry::register_data_object_type(
             RawOrigin::Signed(DEFAULT_LEADER_ACCOUNT_ID).into(),
-            data,
+            data.clone(),
         );
         assert!(id_res.is_ok());
         assert_eq!(
@@ -304,6 +304,7 @@ fn activate_existing() {
                 phase: Phase::Initialization,
                 event: MetaEvent::data_object_type_registry(
                     data_object_type_registry::RawEvent::DataObjectTypeRegistered(
+                        data,
                         expected_data_object_type_id
                     )
                 ),
@@ -312,9 +313,9 @@ fn activate_existing() {
         );
 
         // Retrieve, and ensure it's not active.
-        let data = TestDataObjectTypeRegistry::data_object_types(expected_data_object_type_id);
-        assert!(data.is_some());
-        assert!(!data.unwrap().active);
+        let mut data =
+            TestDataObjectTypeRegistry::data_object_types(expected_data_object_type_id).unwrap();
+        assert!(!data.active);
 
         // Now activate the data object type
         let res = TestDataObjectTypeRegistry::activate_data_object_type(
@@ -322,13 +323,16 @@ fn activate_existing() {
             expected_data_object_type_id,
         );
         assert!(res.is_ok());
+
+        data.active = true;
         assert_eq!(
             *System::events().last().unwrap(),
             EventRecord {
                 phase: Phase::Initialization,
                 event: MetaEvent::data_object_type_registry(
                     data_object_type_registry::RawEvent::DataObjectTypeUpdated(
-                        expected_data_object_type_id
+                        expected_data_object_type_id,
+                        data
                     )
                 ),
                 topics: vec![],

+ 41 - 7
runtime-modules/storage/src/tests/mock.rs

@@ -11,7 +11,10 @@ use sp_runtime::{
 };
 
 use crate::data_directory::ContentIdExists;
+use crate::data_directory::Quota;
+pub use crate::data_directory::{ContentParameters, StorageObjectOwner};
 use crate::data_object_type_registry::IsActiveDataObjectType;
+use crate::ContentId;
 pub use crate::StorageWorkingGroupInstance;
 pub use crate::{data_directory, data_object_storage_registry, data_object_type_registry};
 use common::currency::GovernanceCurrency;
@@ -59,12 +62,12 @@ impl<T: data_object_type_registry::Trait> IsActiveDataObjectType<T> for AnyDataO
 
 pub struct MockContent {}
 impl ContentIdExists<Test> for MockContent {
-    fn has_content(which: &<Test as data_directory::Trait>::ContentId) -> bool {
+    fn has_content(which: &ContentId<Test>) -> bool {
         *which == TEST_MOCK_EXISTING_CID
     }
 
     fn get_data_object(
-        which: &<Test as data_directory::Trait>::ContentId,
+        which: &ContentId<Test>,
     ) -> Result<data_directory::DataObject<Test>, &'static str> {
         match *which {
             TEST_MOCK_EXISTING_CID => Ok(data_directory::DataObjectInternal {
@@ -74,7 +77,7 @@ impl ContentIdExists<Test> for MockContent {
                     block: 10,
                     time: 1024,
                 },
-                owner: 1,
+                owner: StorageObjectOwner::Member(1),
                 liaison: TEST_MOCK_LIAISON_STORAGE_PROVIDER_ID,
                 liaison_judgement: data_directory::LiaisonJudgement::Pending,
                 ipfs_content_id: vec![],
@@ -93,7 +96,7 @@ parameter_types! {
     pub const MaximumBlockLength: u32 = 2 * 1024;
     pub const AvailableBlockRatio: Perbill = Perbill::one();
     pub const MinimumPeriod: u64 = 5;
-    pub const MaxObjectsPerInjection: u32 = 5;
+    pub const DefaultQuota: Quota = Quota::new(5000, 50);
 }
 
 impl system::Trait for Test {
@@ -129,6 +132,18 @@ impl pallet_timestamp::Trait for Test {
     type MinimumPeriod = MinimumPeriod;
 }
 
+impl common::MembershipTypes for Test {
+    type MemberId = u64;
+    type ActorId = u64;
+}
+
+impl common::StorageOwnership for Test {
+    type ChannelId = u64;
+    type DAOId = u64;
+    type ContentId = u64;
+    type DataObjectTypeId = u64;
+}
+
 parameter_types! {
     pub const ExistentialDeposit: u32 = 0;
     pub const StakePoolId: [u8; 8] = *b"joystake";
@@ -157,16 +172,14 @@ impl working_group::Trait<StorageWorkingGroupInstance> for Test {
 
 impl data_object_type_registry::Trait for Test {
     type Event = MetaEvent;
-    type DataObjectTypeId = u64;
 }
 
 impl data_directory::Trait for Test {
     type Event = MetaEvent;
-    type ContentId = u64;
     type StorageProviderHelper = ();
     type IsActiveDataObjectType = AnyDataObjectTypeIsActive;
     type MemberOriginValidator = ();
-    type MaxObjectsPerInjection = MaxObjectsPerInjection;
+    type DefaultQuota = DefaultQuota;
 }
 
 impl crate::data_directory::StorageProviderHelper<Test> for () {
@@ -224,6 +237,9 @@ impl hiring::Trait for Test {
 }
 
 pub struct ExtBuilder {
+    quota_objects_limit_upper_bound: u64,
+    quota_size_limit_upper_bound: u64,
+    global_quota: Quota,
     first_data_object_type_id: u64,
     first_content_id: u64,
     first_relationship_id: u64,
@@ -233,6 +249,9 @@ pub struct ExtBuilder {
 impl Default for ExtBuilder {
     fn default() -> Self {
         Self {
+            quota_objects_limit_upper_bound: 200,
+            quota_size_limit_upper_bound: 20000,
+            global_quota: Quota::new(2000000, 2000),
             first_data_object_type_id: 1,
             first_content_id: 2,
             first_relationship_id: 3,
@@ -246,23 +265,38 @@ impl ExtBuilder {
         self.first_data_object_type_id = first_data_object_type_id;
         self
     }
+
     pub fn first_content_id(mut self, first_content_id: u64) -> Self {
         self.first_content_id = first_content_id;
         self
     }
+
     pub fn first_relationship_id(mut self, first_relationship_id: u64) -> Self {
         self.first_relationship_id = first_relationship_id;
         self
     }
+
     pub fn first_metadata_id(mut self, first_metadata_id: u64) -> Self {
         self.first_metadata_id = first_metadata_id;
         self
     }
+
     pub fn build(self) -> sp_io::TestExternalities {
         let mut t = system::GenesisConfig::default()
             .build_storage::<Test>()
             .unwrap();
 
+        data_directory::GenesisConfig::<Test> {
+            quota_size_limit_upper_bound: self.quota_size_limit_upper_bound,
+            quota_objects_limit_upper_bound: self.quota_objects_limit_upper_bound,
+            global_quota: self.global_quota,
+            data_object_by_content_id: vec![],
+            quotas: vec![],
+            uploading_blocked: false,
+        }
+        .assimilate_storage(&mut t)
+        .unwrap();
+
         data_object_type_registry::GenesisConfig::<Test> {
             first_data_object_type_id: self.first_data_object_type_id,
         }

+ 2 - 3
runtime/Cargo.toml

@@ -75,8 +75,7 @@ service-discovery = { package = 'pallet-service-discovery', default-features = f
 proposals-engine = { package = 'pallet-proposals-engine', default-features = false, path = '../runtime-modules/proposals/engine'}
 proposals-discussion = { package = 'pallet-proposals-discussion', default-features = false, path = '../runtime-modules/proposals/discussion'}
 proposals-codex = { package = 'pallet-proposals-codex', default-features = false, path = '../runtime-modules/proposals/codex'}
-content-directory = { package = 'pallet-content-directory', default-features = false, path = '../runtime-modules/content-directory' }
-# content = { package = 'pallet-content', default-features = false, path = '../runtime-modules/content' }
+content = { package = 'pallet-content', default-features = false, path = '../runtime-modules/content' }
 
 [dev-dependencies]
 sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
@@ -150,7 +149,7 @@ std = [
     'proposals-engine/std',
     'proposals-discussion/std',
     'proposals-codex/std',
-    'content-directory/std',
+    'content/std',
 ]
 runtime-benchmarks = [
     "system/runtime-benchmarks",

部分文件因文件數量過多而無法顯示