mirror of
https://framagit.org/veretcle/scootaloo.git
synced 2025-07-20 17:11:19 +02:00
feature(test): add tests
This commit is contained in:
35
config.rs
Normal file
35
config.rs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
use scootaloo::parse_toml;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_good_toml() {
|
||||||
|
let tConfig = TwitterConfig {
|
||||||
|
username: "test",
|
||||||
|
consumer_key: "foo",
|
||||||
|
consumer_secret: "bar",
|
||||||
|
access_key: "secret",
|
||||||
|
access_secret: "super secret",
|
||||||
|
};
|
||||||
|
|
||||||
|
let mConfig = MastodonConfig {
|
||||||
|
base: "https://www.example.com",
|
||||||
|
client_id: "my_id",
|
||||||
|
client_secret: "this is secret",
|
||||||
|
redirect: "ooo:oooo:o",
|
||||||
|
token: "super secret",
|
||||||
|
};
|
||||||
|
|
||||||
|
let sConfig = ScootalooConfig {
|
||||||
|
db_path: "/tmp/scootaloo/scootaloo.db",
|
||||||
|
cache_path: "/tmp",
|
||||||
|
};
|
||||||
|
|
||||||
|
let test_config = Config {
|
||||||
|
twitter: tConfig,
|
||||||
|
mastodon: mConfig,
|
||||||
|
scootaloo: sConfig,
|
||||||
|
};
|
||||||
|
|
||||||
|
let parsed_config = parse_toml("tests/right_config.toml");
|
||||||
|
|
||||||
|
assert_eq!(parsed_config, test_config);
|
||||||
|
}
|
@@ -1,6 +1,6 @@
|
|||||||
// auto-imports
|
// auto-imports
|
||||||
mod error;
|
mod error;
|
||||||
use error::ScootalooError;
|
use crate::error::ScootalooError;
|
||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
use config::Config;
|
use config::Config;
|
||||||
|
@@ -61,7 +61,7 @@ fn main() {
|
|||||||
},
|
},
|
||||||
("init", Some(sub_m)) => {
|
("init", Some(sub_m)) => {
|
||||||
let config = parse_toml(sub_m.value_of("config").unwrap_or(DEFAULT_CONFIG_PATH));
|
let config = parse_toml(sub_m.value_of("config").unwrap_or(DEFAULT_CONFIG_PATH));
|
||||||
init_db(&config).unwrap();
|
init_db(&config.scootaloo).unwrap();
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
// auto imports
|
// auto imports
|
||||||
use crate::config::MastodonConfig;
|
use crate::config::MastodonConfig;
|
||||||
use crate::twitter::decode_urls;
|
|
||||||
|
|
||||||
// std
|
// std
|
||||||
use std::{
|
use std::{
|
||||||
@@ -16,7 +15,7 @@ use htmlescape::decode_html;
|
|||||||
// egg-mode
|
// egg-mode
|
||||||
use egg_mode::{
|
use egg_mode::{
|
||||||
tweet::Tweet,
|
tweet::Tweet,
|
||||||
entities::MentionEntity,
|
entities::{UrlEntity, MentionEntity},
|
||||||
};
|
};
|
||||||
|
|
||||||
// elefren
|
// elefren
|
||||||
@@ -39,6 +38,20 @@ fn twitter_mentions(ums: &Vec<MentionEntity>) -> HashMap<String, String> {
|
|||||||
decoded_mentions
|
decoded_mentions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Decodes urls from UrlEntities
|
||||||
|
fn decode_urls(urls: &Vec<UrlEntity>) -> HashMap<String, String> {
|
||||||
|
let mut decoded_urls = HashMap::new();
|
||||||
|
|
||||||
|
for url in urls {
|
||||||
|
if url.expanded_url.is_some() {
|
||||||
|
// unwrap is safe here as we just verified that there is something inside expanded_url
|
||||||
|
decoded_urls.insert(String::from(&url.url), String::from(url.expanded_url.as_deref().unwrap()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
decoded_urls
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets Mastodon Data
|
/// Gets Mastodon Data
|
||||||
pub fn get_mastodon_token(masto: &MastodonConfig) -> Mastodon {
|
pub fn get_mastodon_token(masto: &MastodonConfig) -> Mastodon {
|
||||||
let data = Data {
|
let data = Data {
|
||||||
@@ -104,3 +117,52 @@ pub fn register(host: &str) {
|
|||||||
println!("Please insert the following block at the end of your configuration file:\n[mastodon]\n{}", toml);
|
println!("Please insert the following block at the end of your configuration file:\n[mastodon]\n{}", toml);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_twitter_mentions() {
|
||||||
|
let mention_entity = MentionEntity {
|
||||||
|
id: 12345,
|
||||||
|
range: (1, 3),
|
||||||
|
name: String::from("Ta Mere l0l"),
|
||||||
|
screen_name: String::from("tamerelol"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let twitter_ums = vec![mention_entity];
|
||||||
|
|
||||||
|
let mut expected_mentions = HashMap::new();
|
||||||
|
expected_mentions.insert(String::from("@tamerelol"), String::from("@tamerelol@twitter.com"));
|
||||||
|
|
||||||
|
let decoded_mentions = twitter_mentions(&twitter_ums);
|
||||||
|
|
||||||
|
assert_eq!(expected_mentions, decoded_mentions);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_decode_urls() {
|
||||||
|
let url_entity1 = UrlEntity {
|
||||||
|
display_url: String::from("tamerelol"),
|
||||||
|
expanded_url: Some(String::from("https://www.nintendojo.fr/dojobar")),
|
||||||
|
range: (1, 3),
|
||||||
|
url: String::from("https://t.me/tamerelol"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let url_entity2 = UrlEntity {
|
||||||
|
display_url: String::from("tamerelol"),
|
||||||
|
expanded_url: None,
|
||||||
|
range: (1, 3),
|
||||||
|
url: String::from("https://t.me/tamerelol"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let twitter_urls = vec![url_entity1, url_entity2];
|
||||||
|
|
||||||
|
let mut expected_urls = HashMap::new();
|
||||||
|
expected_urls.insert(String::from("https://t.me/tamerelol"), String::from("https://www.nintendojo.fr/dojobar"));
|
||||||
|
|
||||||
|
let decoded_urls = decode_urls(&twitter_urls);
|
||||||
|
|
||||||
|
assert_eq!(expected_urls, decoded_urls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
69
src/state.rs
69
src/state.rs
@@ -1,5 +1,5 @@
|
|||||||
// auto-imports
|
// auto-imports
|
||||||
use crate::config::Config;
|
use crate::config::ScootalooConfig;
|
||||||
|
|
||||||
// std
|
// std
|
||||||
use std::{
|
use std::{
|
||||||
@@ -10,6 +10,9 @@ use std::{
|
|||||||
// log
|
// log
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
|
||||||
|
// rusqlite
|
||||||
|
use rusqlite::{Connection, OpenFlags, params};
|
||||||
|
|
||||||
/// Reads last tweet id from a file
|
/// Reads last tweet id from a file
|
||||||
pub fn read_state(s: &str) -> Option<u64> {
|
pub fn read_state(s: &str) -> Option<u64> {
|
||||||
let state = read_to_string(s);
|
let state = read_to_string(s);
|
||||||
@@ -31,8 +34,68 @@ pub fn write_state(f: &str, s: u64) -> Result<(), std::io::Error> {
|
|||||||
* Main functions
|
* Main functions
|
||||||
*********/
|
*********/
|
||||||
/// Initiates the DB from path
|
/// Initiates the DB from path
|
||||||
pub fn init_db(config: &Config) -> Result<(), Box<dyn Error>> {
|
pub fn init_db(config: &ScootalooConfig) -> Result<(), Box<dyn Error>> {
|
||||||
println!("config.scootaloo.db_path: {}", config.scootaloo.db_path);
|
let conn = Connection::open(&config.db_path)?;
|
||||||
|
|
||||||
|
conn.execute(
|
||||||
|
"CREATE TABLE IF NOT EXISTS tweet_to_toot (
|
||||||
|
tweet_id INTEGER PRIMARY KEY,
|
||||||
|
toot_id TEXT UNIQUE
|
||||||
|
)",
|
||||||
|
[],
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use std::{
|
||||||
|
fs::remove_file,
|
||||||
|
path::Path,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_init_db() {
|
||||||
|
let scootaloo_config = ScootalooConfig {
|
||||||
|
db_path: String::from("/tmp/test_init_db.sqlite"),
|
||||||
|
cache_path: String::from("/tmp/scootaloo"),
|
||||||
|
};
|
||||||
|
|
||||||
|
init_db(&scootaloo_config).unwrap();
|
||||||
|
|
||||||
|
// check that file exist
|
||||||
|
assert!(Path::new(&scootaloo_config.db_path).exists());
|
||||||
|
|
||||||
|
// open said file
|
||||||
|
let conn = Connection::open_with_flags(&scootaloo_config.db_path, OpenFlags::SQLITE_OPEN_READ_ONLY).unwrap();
|
||||||
|
|
||||||
|
conn.execute(
|
||||||
|
"SELECT * from tweet_to_toot;",
|
||||||
|
[],
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
conn.close().unwrap();
|
||||||
|
remove_file(&scootaloo_config.db_path).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_read_state() {
|
||||||
|
let scootaloo_config = ScootalooConfig {
|
||||||
|
db_path: String::from("/tmp/test_read_state.sqlite"),
|
||||||
|
cache_path: String::from("/tmp/scootaloo"),
|
||||||
|
};
|
||||||
|
|
||||||
|
init_db(&scootaloo_config).unwrap();
|
||||||
|
|
||||||
|
let conn = Connection::open(&scootaloo_config.db_path).unwrap();
|
||||||
|
|
||||||
|
conn.execute(
|
||||||
|
"INSERT INTO tweet_to_toot (tweet_id, toot_id) VALUES (?1, ?2)",
|
||||||
|
params![123456789 as u64, String::from("987654321")],
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -4,16 +4,13 @@ use crate::config::TwitterConfig;
|
|||||||
use crate::util::cache_media;
|
use crate::util::cache_media;
|
||||||
|
|
||||||
// std
|
// std
|
||||||
use std::{
|
use std::error::Error;
|
||||||
error::Error,
|
|
||||||
collections::HashMap,
|
|
||||||
};
|
|
||||||
|
|
||||||
// egg-mode
|
// egg-mode
|
||||||
use egg_mode::{
|
use egg_mode::{
|
||||||
Token,
|
Token,
|
||||||
KeyPair,
|
KeyPair,
|
||||||
entities::{UrlEntity, MediaEntity, MediaType},
|
entities::{MediaEntity, MediaType},
|
||||||
user::UserID,
|
user::UserID,
|
||||||
tweet::{
|
tweet::{
|
||||||
Tweet,
|
Tweet,
|
||||||
@@ -43,20 +40,6 @@ pub async fn get_user_timeline(config: &TwitterConfig, token: Token, lid: Option
|
|||||||
Ok(feed.to_vec())
|
Ok(feed.to_vec())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decodes urls from UrlEntities
|
|
||||||
pub fn decode_urls(urls: &Vec<UrlEntity>) -> HashMap<String, String> {
|
|
||||||
let mut decoded_urls = HashMap::new();
|
|
||||||
|
|
||||||
for url in urls {
|
|
||||||
if url.expanded_url.is_some() {
|
|
||||||
// unwrap is safe here as we just verified that there is something inside expanded_url
|
|
||||||
decoded_urls.insert(String::from(&url.url), String::from(url.expanded_url.as_deref().unwrap()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
decoded_urls
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves a single media from a tweet and store it in a temporary file
|
/// Retrieves a single media from a tweet and store it in a temporary file
|
||||||
pub async fn get_tweet_media(m: &MediaEntity, t: &str) -> Result<String, Box<dyn Error>> {
|
pub async fn get_tweet_media(m: &MediaEntity, t: &str) -> Result<String, Box<dyn Error>> {
|
||||||
match m.media_type {
|
match m.media_type {
|
||||||
|
1
tests/bad_test.toml
Normal file
1
tests/bad_test.toml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
blah
|
33
tests/config.rs
Normal file
33
tests/config.rs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
use scootaloo::parse_toml;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_good_toml() {
|
||||||
|
let parse_good_toml = parse_toml("tests/good_test.toml");
|
||||||
|
|
||||||
|
assert_eq!(parse_good_toml.scootaloo.db_path, "/var/random/scootaloo.sqlite");
|
||||||
|
assert_eq!(parse_good_toml.scootaloo.cache_path, "/tmp/scootaloo");
|
||||||
|
|
||||||
|
assert_eq!(parse_good_toml.twitter.username, "tamerelol");
|
||||||
|
assert_eq!(parse_good_toml.twitter.consumer_key, "rand consumer key");
|
||||||
|
assert_eq!(parse_good_toml.twitter.consumer_secret, "secret");
|
||||||
|
assert_eq!(parse_good_toml.twitter.access_key, "rand access key");
|
||||||
|
assert_eq!(parse_good_toml.twitter.access_secret, "super secret");
|
||||||
|
|
||||||
|
assert_eq!(parse_good_toml.mastodon.base, "https://m.nintendojo.fr");
|
||||||
|
assert_eq!(parse_good_toml.mastodon.client_id, "rand client id");
|
||||||
|
assert_eq!(parse_good_toml.mastodon.client_secret, "secret");
|
||||||
|
assert_eq!(parse_good_toml.mastodon.redirect, "urn:ietf:wg:oauth:2.0:oob");
|
||||||
|
assert_eq!(parse_good_toml.mastodon.token, "super secret");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "Cannot open config file tests/no_file.toml: No such file or directory (os error 2)")]
|
||||||
|
fn test_parse_no_toml() {
|
||||||
|
let _parse_no_toml = parse_toml("tests/no_file.toml");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "Cannot parse TOML file tests/bad_test.toml: expected an equals, found a newline at line 1 column 5")]
|
||||||
|
fn test_parse_bad_toml() {
|
||||||
|
let _parse_bad_toml = parse_toml("tests/bad_test.toml");
|
||||||
|
}
|
19
tests/good_test.toml
Normal file
19
tests/good_test.toml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[scootaloo]
|
||||||
|
|
||||||
|
db_path="/var/random/scootaloo.sqlite"
|
||||||
|
cache_path="/tmp/scootaloo"
|
||||||
|
|
||||||
|
[twitter]
|
||||||
|
username="tamerelol"
|
||||||
|
|
||||||
|
consumer_key="rand consumer key"
|
||||||
|
consumer_secret="secret"
|
||||||
|
access_key="rand access key"
|
||||||
|
access_secret="super secret"
|
||||||
|
|
||||||
|
[mastodon]
|
||||||
|
base = "https://m.nintendojo.fr"
|
||||||
|
client_id = "rand client id"
|
||||||
|
client_secret = "secret"
|
||||||
|
redirect = "urn:ietf:wg:oauth:2.0:oob"
|
||||||
|
token = "super secret"
|
Reference in New Issue
Block a user