From e138fbb1d59e806db009827f5082476fa96834a8 Mon Sep 17 00:00:00 2001 From: Mark Lopez Date: Sat, 4 Apr 2026 12:41:39 -0500 Subject: [PATCH] refactor: moved all tests into test mod blocks --- src/client.rs | 96 ++++++++++---------- src/config.rs | 128 ++++++++++++++------------- src/oauth.rs | 107 ++++++++++++----------- src/post.rs | 5 +- src/search.rs | 2 - src/subreddit.rs | 30 ++++--- src/user.rs | 19 ++-- src/utils.rs | 223 +++++++++++++++++++++++------------------------ 8 files changed, 310 insertions(+), 300 deletions(-) diff --git a/src/client.rs b/src/client.rs index df802b8..70aec03 100644 --- a/src/client.rs +++ b/src/client.rs @@ -552,60 +552,62 @@ pub async fn rate_limit_check() -> Result<(), String> { } #[cfg(test)] -use {crate::config::get_setting, sealed_test::prelude::*}; +mod tests { + use super::*; + use {crate::config::get_setting, sealed_test::prelude::*}; -#[tokio::test(flavor = "multi_thread")] -async fn test_rate_limit_check() { - rate_limit_check().await.unwrap(); -} + const POPULAR_URL: &str = "/r/popular/hot.json?&raw_json=1&geo_filter=GLOBAL"; -#[test] -#[sealed_test(env = [("REDLIB_DEFAULT_SUBSCRIPTIONS", "rust")])] -fn test_default_subscriptions() { - tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap().block_on(async { - let subscriptions = get_setting("REDLIB_DEFAULT_SUBSCRIPTIONS"); - assert!(subscriptions.is_some()); - - // check rate limit + #[tokio::test(flavor = "multi_thread")] + async fn test_rate_limit_check() { rate_limit_check().await.unwrap(); - }); -} + } -#[cfg(test)] -const POPULAR_URL: &str = "/r/popular/hot.json?&raw_json=1&geo_filter=GLOBAL"; + #[test] + #[sealed_test(env = [("REDLIB_DEFAULT_SUBSCRIPTIONS", "rust")])] + fn test_default_subscriptions() { + tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap().block_on(async { + let subscriptions = get_setting("REDLIB_DEFAULT_SUBSCRIPTIONS"); + assert!(subscriptions.is_some()); -#[tokio::test(flavor = "multi_thread")] -async fn test_localization_popular() { - let val = json(POPULAR_URL.to_string(), false).await.unwrap(); - assert_eq!("GLOBAL", val["data"]["geo_filter"].as_str().unwrap()); -} + // check rate limit + rate_limit_check().await.unwrap(); + }); + } -#[tokio::test(flavor = "multi_thread")] -async fn test_obfuscated_share_link() { - let share_link = "/r/rust/s/kPgq8WNHRK".into(); - // Correct link without share parameters - let canonical_link = "/r/rust/comments/18t5968/why_use_tuple_struct_over_standard_struct/kfbqlbc/".into(); - assert_eq!(canonical_path(share_link, 3).await, Ok(Some(canonical_link))); -} + #[tokio::test(flavor = "multi_thread")] + async fn test_localization_popular() { + let val = json(POPULAR_URL.to_string(), false).await.unwrap(); + assert_eq!("GLOBAL", val["data"]["geo_filter"].as_str().unwrap()); + } -#[tokio::test(flavor = "multi_thread")] -async fn test_private_sub() { - let link = json("/r/suicide/about.json?raw_json=1".into(), true).await; - assert!(link.is_err()); - assert_eq!(link, Err("private".into())); -} + #[tokio::test(flavor = "multi_thread")] + async fn test_obfuscated_share_link() { + let share_link = "/r/rust/s/kPgq8WNHRK".into(); + // Correct link without share parameters + let canonical_link = "/r/rust/comments/18t5968/why_use_tuple_struct_over_standard_struct/kfbqlbc/".into(); + assert_eq!(canonical_path(share_link, 3).await, Ok(Some(canonical_link))); + } -#[tokio::test(flavor = "multi_thread")] -async fn test_banned_sub() { - let link = json("/r/aaa/about.json?raw_json=1".into(), true).await; - assert!(link.is_err()); - assert_eq!(link, Err("banned".into())); -} + #[tokio::test(flavor = "multi_thread")] + async fn test_private_sub() { + let link = json("/r/suicide/about.json?raw_json=1".into(), true).await; + assert!(link.is_err()); + assert_eq!(link, Err("private".into())); + } -#[tokio::test(flavor = "multi_thread")] -async fn test_gated_sub() { - // quarantine to false to specifically catch when we _don't_ catch it - let link = json("/r/drugs/about.json?raw_json=1".into(), false).await; - assert!(link.is_err()); - assert_eq!(link, Err("gated".into())); + #[tokio::test(flavor = "multi_thread")] + async fn test_banned_sub() { + let link = json("/r/aaa/about.json?raw_json=1".into(), true).await; + assert!(link.is_err()); + assert_eq!(link, Err("banned".into())); + } + + #[tokio::test(flavor = "multi_thread")] + async fn test_gated_sub() { + // quarantine to false to specifically catch when we _don't_ catch it + let link = json("/r/drugs/about.json?raw_json=1".into(), false).await; + assert!(link.is_err()); + assert_eq!(link, Err("gated".into())); + } } diff --git a/src/config.rs b/src/config.rs index b1a7cdb..8f92c9b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -196,75 +196,79 @@ pub fn get_setting(name: &str) -> Option { } #[cfg(test)] -use {sealed_test::prelude::*, std::fs::write}; +mod tests { + use super::*; + use {sealed_test::prelude::*, std::fs::write}; -#[test] -fn test_deserialize() { - // Must handle empty input - let result = toml::from_str::(""); - assert!(result.is_ok(), "Error: {}", result.unwrap_err()); -} + #[test] + fn test_deserialize() { + // Must handle empty input + let result = toml::from_str::(""); + assert!(result.is_ok(), "Error: {}", result.unwrap_err()); + } -#[test] -#[sealed_test(env = [("REDLIB_SFW_ONLY", "on")])] -fn test_env_var() { - assert!(crate::utils::sfw_only()) -} + #[test] + #[sealed_test(env = [("REDLIB_SFW_ONLY", "on")])] + fn test_env_var() { + assert!(crate::utils::sfw_only()) + } -#[test] -#[sealed_test] -fn test_config() { - let config_to_write = r#"REDLIB_DEFAULT_COMMENT_SORT = "best""#; - write("redlib.toml", config_to_write).unwrap(); - assert_eq!(get_setting("REDLIB_DEFAULT_COMMENT_SORT"), Some("best".into())); -} + #[test] + #[sealed_test] + fn test_config() { + let config_to_write = r#"REDLIB_DEFAULT_COMMENT_SORT = "best""#; + write("redlib.toml", config_to_write).unwrap(); + assert_eq!(get_setting("REDLIB_DEFAULT_COMMENT_SORT"), Some("best".into())); + } -#[test] -#[sealed_test] -fn test_config_legacy() { - let config_to_write = r#"LIBREDDIT_DEFAULT_COMMENT_SORT = "best""#; - write("libreddit.toml", config_to_write).unwrap(); - assert_eq!(get_setting("REDLIB_DEFAULT_COMMENT_SORT"), Some("best".into())); -} + #[test] + #[sealed_test] + fn test_config_legacy() { + let config_to_write = r#"LIBREDDIT_DEFAULT_COMMENT_SORT = "best""#; + write("libreddit.toml", config_to_write).unwrap(); + assert_eq!(get_setting("REDLIB_DEFAULT_COMMENT_SORT"), Some("best".into())); + } -#[test] -#[sealed_test(env = [("LIBREDDIT_SFW_ONLY", "on")])] -fn test_env_var_legacy() { - assert!(crate::utils::sfw_only()) -} + #[test] + #[sealed_test(env = [("LIBREDDIT_SFW_ONLY", "on")])] + fn test_env_var_legacy() { + assert!(crate::utils::sfw_only()) + } -#[test] -#[sealed_test(env = [("REDLIB_DEFAULT_COMMENT_SORT", "top")])] -fn test_env_config_precedence() { - let config_to_write = r#"REDLIB_DEFAULT_COMMENT_SORT = "best""#; - write("redlib.toml", config_to_write).unwrap(); - assert_eq!(get_setting("REDLIB_DEFAULT_COMMENT_SORT"), Some("top".into())) -} + #[test] + #[sealed_test(env = [("REDLIB_DEFAULT_COMMENT_SORT", "top")])] + fn test_env_config_precedence() { + let config_to_write = r#"REDLIB_DEFAULT_COMMENT_SORT = "best""#; + write("redlib.toml", config_to_write).unwrap(); + assert_eq!(get_setting("REDLIB_DEFAULT_COMMENT_SORT"), Some("top".into())) + } -#[test] -#[sealed_test(env = [("REDLIB_DEFAULT_COMMENT_SORT", "top")])] -fn test_alt_env_config_precedence() { - let config_to_write = r#"REDLIB_DEFAULT_COMMENT_SORT = "best""#; - write("redlib.toml", config_to_write).unwrap(); - assert_eq!(get_setting("REDLIB_DEFAULT_COMMENT_SORT"), Some("top".into())) -} -#[test] -#[sealed_test(env = [("REDLIB_DEFAULT_SUBSCRIPTIONS", "news+bestof")])] -fn test_default_subscriptions() { - assert_eq!(get_setting("REDLIB_DEFAULT_SUBSCRIPTIONS"), Some("news+bestof".into())); -} + #[test] + #[sealed_test(env = [("REDLIB_DEFAULT_COMMENT_SORT", "top")])] + fn test_alt_env_config_precedence() { + let config_to_write = r#"REDLIB_DEFAULT_COMMENT_SORT = "best""#; + write("redlib.toml", config_to_write).unwrap(); + assert_eq!(get_setting("REDLIB_DEFAULT_COMMENT_SORT"), Some("top".into())) + } -#[test] -#[sealed_test(env = [("REDLIB_DEFAULT_FILTERS", "news+bestof")])] -fn test_default_filters() { - assert_eq!(get_setting("REDLIB_DEFAULT_FILTERS"), Some("news+bestof".into())); -} + #[test] + #[sealed_test(env = [("REDLIB_DEFAULT_SUBSCRIPTIONS", "news+bestof")])] + fn test_default_subscriptions() { + assert_eq!(get_setting("REDLIB_DEFAULT_SUBSCRIPTIONS"), Some("news+bestof".into())); + } -#[test] -#[sealed_test] -fn test_pushshift() { - let config_to_write = r#"REDLIB_PUSHSHIFT_FRONTEND = "https://api.pushshift.io""#; - write("redlib.toml", config_to_write).unwrap(); - assert!(get_setting("REDLIB_PUSHSHIFT_FRONTEND").is_some()); - assert_eq!(get_setting("REDLIB_PUSHSHIFT_FRONTEND"), Some("https://api.pushshift.io".into())); + #[test] + #[sealed_test(env = [("REDLIB_DEFAULT_FILTERS", "news+bestof")])] + fn test_default_filters() { + assert_eq!(get_setting("REDLIB_DEFAULT_FILTERS"), Some("news+bestof".into())); + } + + #[test] + #[sealed_test] + fn test_pushshift() { + let config_to_write = r#"REDLIB_PUSHSHIFT_FRONTEND = "https://api.pushshift.io""#; + write("redlib.toml", config_to_write).unwrap(); + assert!(get_setting("REDLIB_PUSHSHIFT_FRONTEND").is_some()); + assert_eq!(get_setting("REDLIB_PUSHSHIFT_FRONTEND"), Some("https://api.pushshift.io".into())); + } } diff --git a/src/oauth.rs b/src/oauth.rs index 49b0a2b..2eaff18 100644 --- a/src/oauth.rs +++ b/src/oauth.rs @@ -469,62 +469,67 @@ fn choose(list: &[T]) -> T { *fastrand::choose_multiple(list.iter(), 1)[0] } -#[tokio::test(flavor = "multi_thread")] -async fn test_mobile_spoof_backend() { - // Test MobileSpoofAuth backend specifically - let mut backend = MobileSpoofAuth::new(); - let response = backend.authenticate().await; - assert!(response.is_ok()); - let response = response.unwrap(); - assert!(!response.token.is_empty()); - assert!(response.expires_in > 0); - assert!(!backend.user_agent().is_empty()); - assert!(!backend.get_headers().is_empty()); -} +#[cfg(test)] +mod tests { + use super::*; -#[tokio::test(flavor = "multi_thread")] -async fn test_generic_web_backend() { - // Test GenericWebAuth backend specifically - let mut backend = GenericWebAuth::new(); - let response = backend.authenticate().await; - assert!(response.is_ok()); - let response = response.unwrap(); - assert!(!response.token.is_empty()); - assert!(response.expires_in > 0); - assert!(!backend.user_agent().is_empty()); -} + #[tokio::test(flavor = "multi_thread")] + async fn test_mobile_spoof_backend() { + // Test MobileSpoofAuth backend specifically + let mut backend = MobileSpoofAuth::new(); + let response = backend.authenticate().await; + assert!(response.is_ok()); + let response = response.unwrap(); + assert!(!response.token.is_empty()); + assert!(response.expires_in > 0); + assert!(!backend.user_agent().is_empty()); + assert!(!backend.get_headers().is_empty()); + } -#[tokio::test(flavor = "multi_thread")] -async fn test_oauth_client() { - // Integration test - tests the overall Oauth client - assert!(OAUTH_CLIENT.load_full().headers_map.contains_key("Authorization")); -} + #[tokio::test(flavor = "multi_thread")] + async fn test_generic_web_backend() { + // Test GenericWebAuth backend specifically + let mut backend = GenericWebAuth::new(); + let response = backend.authenticate().await; + assert!(response.is_ok()); + let response = response.unwrap(); + assert!(!response.token.is_empty()); + assert!(response.expires_in > 0); + assert!(!backend.user_agent().is_empty()); + } -#[tokio::test(flavor = "multi_thread")] -async fn test_oauth_client_refresh() { - force_refresh_token().await; -} + #[tokio::test(flavor = "multi_thread")] + async fn test_oauth_client() { + // Integration test - tests the overall Oauth client + assert!(OAUTH_CLIENT.load_full().headers_map.contains_key("Authorization")); + } -#[tokio::test(flavor = "multi_thread")] -async fn test_oauth_token_exists() { - let client = OAUTH_CLIENT.load_full(); - let auth_header = client.headers_map.get("Authorization").unwrap(); - assert!(auth_header.starts_with("Bearer ")); -} + #[tokio::test(flavor = "multi_thread")] + async fn test_oauth_client_refresh() { + force_refresh_token().await; + } -#[tokio::test(flavor = "multi_thread")] -async fn test_oauth_headers_len() { - assert!(OAUTH_CLIENT.load_full().headers_map.len() >= 3); -} + #[tokio::test(flavor = "multi_thread")] + async fn test_oauth_token_exists() { + let client = OAUTH_CLIENT.load_full(); + let auth_header = client.headers_map.get("Authorization").unwrap(); + assert!(auth_header.starts_with("Bearer ")); + } -#[test] -fn test_creating_device() { - Device::new(); -} + #[tokio::test(flavor = "multi_thread")] + async fn test_oauth_headers_len() { + assert!(OAUTH_CLIENT.load_full().headers_map.len() >= 3); + } -#[test] -fn test_creating_backends() { - // Test that both backends can be created - MobileSpoofAuth::new(); - GenericWebAuth::new(); + #[test] + fn test_creating_device() { + Device::new(); + } + + #[test] + fn test_creating_backends() { + // Test that both backends can be created + MobileSpoofAuth::new(); + GenericWebAuth::new(); + } } diff --git a/src/post.rs b/src/post.rs index 78bcaf3..8dac506 100644 --- a/src/post.rs +++ b/src/post.rs @@ -1,6 +1,4 @@ #![allow(clippy::cmp_owned)] - -// CRATES use crate::client::json; use crate::config::get_setting; use crate::server::RequestExt; @@ -8,9 +6,8 @@ use crate::subreddit::{can_access_quarantine, quarantine}; use crate::utils::{ error, format_num, get_filters, nsfw_landing, param, parse_post, rewrite_emotes, setting, template, time, val, Author, Awards, Comment, Flair, FlairPart, Post, Preferences, }; -use hyper::{Body, Request, Response}; - use askama::Template; +use hyper::{Body, Request, Response}; use regex::Regex; use std::collections::{HashMap, HashSet}; use std::sync::LazyLock; diff --git a/src/search.rs b/src/search.rs index c7d6b00..c04d1f8 100644 --- a/src/search.rs +++ b/src/search.rs @@ -1,6 +1,4 @@ #![allow(clippy::cmp_owned)] - -// CRATES use crate::utils::{self, catch_random, error, filter_posts, format_num, format_url, get_filters, param, redirect, setting, template, val, Post, Preferences}; use crate::{ client::json, diff --git a/src/subreddit.rs b/src/subreddit.rs index 4046be1..30b0fe7 100644 --- a/src/subreddit.rs +++ b/src/subreddit.rs @@ -1,12 +1,11 @@ #![allow(clippy::cmp_owned)] -use crate::{config, utils}; -// CRATES use crate::utils::{ catch_random, error, filter_posts, format_num, format_url, get_filters, info, nsfw_landing, param, redirect, rewrite_urls, setting, template, val, Post, Preferences, Subreddit, }; use crate::{client::json, server::RequestExt, server::ResponseExt}; +use crate::{config, utils}; use askama::Template; use cookie::Cookie; use htmlescape::decode_html; @@ -645,16 +644,21 @@ pub async fn rss(req: Request) -> Result, String> { Ok(res) } -#[tokio::test(flavor = "multi_thread")] -async fn test_fetching_subreddit() { - let subreddit = subreddit("rust", false).await; - assert!(subreddit.is_ok()); -} +#[cfg(test)] +mod tests { + use super::*; -#[tokio::test(flavor = "multi_thread")] -async fn test_gated_and_quarantined() { - let quarantined = subreddit("edgy", true).await; - assert!(quarantined.is_ok()); - let gated = subreddit("drugs", true).await; - assert!(gated.is_ok()); + #[tokio::test(flavor = "multi_thread")] + async fn test_fetching_subreddit() { + let subreddit = subreddit("rust", false).await; + assert!(subreddit.is_ok()); + } + + #[tokio::test(flavor = "multi_thread")] + async fn test_gated_and_quarantined() { + let quarantined = subreddit("edgy", true).await; + assert!(quarantined.is_ok()); + let gated = subreddit("drugs", true).await; + assert!(gated.is_ok()); + } } diff --git a/src/user.rs b/src/user.rs index a352d25..36a06c4 100644 --- a/src/user.rs +++ b/src/user.rs @@ -1,6 +1,4 @@ #![allow(clippy::cmp_owned)] - -// CRATES use crate::client::json; use crate::server::RequestExt; use crate::utils::{error, filter_posts, format_url, get_filters, nsfw_landing, param, setting, template, Post, Preferences, User}; @@ -58,7 +56,7 @@ pub async fn profile(req: Request) -> Result, String> { // Return landing page if this post if this Reddit deems this user NSFW, // but we have also disabled the display of NSFW content or if the instance // is SFW-only. - if user.nsfw && crate::utils::should_be_nsfw_gated(&req, &req_url) { + if user.nsfw && utils::should_be_nsfw_gated(&req, &req_url) { return Ok(nsfw_landing(req, req_url).await.unwrap_or_default()); } @@ -185,9 +183,14 @@ pub async fn rss(req: Request) -> Result, String> { Ok(res) } -#[tokio::test(flavor = "multi_thread")] -async fn test_fetching_user() { - let user = user("spez").await; - assert!(user.is_ok()); - assert!(user.unwrap().karma > 100); +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test(flavor = "multi_thread")] + async fn test_fetching_user() { + let user = user("spez").await; + assert!(user.is_ok()); + assert!(user.unwrap().karma > 100); + } } diff --git a/src/utils.rs b/src/utils.rs index efe98b7..cac0fcd 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -2,9 +2,6 @@ #![allow(clippy::cmp_owned)] use crate::config::{self, get_setting}; -// -// CRATES -// use crate::{client::json, server::RequestExt}; use askama::Template; use cookie::Cookie; @@ -1449,7 +1446,7 @@ pub fn get_post_url(post: &Post) -> String { #[cfg(test)] mod tests { - use super::{format_num, format_url, rewrite_urls, Preferences}; + use super::{deflate_compress, deflate_decompress, format_num, format_url, render_bullet_lists, rewrite_emotes, rewrite_urls, url_path_basename, Post, Preferences}; #[test] fn format_num_works() { @@ -1546,76 +1543,75 @@ mod tests { assert_eq!(urlencoded, "theme=laserwave&front_page=default&layout=compact&wide=on&blur_spoiler=on&show_nsfw=off&blur_nsfw=on&hide_hls_notification=off&video_quality=best&hide_sidebar_and_summary=off&use_hls=on&autoplay_videos=on&fixed_navbar=on&disable_visit_reddit_confirmation=on&comment_sort=confidence&post_sort=top&subscriptions=memes%2Bmildlyinteresting&filters=&hide_awards=off&hide_score=off&remove_default_feeds=off"); } -} -#[test] -fn test_rewriting_emoji() { - let input = r#"

How can you have such hard feelings towards a license? Let people use what license they want, and BSD is one of the least restrictive ones AFAIK.

"#; - let output = r#"

How can you have such hard feelings towards a license? Let people use what license they want, and BSD is one of the least restrictive ones AFAIK.

"#; - assert_eq!(rewrite_urls(input), output); -} - -#[tokio::test(flavor = "multi_thread")] -async fn test_fetching_subreddit_quarantined() { - let subreddit = Post::fetch("/r/drugs", true).await; - assert!(subreddit.is_ok()); - assert!(!subreddit.unwrap().0.is_empty()); -} - -#[tokio::test(flavor = "multi_thread")] -async fn test_fetching_nsfw_subreddit() { - // Gonwild is a place for closed, Euclidean Geometric shapes to exchange their nth terms for karma; showing off their edges in a comfortable environment without pressure. - // Find a good sub that is tagged NSFW but that actually isn't in case my future employers are watching (they probably are) - // switched from randnsfw as it is no longer functional. - let subreddit = Post::fetch("/r/gonwild", false).await; - assert!(subreddit.is_ok()); - assert!(!subreddit.unwrap().0.is_empty()); -} - -#[tokio::test(flavor = "multi_thread")] -async fn test_fetching_ws() { - let subreddit = Post::fetch("/r/popular", false).await; - assert!(subreddit.is_ok()); - for post in subreddit.unwrap().0 { - assert!(post.ws_url.starts_with("wss://k8s-lb.wss.redditmedia.com/link/")); + #[test] + fn test_rewriting_emoji() { + let input = r#"

How can you have such hard feelings towards a license? Let people use what license they want, and BSD is one of the least restrictive ones AFAIK.

"#; + let output = r#"

How can you have such hard feelings towards a license? Let people use what license they want, and BSD is one of the least restrictive ones AFAIK.

"#; + assert_eq!(rewrite_urls(input), output); } -} -#[test] -fn test_rewriting_image_links() { - let input = - r#"

caption 1

"#; - let output = r#"
caption 1
"#; - assert_eq!(rewrite_urls(input), output); -} + #[tokio::test(flavor = "multi_thread")] + async fn test_fetching_subreddit_quarantined() { + let subreddit = Post::fetch("/r/drugs", true).await; + assert!(subreddit.is_ok()); + assert!(!subreddit.unwrap().0.is_empty()); + } -#[test] -fn test_url_path_basename() { - // without trailing slash - assert_eq!(url_path_basename("/first/last"), "last"); - // with trailing slash - assert_eq!(url_path_basename("/first/last/"), "last"); - // with query parameters - assert_eq!(url_path_basename("/first/last/?some=query"), "last"); - // file path - assert_eq!(url_path_basename("/cdn/image.jpg"), "image.jpg"); - // when a full url is passed instead of just a path - assert_eq!(url_path_basename("https://doma.in/first/last"), "last"); - // empty path - assert_eq!(url_path_basename("/"), ""); -} + #[tokio::test(flavor = "multi_thread")] + async fn test_fetching_nsfw_subreddit() { + // Gonwild is a place for closed, Euclidean Geometric shapes to exchange their nth terms for karma; showing off their edges in a comfortable environment without pressure. + // Find a good sub that is tagged NSFW but that actually isn't in case my future employers are watching (they probably are) + // switched from randnsfw as it is no longer functional. + let subreddit = Post::fetch("/r/gonwild", false).await; + assert!(subreddit.is_ok()); + assert!(!subreddit.unwrap().0.is_empty()); + } -#[test] -fn test_rewriting_emotes() { - let json_input = serde_json::from_str(r#"{"emote|t5_31hpy|2028":{"e":"Image","id":"emote|t5_31hpy|2028","m":"image/png","s":{"u":"https://reddit-econ-prod-assets-permanent.s3.amazonaws.com/asset-manager/t5_31hpy/PW6WsOaLcd.png","x":60,"y":60},"status":"valid","t":"sticker"}}"#).expect("Valid JSON"); - let comment_input = r#"

:2028:

"#; - let output = r#"

"#; - assert_eq!(rewrite_emotes(&json_input, comment_input.to_string()), output); -} + #[tokio::test(flavor = "multi_thread")] + async fn test_fetching_ws() { + let subreddit = Post::fetch("/r/popular", false).await; + assert!(subreddit.is_ok()); + for post in subreddit.unwrap().0 { + assert!(post.ws_url.starts_with("wss://k8s-lb.wss.redditmedia.com/link/")); + } + } -#[test] -fn test_rewriting_bullet_list() { - let input = r#"

Hi, I've bought this very same monitor and found no calibration whatsoever. I have an ICC profile that has been set up since I've installed its driver from the LG website and it works ok. I also used http://www.lagom.nl/lcd-test/ to calibrate it. After some good tinkering I've found the following settings + the color profile from the driver gets me past all the tests perfectly: + #[test] + fn test_rewriting_image_links() { + let input = + r#"

caption 1

"#; + let output = r#"
caption 1
"#; + assert_eq!(rewrite_urls(input), output); + } + + #[test] + fn test_url_path_basename() { + // without trailing slash + assert_eq!(url_path_basename("/first/last"), "last"); + // with trailing slash + assert_eq!(url_path_basename("/first/last/"), "last"); + // with query parameters + assert_eq!(url_path_basename("/first/last/?some=query"), "last"); + // file path + assert_eq!(url_path_basename("/cdn/image.jpg"), "image.jpg"); + // when a full url is passed instead of just a path + assert_eq!(url_path_basename("https://doma.in/first/last"), "last"); + // empty path + assert_eq!(url_path_basename("/"), ""); + } + + #[test] + fn test_rewriting_emotes() { + let json_input = serde_json::from_str(r#"{"emote|t5_31hpy|2028":{"e":"Image","id":"emote|t5_31hpy|2028","m":"image/png","s":{"u":"https://reddit-econ-prod-assets-permanent.s3.amazonaws.com/asset-manager/t5_31hpy/PW6WsOaLcd.png","x":60,"y":60},"status":"valid","t":"sticker"}}"#).expect("Valid JSON"); + let comment_input = r#"

