use soroban_sdk::{Env, Symbol, Vec};
use super::error::AccountError;
use super::traits::SessionKeyProvider;
use super::types::{SessionKey, SessionScope};
pub struct SessionBuilder<'a> {
env: &'a Env,
allowed_actions: Vec<Symbol>,
max_operations: u32,
expires_at: u64,
}
impl<'a> SessionBuilder<'a> {
pub fn new(env: &'a Env) -> Self {
Self {
env,
allowed_actions: Vec::new(env),
max_operations: 0,
expires_at: 0,
}
}
pub fn allow_action(mut self, action: Symbol) -> Self {
self.allowed_actions.push_back(action);
self
}
pub fn max_operations(mut self, count: u32) -> Self {
self.max_operations = count;
self
}
pub fn expires_at(mut self, timestamp: u64) -> Self {
self.expires_at = timestamp;
self
}
pub fn build_scope(self) -> SessionScope {
SessionScope {
allowed_actions: self.allowed_actions,
max_operations: self.max_operations,
expires_at: self.expires_at,
}
}
pub fn create<P: SessionKeyProvider>(
self,
provider: &mut P,
) -> Result<SessionKey, AccountError> {
let env = self.env;
let scope = self.build_scope();
provider.create_session(env, scope)
}
}
#[cfg(test)]
mod tests {
use super::*;
use soroban_sdk::{symbol_short, Env};
#[test]
fn test_session_builder_new() {
let env = Env::default();
let builder = SessionBuilder::new(&env);
let scope = builder.build_scope();
assert_eq!(scope.allowed_actions.len(), 0);
assert_eq!(scope.max_operations, 0);
assert_eq!(scope.expires_at, 0);
}
#[test]
fn test_session_builder_allow_action() {
let env = Env::default();
let scope = SessionBuilder::new(&env)
.allow_action(symbol_short!("move"))
.allow_action(symbol_short!("attack"))
.build_scope();
assert_eq!(scope.allowed_actions.len(), 2);
}
#[test]
fn test_session_builder_max_operations() {
let env = Env::default();
let scope = SessionBuilder::new(&env).max_operations(100).build_scope();
assert_eq!(scope.max_operations, 100);
}
#[test]
fn test_session_builder_expires_at() {
let env = Env::default();
let scope = SessionBuilder::new(&env).expires_at(5000).build_scope();
assert_eq!(scope.expires_at, 5000);
}
#[test]
fn test_session_builder_full_chain() {
let env = Env::default();
let scope = SessionBuilder::new(&env)
.allow_action(symbol_short!("move"))
.allow_action(symbol_short!("attack"))
.allow_action(symbol_short!("trade"))
.max_operations(200)
.expires_at(10000)
.build_scope();
assert_eq!(scope.allowed_actions.len(), 3);
assert_eq!(scope.max_operations, 200);
assert_eq!(scope.expires_at, 10000);
assert_eq!(scope.allowed_actions.get(0).unwrap(), symbol_short!("move"));
}
}