Files
pezkuwi-subxt/substrate/frame/identity/src/tests.rs
T
georgepisaltu 21fbc00d04 Identity pallet improvements (#2048)
This PR is a follow up to #1661 

- [x] rename the `simple` module to `legacy`
- [x] fix benchmarks to disregard the number of additional fields
- [x] change the storage deposits to charge per encoded byte of the
identity information instance, removing the need for `fn
additional(&self) -> usize` in `IdentityInformationProvider`
- [x] ~add an extrinsic to rejig deposits to account for the change
above~
- [ ] ~ensure through proper configuration that the new byte-based
deposit is always lower than whatever is reserved now~
- [x] remove `IdentityFields` from the `set_fields` extrinsic signature,
as per [this
discussion](https://github.com/paritytech/polkadot-sdk/pull/1661#discussion_r1371703403)

> ensure through proper configuration that the new byte-based deposit is
always lower than whatever is reserved now

Not sure this is needed anymore. If the new deposits are higher than
what is currently on chain and users don't have enough funds to reserve
what is needed, the extrinisc fails and they're basically grandfathered
and frozen until they add more funds and/or make a change to their
identity. This behavior seems fine to me. Original idea
[here](https://github.com/paritytech/polkadot-sdk/pull/1661#issuecomment-1779606319).

> add an extrinsic to rejig deposits to account for the change above

This was initially implemented but now removed from this PR in favor of
the implementation detailed
[here](https://github.com/paritytech/polkadot-sdk/pull/2088).

---------

Signed-off-by: georgepisaltu <george.pisaltu@parity.io>
Co-authored-by: joepetrowski <joe@parity.io>
2023-11-03 20:38:26 +01:00

715 lines
24 KiB
Rust

// This file is part of Substrate.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Tests for Identity Pallet
use super::*;
use crate::{
self as pallet_identity,
legacy::{IdentityField, IdentityInfo},
};
use codec::{Decode, Encode};
use frame_support::{
assert_noop, assert_ok, ord_parameter_types, parameter_types,
traits::{ConstU32, ConstU64, EitherOfDiverse, Get},
BoundedVec,
};
use frame_system::{EnsureRoot, EnsureSignedBy};
use sp_core::H256;
use sp_runtime::{
traits::{BadOrigin, BlakeTwo256, IdentityLookup},
BuildStorage,
};
type Block = frame_system::mocking::MockBlock<Test>;
frame_support::construct_runtime!(
pub enum Test
{
System: frame_system::{Pallet, Call, Config<T>, Storage, Event<T>},
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
Identity: pallet_identity::{Pallet, Call, Storage, Event<T>},
}
);
impl frame_system::Config for Test {
type BaseCallFilter = frame_support::traits::Everything;
type BlockWeights = ();
type BlockLength = ();
type RuntimeOrigin = RuntimeOrigin;
type Nonce = u64;
type Hash = H256;
type RuntimeCall = RuntimeCall;
type Hashing = BlakeTwo256;
type AccountId = u64;
type Lookup = IdentityLookup<Self::AccountId>;
type Block = Block;
type RuntimeEvent = RuntimeEvent;
type BlockHashCount = ConstU64<250>;
type DbWeight = ();
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = pallet_balances::AccountData<u64>;
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type SS58Prefix = ();
type OnSetCode = ();
type MaxConsumers = ConstU32<16>;
}
impl pallet_balances::Config for Test {
type Balance = u64;
type RuntimeEvent = RuntimeEvent;
type DustRemoval = ();
type ExistentialDeposit = ConstU64<1>;
type AccountStore = System;
type MaxLocks = ();
type MaxReserves = ();
type ReserveIdentifier = [u8; 8];
type WeightInfo = ();
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type MaxHolds = ();
}
parameter_types! {
pub const MaxAdditionalFields: u32 = 2;
pub const MaxRegistrars: u32 = 20;
}
ord_parameter_types! {
pub const One: u64 = 1;
pub const Two: u64 = 2;
}
type EnsureOneOrRoot = EitherOfDiverse<EnsureRoot<u64>, EnsureSignedBy<One, u64>>;
type EnsureTwoOrRoot = EitherOfDiverse<EnsureRoot<u64>, EnsureSignedBy<Two, u64>>;
impl pallet_identity::Config for Test {
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type Slashed = ();
type BasicDeposit = ConstU64<100>;
type ByteDeposit = ConstU64<10>;
type SubAccountDeposit = ConstU64<100>;
type MaxSubAccounts = ConstU32<2>;
type IdentityInformation = IdentityInfo<MaxAdditionalFields>;
type MaxRegistrars = MaxRegistrars;
type RegistrarOrigin = EnsureOneOrRoot;
type ForceOrigin = EnsureTwoOrRoot;
type WeightInfo = ();
}
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::<Test>::default().build_storage().unwrap();
pallet_balances::GenesisConfig::<Test> {
balances: vec![(1, 100), (2, 100), (3, 100), (10, 1000), (20, 1000), (30, 1000)],
}
.assimilate_storage(&mut t)
.unwrap();
t.into()
}
fn ten() -> IdentityInfo<MaxAdditionalFields> {
IdentityInfo {
display: Data::Raw(b"ten".to_vec().try_into().unwrap()),
legal: Data::Raw(b"The Right Ordinal Ten, Esq.".to_vec().try_into().unwrap()),
..Default::default()
}
}
fn twenty() -> IdentityInfo<MaxAdditionalFields> {
IdentityInfo {
display: Data::Raw(b"twenty".to_vec().try_into().unwrap()),
legal: Data::Raw(b"The Right Ordinal Twenty, Esq.".to_vec().try_into().unwrap()),
..Default::default()
}
}
fn id_deposit(id: &IdentityInfo<MaxAdditionalFields>) -> u64 {
let base_deposit: u64 = <<Test as Config>::BasicDeposit as Get<u64>>::get();
let byte_deposit: u64 = <<Test as Config>::ByteDeposit as Get<u64>>::get() *
TryInto::<u64>::try_into(id.encoded_size()).unwrap();
base_deposit + byte_deposit
}
#[test]
fn identity_fields_repr_works() {
// `IdentityField` sanity checks.
assert_eq!(IdentityField::Display as u64, 1 << 0);
assert_eq!(IdentityField::Legal as u64, 1 << 1);
assert_eq!(IdentityField::Web as u64, 1 << 2);
assert_eq!(IdentityField::Riot as u64, 1 << 3);
assert_eq!(IdentityField::Email as u64, 1 << 4);
assert_eq!(IdentityField::PgpFingerprint as u64, 1 << 5);
assert_eq!(IdentityField::Image as u64, 1 << 6);
assert_eq!(IdentityField::Twitter as u64, 1 << 7);
let fields = IdentityField::Legal |
IdentityField::Web |
IdentityField::Riot |
IdentityField::PgpFingerprint |
IdentityField::Twitter;
assert!(!fields.contains(IdentityField::Display));
assert!(fields.contains(IdentityField::Legal));
assert!(fields.contains(IdentityField::Web));
assert!(fields.contains(IdentityField::Riot));
assert!(!fields.contains(IdentityField::Email));
assert!(fields.contains(IdentityField::PgpFingerprint));
assert!(!fields.contains(IdentityField::Image));
assert!(fields.contains(IdentityField::Twitter));
// Ensure that the `u64` representation matches what we expect.
assert_eq!(
fields.bits(),
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_10101110
);
}
#[test]
fn editing_subaccounts_should_work() {
new_test_ext().execute_with(|| {
let data = |x| Data::Raw(vec![x; 1].try_into().unwrap());
assert_noop!(
Identity::add_sub(RuntimeOrigin::signed(10), 20, data(1)),
Error::<Test>::NoIdentity
);
let ten = ten();
assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten.clone())));
let id_deposit = id_deposit(&ten);
assert_eq!(Balances::free_balance(10), 1000 - id_deposit);
let sub_deposit: u64 = <<Test as Config>::SubAccountDeposit as Get<u64>>::get();
// first sub account
assert_ok!(Identity::add_sub(RuntimeOrigin::signed(10), 1, data(1)));
assert_eq!(SuperOf::<Test>::get(1), Some((10, data(1))));
assert_eq!(Balances::free_balance(10), 1000 - id_deposit - sub_deposit);
// second sub account
assert_ok!(Identity::add_sub(RuntimeOrigin::signed(10), 2, data(2)));
assert_eq!(SuperOf::<Test>::get(1), Some((10, data(1))));
assert_eq!(SuperOf::<Test>::get(2), Some((10, data(2))));
assert_eq!(Balances::free_balance(10), 1000 - id_deposit - 2 * sub_deposit);
// third sub account is too many
assert_noop!(
Identity::add_sub(RuntimeOrigin::signed(10), 3, data(3)),
Error::<Test>::TooManySubAccounts
);
// rename first sub account
assert_ok!(Identity::rename_sub(RuntimeOrigin::signed(10), 1, data(11)));
assert_eq!(SuperOf::<Test>::get(1), Some((10, data(11))));
assert_eq!(SuperOf::<Test>::get(2), Some((10, data(2))));
assert_eq!(Balances::free_balance(10), 1000 - id_deposit - 2 * sub_deposit);
// remove first sub account
assert_ok!(Identity::remove_sub(RuntimeOrigin::signed(10), 1));
assert_eq!(SuperOf::<Test>::get(1), None);
assert_eq!(SuperOf::<Test>::get(2), Some((10, data(2))));
assert_eq!(Balances::free_balance(10), 1000 - id_deposit - sub_deposit);
// add third sub account
assert_ok!(Identity::add_sub(RuntimeOrigin::signed(10), 3, data(3)));
assert_eq!(SuperOf::<Test>::get(1), None);
assert_eq!(SuperOf::<Test>::get(2), Some((10, data(2))));
assert_eq!(SuperOf::<Test>::get(3), Some((10, data(3))));
assert_eq!(Balances::free_balance(10), 1000 - id_deposit - 2 * sub_deposit);
});
}
#[test]
fn resolving_subaccount_ownership_works() {
new_test_ext().execute_with(|| {
let data = |x| Data::Raw(vec![x; 1].try_into().unwrap());
let sub_deposit: u64 = <<Test as Config>::SubAccountDeposit as Get<u64>>::get();
let ten = ten();
let ten_deposit = id_deposit(&ten);
let twenty = twenty();
let twenty_deposit = id_deposit(&twenty);
assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten)));
assert_eq!(Balances::free_balance(10), 1000 - ten_deposit);
assert_ok!(Identity::set_identity(RuntimeOrigin::signed(20), Box::new(twenty)));
assert_eq!(Balances::free_balance(20), 1000 - twenty_deposit);
// 10 claims 1 as a subaccount
assert_ok!(Identity::add_sub(RuntimeOrigin::signed(10), 1, data(1)));
assert_eq!(Balances::free_balance(1), 100);
assert_eq!(Balances::free_balance(10), 1000 - ten_deposit - sub_deposit);
assert_eq!(Balances::reserved_balance(10), ten_deposit + sub_deposit);
// 20 cannot claim 1 now
assert_noop!(
Identity::add_sub(RuntimeOrigin::signed(20), 1, data(1)),
Error::<Test>::AlreadyClaimed
);
// 1 wants to be with 20 so it quits from 10
assert_ok!(Identity::quit_sub(RuntimeOrigin::signed(1)));
// 1 gets the 10 that 10 paid.
assert_eq!(Balances::free_balance(1), 100 + sub_deposit);
assert_eq!(Balances::free_balance(10), 1000 - ten_deposit - sub_deposit);
assert_eq!(Balances::reserved_balance(10), ten_deposit);
// 20 can claim 1 now
assert_ok!(Identity::add_sub(RuntimeOrigin::signed(20), 1, data(1)));
});
}
#[test]
fn trailing_zeros_decodes_into_default_data() {
let encoded = Data::Raw(b"Hello".to_vec().try_into().unwrap()).encode();
assert!(<(Data, Data)>::decode(&mut &encoded[..]).is_err());
let input = &mut &encoded[..];
let (a, b) = <(Data, Data)>::decode(&mut AppendZerosInput::new(input)).unwrap();
assert_eq!(a, Data::Raw(b"Hello".to_vec().try_into().unwrap()));
assert_eq!(b, Data::None);
}
#[test]
fn adding_registrar_invalid_index() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3));
assert_ok!(Identity::set_fee(RuntimeOrigin::signed(3), 0, 10));
let fields = IdentityField::Display | IdentityField::Legal;
assert_noop!(
Identity::set_fields(RuntimeOrigin::signed(3), 100, fields.bits()),
Error::<Test>::InvalidIndex
);
});
}
#[test]
fn adding_registrar_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3));
assert_ok!(Identity::set_fee(RuntimeOrigin::signed(3), 0, 10));
let fields = IdentityField::Display | IdentityField::Legal;
assert_ok!(Identity::set_fields(RuntimeOrigin::signed(3), 0, fields.bits()));
assert_eq!(
Identity::registrars(),
vec![Some(RegistrarInfo { account: 3, fee: 10, fields: fields.bits() })]
);
});
}
#[test]
fn amount_of_registrars_is_limited() {
new_test_ext().execute_with(|| {
for i in 1..MaxRegistrars::get() + 1 {
assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), i as u64));
}
let last_registrar = MaxRegistrars::get() as u64 + 1;
assert_noop!(
Identity::add_registrar(RuntimeOrigin::signed(1), last_registrar),
Error::<Test>::TooManyRegistrars
);
});
}
#[test]
fn registration_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3));
assert_ok!(Identity::set_fee(RuntimeOrigin::signed(3), 0, 10));
let mut three_fields = ten();
three_fields.additional.try_push(Default::default()).unwrap();
three_fields.additional.try_push(Default::default()).unwrap();
assert!(three_fields.additional.try_push(Default::default()).is_err());
let ten = ten();
let id_deposit = id_deposit(&ten);
assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten.clone())));
assert_eq!(Identity::identity(10).unwrap().info, ten);
assert_eq!(Balances::free_balance(10), 1000 - id_deposit);
assert_ok!(Identity::clear_identity(RuntimeOrigin::signed(10)));
assert_eq!(Balances::free_balance(10), 1000);
assert_noop!(Identity::clear_identity(RuntimeOrigin::signed(10)), Error::<Test>::NotNamed);
});
}
#[test]
fn uninvited_judgement_should_work() {
new_test_ext().execute_with(|| {
assert_noop!(
Identity::provide_judgement(
RuntimeOrigin::signed(3),
0,
10,
Judgement::Reasonable,
H256::random()
),
Error::<Test>::InvalidIndex
);
assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3));
assert_noop!(
Identity::provide_judgement(
RuntimeOrigin::signed(3),
0,
10,
Judgement::Reasonable,
H256::random()
),
Error::<Test>::InvalidTarget
);
assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten())));
assert_noop!(
Identity::provide_judgement(
RuntimeOrigin::signed(3),
0,
10,
Judgement::Reasonable,
H256::random()
),
Error::<Test>::JudgementForDifferentIdentity
);
let identity_hash = BlakeTwo256::hash_of(&ten());
assert_noop!(
Identity::provide_judgement(
RuntimeOrigin::signed(10),
0,
10,
Judgement::Reasonable,
identity_hash
),
Error::<Test>::InvalidIndex
);
assert_noop!(
Identity::provide_judgement(
RuntimeOrigin::signed(3),
0,
10,
Judgement::FeePaid(1),
identity_hash
),
Error::<Test>::InvalidJudgement
);
assert_ok!(Identity::provide_judgement(
RuntimeOrigin::signed(3),
0,
10,
Judgement::Reasonable,
identity_hash
));
assert_eq!(Identity::identity(10).unwrap().judgements, vec![(0, Judgement::Reasonable)]);
});
}
#[test]
fn clearing_judgement_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3));
assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten())));
assert_ok!(Identity::provide_judgement(
RuntimeOrigin::signed(3),
0,
10,
Judgement::Reasonable,
BlakeTwo256::hash_of(&ten())
));
assert_ok!(Identity::clear_identity(RuntimeOrigin::signed(10)));
assert_eq!(Identity::identity(10), None);
});
}
#[test]
fn killing_slashing_should_work() {
new_test_ext().execute_with(|| {
let ten = ten();
let id_deposit = id_deposit(&ten);
assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten)));
assert_noop!(Identity::kill_identity(RuntimeOrigin::signed(1), 10), BadOrigin);
assert_ok!(Identity::kill_identity(RuntimeOrigin::signed(2), 10));
assert_eq!(Identity::identity(10), None);
assert_eq!(Balances::free_balance(10), 1000 - id_deposit);
assert_noop!(
Identity::kill_identity(RuntimeOrigin::signed(2), 10),
Error::<Test>::NotNamed
);
});
}
#[test]
fn setting_subaccounts_should_work() {
new_test_ext().execute_with(|| {
let ten = ten();
let id_deposit = id_deposit(&ten);
let sub_deposit: u64 = <<Test as Config>::SubAccountDeposit as Get<u64>>::get();
let mut subs = vec![(20, Data::Raw(vec![40; 1].try_into().unwrap()))];
assert_noop!(
Identity::set_subs(RuntimeOrigin::signed(10), subs.clone()),
Error::<Test>::NotFound
);
assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten)));
assert_eq!(Balances::free_balance(10), 1000 - id_deposit);
assert_ok!(Identity::set_subs(RuntimeOrigin::signed(10), subs.clone()));
assert_eq!(Balances::free_balance(10), 1000 - id_deposit - sub_deposit);
assert_eq!(Identity::subs_of(10), (sub_deposit, vec![20].try_into().unwrap()));
assert_eq!(Identity::super_of(20), Some((10, Data::Raw(vec![40; 1].try_into().unwrap()))));
// push another item and re-set it.
subs.push((30, Data::Raw(vec![50; 1].try_into().unwrap())));
assert_ok!(Identity::set_subs(RuntimeOrigin::signed(10), subs.clone()));
assert_eq!(Balances::free_balance(10), 1000 - id_deposit - 2 * sub_deposit);
assert_eq!(Identity::subs_of(10), (2 * sub_deposit, vec![20, 30].try_into().unwrap()));
assert_eq!(Identity::super_of(20), Some((10, Data::Raw(vec![40; 1].try_into().unwrap()))));
assert_eq!(Identity::super_of(30), Some((10, Data::Raw(vec![50; 1].try_into().unwrap()))));
// switch out one of the items and re-set.
subs[0] = (40, Data::Raw(vec![60; 1].try_into().unwrap()));
assert_ok!(Identity::set_subs(RuntimeOrigin::signed(10), subs.clone()));
// no change in the balance
assert_eq!(Balances::free_balance(10), 1000 - id_deposit - 2 * sub_deposit);
assert_eq!(Identity::subs_of(10), (2 * sub_deposit, vec![40, 30].try_into().unwrap()));
assert_eq!(Identity::super_of(20), None);
assert_eq!(Identity::super_of(30), Some((10, Data::Raw(vec![50; 1].try_into().unwrap()))));
assert_eq!(Identity::super_of(40), Some((10, Data::Raw(vec![60; 1].try_into().unwrap()))));
// clear
assert_ok!(Identity::set_subs(RuntimeOrigin::signed(10), vec![]));
assert_eq!(Balances::free_balance(10), 1000 - id_deposit);
assert_eq!(Identity::subs_of(10), (0, BoundedVec::default()));
assert_eq!(Identity::super_of(30), None);
assert_eq!(Identity::super_of(40), None);
subs.push((20, Data::Raw(vec![40; 1].try_into().unwrap())));
assert_noop!(
Identity::set_subs(RuntimeOrigin::signed(10), subs.clone()),
Error::<Test>::TooManySubAccounts
);
});
}
#[test]
fn clearing_account_should_remove_subaccounts_and_refund() {
new_test_ext().execute_with(|| {
let ten = ten();
assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten.clone())));
assert_eq!(Balances::free_balance(10), 1000 - id_deposit(&ten));
assert_ok!(Identity::set_subs(
RuntimeOrigin::signed(10),
vec![(20, Data::Raw(vec![40; 1].try_into().unwrap()))]
));
assert_ok!(Identity::clear_identity(RuntimeOrigin::signed(10)));
assert_eq!(Balances::free_balance(10), 1000);
assert!(Identity::super_of(20).is_none());
});
}
#[test]
fn killing_account_should_remove_subaccounts_and_not_refund() {
new_test_ext().execute_with(|| {
let ten = ten();
let id_deposit = id_deposit(&ten);
let sub_deposit: u64 = <<Test as Config>::SubAccountDeposit as Get<u64>>::get();
assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten)));
assert_eq!(Balances::free_balance(10), 1000 - id_deposit);
assert_ok!(Identity::set_subs(
RuntimeOrigin::signed(10),
vec![(20, Data::Raw(vec![40; 1].try_into().unwrap()))]
));
assert_eq!(Balances::free_balance(10), 1000 - id_deposit - sub_deposit);
assert_ok!(Identity::kill_identity(RuntimeOrigin::signed(2), 10));
assert_eq!(Balances::free_balance(10), 1000 - id_deposit - sub_deposit);
assert!(Identity::super_of(20).is_none());
});
}
#[test]
fn cancelling_requested_judgement_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3));
assert_ok!(Identity::set_fee(RuntimeOrigin::signed(3), 0, 10));
assert_noop!(
Identity::cancel_request(RuntimeOrigin::signed(10), 0),
Error::<Test>::NoIdentity
);
let ten = ten();
assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten.clone())));
assert_eq!(Balances::free_balance(10), 1000 - id_deposit(&ten));
assert_ok!(Identity::request_judgement(RuntimeOrigin::signed(10), 0, 10));
assert_ok!(Identity::cancel_request(RuntimeOrigin::signed(10), 0));
assert_eq!(Balances::free_balance(10), 1000 - id_deposit(&ten));
assert_noop!(
Identity::cancel_request(RuntimeOrigin::signed(10), 0),
Error::<Test>::NotFound
);
assert_ok!(Identity::provide_judgement(
RuntimeOrigin::signed(3),
0,
10,
Judgement::Reasonable,
BlakeTwo256::hash_of(&ten)
));
assert_noop!(
Identity::cancel_request(RuntimeOrigin::signed(10), 0),
Error::<Test>::JudgementGiven
);
});
}
#[test]
fn requesting_judgement_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3));
assert_ok!(Identity::set_fee(RuntimeOrigin::signed(3), 0, 10));
let ten = ten();
let id_deposit = id_deposit(&ten);
assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten.clone())));
assert_eq!(Balances::free_balance(10), 1000 - id_deposit);
assert_noop!(
Identity::request_judgement(RuntimeOrigin::signed(10), 0, 9),
Error::<Test>::FeeChanged
);
assert_ok!(Identity::request_judgement(RuntimeOrigin::signed(10), 0, 10));
// 10 for the judgement request and the deposit for the identity.
assert_eq!(Balances::free_balance(10), 1000 - id_deposit - 10);
// Re-requesting won't work as we already paid.
assert_noop!(
Identity::request_judgement(RuntimeOrigin::signed(10), 0, 10),
Error::<Test>::StickyJudgement
);
assert_ok!(Identity::provide_judgement(
RuntimeOrigin::signed(3),
0,
10,
Judgement::Erroneous,
BlakeTwo256::hash_of(&ten)
));
// Registrar got their payment now.
// 100 initial balance and 10 for the judgement.
assert_eq!(Balances::free_balance(3), 100 + 10);
// Re-requesting still won't work as it's erroneous.
assert_noop!(
Identity::request_judgement(RuntimeOrigin::signed(10), 0, 10),
Error::<Test>::StickyJudgement
);
// Requesting from a second registrar still works.
assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 4));
assert_ok!(Identity::request_judgement(RuntimeOrigin::signed(10), 1, 10));
// Re-requesting after the judgement has been reduced works.
assert_ok!(Identity::provide_judgement(
RuntimeOrigin::signed(3),
0,
10,
Judgement::OutOfDate,
BlakeTwo256::hash_of(&ten)
));
assert_ok!(Identity::request_judgement(RuntimeOrigin::signed(10), 0, 10));
});
}
#[test]
fn provide_judgement_should_return_judgement_payment_failed_error() {
new_test_ext().execute_with(|| {
let ten = ten();
let id_deposit = id_deposit(&ten);
assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3));
assert_ok!(Identity::set_fee(RuntimeOrigin::signed(3), 0, 10));
assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten.clone())));
assert_ok!(Identity::request_judgement(RuntimeOrigin::signed(10), 0, 10));
// 10 for the judgement request and the deposit for the identity.
assert_eq!(Balances::free_balance(10), 1000 - id_deposit - 10);
// This forces judgement payment failed error
Balances::make_free_balance_be(&3, 0);
assert_noop!(
Identity::provide_judgement(
RuntimeOrigin::signed(3),
0,
10,
Judgement::Erroneous,
BlakeTwo256::hash_of(&ten)
),
Error::<Test>::JudgementPaymentFailed
);
});
}
#[test]
fn field_deposit_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3));
assert_ok!(Identity::set_fee(RuntimeOrigin::signed(3), 0, 10));
let id = IdentityInfo {
additional: vec![
(
Data::Raw(b"number".to_vec().try_into().unwrap()),
Data::Raw(10u32.encode().try_into().unwrap()),
),
(
Data::Raw(b"text".to_vec().try_into().unwrap()),
Data::Raw(b"10".to_vec().try_into().unwrap()),
),
]
.try_into()
.unwrap(),
..Default::default()
};
let id_deposit = id_deposit(&id);
assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(id)));
assert_eq!(Balances::free_balance(10), 1000 - id_deposit);
});
}
#[test]
fn setting_account_id_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3));
// account 4 cannot change the first registrar's identity since it's owned by 3.
assert_noop!(
Identity::set_account_id(RuntimeOrigin::signed(4), 0, 3),
Error::<Test>::InvalidIndex
);
// account 3 can, because that's the registrar's current account.
assert_ok!(Identity::set_account_id(RuntimeOrigin::signed(3), 0, 4));
// account 4 can now, because that's their new ID.
assert_ok!(Identity::set_account_id(RuntimeOrigin::signed(4), 0, 3));
});
}
#[test]
fn test_has_identity() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten())));
assert!(Identity::has_identity(&10, IdentityField::Display as u64));
assert!(Identity::has_identity(&10, IdentityField::Legal as u64));
assert!(Identity::has_identity(
&10,
IdentityField::Display as u64 | IdentityField::Legal as u64
));
assert!(!Identity::has_identity(
&10,
IdentityField::Display as u64 | IdentityField::Legal as u64 | IdentityField::Web as u64
));
});
}