about summary refs log tree commit diff
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs211
1 files changed, 149 insertions, 62 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 27adc1a..d1bff68 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,22 +1,22 @@
 use tide::{Request, Response};
 
 mod database;
+mod frontend;
 mod indieauth;
 mod micropub;
-mod frontend;
 
 use crate::indieauth::IndieAuthMiddleware;
 
 #[derive(Clone)]
 pub struct ApplicationState<StorageBackend>
 where
-    StorageBackend: database::Storage + Send + Sync + 'static
+    StorageBackend: database::Storage + Send + Sync + 'static,
 {
     token_endpoint: surf::Url,
     authorization_endpoint: surf::Url,
     media_endpoint: Option<String>,
     http_client: surf::Client,
-    storage: StorageBackend
+    storage: StorageBackend,
 }
 
 type App<Storage> = tide::Server<ApplicationState<Storage>>;
@@ -25,70 +25,105 @@ static MICROPUB_CLIENT: &[u8] = include_bytes!("./index.html");
 
 fn equip_app<Storage>(mut app: App<Storage>) -> App<Storage>
 where
-    Storage: database::Storage + Send + Sync + Clone
+    Storage: database::Storage + Send + Sync + Clone,
 {
-    app.at("/micropub").with(IndieAuthMiddleware::new())
+    app.at("/micropub")
+        .with(IndieAuthMiddleware::new())
         .get(micropub::get_handler)
         .post(micropub::post_handler);
     // The Micropub client. It'll start small, but could grow into something full-featured!
     app.at("/micropub/client").get(|_: Request<_>| async move {
-        Ok(Response::builder(200).body(MICROPUB_CLIENT).content_type("text/html").build())
+        Ok(Response::builder(200)
+            .body(MICROPUB_CLIENT)
+            .content_type("text/html")
+            .build())
     });
-    app.at("/").with(frontend::ErrorHandlerMiddleware {})
+    app.at("/")
+        .with(frontend::ErrorHandlerMiddleware {})
         .get(frontend::mainpage)
         .post(frontend::onboarding_receiver);
-    app.at("/static/*path").with(frontend::ErrorHandlerMiddleware {}).get(frontend::handle_static);
-    app.at("/*path").with(frontend::ErrorHandlerMiddleware {}).get(frontend::render_post);
-    app.at("/coffee").with(frontend::ErrorHandlerMiddleware {}).get(frontend::coffee);
+    app.at("/static/*path")
+        .with(frontend::ErrorHandlerMiddleware {})
+        .get(frontend::handle_static);
+    app.at("/*path")
+        .with(frontend::ErrorHandlerMiddleware {})
+        .get(frontend::render_post);
+    app.at("/coffee")
+        .with(frontend::ErrorHandlerMiddleware {})
+        .get(frontend::coffee);
     app.at("/health").get(|_| async { Ok("OK") });
 
     app
 }
 
