A lexicon-driven AppView for ATProto.
Something went wrong. Try again.
Rust
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226// tests/plugin_executor.rs
use happyview::db::DatabaseBackend;use happyview::lexicon::LexiconRegistry;use happyview::plugin::{ ExecutionError, LoadedPlugin, PluginExecutor, PluginInfo, PluginRegistry, PluginSource, WasmRuntime,};use std::collections::HashMap;use std::sync::Arc;
type Secrets = HashMap<String, String>;
async fn create_test_executor() -> (PluginExecutor, Arc<PluginRegistry>) { // Create in-memory database sqlx::any::install_default_drivers(); let db = sqlx::AnyPool::connect("sqlite::memory:") .await .expect("Failed to create test database");
let runtime = Arc::new(WasmRuntime::new().expect("Failed to create runtime")); let registry = Arc::new(PluginRegistry::new()); let lexicons = Arc::new(LexiconRegistry::new()); let http_client = reqwest::Client::new();
let executor = PluginExecutor::new( runtime, registry.clone(), db, DatabaseBackend::Sqlite, http_client, lexicons, );
(executor, registry)}
fn load_test_plugin() -> LoadedPlugin { let wasm_bytes = std::fs::read( "tests/fixtures/test_plugin/target/wasm32-unknown-unknown/release/test_plugin.wasm", ) .expect( "Test plugin not built. Run: cd tests/fixtures/test_plugin && cargo build --target wasm32-unknown-unknown --release", );
LoadedPlugin { info: PluginInfo { id: "test".into(), name: "Test Plugin".into(), version: "1.0.0".into(), api_version: "1".into(), icon_url: None, required_secrets: vec![], auth_type: "oauth2".into(), config_schema: None, }, source: PluginSource::File { path: "tests/fixtures/test_plugin".into(), }, wasm_bytes, }}
#[tokio::test]async fn test_plugin_info() { let (executor, registry) = create_test_executor().await; let plugin = load_test_plugin(); registry.register(plugin).await;
let mut instance = executor .instantiate( "test", "user:did:plc:test", Secrets::new(), serde_json::Value::Null, ) .await .expect("Failed to instantiate");
let info = instance .call_plugin_info() .await .expect("Failed to get info");
assert_eq!(info.id, "test"); assert_eq!(info.name, "Test Plugin"); assert_eq!(info.version, "1.0.0");}
#[tokio::test]async fn test_get_authorize_url() { let (executor, registry) = create_test_executor().await; let plugin = load_test_plugin(); registry.register(plugin).await;
let mut instance = executor .instantiate("test", "state:123", Secrets::new(), serde_json::Value::Null) .await .expect("Failed to instantiate");
let url = instance .call_get_authorize_url( "state123", "https://app.example/callback", &serde_json::Value::Null, ) .await .expect("Failed to get URL");
assert!(url.starts_with("https://"));}
#[tokio::test]async fn test_handle_callback() { let (executor, registry) = create_test_executor().await; let plugin = load_test_plugin(); registry.register(plugin).await;
let mut instance = executor .instantiate( "test", "user:did:plc:test", Secrets::new(), serde_json::Value::Null, ) .await .expect("Failed to instantiate");
let tokens = instance .call_handle_callback("code123", "state123", &serde_json::Value::Null) .await .expect("Failed to handle callback");
assert_eq!(tokens.access_token, "test-token"); assert_eq!(tokens.token_type, "Bearer");}
#[tokio::test]async fn test_refresh_tokens() { let (executor, registry) = create_test_executor().await; let plugin = load_test_plugin(); registry.register(plugin).await;
let mut instance = executor .instantiate( "test", "user:did:plc:test", Secrets::new(), serde_json::Value::Null, ) .await .expect("Failed to instantiate");
let tokens = instance .call_refresh_tokens("old-refresh-token", &serde_json::Value::Null) .await .expect("Failed to refresh tokens");
assert_eq!(tokens.access_token, "refreshed-token");}
#[tokio::test]async fn test_get_profile() { let (executor, registry) = create_test_executor().await; let plugin = load_test_plugin(); registry.register(plugin).await;
let mut instance = executor .instantiate( "test", "user:did:plc:test", Secrets::new(), serde_json::Value::Null, ) .await .expect("Failed to instantiate");
let profile = instance .call_get_profile("test-token", &serde_json::Value::Null) .await .expect("Failed to get profile");
assert_eq!(profile.account_id, "12345"); assert_eq!(profile.display_name, Some("Test User".into()));}
#[tokio::test]async fn test_sync_account() { let (executor, registry) = create_test_executor().await; let plugin = load_test_plugin(); registry.register(plugin).await;
let mut instance = executor .instantiate( "test", "user:did:plc:test", Secrets::new(), serde_json::Value::Null, ) .await .expect("Failed to instantiate");
let records = instance .call_sync_account("test-token", &serde_json::Value::Null) .await .expect("Failed to sync account");
assert!(records.is_empty()); // Test plugin returns empty array}
#[tokio::test]async fn test_plugin_not_found() { let (executor, _registry) = create_test_executor().await;
let result = executor .instantiate( "nonexistent", "scope", Secrets::new(), serde_json::Value::Null, ) .await;
assert!(matches!(result, Err(ExecutionError::PluginNotFound(_))));}