From 7a1280918e13bab5973b69a3f851ecfe57bd6f4a Mon Sep 17 00:00:00 2001
From: Hugo Trentesaux <hugo.trentesaux@lilo.org>
Date: Wed, 3 May 2023 12:45:35 +0200
Subject: [PATCH] add tests (nodes/rust/duniter-v2s!151)

* fix not enough for transfer

* cucumber: add identity validation

* wip add revocation test
---
 .../identity_creation.feature                 | 22 +++++---
 end2end-tests/tests/common/identity.rs        | 29 ++++++++++-
 end2end-tests/tests/common/mod.rs             |  5 +-
 end2end-tests/tests/cucumber_tests.rs         | 43 ++++++++++------
 pallets/duniter-wot/src/tests.rs              | 50 +++++++++++++++++++
 5 files changed, 124 insertions(+), 25 deletions(-)

diff --git a/end2end-tests/cucumber-features/identity_creation.feature b/end2end-tests/cucumber-features/identity_creation.feature
index 2cc5bcc99..81113d8b1 100644
--- a/end2end-tests/cucumber-features/identity_creation.feature
+++ b/end2end-tests/cucumber-features/identity_creation.feature
@@ -5,11 +5,21 @@ Feature: Identity creation
     # - account creation fees (3 ÄžD) 
     # - existential deposit (2 ÄžD)
     # - transaction fees (below 1 ÄžD)
-    When alice sends 6 ÄžD to ferdie
+    When alice sends 6 ÄžD to dave
+    When bob sends 6 ÄžD to eve
     # alice last certification is counted from block zero
-    # then next cert can be done after cert_period
+    # then next cert can be done after cert_period, which is 15
     When 15 block later
-    When alice creates identity for ferdie
-    Then ferdie identity should be created
-    When ferdie confirms his identity with pseudo "Ferdie"
-    Then ferdie identity should be confirmed 
+    When alice creates identity for dave
+    Then dave identity should be created
+    Then dave should be certified by alice
+    When dave confirms his identity with pseudo "dave"
+    Then dave identity should be confirmed
+    When 3 block later
+    When bob certifies dave
+    When charlie certifies dave
+    Then dave should be certified by bob
+    Then dave should be certified by charlie
+    When 3 block later
+    When eve validates dave identity
+    Then dave identity should be validated
diff --git a/end2end-tests/tests/common/identity.rs b/end2end-tests/tests/common/identity.rs
index 0f21cb5aa..58e881264 100644
--- a/end2end-tests/tests/common/identity.rs
+++ b/end2end-tests/tests/common/identity.rs
@@ -72,8 +72,27 @@ pub async fn confirm_identity(client: &Client, from: AccountKeyring, pseudo: Str
     Ok(())
 }
 
-// get identity value from account keyring name
-pub async fn get_identity_value(world: &mut DuniterWorld, account: String) -> Result<IdtyValue> {
+pub async fn validate_identity(client: &Client, from: AccountKeyring, to: u32) -> Result<()> {
+    let from = PairSigner::new(from.pair());
+
+    let _events = create_block_with_extrinsic(
+        client,
+        client
+            .tx()
+            .create_signed(
+                &gdev::tx().identity().validate_identity(to),
+                &from,
+                BaseExtrinsicParamsBuilder::new(),
+            )
+            .await?,
+    )
+    .await?;
+
+    Ok(())
+}
+
+// get identity index from account keyring name
+pub async fn get_identity_index(world: &mut DuniterWorld, account: String) -> Result<u32> {
     let account = AccountKeyring::from_str(&account)
         .expect("unknown account")
         .to_account_id();
@@ -84,6 +103,12 @@ pub async fn get_identity_value(world: &mut DuniterWorld, account: String) -> Re
         .ok_or_else(|| anyhow::anyhow!("identity {} has no associated index", account))
         .unwrap();
 
+    Ok(identity_index)
+}
+// get identity value from account keyring name
+pub async fn get_identity_value(world: &mut DuniterWorld, account: String) -> Result<IdtyValue> {
+    let identity_index = get_identity_index(world, account).await.unwrap();
+
     let identity_value = world
         .read(&gdev::storage().identity().identities(identity_index))
         .await?
diff --git a/end2end-tests/tests/common/mod.rs b/end2end-tests/tests/common/mod.rs
index c1fd35076..56ccdea5d 100644
--- a/end2end-tests/tests/common/mod.rs
+++ b/end2end-tests/tests/common/mod.rs
@@ -21,7 +21,10 @@ pub mod cert;
 pub mod identity;
 pub mod oneshot;
 
-#[subxt::subxt(runtime_metadata_path = "../resources/metadata.scale")]
+#[subxt::subxt(
+    runtime_metadata_path = "../resources/metadata.scale",
+    derive_for_all_types = "Eq, PartialEq"
+)]
 pub mod gdev {}
 
 use anyhow::anyhow;