:2028:

"#; + let output = r#"

"#; + assert_eq!(rewrite_emotes(&json_input, comment_input.to_string()), output); + } + + #[test] + fn test_rewriting_bullet_list() { + let input = r#"

Hi, I've bought this very same monitor and found no calibration whatsoever. I have an ICC profile that has been set up since I've installed its driver from the LG website and it works ok. I also used http://www.lagom.nl/lcd-test/ to calibrate it. After some good tinkering I've found the following settings + the color profile from the driver gets me past all the tests perfectly: - Brightness 50 (still have to settle on this one, it's personal preference, it controls the backlight, not the colors) - Contrast 70 (which for me was the default one) - Picture mode Custom @@ -1630,59 +1626,60 @@ fn test_rewriting_bullet_list() { - Color Temp Medium How`s your monitor by the way? Any IPS bleed whatsoever? I either got lucky or the panel is pretty good, 0 bleed for me, just the usual IPS glow. How about the pixels? I see the pixels even at one meter away, especially on Microsoft Edge's icon for example, the blue background is just blocky, don't know why.

"#; - let output = r#"

Hi, I've bought this very same monitor and found no calibration whatsoever. I have an ICC profile that has been set up since I've installed its driver from the LG website and it works ok. I also used http://www.lagom.nl/lcd-test/ to calibrate it. After some good tinkering I've found the following settings + the color profile from the driver gets me past all the tests perfectly: + let output = r#"

