gnostr_relay/
lib.rs

1#[derive(thiserror::Error, Debug)]
2pub enum Error {
3    #[error(transparent)]
4    Db(#[from] nostr_db::Error),
5    #[error(transparent)]
6    Io(#[from] std::io::Error),
7    #[error(transparent)]
8    Config(#[from] config::ConfigError),
9    #[error(transparent)]
10    Notify(#[from] notify::Error),
11    #[error(transparent)]
12    Json(#[from] serde_json::Error),
13    #[error("invalid: {0}")]
14    Invalid(String),
15    #[error("{0}")]
16    Message(String),
17    #[error("{0}")]
18    Str(&'static str),
19}
20
21impl actix_web::ResponseError for Error {}
22
23pub type Result<T, E = Error> = core::result::Result<T, E>;
24
25mod app;
26pub mod duration;
27mod extension;
28mod hash;
29mod list;
30pub mod message;
31mod reader;
32mod server;
33mod session;
34pub mod setting;
35mod subscriber;
36mod writer;
37
38pub use metrics;
39pub use nostr_db as db;
40pub use {
41    app::*, extension::*, list::List, reader::Reader, server::Server, session::Session,
42    setting::Setting, subscriber::Subscriber, writer::Writer,
43};
44
45#[cfg(test)]
46pub fn temp_data_path(p: &str) -> anyhow::Result<tempfile::TempDir> {
47    Ok(tempfile::Builder::new()
48        .prefix(&format!("nostr-relay-test-db-{}", p))
49        .tempdir()?)
50}
51
52#[cfg(test)]
53pub fn create_test_app(db_path: &str) -> anyhow::Result<App> {
54    Ok(App::create(
55        None,
56        false,
57        None,
58        Some(temp_data_path(db_path)?),
59    )?)
60}
61
62#[cfg(test)]
63mod lib_tests {
64    use super::*;
65    use actix_web::http::StatusCode;
66    use actix_web::ResponseError;
67
68    #[test]
69    fn test_error_display() {
70        let db_error = Error::Db(nostr_db::Error::Io(std::io::Error::new(
71            std::io::ErrorKind::Other,
72            "db error",
73        )));
74        assert_eq!(format!("{}", db_error), "io: db error");
75
76        let io_error = Error::Io(std::io::Error::new(
77            std::io::ErrorKind::NotFound,
78            "file not found",
79        ));
80        assert_eq!(format!("{}", io_error), "file not found");
81
82        let config_error = Error::Config(config::ConfigError::Message("config error".to_string()));
83        assert_eq!(format!("{}", config_error), "config error");
84
85        let notify_error = Error::Notify(notify::Error::new(notify::ErrorKind::PathNotFound));
86        assert_eq!(format!("{}", notify_error), "No path was found.");
87
88        let json_error = Error::Json(serde_json::from_str::<serde_json::Value>("{").unwrap_err());
89        assert!(format!("{}", json_error).contains("EOF while parsing an object"));
90
91        let invalid_error = Error::Invalid("invalid input".to_string());
92        assert_eq!(format!("{}", invalid_error), "invalid: invalid input");
93
94        let message_error = Error::Message("custom message".to_string());
95        assert_eq!(format!("{}", message_error), "custom message");
96
97        let str_error = Error::Str("static string error");
98        assert_eq!(format!("{}", str_error), "static string error");
99    }
100
101    #[test]
102    fn test_error_response_error() {
103        let error = Error::Invalid("test".to_string());
104        let response = error.error_response();
105        assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR);
106    }
107
108    #[test]
109    fn test_temp_data_path() -> anyhow::Result<()> {
110        let temp_dir = temp_data_path("test_temp_data_path")?;
111        assert!(temp_dir.path().exists());
112        assert!(temp_dir.path().is_dir());
113        Ok(())
114    }
115
116    #[actix_web::test]
117    async fn test_create_test_app() -> anyhow::Result<()> {
118        let _app = create_test_app("test_create_test_app")?;
119        // You might want to add more assertions here to check the app's state
120        // For now, just ensuring it creates without error is a good start.
121        Ok(())
122    }
123}