feedly_api 0.3.0

rust implementation of the feedly REST API
Documentation
use super::models::{Entry, SubscriptionInput, Tag};
use super::FeedlyApi;
use chrono::Utc;

fn read_secrets() -> (String, String) {
    (String::from(""), String::from(""))
}

fn generate_api() -> FeedlyApi {
    let api = FeedlyApi::new(
        String::from(""),
        String::from(""),
        String::from(""),
        String::from(""),
        Utc::now(),
    )
    .unwrap();
    api
}

#[tokio::test(basic_scheduler)]
async fn login_url() {
    let (id, secret) = self::read_secrets();
    let url = FeedlyApi::login_url(&id, &secret).unwrap();
    let expected = format!("http://cloud.feedly.com/v3/auth/auth?client_secret={}&client_id={}&redirect_uri=http://localhost/&scope=https://cloud.feedly.com/subscriptions&response_type=code&state=getting_code", secret, id);
    assert_eq!(url.as_str(), &expected);
}

#[tokio::test(basic_scheduler)]
async fn get_token() {
    let (id, secret) = self::read_secrets();
    let auth_code = String::from("");
    let acces_token = FeedlyApi::request_auth_token(&id, &secret, auth_code, &reqwest::Client::new())
        .await
        .unwrap();

    assert_eq!(
        acces_token.state,
        Some(String::from("feedly-api rust crate"))
    );
    assert!(acces_token.expires_in > 600000);
}

#[tokio::test(basic_scheduler)]
async fn subscriptions() {
    let api = self::generate_api();

    // get subscriptions
    let subscriptions = api.get_subsriptions(&reqwest::Client::new()).await.unwrap();
    assert_eq!(
        subscriptions.get(0).unwrap().title,
        String::from("Planet GNOME")
    );
    let count_before = subscriptions.len();

    // add new subscription
    let new_subscription = SubscriptionInput {
        id: String::from("feed/https://rss.golem.de/rss.php?feed=ATOM1.0"),
        title: Some(String::from("Golem")),
        categories: None,
    };
    api.add_subscription(new_subscription, &reqwest::Client::new()).await.unwrap();
    let subscriptions = api.get_subsriptions(&reqwest::Client::new()).await.unwrap();
    assert_eq!(&subscriptions.get(1).unwrap().title, "Golem");

    // rename added subscription
    let update_subscription = SubscriptionInput {
        id: String::from("feed/https://rss.golem.de/rss.php?feed=ATOM1.0"),
        title: Some(String::from("GolemXYZ")),
        categories: None,
    };
    api.update_subscriptions(vec![update_subscription], &reqwest::Client::new())
        .await
        .unwrap();
    let subscriptions = api.get_subsriptions(&reqwest::Client::new()).await.unwrap();
    assert_eq!(&subscriptions.get(1).unwrap().title, "GolemXYZ");

    // delete added subscription
    api.delete_subscription(&subscriptions.get(1).unwrap().id, &reqwest::Client::new())
        .await
        .unwrap();
    let subscriptions = api.get_subsriptions(&reqwest::Client::new()).await.unwrap();
    assert_eq!(subscriptions.len(), count_before);
}

#[tokio::test(basic_scheduler)]
async fn tags() {
    let api = self::generate_api();
    let entry_id = "vW7ltq/KF6A6KAnuQylk2Q7xpz+R7bniO3psKBctmBE=_1646c2afacc:11c13a7:b83afde1";

    // get tags
    let tags = api.get_tags(&reqwest::Client::new()).await.unwrap();
    assert_eq!(tags.get(1).unwrap().label, Some(String::from("test")));

    // create new tag and tag entry with it
    let new_tag_name = "testTag123";
    let new_tag_id = api.generate_tag_id(new_tag_name, &reqwest::Client::new()).await.unwrap();
    api.tag_entry(entry_id, vec![&new_tag_id], &reqwest::Client::new()).await.unwrap();

    let tags = api.get_tags(&reqwest::Client::new()).await.unwrap();
    let tag = tags.get(2).unwrap();
    assert_eq!(tag.label, Some(String::from(new_tag_name)));

    let tag_id = &tag.id;

    let entries = api.get_entries(vec![entry_id.clone()], &reqwest::Client::new()).await.unwrap();
    let entry: &Entry = entries.get(0).as_ref().unwrap();
    let tags: &Vec<Tag> = entry.tags.as_ref().unwrap();
    let tag: &Tag = tags.get(1).as_ref().unwrap();
    assert_eq!(&tag.id, tag_id);

    // remove tag from entry
    api.untag_entries(vec![entry_id.clone()], vec![tag_id], &reqwest::Client::new())
        .await
        .unwrap();

    let entries = api.get_entries(vec![entry_id.clone()], &reqwest::Client::new()).await.unwrap();
    let entry: &Entry = entries.get(0).as_ref().unwrap();
    let tags: &Vec<Tag> = entry.tags.as_ref().unwrap();
    assert!(tags.get(1).is_none());

    // delte tag
    api.delete_tags(vec![tag_id], &reqwest::Client::new()).await.unwrap();

    let tags = api.get_tags(&reqwest::Client::new()).await.unwrap();
    assert!(tags.get(2).is_none());
}

#[tokio::test(basic_scheduler)]
async fn streams() {
    let api = self::generate_api();

    let stream = api
        .get_stream(
            "feed/http://planet.gnome.org/rss20.xml",
            None,
            None,
            None,
            None,
            None,
            &reqwest::Client::new(),
        )
        .await
        .unwrap();

    assert!(stream.items.get(0).is_some());
}

#[tokio::test(basic_scheduler)]
async fn categories() {
    let api = self::generate_api();

    let categories = api.get_categories(&reqwest::Client::new()).await.unwrap();
    assert!(categories.get(0).is_some());
}

#[tokio::test(basic_scheduler)]
async fn discover_news() {
    let client = reqwest::Client::new();
    let search_result = FeedlyApi::search_feedly_cloud(&client, "golem", Some(2), Some("de_DE"))
        .await
        .unwrap();

    assert_eq!(
        search_result.related,
        Some(vec!["tech".to_owned(), "it".to_owned()])
    );
}

#[tokio::test(basic_scheduler)]
async fn discover_cooking() {
    let client = reqwest::Client::new();
    let search_result = FeedlyApi::search_feedly_cloud(&client, "cooking", Some(5), Some("en_EN"))
        .await
        .unwrap();

    assert_eq!(
        search_result.related,
        Some(vec!["food".to_owned(), "recipes".to_owned()])
    );
}