Skip to content

Commit

Permalink
Improve docs for mock auth fns (#943)
Browse files Browse the repository at this point in the history
### What
Improve docs for mock auth fns.

### Why
I didn't add examples to the mock_auths fn, and some links were broken.
  • Loading branch information
leighmcculloch authored May 15, 2023
1 parent 6140596 commit c8c5cb1
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 15 deletions.
15 changes: 15 additions & 0 deletions soroban-sdk-macros/src/derive_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ pub fn derive_client(crate_path: &Path, ty: &str, name: &str, fns: &[syn_ext::Fn
#crate_path::Address::from_contract_id(&self.contract_id)
}

/// Set authorizations in the environment which will be consumed by
/// contracts when they invoke `Address::require_auth` or
/// `Address::require_auth_for_args` functions.
///
/// See `soroban_sdk::Env::set_auths` for more details and examples.
#[cfg(any(test, feature = "testutils"))]
pub fn set_auths(&self, auths: &'a [#crate_path::xdr::ContractAuth]) -> Self {
Self {
Expand All @@ -169,6 +174,11 @@ pub fn derive_client(crate_path: &Path, ty: &str, name: &str, fns: &[syn_ext::Fn
}
}

/// Mock authorizations in the environment which will cause matching invokes
/// of `Address::require_auth` and `Address::require_auth_for_args` to
/// pass.
///
/// See `soroban_sdk::Env::set_auths` for more details and examples.
#[cfg(any(test, feature = "testutils"))]
pub fn mock_auths(&self, mock_auths: &'a [#crate_path::testutils::MockAuth<'a>]) -> Self {
Self {
Expand All @@ -180,6 +190,11 @@ pub fn derive_client(crate_path: &Path, ty: &str, name: &str, fns: &[syn_ext::Fn
}
}

/// Mock all calls to the `Address::require_auth` and
/// `Address::require_auth_for_args` functions in invoked contracts,
/// having them succeed as if authorization was provided.
///
/// See `soroban_sdk::Env::set_auths` for more details and examples.
#[cfg(any(test, feature = "testutils"))]
pub fn mock_all_auths(&self) -> Self {
Self {
Expand Down
81 changes: 66 additions & 15 deletions soroban-sdk/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -761,19 +761,67 @@ impl Env {
}

/// Set authorizations in the environment which will be consumed by
/// contracts when they invoke [`require_auth`] or [`require_auth_for_args`]
/// functions.
/// contracts when they invoke [`Address::require_auth`] or
/// [`Address::require_auth_for_args`] functions.
///
/// To mock auth for testing, use [`mock_all_auths`]. If mocking of auths is
/// enabled, calling [`set_auths`] disables any mocking.
/// This function can also be called on contract clients.
///
/// To mock auth for testing, use [`mock_all_auths`][Self::mock_all_auths]
/// or [`mock_auths`][Self::mock_auths]. If mocking of auths is enabled,
/// calling [`set_auths`][Self::set_auths] disables any mocking.
pub fn set_auths(&self, auths: &[ContractAuth]) {
self.env_impl
.set_authorization_entries(auths.to_vec())
.unwrap();
}

// Mock authorizations in the environment which will cause matching invokes of
// [`require_auth`] and [`require_auth_for_args`] to pass.
/// Mock authorizations in the environment which will cause matching invokes
/// of [`Address::require_auth`] and [`Address::require_auth_for_args`] to
/// pass.
///
/// This function can also be called on contract clients.
///
/// Authorizations not matching a mocked auth will fail.
///
/// To mock all auths, use [`mock_all_auths`][Self::mock_all_auths].
///
/// ### Examples
/// ```
/// use soroban_sdk::{contractimpl, Env, Address, testutils::{Address as _, MockAuth, MockAuthInvoke}, IntoVal};
///
/// pub struct HelloContract;
///
/// #[contractimpl]
/// impl HelloContract {
/// pub fn hello(env: Env, from: Address) {
/// from.require_auth();
/// // TODO
/// }
/// }
///
/// #[test]
/// fn test() {
/// # }
/// # fn main() {
/// let env = Env::default();
/// let contract_id = env.register_contract(None, HelloContract);
///
/// let client = HelloContractClient::new(&env, &contract_id);
/// let addr = Address::random(&env);
/// client.mock_auths(&[
/// MockAuth {
/// address: &addr,
/// nonce: 0,
/// invoke: &MockAuthInvoke {
/// contract: &contract_id,
/// fn_name: "hello",
/// args: (&addr,).into_val(&env),
/// sub_invokes: &[],
/// },
/// },
/// ]).hello(&addr);
/// }
/// ```
pub fn mock_auths(&self, auths: &[MockAuth]) {
for a in auths {
let Some(contract_id) = a.address.contract_id() else {
Expand All @@ -789,9 +837,9 @@ impl Env {
self.env_impl.set_authorization_entries(auths).unwrap();
}

/// Mock all calls to the [`require_auth`] and [`require_auth_for_args`]
/// functions in invoked contracts, having them succeed as if authorization
/// was provided.
/// Mock all calls to the [`Address::require_auth`] and
/// [`Address::require_auth_for_args`] functions in invoked contracts,
/// having them succeed as if authorization was provided.
///
/// When mocking is enabled, if the [`Address`] being authorized is the
/// address of a contract, that contract's `__check_auth` function will not
Expand All @@ -801,9 +849,11 @@ impl Env {
/// When mocking is enabled, if the [`Address`] being authorized is the
/// address of an account, the account does not need to exist.
///
/// To disable mocking, see [`set_auths`].
/// This function can also be called on contract clients.
///
/// To disable mocking, see [`set_auths`][Self::set_auths].
///
/// To access a list of auths that have occurred, see [`auths`].
/// To access a list of auths that have occurred, see [`auths`][Self::auths].
///
/// It is not currently possible to mock a subset of auths.
///
Expand Down Expand Up @@ -852,10 +902,11 @@ impl Env {
/// of the function invocation).
///
/// The order of the returned vector is defined by the order of
/// [`require_auth`] calls. Repeated calls to [`require_auth`] with the same
/// address and args in the same tree of contract invocations will appear
/// only once in the vector. Calls to [`require_auth`] in disjoint call
/// trees for the same address will present in the list.
/// [`Address::require_auth`] calls. Repeated calls to
/// [`Address::require_auth`] with the same address and args in the same
/// tree of contract invocations will appear only once in the vector. Calls
/// to [`Address::require_auth`] in disjoint call trees for the same address
/// will present in the list.
///
/// ### Examples
/// ```
Expand Down

0 comments on commit c8c5cb1

Please sign in to comment.