diff --git a/end2end-tests/tests/cucumber_tests.rs b/end2end-tests/tests/cucumber_tests.rs
index cd7876032..094932d4b 100644
--- a/end2end-tests/tests/cucumber_tests.rs
+++ b/end2end-tests/tests/cucumber_tests.rs
@@ -313,6 +313,15 @@ async fn confirm_identity(world: &mut DuniterWorld, from: String, pseudo: String
     common::identity::confirm_identity(world.client(), from, pseudo).await
 }
 
+#[when(regex = r#"([a-zA-Z]+) validates ([a-zA-Z]+) identity"#)]
+async fn validate_identity(world: &mut DuniterWorld, from: String, to: String) -> Result<()> {
+    // input names to keyrings
+    let from = AccountKeyring::from_str(&from).expect("unknown from");
+    let to: u32 = common::identity::get_identity_index(world, to).await?;
+
+    common::identity::validate_identity(world.client(), from, to).await
+}
+
 // ===== then ====
 
 #[then(regex = r"([a-zA-Z]+) should have (\d+) (ÄžD|cÄžD)")]
@@ -430,28 +439,30 @@ async fn should_be_certified_by(
 
 use gdev::runtime_types::pallet_identity::types::IdtyStatus;
 
-#[then(regex = r"([a-zA-Z]+) identity should be created")]
-async fn identity_should_be_created(world: &mut DuniterWorld, receiver: String) -> Result<()> {
-    let identity_value = common::identity::get_identity_value(world, receiver).await?;
+// status from string
+impl FromStr for IdtyStatus {
+    type Err = String;
 
-    match identity_value.status {
-        IdtyStatus::Created => Ok(()),
-        IdtyStatus::ConfirmedByOwner | IdtyStatus::Validated => {
-            Err(anyhow::anyhow!("status not created").into())
+    fn from_str(input: &str) -> std::result::Result<IdtyStatus, String> {
+        match input {
+            "created" => Ok(IdtyStatus::Created),
+            "confirmed" => Ok(IdtyStatus::ConfirmedByOwner),
+            "validated" => Ok(IdtyStatus::Validated),
+            _ => Err(format!("'{input}' does not match a status")),
         }
     }
 }
 
-#[then(regex = r"([a-zA-Z]+) identity should be confirmed")]
-async fn identity_should_be_confirmed(world: &mut DuniterWorld, name: String) -> Result<()> {
+#[then(regex = r"([a-zA-Z]+) identity should be ([a-zA-Z ]+)")]
+async fn identity_status_should_be(
+    world: &mut DuniterWorld,
+    name: String,
+    status: String,
+) -> Result<()> {
     let identity_value = common::identity::get_identity_value(world, name).await?;
-
-    match identity_value.status {
-        IdtyStatus::ConfirmedByOwner => Ok(()),
-        IdtyStatus::Created | IdtyStatus::Validated => {
-            Err(anyhow::anyhow!("status not confirmed by owner").into())
-        }
-    }
+    let expected_status = IdtyStatus::from_str(&status)?;
+    assert_eq!(identity_value.status, expected_status);
+    Ok(())
 }
 
 // ============================================================
diff --git a/pallets/duniter-wot/src/tests.rs b/pallets/duniter-wot/src/tests.rs
index 1f40cab21..3c51f2f6b 100644
--- a/pallets/duniter-wot/src/tests.rs
+++ b/pallets/duniter-wot/src/tests.rs
@@ -251,6 +251,56 @@ fn test_confirm_idty_ok() {
     });
 }
 
+#[test]
+fn test_revoke_idty() {
+    new_test_ext(5, 1).execute_with(|| {
+        run_to_block(2);
+
+        // Alice identity can not be revoked because she's smith
+        assert_noop!(
+            Identity::revoke_identity(
+                RuntimeOrigin::signed(1),
+                1,
+                1,
+                TestSignature(
+                    1,
+                    (
+                        REVOCATION_PAYLOAD_PREFIX,
+                        RevocationPayload {
+                            idty_index: 1u32,
+                            genesis_hash: System::block_hash(0),
+                        }
+                    )
+                        .encode()
+                )
+            ),
+            pallet_duniter_wot::Error::<Test, Instance2>::NotAllowedToRemoveIdty
+        );
+
+        // Anyone should be able to submit Bob revocation certificate
+        assert_ok!(Identity::revoke_identity(
+            RuntimeOrigin::signed(42),
+            2,
+            2,
+            TestSignature(
+                2,
+                (
+                    REVOCATION_PAYLOAD_PREFIX,
+                    RevocationPayload {
+                        idty_index: 2u32,
+                        genesis_hash: System::block_hash(0),
+                    }
+                )
+                    .encode()
+            )
+        ));
+
+        System::assert_has_event(RuntimeEvent::Identity(
+            pallet_identity::Event::IdtyRemoved { idty_index: 2 },
+        ));
+    });
+}
+
 #[test]
 fn test_idty_membership_expire_them_requested() {
     new_test_ext(3, 2).execute_with(|| {
-- 
GitLab