Skip to content
Snippets Groups Projects
Commit 33630d52 authored by Hugo Trentesaux's avatar Hugo Trentesaux Committed by Éloïs
Browse files

tests(cucumber): add certification (!56)

* tests(cucumber): improve regex

* tests(cucumber): add certification
parent 0e52bc57
No related branches found
No related tags found
1 merge request!56tests(cucumber): add certification
...@@ -1517,6 +1517,7 @@ dependencies = [ ...@@ -1517,6 +1517,7 @@ dependencies = [
name = "duniter-end2end-tests" name = "duniter-end2end-tests"
version = "3.0.0" version = "3.0.0"
dependencies = [ dependencies = [
"anyhow",
"async-trait", "async-trait",
"clap", "clap",
"ctrlc", "ctrlc",
......
...@@ -9,6 +9,7 @@ repository = 'https://git.duniter.org/nodes/rust/duniter-v2s' ...@@ -9,6 +9,7 @@ repository = 'https://git.duniter.org/nodes/rust/duniter-v2s'
version = '3.0.0' version = '3.0.0'
[dev-dependencies] [dev-dependencies]
anyhow = "1.0"
async-trait = "0.1" async-trait = "0.1"
clap = { version = "3.0", features = ["derive"] } clap = { version = "3.0", features = ["derive"] }
ctrlc = "3.2.2" ctrlc = "3.2.2"
......
@genesis.wot
Feature: Certification
Scenario: Dave certifies Alice
When dave certifies alice
Then alice should be certified by dave
@ignoreErrors
Scenario: Dave certifies Alice (but dave is not certified by charlie, this test should fail)
When dave certifies alice
Then dave should be certified by charlie
\ No newline at end of file
{
"first_ud": 1000,
"first_ud_reeval": 100,
"identities": {
"Alice": {
"balance": 1000,
"certs": ["Bob", "Charlie", "Dave"],
"pubkey": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"
},
"Bob": {
"balance": 1000,
"certs": ["Alice", "Charlie", "Dave"],
"pubkey": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
},
"Charlie": {
"balance": 1000,
"certs": ["Alice", "Bob"],
"pubkey": "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y"
},
"Dave": {
"balance": 1000,
"certs": [],
"pubkey": "5DAAnrj7VHTznn2AWBemMuyBwZWs6FNFjdyVXUeYum3PTXFy"
}
},
"parameters": {
"babe_epoch_duration": 30,
"cert_period": 15,
"cert_max_by_issuer": 10,
"cert_min_received_cert_to_issue_cert": 2,
"cert_renewable_period": 50,
"cert_validity_period": 1000,
"idty_confirm_period": 40,
"idty_creation_period": 50,
"membership_period": 1000,
"membership_renewable_period": 50,
"pending_membership_period": 500,
"ud_creation_period": 10,
"ud_reeval_period": 100,
"smith_cert_period": 15,
"smith_cert_max_by_issuer": 8,
"smith_cert_min_received_cert_to_issue_cert": 2,
"smith_cert_renewable_period": 50,
"smith_cert_validity_period": 1000,
"smith_membership_period": 1000,
"smith_membership_renewable_period": 20,
"smith_pending_membership_period": 500,
"smiths_wot_first_cert_issuable_on": 20,
"smiths_wot_min_cert_for_membership": 2,
"wot_first_cert_issuable_on": 20,
"wot_min_cert_for_create_idty_right": 2,
"wot_min_cert_for_membership": 2
},
"smiths": {
"Alice": {
"certs": ["Bob", "Charlie"]
},
"Bob": {
"certs": ["Alice", "Charlie"]
},
"Charlie": {
"certs": ["Alice", "Bob"]
}
},
"sudo_key": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"
}
// Copyright 2021 Axiom-Team
//
// This file is part of Substrate-Libre-Currency.
//
// Substrate-Libre-Currency is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// Substrate-Libre-Currency is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>.
use super::node_runtime::runtime_types::gdev_runtime;
use super::node_runtime::runtime_types::pallet_certification;
use super::*;
use sp_keyring::AccountKeyring;
use subxt::{sp_runtime::MultiAddress, PairSigner};
pub async fn certify(
api: &Api,
client: &Client,
from: AccountKeyring,
to: AccountKeyring,
) -> Result<()> {
let from = PairSigner::new(from.pair());
let to = to.to_account_id();
let _events = create_block_with_extrinsic(
client,
api.tx()
.cert()
.add_cert(to)
.create_signed(&from, ())
.await?,
)
.await?;
Ok(())
}
...@@ -17,10 +17,12 @@ ...@@ -17,10 +17,12 @@
#![allow(clippy::enum_variant_names, dead_code, unused_imports)] #![allow(clippy::enum_variant_names, dead_code, unused_imports)]
pub mod balances; pub mod balances;
pub mod cert;
#[subxt::subxt(runtime_metadata_path = "../resources/metadata.scale")] #[subxt::subxt(runtime_metadata_path = "../resources/metadata.scale")]
pub mod node_runtime {} pub mod node_runtime {}
use anyhow::anyhow;
use serde_json::Value; use serde_json::Value;
use sp_keyring::AccountKeyring; use sp_keyring::AccountKeyring;
use std::io::prelude::*; use std::io::prelude::*;
......
...@@ -28,6 +28,8 @@ use std::sync::{ ...@@ -28,6 +28,8 @@ use std::sync::{
Arc, Arc,
}; };
// ===== world =====
#[derive(WorldInit)] #[derive(WorldInit)]
pub struct DuniterWorld { pub struct DuniterWorld {
ignore_errors: bool, ignore_errors: bool,
...@@ -119,6 +121,8 @@ fn parse_amount(amount: u64, unit: &str) -> (u64, bool) { ...@@ -119,6 +121,8 @@ fn parse_amount(amount: u64, unit: &str) -> (u64, bool) {
} }
} }
// ===== given =====
#[given(regex = r"([a-zA-Z]+) ha(?:ve|s) (\d+) (ĞD|cĞD|UD|mUD)")] #[given(regex = r"([a-zA-Z]+) ha(?:ve|s) (\d+) (ĞD|cĞD|UD|mUD)")]
async fn who_have(world: &mut DuniterWorld, who: String, amount: u64, unit: String) -> Result<()> { async fn who_have(world: &mut DuniterWorld, who: String, amount: u64, unit: String) -> Result<()> {
// Parse inputs // Parse inputs
...@@ -141,6 +145,8 @@ async fn who_have(world: &mut DuniterWorld, who: String, amount: u64, unit: Stri ...@@ -141,6 +145,8 @@ async fn who_have(world: &mut DuniterWorld, who: String, amount: u64, unit: Stri
Ok(()) Ok(())
} }
// ===== when =====
#[when(regex = r"(\d+) blocks? later")] #[when(regex = r"(\d+) blocks? later")]
async fn n_blocks_later(world: &mut DuniterWorld, n: usize) -> Result<()> { async fn n_blocks_later(world: &mut DuniterWorld, n: usize) -> Result<()> {
for _ in 0..n { for _ in 0..n {
...@@ -175,7 +181,7 @@ async fn transfer( ...@@ -175,7 +181,7 @@ async fn transfer(
} }
} }
#[when(regex = r"([a-zA-Z]+) sends all (?:his|her) (?:ĞDs?|DUs?) to ([a-zA-Z]+)")] #[when(regex = r"([a-zA-Z]+) sends? all (?:his|her) (?:ĞDs?|DUs?|UDs?) to ([a-zA-Z]+)")]
async fn send_all_to(world: &mut DuniterWorld, from: String, to: String) -> Result<()> { async fn send_all_to(world: &mut DuniterWorld, from: String, to: String) -> Result<()> {
// Parse inputs // Parse inputs
let from = AccountKeyring::from_str(&from).expect("unknown from"); let from = AccountKeyring::from_str(&from).expect("unknown from");
...@@ -184,6 +190,17 @@ async fn send_all_to(world: &mut DuniterWorld, from: String, to: String) -> Resu ...@@ -184,6 +190,17 @@ async fn send_all_to(world: &mut DuniterWorld, from: String, to: String) -> Resu
common::balances::transfer_all(world.api(), world.client(), from, to).await common::balances::transfer_all(world.api(), world.client(), from, to).await
} }
#[when(regex = r"([a-zA-Z]+) certifies ([a-zA-Z]+)")]
async fn certifies(world: &mut DuniterWorld, from: String, to: String) -> Result<()> {
// Parse inputs
let from = AccountKeyring::from_str(&from).expect("unknown from");
let to = AccountKeyring::from_str(&to).expect("unknown to");
common::cert::certify(world.api(), world.client(), from, to).await
}
// ===== 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)")]
async fn should_have( async fn should_have(
world: &mut DuniterWorld, world: &mut DuniterWorld,
...@@ -232,6 +249,48 @@ async fn monetary_mass_should_be(world: &mut DuniterWorld, amount: u64, cents: u ...@@ -232,6 +249,48 @@ async fn monetary_mass_should_be(world: &mut DuniterWorld, amount: u64, cents: u
Ok(()) Ok(())
} }
#[then(regex = r"([a-zA-Z]+) should be certified by ([a-zA-Z]+)")]
async fn should_be_certified_by(
world: &mut DuniterWorld,
receiver: String,
issuer: String,
) -> Result<()> {
// Parse inputs
let receiver_account = AccountKeyring::from_str(&receiver)
.expect("unknown to")
.to_account_id();
let issuer_account = AccountKeyring::from_str(&issuer)
.expect("unknown to")
.to_account_id();
let issuer_index = world
.api()
.storage()
.identity()
.identity_index_of(issuer_account, None)
.await?
.unwrap();
let receiver_index = world
.api()
.storage()
.identity()
.identity_index_of(receiver_account, None)
.await?
.unwrap();
let _certification = world
.api()
.storage()
.cert()
.storage_certs_by_issuer(issuer_index, receiver_index, None)
.await?
.ok_or_else(|| anyhow::anyhow!("no certification found from {} to {}", issuer, receiver))?;
Ok(())
}
// ============================================================
#[derive(clap::Args)] #[derive(clap::Args)]
struct CustomOpts { struct CustomOpts {
/// Keep running /// Keep running
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment