newsblur_api_updated 0.4.1

rust implementation of the NewsBlur-API
Documentation
use crate::NewsBlurApi;
use reqwest::Client;
use std::env;
use test_log::test;
use url::Url;

fn test_setup_env() -> NewsBlurApi {
    dotenv::dotenv().expect("Failed to read .env file");
    let url = "https://newsblur.com";
    let user = env::var("NEWSBLUR_USER").expect("Failed to read NEWSBLUR_USER");
    let pw = env::var("NEWSBLUR_PW").expect("Failed to read NEWSBLUR_PW");

    let url = Url::parse(url).unwrap();
    NewsBlurApi::new(&url, &user, &pw, None)
}

fn client() -> Client {
    Client::builder().user_agent("curl/7.64.0").build().unwrap()
}

#[test(tokio::test)]
async fn login() {
    let mut api = test_setup_env();
    let client = client();

    let _cookie = api.login(&client).await.unwrap();
}

#[test(tokio::test)]
async fn logout() {
    let mut api = test_setup_env();
    let client = client();

    let _cookie = api.login(&client).await.unwrap();
    api.logout(&client).await.unwrap();
}

#[test(tokio::test)]
async fn search_feed() {
    let mut api = test_setup_env();
    let client = client();

    let _cookie = api.login(&client).await.unwrap();
    api.search_feed(&client, "www.abc.net.au/news/feed/51120/rss.xml")
        .await
        .unwrap();
}

#[test(tokio::test)]
async fn get_feeds() {
    let mut api = test_setup_env();
    let client = client();

    let _cookie = api.login(&client).await.unwrap();
    api.get_feeds(&client).await.unwrap();
}

#[test(tokio::test)]
async fn favicons() {
    let mut api = test_setup_env();
    let client = client();

    let _cookie = api.login(&client).await.unwrap();

    let response = api.get_feeds(&client).await.unwrap();
    let feeds = &response["feeds"].as_object().unwrap();

    for feed in feeds.iter().take(70) {
        let _favicon = api.favicons(&client, feed.0).await.unwrap();
    }
}

#[test(tokio::test)]
async fn get_original_page() {
    let mut api = test_setup_env();
    let client = client();

    let _cookie = api.login(&client).await.unwrap();

    let response = api.get_feeds(&client).await.unwrap();
    let feeds = &response["feeds"].as_object().unwrap();

    for feed in feeds.iter().take(70) {
        let _original = api.get_original_page(&client, feed.0).await.unwrap();
    }
}

#[test(tokio::test)]
async fn refresh_feeds() {
    let mut api = test_setup_env();
    let client = client();

    let _cookie = api.login(&client).await.unwrap();
    let _response = api.refresh_feeds(&client).await.unwrap();
}

#[test(tokio::test)]
async fn get_stories() {
    let mut api = test_setup_env();
    let client = client();

    let _cookie = api.login(&client).await.unwrap();

    let response = api.get_feeds(&client).await.unwrap();
    let feeds = &response["feeds"].as_object().unwrap();

    for feed in feeds.iter().take(70) {
        let response = api.get_stories(&client, feed.0, false, 1).await.unwrap();
        assert_ne!(response["stories"], serde_json::Value::Null);

        let response = api.get_stories(&client, feed.0, false, 2).await.unwrap();
        assert_ne!(response["stories"], serde_json::Value::Null);
    }
}

#[test(tokio::test)]
async fn read_stories() {
    let mut api = test_setup_env();
    let client = client();

    let _cookie = api.login(&client).await.unwrap();

    let response = api.get_feeds(&client).await.unwrap();
    let feeds = &response["feeds"].as_object().unwrap();

    for feed in feeds.iter().take(10) {
        let response = api.get_stories(&client, feed.0, false, 1).await.unwrap();
        let story_hash = &response["stories"][0]["guid_hash"].as_str().unwrap();
        let read = response["stories"][0]["read_status"].as_i64().unwrap();
        let full_hash = format!("{}:{}", feed.0, story_hash);

        if read > 0 {
            api.mark_story_unread(&client, &[&full_hash]).await.unwrap();
            api.mark_stories_read(&client, &[&full_hash]).await.unwrap();
        } else {
            api.mark_stories_read(&client, &[&full_hash]).await.unwrap();
            api.mark_story_unread(&client, &[&full_hash]).await.unwrap();
        }
    }
}

#[test(tokio::test)]
async fn star_stories() {
    let mut api = test_setup_env();
    let client = client();

    let _cookie = api.login(&client).await.unwrap();

    let response = api.get_feeds(&client).await.unwrap();
    let feeds = &response["feeds"].as_object().unwrap();

    let feed = feeds.iter().next().unwrap();
    let response = api.get_stories(&client, feed.0, false, 1).await.unwrap();
    let story_hash = response["stories"][0]["guid_hash"].as_str().unwrap();
    let full_hash = format!("{}:{}", feed.0, story_hash);

    api.mark_story_hash_as_starred(&client, &full_hash)
        .await
        .unwrap();
    api.mark_story_hash_as_unstarred(&client, &full_hash)
        .await
        .unwrap();
}

#[test(tokio::test)]
async fn get_unread_feeds() {
    let mut api = test_setup_env();
    let client = client();

    let _cookie = api.login(&client).await.unwrap();
    let response = api.get_unread_story_hashes(&client).await.unwrap();
    let _hashes = &response["unread_feed_story_hashes"];
}

#[test(tokio::test)]
async fn get_stared_feeds() {
    let mut api = test_setup_env();
    let client = client();

    let _cookie = api.login(&client).await.unwrap();
    let response = api.get_stared_story_hashes(&client).await.unwrap();
    let _hashes = &response["starred_story_hashes"];
}