fix(ticket116): isoler crash plugin hello-plugin + erreur explicite UI
This commit is contained in:
@ -302,7 +302,113 @@ fn open_folder(path: &PathBuf) -> Result<(), ErrorDto> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::block_on_protocol_future;
|
||||
use super::{asset_allowed, block_on_protocol_future};
|
||||
use std::sync::Mutex;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use domain::ports::{
|
||||
PluginManifestBytes, PluginManifestError, PluginPackageStore, PluginRegistryError,
|
||||
PluginRegistryStore, PluginStoreError,
|
||||
};
|
||||
use domain::{
|
||||
ContentHash, LocalPath, PluginId, PluginInstallSource, PluginLifecycleState,
|
||||
PluginRegistry, PluginRegistryEntry, RelativePath, RemovalOutcome, StagedPluginPackage,
|
||||
};
|
||||
use http::StatusCode;
|
||||
|
||||
struct FakeRegistry {
|
||||
registry: Mutex<PluginRegistry>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl PluginRegistryStore for FakeRegistry {
|
||||
async fn load_registry(&self) -> Result<PluginRegistry, PluginRegistryError> {
|
||||
Ok(self.registry.lock().unwrap().clone())
|
||||
}
|
||||
|
||||
async fn save_registry(
|
||||
&self,
|
||||
registry: &PluginRegistry,
|
||||
) -> Result<(), PluginRegistryError> {
|
||||
*self.registry.lock().unwrap() = registry.clone();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
struct FakePackages {
|
||||
manifest: Vec<u8>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl PluginPackageStore for FakePackages {
|
||||
async fn list_installed(&self) -> Result<Vec<domain::PluginPackageRef>, PluginStoreError> {
|
||||
Ok(Vec::new())
|
||||
}
|
||||
|
||||
async fn read_manifest(
|
||||
&self,
|
||||
_package: &domain::PluginPackageRef,
|
||||
) -> Result<PluginManifestBytes, PluginStoreError> {
|
||||
Ok(PluginManifestBytes {
|
||||
bytes: self.manifest.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
async fn install_from_archive(
|
||||
&self,
|
||||
_archive: &LocalPath,
|
||||
) -> Result<StagedPluginPackage, PluginStoreError> {
|
||||
Err(PluginStoreError::Invalid("not used".to_owned()))
|
||||
}
|
||||
|
||||
async fn install_from_directory(
|
||||
&self,
|
||||
_dir: &LocalPath,
|
||||
) -> Result<StagedPluginPackage, PluginStoreError> {
|
||||
Err(PluginStoreError::Invalid("not used".to_owned()))
|
||||
}
|
||||
|
||||
async fn commit_install(
|
||||
&self,
|
||||
_staged: StagedPluginPackage,
|
||||
_plugin_id: &PluginId,
|
||||
) -> Result<domain::PluginPackageRef, PluginStoreError> {
|
||||
Err(PluginStoreError::Invalid("not used".to_owned()))
|
||||
}
|
||||
|
||||
async fn remove_package(
|
||||
&self,
|
||||
_plugin_id: &PluginId,
|
||||
) -> Result<RemovalOutcome, PluginStoreError> {
|
||||
Ok(RemovalOutcome::NotFound)
|
||||
}
|
||||
|
||||
fn bundle_url(
|
||||
&self,
|
||||
plugin_id: &PluginId,
|
||||
entry: &RelativePath,
|
||||
hash: &ContentHash,
|
||||
) -> Result<domain::PluginBundleUrl, PluginStoreError> {
|
||||
Ok(domain::PluginBundleUrl::new(format!(
|
||||
"idea-plugin://{}/current/{}/{}",
|
||||
plugin_id.as_str(),
|
||||
hash.as_str(),
|
||||
entry.as_str()
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
struct RejectingValidator;
|
||||
|
||||
impl domain::ports::PluginManifestValidator for RejectingValidator {
|
||||
fn validate(
|
||||
&self,
|
||||
_bytes: &[u8],
|
||||
_package: &domain::PluginPackageRef,
|
||||
) -> Result<domain::PluginManifest, PluginManifestError> {
|
||||
Err(PluginManifestError::Invalid("broken manifest".to_owned()))
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn protocol_future_can_be_waited_inside_tauri_runtime() {
|
||||
@ -310,4 +416,43 @@ mod tests {
|
||||
|
||||
assert_eq!(value, 42);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn asset_allowed_confines_invalid_active_manifest_to_forbidden() {
|
||||
let plugin_id = PluginId::new("dev.acme.gitgraph").unwrap();
|
||||
let hash = ContentHash::new("abc123").unwrap();
|
||||
let registry = FakeRegistry {
|
||||
registry: Mutex::new(PluginRegistry {
|
||||
version: 1,
|
||||
plugins: vec![PluginRegistryEntry {
|
||||
id: plugin_id.clone(),
|
||||
lifecycle_state: PluginLifecycleState::Enabled,
|
||||
source: PluginInstallSource::Directory {
|
||||
path_label: "/source/plugin".to_owned(),
|
||||
},
|
||||
content_hash: hash.clone(),
|
||||
restart_required: false,
|
||||
error: None,
|
||||
}],
|
||||
}),
|
||||
};
|
||||
let packages = FakePackages {
|
||||
manifest: br#"{"broken":true}"#.to_vec(),
|
||||
};
|
||||
let rel = RelativePath::new("dist/index.js").unwrap();
|
||||
|
||||
let err = asset_allowed(
|
||||
&plugin_id,
|
||||
hash.as_str(),
|
||||
&rel,
|
||||
®istry,
|
||||
&packages,
|
||||
&RejectingValidator,
|
||||
)
|
||||
.await
|
||||
.unwrap_err();
|
||||
|
||||
assert_eq!(err.0, StatusCode::FORBIDDEN);
|
||||
assert!(err.1.contains("broken manifest"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user