-pub async fn get_app_with_redis(token_endpoint: surf::Url, authorization_endpoint: surf::Url, redis_uri: String, media_endpoint: Option<String>) -> App<database::RedisStorage> {
-    let app = tide::with_state(ApplicationState { 
-        token_endpoint, media_endpoint,
+pub async fn get_app_with_redis(
+    token_endpoint: surf::Url,
+    authorization_endpoint: surf::Url,
+    redis_uri: String,
+    media_endpoint: Option<String>,
+) -> App<database::RedisStorage> {
+    let app = tide::with_state(ApplicationState {
+        token_endpoint,
+        media_endpoint,
         authorization_endpoint,
         storage: database::RedisStorage::new(redis_uri).await.unwrap(),
         http_client: surf::Client::new(),
     });
-    
+
     equip_app(app)
 }
 
 #[cfg(test)]
-pub async fn get_app_with_test_redis(token_endpoint: surf::Url) -> (database::RedisInstance, database::RedisStorage, App<database::RedisStorage>) {
+pub async fn get_app_with_test_redis(
+    token_endpoint: surf::Url,
+) -> (
+    database::RedisInstance,
+    database::RedisStorage,
+    App<database::RedisStorage>,
+) {
     use surf::Url;
 
     let redis_instance = database::get_redis_instance().await;
-    let backend = database::RedisStorage::new(redis_instance.uri().to_string()).await.unwrap();
+    let backend = database::RedisStorage::new(redis_instance.uri().to_string())
+        .await
+        .unwrap();
     let app = tide::with_state(ApplicationState {
-        token_endpoint, media_endpoint: None,
+        token_endpoint,
+        media_endpoint: None,
         authorization_endpoint: Url::parse("https://indieauth.com/auth").unwrap(),
         storage: backend.clone(),
         http_client: surf::Client::new(),
     });
-    return (redis_instance, backend, equip_app(app))
+    return (redis_instance, backend, equip_app(app));
 }
 
 #[cfg(test)]
 #[allow(unused_variables)]
 mod tests {
     use super::*;
+    use database::Storage;
+    use mockito::mock;
     use serde_json::json;
     use tide_testing::TideTestingExt;
-    use mockito::mock;
-    use database::Storage;
 
     // Helpers
-    async fn create_app() -> (database::RedisStorage, App<database::RedisStorage>, database::RedisInstance) {
+    async fn create_app() -> (
+        database::RedisStorage,
+        App<database::RedisStorage>,
+        database::RedisInstance,
+    ) {
         //get_app_with_memory_for_testing(surf::Url::parse(&*mockito::server_url()).unwrap()).await
-        let (r, b, a) = get_app_with_test_redis(surf::Url::parse(&*mockito::server_url()).unwrap()).await;
+        let (r, b, a) =
+            get_app_with_test_redis(surf::Url::parse(&*mockito::server_url()).unwrap()).await;
         (b, a, r)
     }
 
-    async fn post_json(app: &App<database::RedisStorage>, json: serde_json::Value) -> surf::Response {
-        let request = app.post("/micropub")
+    async fn post_json(
+        app: &App<database::RedisStorage>,
+        json: serde_json::Value,
+    ) -> surf::Response {
+        let request = app
+            .post("/micropub")
             .header("Authorization", "Bearer test")
             .header("Content-Type", "application/json")
             .body(json);
@@ -105,22 +140,30 @@ mod tests {
 
         let (db, app, _r) = create_app().await;
 
-        let response = post_json(&app, json!({
-            "type": ["h-entry"],
-            "properties": {
-                "content": ["Fake news about Aaron Parecki!"],
-                "uid": ["https://aaronparecki.com/posts/fake-news"]
-            }
-        })).await;
+        let response = post_json(
+            &app,
+            json!({
+                "type": ["h-entry"],
+                "properties": {
+                    "content": ["Fake news about Aaron Parecki!"],
+                    "uid": ["https://aaronparecki.com/posts/fake-news"]
+                }
+            }),
+        )
+        .await;
         assert_eq!(response.status(), 403);
 
-        let response = post_json(&app, json!({
-            "type": ["h-entry"],
-            "properties": {
-                "content": ["More fake news about Aaron Parecki!"],
-                "url": ["https://aaronparecki.com/posts/more-fake-news"]
-            }
-        })).await;
+        let response = post_json(
+            &app,
+            json!({
+                "type": ["h-entry"],
+                "properties": {
+                    "content": ["More fake news about Aaron Parecki!"],
+                    "url": ["https://aaronparecki.com/posts/more-fake-news"]
+                }
+            }),
+        )
+        .await;
         assert_eq!(response.status(), 403);
 
         let response = post_json(&app, json!({
@@ -143,9 +186,12 @@ mod tests {
 
         let (db, app, _r) = create_app().await;
 
-        let response: serde_json::Value = app.get("/micropub?q=config")
+        let response: serde_json::Value = app
+            .get("/micropub?q=config")
             .header("Authorization", "test")
-            .recv_json().await.unwrap();
+            .recv_json()
+            .await
+            .unwrap();
         assert!(!response["q"].as_array().unwrap().is_empty());
     }
 
@@ -159,9 +205,12 @@ mod tests {
 
         let (db, app, _r) = create_app().await;
 
-        let response: surf::Response = app.get("/micropub?q=config")
+        let response: surf::Response = app
+            .get("/micropub?q=config")
             .header("Authorization", "test")
-            .send().await.unwrap();
+            .send()
+            .await
+            .unwrap();
         assert_eq!(response.status(), 401);
     }
 
@@ -184,17 +233,27 @@ mod tests {
 
         let (storage, app, _r) = create_app().await;
 
-        let request: surf::RequestBuilder = app.post("/micropub")
+        let request: surf::RequestBuilder = app
+            .post("/micropub")
             .header("Authorization", "Bearer test")
             .header("Content-Type", "application/x-www-form-urlencoded")
             .body("h=entry&content=something%20interesting&category[]=test&category[]=stuff");
         let mut response: surf::Response = request.send().await.unwrap();
-        println!("{:#}", response.body_json::<serde_json::Value>().await.unwrap());
+        println!(
+            "{:#}",
+            response.body_json::<serde_json::Value>().await.unwrap()
+        );
         assert!(response.status() == 201 || response.status() == 202);
         let uid = response.header("Location").unwrap().last().to_string();
         // Assume the post is in the database at this point.
         let post = storage.get_post(&uid).await.unwrap().unwrap();
-        assert_eq!(post["properties"]["content"][0]["html"].as_str().unwrap().trim(), "<p>something interesting</p>");
+        assert_eq!(
+            post["properties"]["content"][0]["html"]
+                .as_str()
+                .unwrap()
+                .trim(),
+            "<p>something interesting</p>"
+        );
     }
 
     #[async_std::test]
@@ -207,35 +266,63 @@ mod tests {
 
         let (storage, app, _r) = create_app().await;
 
-        let mut response = post_json(&app, json!({
-            "type": ["h-entry"],
-            "properties": {
-                "content": ["This is content!"]
-            }
-        })).await;
-        println!("{:#}", response.body_json::<serde_json::Value>().await.unwrap());
+        let mut response = post_json(
+            &app,
+            json!({
+                "type": ["h-entry"],
+                "properties": {
+                    "content": ["This is content!"]
+                }
+            }),
+        )
+        .await;
+        println!(
+            "{:#}",
+            response.body_json::<serde_json::Value>().await.unwrap()
+        );
         assert!(response.status() == 201 || response.status() == 202);
         let uid = response.header("Location").unwrap().last().to_string();
         // Assume the post is in the database at this point.
         let post = storage.get_post(&uid).await.unwrap().unwrap();
-        assert_eq!(post["properties"]["content"][0]["html"].as_str().unwrap().trim(), "<p>This is content!</p>");
-        let feed = storage.get_post("https://fireburn.ru/feeds/main").await.unwrap().unwrap();
+        assert_eq!(
+            post["properties"]["content"][0]["html"]
+                .as_str()
+                .unwrap()
+                .trim(),
+            "<p>This is content!</p>"
+        );
+        let feed = storage
+            .get_post("https://fireburn.ru/feeds/main")
+            .await
+            .unwrap()
+            .unwrap();
         assert_eq!(feed["children"].as_array().unwrap().len(), 1);
         assert_eq!(feed["children"][0].as_str().unwrap(), uid);
         let first_uid = uid;
         // Test creation of a second post
-        let mut response = post_json(&app, json!({
-            "type": ["h-entry"],
-            "properties": {
-                "content": ["#moar content for you!"]
-            }
-        })).await;
-        println!("{:#}", response.body_json::<serde_json::Value>().await.unwrap());
+        let mut response = post_json(
+            &app,
+            json!({
+                "type": ["h-entry"],
+                "properties": {
+                    "content": ["#moar content for you!"]
+                }
+            }),
+        )
+        .await;
+        println!(
+            "{:#}",
+            response.body_json::<serde_json::Value>().await.unwrap()
+        );
         assert!(response.status() == 201 || response.status() == 202);
         let uid = response.header("Location").unwrap().last().to_string();
         // Assume the post is in the database at this point.
         //println!("Keys in database: {:?}", storage.mapping.read().await.keys());
-        let new_feed = storage.get_post("https://fireburn.ru/feeds/main").await.unwrap().unwrap();
+        let new_feed = storage
+            .get_post("https://fireburn.ru/feeds/main")
+            .await
+            .unwrap()
+            .unwrap();
         println!("{}", new_feed["children"]);
         assert_eq!(new_feed["children"].as_array().unwrap().len(), 2);
         assert_eq!(new_feed["children"][0].as_str().unwrap(), uid);