use doido_storage::config::YamlConfig;
use doido_storage::{Service, ServiceBackend};
const YAML: &str = r#"
storage:
service: test
services:
local: { type: disk, root: uploads }
test: { type: memory }
amazon: { type: s3, bucket: my-bucket, region: us-east-1 }
"#;
#[test]
fn parses_named_services_and_selection() {
let cfg = YamlConfig::from_yaml(YAML).unwrap().storage;
assert_eq!(cfg.service.as_deref(), Some("test"));
assert_eq!(cfg.services.len(), 3);
assert_eq!(cfg.services["local"].backend, ServiceBackend::Disk);
assert_eq!(cfg.services["local"].root.as_deref(), Some("uploads"));
assert_eq!(cfg.services["test"].backend, ServiceBackend::Memory);
assert_eq!(cfg.services["amazon"].backend, ServiceBackend::S3);
}
#[test]
fn parses_gcs_and_custom_backends() {
let yaml = r#"
storage:
services:
google: { type: gcs, bucket: b }
files: { type: dropbox, token: xyz }
"#;
let cfg = YamlConfig::from_yaml(yaml).unwrap().storage;
assert_eq!(cfg.services["google"].backend, ServiceBackend::Gcs);
assert_eq!(
cfg.services["files"].backend,
ServiceBackend::Custom("dropbox".to_string())
);
assert_eq!(cfg.services["files"].option_str("token"), Some("xyz"));
}
#[tokio::test]
async fn gcs_without_feature_errors_clearly() {
let yaml = "storage:\n service: g\n services:\n g: { type: gcs, bucket: b }\n";
let cfg = YamlConfig::from_yaml(yaml).unwrap().storage;
let result = cfg.build().await;
#[cfg(not(feature = "storage-gcs"))]
{
let err = match result {
Ok(_) => panic!("expected an error selecting gcs without the feature"),
Err(e) => e.to_string(),
};
assert!(err.contains("storage-gcs"), "unexpected error: {err}");
}
#[cfg(feature = "storage-gcs")]
{
if let Err(e) = result {
assert!(!e.to_string().contains("without the `storage-gcs` feature"));
}
}
}
#[tokio::test]
async fn builds_the_selected_service() {
let cfg = YamlConfig::from_yaml(YAML).unwrap().storage;
let svc = cfg.build().await.unwrap();
assert_eq!(svc.name(), "test"); }
#[tokio::test]
async fn empty_config_defaults_to_disk() {
let cfg = doido_storage::StorageConfig::default();
let svc = cfg.build().await.unwrap();
assert_eq!(svc.name(), "local");
}
#[tokio::test]
async fn s3_without_feature_errors_clearly() {
let cfg = YamlConfig::from_yaml(YAML).unwrap().storage;
let result = cfg.build_named("amazon").await;
#[cfg(not(feature = "storage-s3"))]
{
let err = match result {
Ok(_) => panic!("expected an error selecting s3 without the feature"),
Err(e) => e.to_string(),
};
assert!(err.contains("storage-s3"), "unexpected error: {err}");
}
#[cfg(feature = "storage-s3")]
{
if let Err(e) = result {
assert!(!e.to_string().contains("without the `storage-s3` feature"));
}
}
}
#[tokio::test]
async fn build_named_missing_service_errors() {
let cfg = YamlConfig::from_yaml(YAML).unwrap().storage;
let err = match cfg.build_named("missing").await {
Ok(_) => panic!("expected missing service error"),
Err(e) => e.to_string(),
};
assert!(err.contains("missing") || err.contains("service"));
}
#[tokio::test]
async fn disk_public_flag_propagates() {
let yaml = r#"
storage:
service: pub
services:
pub: { type: disk, root: uploads, public: true }
"#;
let cfg = YamlConfig::from_yaml(yaml).unwrap().storage;
let svc = cfg.build().await.unwrap();
assert!(svc.public());
}
#[test]
fn load_without_config_file_is_usable() {
let cfg = doido_storage::config::load();
assert!(cfg.services.is_empty() || cfg.service.is_some() || cfg.services.contains_key("local"));
}