Hi, I've bought this very same monitor and found no calibration whatsoever. I have an ICC profile that has been set up since I've installed its driver from the LG website and it works ok. I also used http://www.lagom.nl/lcd-test/ to calibrate it. After some good tinkering I've found the following settings + the color profile from the driver gets me past all the tests perfectly:

  • Brightness 50 (still have to settle on this one, it's personal preference, it controls the backlight, not the colors)
  • Contrast 70 (which for me was the default one)
  • Picture mode Custom
  • Super resolution + Off (it looks horrible anyway)
  • Sharpness 50 (default one I think)
  • Black level High (low messes up gray colors)
  • DFC Off
  • Response Time Middle (personal preference, https://www.blurbusters.com/ show horrible overdrive with it on high)
  • Freesync doesn't matter
  • Black stabilizer 50
  • Gamma setting on 0
  • Color Temp Medium
How`s your monitor by the way? Any IPS bleed whatsoever? I either got lucky or the panel is pretty good, 0 bleed for me, just the usual IPS glow. How about the pixels? I see the pixels even at one meter away, especially on Microsoft Edge's icon for example, the blue background is just blocky, don't know why.

"#; - assert_eq!(render_bullet_lists(input), output); -} - -#[test] -fn test_default_prefs_serialization_loop_json() { - let prefs = Preferences::default(); - let serialized = serde_json::to_string(&prefs).unwrap(); - let deserialized: Preferences = serde_json::from_str(&serialized).unwrap(); - assert_eq!(prefs, deserialized); -} - -#[test] -fn test_default_prefs_serialization_loop_bincode() { - let prefs = Preferences::default(); - test_round_trip(&prefs, false); - test_round_trip(&prefs, true); -} - -static KNOWN_GOOD_CONFIGS: &[&str] = &[ - "ఴӅβØØҞÉဏႢձĬ༧ȒʯऌԔӵ୮༏", - "ਧՊΥÀÃǎƱГ۸ඣമĖฤ႙ʟาúໜϾௐɥঀĜໃહཞઠѫҲɂఙ࿔DzઉƲӟӻĻฅΜδ໖ԜǗဖငƦơ৶Ą௩ԹʛใЛʃශаΏ", - "ਧԩΥÀÃΊ౭൩ඔႠϼҭöҪƸռઇԾॐნɔາǒՍҰच௨ಖມŃЉŐདƦ๙ϩএఠȝഽйʮჯඒϰळՋ௮ສ৵ऎΦѧਹಧଟƙŃ३î༦ŌပղयƟแҜ།", -]; - -#[test] -fn test_known_good_configs_deserialization() { - for config in KNOWN_GOOD_CONFIGS { - let bytes = base2048::decode(config).unwrap(); - let decompressed = deflate_decompress(bytes).unwrap(); - assert!(bincode::deserialize::(&decompressed).is_ok()); + assert_eq!(render_bullet_lists(input), output); } -} -#[test] -fn test_known_good_configs_full_round_trip() { - for config in KNOWN_GOOD_CONFIGS { - let bytes = base2048::decode(config).unwrap(); - let decompressed = deflate_decompress(bytes).unwrap(); - let prefs: Preferences = bincode::deserialize(&decompressed).unwrap(); + #[test] + fn test_default_prefs_serialization_loop_json() { + let prefs = Preferences::default(); + let serialized = serde_json::to_string(&prefs).unwrap(); + let deserialized: Preferences = serde_json::from_str(&serialized).unwrap(); + assert_eq!(prefs, deserialized); + } + + #[test] + fn test_default_prefs_serialization_loop_bincode() { + let prefs = Preferences::default(); test_round_trip(&prefs, false); test_round_trip(&prefs, true); } -} -fn test_round_trip(input: &Preferences, compression: bool) { - let serialized = bincode::serialize(input).unwrap(); - let compressed = if compression { deflate_compress(serialized).unwrap() } else { serialized }; - let decompressed = if compression { deflate_decompress(compressed).unwrap() } else { compressed }; - let deserialized: Preferences = bincode::deserialize(&decompressed).unwrap(); - assert_eq!(*input, deserialized); + static KNOWN_GOOD_CONFIGS: &[&str] = &[ + "ఴӅβØØҞÉဏႢձĬ༧ȒʯऌԔӵ୮༏", + "ਧՊΥÀÃǎƱГ۸ඣമĖฤ႙ʟาúໜϾௐɥঀĜໃહཞઠѫҲɂఙ࿔DzઉƲӟӻĻฅΜδ໖ԜǗဖငƦơ৶Ą௩ԹʛใЛʃශаΏ", + "ਧԩΥÀÃΊ౭൩ඔႠϼҭöҪƸռઇԾॐნɔາǒՍҰच௨ಖມŃЉŐདƦ๙ϩএఠȝഽйʮჯඒϰळՋ௮ສ৵ऎΦѧਹಧଟƙŃ३î༦ŌပղयƟแҜ།", + ]; + + #[test] + fn test_known_good_configs_deserialization() { + for config in KNOWN_GOOD_CONFIGS { + let bytes = base2048::decode(config).unwrap(); + let decompressed = deflate_decompress(bytes).unwrap(); + assert!(bincode::deserialize::(&decompressed).is_ok()); + } + } + + #[test] + fn test_known_good_configs_full_round_trip() { + for config in KNOWN_GOOD_CONFIGS { + let bytes = base2048::decode(config).unwrap(); + let decompressed = deflate_decompress(bytes).unwrap(); + let prefs: Preferences = bincode::deserialize(&decompressed).unwrap(); + test_round_trip(&prefs, false); + test_round_trip(&prefs, true); + } + } + + fn test_round_trip(input: &Preferences, compression: bool) { + let serialized = bincode::serialize(input).unwrap(); + let compressed = if compression { deflate_compress(serialized).unwrap() } else { serialized }; + let decompressed = if compression { deflate_decompress(compressed).unwrap() } else { compressed }; + let deserialized: Preferences = bincode::deserialize(&decompressed).unwrap(); + assert_eq!(*input, deserialized); + } }