Skip to content

Commit

Permalink
test: add integration tests for Pausable plugins (#51)
Browse files Browse the repository at this point in the history
* Add integration tests, refactor helpers

* Remove unit tests of Pausable

* Test `pa_unpause_feature` is protected by acl

* Update rust version in test contracts

* Make Makefile targets phony

* Revert update of rust version in test contracts

* Remove unused functions from test contract
  • Loading branch information
mooori authored Dec 21, 2022
1 parent cdd2ea3 commit ffc2012
Show file tree
Hide file tree
Showing 13 changed files with 1,035 additions and 725 deletions.
450 changes: 0 additions & 450 deletions near-plugins/src/pausable.rs

Large diffs are not rendered by default.

327 changes: 134 additions & 193 deletions near-plugins/tests/access_controllable.rs

Large diffs are not rendered by default.

126 changes: 47 additions & 79 deletions near-plugins/tests/common/access_controllable_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,6 @@ use near_sdk::serde_json::json;
use workspaces::result::ExecutionFinalResult;
use workspaces::{Account, AccountId, Contract};

/// Specifies who calls a method on the contract.
#[derive(Clone)]
pub enum Caller {
/// The contract itself.
Contract,
/// The provided account.
Account(Account),
}

impl From<Account> for Caller {
fn from(account: Account) -> Self {
Self::Account(account)
}
}

/// Wrapper for a contract that is `#[access_controllable]`. It allows
/// implementing helpers for calling contract methods.
pub struct AccessControllableContract {
Expand All @@ -32,20 +17,12 @@ impl AccessControllableContract {
&self.contract
}

fn account(&self, caller: Caller) -> Account {
match caller {
Caller::Contract => self.contract.as_account().clone(),
Caller::Account(account) => account,
}
}

pub async fn acl_is_super_admin(
&self,
caller: Caller,
caller: &Account,
account_id: &AccountId,
) -> anyhow::Result<bool> {
let res = self
.account(caller)
let res = caller
.call(self.contract.id(), "acl_is_super_admin")
.args_json(json!({
"account_id": account_id,
Expand All @@ -55,20 +32,22 @@ impl AccessControllableContract {
Ok(res.json::<bool>()?)
}

pub async fn assert_acl_is_super_admin(&self, expected: bool, account_id: &AccountId) {
let is_super_admin = self
.acl_is_super_admin(Caller::Contract, account_id)
.await
.unwrap();
pub async fn assert_acl_is_super_admin(
&self,
expected: bool,
caller: &Account,
account_id: &AccountId,
) {
let is_super_admin = self.acl_is_super_admin(caller, account_id).await.unwrap();
assert_eq!(is_super_admin, expected);
}

pub async fn acl_init_super_admin(
&self,
caller: Caller,
caller: &Account,
account_id: &AccountId,
) -> workspaces::Result<ExecutionFinalResult> {
self.account(caller)
caller
.call(self.contract.id(), "acl_init_super_admin")
.args_json(json!({
"account_id": account_id,
Expand All @@ -80,10 +59,10 @@ impl AccessControllableContract {

pub async fn acl_add_super_admin_unchecked(
&self,
caller: Caller,
caller: &Account,
account_id: &AccountId,
) -> workspaces::Result<ExecutionFinalResult> {
self.account(caller)
caller
.call(self.contract.id(), "acl_add_super_admin_unchecked")
.args_json(json!({
"account_id": account_id,
Expand All @@ -95,10 +74,10 @@ impl AccessControllableContract {

pub async fn acl_revoke_super_admin_unchecked(
&self,
caller: Caller,
caller: &Account,
account_id: &AccountId,
) -> workspaces::Result<ExecutionFinalResult> {
self.account(caller)
caller
.call(self.contract.id(), "acl_revoke_super_admin_unchecked")
.args_json(json!({
"account_id": account_id,
Expand All @@ -110,12 +89,11 @@ impl AccessControllableContract {

pub async fn acl_is_admin(
&self,
caller: Caller,
caller: &Account,
role: &str,
account_id: &AccountId,
) -> anyhow::Result<bool> {
let res = self
.account(caller)
let res = caller
.call(self.contract.id(), "acl_is_admin")
.args_json(json!({
"role": role,
Expand All @@ -128,20 +106,19 @@ impl AccessControllableContract {

pub async fn assert_acl_is_admin(&self, expected: bool, role: &str, account_id: &AccountId) {
let is_admin = self
.acl_is_admin(Caller::Contract, role, account_id)
.acl_is_admin(self.contract.as_account(), role, account_id)
.await
.unwrap();
assert_eq!(is_admin, expected);
}

pub async fn acl_add_admin(
&self,
caller: Caller,
caller: &Account,
role: &str,
account_id: &AccountId,
) -> anyhow::Result<Option<bool>> {
let res = self
.account(caller)
let res = caller
.call(self.contract.id(), "acl_add_admin")
.args_json(json!({
"role": role,
Expand All @@ -157,11 +134,11 @@ impl AccessControllableContract {

pub async fn acl_add_admin_unchecked(
&self,
caller: Caller,
caller: &Account,
role: &str,
account_id: &AccountId,
) -> workspaces::Result<ExecutionFinalResult> {
self.account(caller)
caller
.call(self.contract.id(), "acl_add_admin_unchecked")
.args_json(json!({
"role": role,
Expand All @@ -174,12 +151,11 @@ impl AccessControllableContract {

pub async fn acl_revoke_admin(
&self,
caller: Caller,
caller: &Account,
role: &str,
account_id: &AccountId,
) -> anyhow::Result<Option<bool>> {
let res = self
.account(caller)
let res = caller
.call(self.contract.id(), "acl_revoke_admin")
.args_json(json!({
"role": role,
Expand All @@ -193,9 +169,8 @@ impl AccessControllableContract {
Ok(res)
}

pub async fn acl_renounce_admin(&self, caller: Caller, role: &str) -> anyhow::Result<bool> {
let res = self
.account(caller)
pub async fn acl_renounce_admin(&self, caller: &Account, role: &str) -> anyhow::Result<bool> {
let res = caller
.call(self.contract.id(), "acl_renounce_admin")
.args_json(json!({
"role": role,
Expand All @@ -210,11 +185,11 @@ impl AccessControllableContract {

pub async fn acl_revoke_admin_unchecked(
&self,
caller: Caller,
caller: &Account,
role: &str,
account_id: &AccountId,
) -> workspaces::Result<ExecutionFinalResult> {
self.account(caller)
caller
.call(self.contract.id(), "acl_revoke_admin_unchecked")
.args_json(json!({
"role": role,
Expand All @@ -227,12 +202,11 @@ impl AccessControllableContract {

pub async fn acl_has_role(
&self,
caller: Caller,
caller: &Account,
role: &str,
account_id: &AccountId,
) -> anyhow::Result<bool> {
let res = self
.account(caller)
let res = caller
.call(self.contract.id(), "acl_has_role")
.args_json(json!({
"role": role,
Expand All @@ -245,20 +219,19 @@ impl AccessControllableContract {

pub async fn assert_acl_has_role(&self, expected: bool, role: &str, account_id: &AccountId) {
let has_role = self
.acl_has_role(Caller::Contract, role, account_id)
.acl_has_role(self.contract.as_account(), role, account_id)
.await
.unwrap();
assert_eq!(has_role, expected);
}

pub async fn acl_grant_role(
&self,
caller: Caller,
caller: &Account,
role: &str,
account_id: &AccountId,
) -> anyhow::Result<Option<bool>> {
let res = self
.account(caller)
let res = caller
.call(self.contract.id(), "acl_grant_role")
.args_json(json!({
"role": role,
Expand All @@ -274,11 +247,11 @@ impl AccessControllableContract {

pub async fn acl_grant_role_unchecked(
&self,
caller: Caller,
caller: &Account,
role: &str,
account_id: &AccountId,
) -> workspaces::Result<ExecutionFinalResult> {
self.account(caller)
caller
.call(self.contract.id(), "acl_grant_role_unchecked")
.args_json(json!({
"role": role,
Expand All @@ -291,12 +264,11 @@ impl AccessControllableContract {

pub async fn acl_revoke_role(
&self,
caller: Caller,
caller: &Account,
role: &str,
account_id: &AccountId,
) -> anyhow::Result<Option<bool>> {
let res = self
.account(caller)
let res = caller
.call(self.contract.id(), "acl_revoke_role")
.args_json(json!({
"role": role,
Expand All @@ -310,9 +282,8 @@ impl AccessControllableContract {
Ok(res)
}

pub async fn acl_renounce_role(&self, caller: Caller, role: &str) -> anyhow::Result<bool> {
let res = self
.account(caller)
pub async fn acl_renounce_role(&self, caller: &Account, role: &str) -> anyhow::Result<bool> {
let res = caller
.call(self.contract.id(), "acl_renounce_role")
.args_json(json!({
"role": role,
Expand All @@ -327,11 +298,11 @@ impl AccessControllableContract {

pub async fn acl_revoke_role_unchecked(
&self,
caller: Caller,
caller: &Account,
role: &str,
account_id: &AccountId,
) -> workspaces::Result<ExecutionFinalResult> {
self.account(caller)
caller
.call(self.contract.id(), "acl_revoke_role_unchecked")
.args_json(json!({
"role": role,
Expand All @@ -344,12 +315,11 @@ impl AccessControllableContract {

pub async fn acl_get_super_admins(
&self,
caller: Caller,
caller: &Account,
skip: u64,
limit: u64,
) -> anyhow::Result<Vec<AccountId>> {
let res = self
.account(caller)
let res = caller
.call(self.contract.id(), "acl_get_super_admins")
.args_json(json!({
"skip": skip,
Expand All @@ -365,13 +335,12 @@ impl AccessControllableContract {

pub async fn acl_get_admins(
&self,
caller: Caller,
caller: &Account,
role: &str,
skip: u64,
limit: u64,
) -> anyhow::Result<Vec<AccountId>> {
let res = self
.account(caller)
let res = caller
.call(self.contract.id(), "acl_get_admins")
.args_json(json!({
"role": role,
Expand All @@ -388,13 +357,12 @@ impl AccessControllableContract {

pub async fn acl_get_grantees(
&self,
caller: Caller,
caller: &Account,
role: &str,
skip: u64,
limit: u64,
) -> anyhow::Result<Vec<AccountId>> {
let res = self
.account(caller)
let res = caller
.call(self.contract.id(), "acl_get_grantees")
.args_json(json!({
"role": role,
Expand Down
1 change: 1 addition & 0 deletions near-plugins/tests/common/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod access_controllable_contract;
pub mod pausable_contract;
pub mod repo;
pub mod utils;
Loading

0 comments on commit ffc2012

Please sign in to comment.