Skip to content
Snippets Groups Projects
Commit 7a128091 authored by Hugo Trentesaux's avatar Hugo Trentesaux
Browse files

add tests (!151)

* fix not enough for transfer

* cucumber: add identity validation

* wip add revocation test
parent 14e540ea
Branches
Tags
1 merge request!151add tests
Pipeline #20222 failed
...@@ -5,11 +5,21 @@ Feature: Identity creation ...@@ -5,11 +5,21 @@ Feature: Identity creation
# - account creation fees (3 ĞD) # - account creation fees (3 ĞD)
# - existential deposit (2 ĞD) # - existential deposit (2 ĞD)
# - transaction fees (below 1 Ğ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 # 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 15 block later
When alice creates identity for ferdie When alice creates identity for dave
Then ferdie identity should be created Then dave identity should be created
When ferdie confirms his identity with pseudo "Ferdie" Then dave should be certified by alice
Then ferdie identity should be confirmed 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
...@@ -72,8 +72,27 @@ pub async fn confirm_identity(client: &Client, from: AccountKeyring, pseudo: Str ...@@ -72,8 +72,27 @@ pub async fn confirm_identity(client: &Client, from: AccountKeyring, pseudo: Str
Ok(()) Ok(())
} }
// get identity value from account keyring name pub async fn validate_identity(client: &Client, from: AccountKeyring, to: u32) -> Result<()> {
pub async fn get_identity_value(world: &mut DuniterWorld, account: String) -> Result<IdtyValue> { 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) let account = AccountKeyring::from_str(&account)
.expect("unknown account") .expect("unknown account")
.to_account_id(); .to_account_id();
...@@ -84,6 +103,12 @@ pub async fn get_identity_value(world: &mut DuniterWorld, account: String) -> Re ...@@ -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)) .ok_or_else(|| anyhow::anyhow!("identity {} has no associated index", account))
.unwrap(); .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 let identity_value = world
.read(&gdev::storage().identity().identities(identity_index)) .read(&gdev::storage().identity().identities(identity_index))
.await? .await?
......
...@@ -21,7 +21,10 @@ pub mod cert; ...@@ -21,7 +21,10 @@ pub mod cert;
pub mod identity; pub mod identity;
pub mod oneshot; 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 {} pub mod gdev {}
use anyhow::anyhow; use anyhow::anyhow;
......
...@@ -313,6 +313,15 @@ async fn confirm_identity(world: &mut DuniterWorld, from: String, pseudo: String ...@@ -313,6 +313,15 @@ async fn confirm_identity(world: &mut DuniterWorld, from: String, pseudo: String
common::identity::confirm_identity(world.client(), from, pseudo).await 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 ====
#[then(regex = r"([a-zA-Z]+) should have (\d+) (ĞD|cĞD)")] #[then(regex = r"([a-zA-Z]+) should have (\d+) (ĞD|cĞD)")]
...@@ -430,28 +439,30 @@ async fn should_be_certified_by( ...@@ -430,28 +439,30 @@ async fn should_be_certified_by(
use gdev::runtime_types::pallet_identity::types::IdtyStatus; use gdev::runtime_types::pallet_identity::types::IdtyStatus;
#[then(regex = r"([a-zA-Z]+) identity should be created")] // status from string
async fn identity_should_be_created(world: &mut DuniterWorld, receiver: String) -> Result<()> { impl FromStr for IdtyStatus {
let identity_value = common::identity::get_identity_value(world, receiver).await?; type Err = String;
match identity_value.status { fn from_str(input: &str) -> std::result::Result<IdtyStatus, String> {
IdtyStatus::Created => Ok(()), match input {
IdtyStatus::ConfirmedByOwner | IdtyStatus::Validated => { "created" => Ok(IdtyStatus::Created),
Err(anyhow::anyhow!("status not created").into()) "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")] #[then(regex = r"([a-zA-Z]+) identity should be ([a-zA-Z ]+)")]
async fn identity_should_be_confirmed(world: &mut DuniterWorld, name: String) -> Result<()> { 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?; let identity_value = common::identity::get_identity_value(world, name).await?;
let expected_status = IdtyStatus::from_str(&status)?;
match identity_value.status { assert_eq!(identity_value.status, expected_status);
IdtyStatus::ConfirmedByOwner => Ok(()), Ok(())
IdtyStatus::Created | IdtyStatus::Validated => {
Err(anyhow::anyhow!("status not confirmed by owner").into())
}
}
} }
// ============================================================ // ============================================================
......
...@@ -251,6 +251,56 @@ fn test_confirm_idty_ok() { ...@@ -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] #[test]
fn test_idty_membership_expire_them_requested() { fn test_idty_membership_expire_them_requested() {
new_test_ext(3, 2).execute_with(|| { new_test_ext(3, 2).execute_with(|| {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment