Start adding a webmention.io client for retrieving comments.
continuous-integration/drone/push Build is failing Details
continuous-integration/drone Build is passing Details

This commit is contained in:
projectmoon 2024-03-28 20:23:31 +01:00
parent 1fe590925b
commit 4ff8db7ee6
6 changed files with 689 additions and 15 deletions

409
Cargo.lock generated
View File

@ -147,6 +147,12 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]]
name = "bumpalo"
version = "3.15.4"
@ -356,12 +362,43 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "fastrand"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "form_urlencoded"
version = "1.2.1"
@ -377,7 +414,7 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"fuchsia-zircon-sys",
]
@ -438,6 +475,7 @@ dependencies = [
"germ",
"once_cell",
"regex",
"reqwest 0.12.2",
"tokio 1.36.0",
"url",
"writefreely_client",
@ -517,7 +555,26 @@ dependencies = [
"futures-core",
"futures-sink",
"futures-util",
"http",
"http 0.2.12",
"indexmap",
"slab",
"tokio 1.36.0",
"tokio-util",
"tracing",
]
[[package]]
name = "h2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4"
dependencies = [
"bytes 1.5.0",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
"http 1.1.0",
"indexmap",
"slab",
"tokio 1.36.0",
@ -554,6 +611,17 @@ dependencies = [
"itoa",
]
[[package]]
name = "http"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
dependencies = [
"bytes 1.5.0",
"fnv",
"itoa",
]
[[package]]
name = "http-body"
version = "0.4.6"
@ -561,7 +629,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
dependencies = [
"bytes 1.5.0",
"http",
"http 0.2.12",
"pin-project-lite 0.2.13",
]
[[package]]
name = "http-body"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643"
dependencies = [
"bytes 1.5.0",
"http 1.1.0",
]
[[package]]
name = "http-body-util"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d"
dependencies = [
"bytes 1.5.0",
"futures-core",
"http 1.1.0",
"http-body 1.0.0",
"pin-project-lite 0.2.13",
]
@ -587,9 +678,9 @@ dependencies = [
"futures-channel",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"h2 0.3.25",
"http 0.2.12",
"http-body 0.4.6",
"httparse",
"httpdate",
"itoa",
@ -601,6 +692,26 @@ dependencies = [
"want",
]
[[package]]
name = "hyper"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a"
dependencies = [
"bytes 1.5.0",
"futures-channel",
"futures-util",
"h2 0.4.3",
"http 1.1.0",
"http-body 1.0.0",
"httparse",
"itoa",
"pin-project-lite 0.2.13",
"smallvec",
"tokio 1.36.0",
"want",
]
[[package]]
name = "hyper-rustls"
version = "0.24.2"
@ -608,13 +719,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
dependencies = [
"futures-util",
"http",
"hyper",
"http 0.2.12",
"hyper 0.14.28",
"rustls 0.21.10",
"tokio 1.36.0",
"tokio-rustls 0.24.1",
]
[[package]]
name = "hyper-tls"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
dependencies = [
"bytes 1.5.0",
"http-body-util",
"hyper 1.2.0",
"hyper-util",
"native-tls",
"tokio 1.36.0",
"tokio-native-tls",
"tower-service",
]
[[package]]
name = "hyper-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa"
dependencies = [
"bytes 1.5.0",
"futures-channel",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"hyper 1.2.0",
"pin-project-lite 0.2.13",
"socket2",
"tokio 1.36.0",
"tower",
"tower-service",
"tracing",
]
[[package]]
name = "iana-time-zone"
version = "0.1.60"
@ -725,6 +872,12 @@ version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "linux-raw-sys"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
[[package]]
name = "lock_api"
version = "0.4.11"
@ -804,6 +957,24 @@ dependencies = [
"ws2_32-sys",
]
[[package]]
name = "native-tls"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
dependencies = [
"lazy_static",
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]
[[package]]
name = "net2"
version = "0.2.39"
@ -855,6 +1026,50 @@ version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "openssl"
version = "0.10.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f"
dependencies = [
"bitflags 2.5.0",
"cfg-if 1.0.0",
"foreign-types",
"libc",
"once_cell",
"openssl-macros",
"openssl-sys",
]
[[package]]
name = "openssl-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
]
[[package]]
name = "openssl-probe"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-sys"
version = "0.9.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "parking_lot"
version = "0.12.1"
@ -884,6 +1099,26 @@ version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pin-project"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
]
[[package]]
name = "pin-project-lite"
version = "0.1.12"
@ -902,6 +1137,12 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkg-config"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "proc-macro2"
version = "1.0.79"
@ -936,7 +1177,7 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
dependencies = [
"bitflags",
"bitflags 1.3.2",
]
[[package]]
@ -979,10 +1220,10 @@ dependencies = [
"encoding_rs",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"hyper",
"h2 0.3.25",
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.28",
"hyper-rustls",
"ipnet",
"js-sys",
@ -1009,6 +1250,48 @@ dependencies = [
"winreg",
]
[[package]]
name = "reqwest"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d66674f2b6fb864665eea7a3c1ac4e3dfacd2fda83cf6f935a612e01b0e3338"
dependencies = [
"base64 0.21.7",
"bytes 1.5.0",
"encoding_rs",
"futures-core",
"futures-util",
"h2 0.4.3",
"http 1.1.0",
"http-body 1.0.0",
"http-body-util",
"hyper 1.2.0",
"hyper-tls",
"hyper-util",
"ipnet",
"js-sys",
"log",
"mime",
"native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite 0.2.13",
"rustls-pemfile",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"system-configuration",
"tokio 1.36.0",
"tokio-native-tls",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"winreg",
]
[[package]]
name = "ring"
version = "0.16.20"
@ -1045,6 +1328,19 @@ version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustix"
version = "0.38.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
dependencies = [
"bitflags 2.5.0",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
]
[[package]]
name = "rustls"
version = "0.18.1"
@ -1095,6 +1391,15 @@ version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
[[package]]
name = "schannel"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
@ -1121,6 +1426,29 @@ dependencies = [
"untrusted 0.9.0",
]
[[package]]
name = "security-framework"
version = "2.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de"
dependencies = [
"bitflags 1.3.2",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "serde"
version = "1.0.197"
@ -1267,7 +1595,7 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"core-foundation",
"system-configuration-sys",
]
@ -1282,6 +1610,18 @@ dependencies = [
"libc",
]
[[package]]
name = "tempfile"
version = "3.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
dependencies = [
"cfg-if 1.0.0",
"fastrand",
"rustix",
"windows-sys 0.52.0",
]
[[package]]
name = "thiserror"
version = "1.0.58"
@ -1376,6 +1716,16 @@ dependencies = [
"syn 2.0.53",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
dependencies = [
"native-tls",
"tokio 1.36.0",
]
[[package]]
name = "tokio-rustls"
version = "0.14.1"
@ -1412,6 +1762,28 @@ dependencies = [
"tracing",
]
[[package]]
name = "tower"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
dependencies = [
"futures-core",
"futures-util",
"pin-project",
"pin-project-lite 0.2.13",
"tokio 1.36.0",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-layer"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
[[package]]
name = "tower-service"
version = "0.3.2"
@ -1424,6 +1796,7 @@ version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
"log",
"pin-project-lite 0.2.13",
"tracing-core",
]
@ -1493,6 +1866,12 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "want"
version = "0.3.1"
@ -1801,7 +2180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14cda99045977785c78822ba8cb1243e877105801328dc2171465dd878c1bf98"
dependencies = [
"chrono",
"reqwest",
"reqwest 0.11.27",
"serde",
"serde_json",
"serde_repr",

View File

@ -15,6 +15,7 @@ gemini-feed = "0.1.0"
germ = {version = "0.4", features = ["blocking"] }
once_cell = "1.19.0"
regex = "1.10.3"
reqwest = { version = "0.12", features = ["json"] }
tokio = {version = "1.36", features = [ "full" ] }
url = "2.5.0"
writefreely_client = "0.2.0"

View File

@ -1,3 +1,4 @@
pub(crate) mod sync;
pub(crate) mod login;
pub(crate) mod logout;
pub(crate) mod sync_webmentions;

View File

@ -0,0 +1,18 @@
use anyhow::Result;
pub(crate) struct SyncWebmentionsCommand<'a> {
webmention_io_url: &'a str,
webmention_io_token: &'a str,
}
// How will this work? This tool is stateless. The easiest solution is
// to require last ID passed in, but that doesn't really make sense.
// We can have it operate on a directory of comment files, and store
// the state in the files themselves. Replicate the logic in the nu
// shell stuff.
impl SyncWebmentionsCommand<'_> {
pub async fn execute(self) -> Result<()> {
Ok(())
}
}

View File

@ -4,6 +4,7 @@ use commands::{login::LoginCommand, logout::LogoutCommand};
use anyhow::Result;
mod webmentions;
mod gemfeed;
mod sanitization;
mod wf;

274
src/webmentions.rs Normal file
View File

@ -0,0 +1,274 @@
use anyhow::{anyhow, Result};
use chrono::{DateTime, FixedOffset};
use url::Url;
const WEBMENTIONS_IO_ENDPOINT: &'static str = "/api/mentions.jf2";
trait ToQueryPair<T> {
fn to_query_pair(&self) -> T;
}
pub(crate) enum WebmentionsSince {
SinceId(usize),
SinceDate(DateTime<FixedOffset>),
}
impl ToQueryPair<(String, String)> for WebmentionsSince {
fn to_query_pair(&self) -> (String, String) {
match self {
Self::SinceId(id) => ("since_id".to_string(), id.to_string()),
Self::SinceDate(date) => ("since".to_string(), format!("{}", date.format("%FT%T%z"))),
}
}
}
pub(crate) enum WebmentionType {
InReplyTo,
LikeOf,
RepostOf,
BookmarkOf,
MentionOf,
Rsvp,
}
impl ToString for WebmentionType {
fn to_string(&self) -> String {
match self {
Self::InReplyTo => "in-reply-to".to_string(),
Self::LikeOf => "like-of".to_string(),
Self::RepostOf => "repost-of".to_string(),
Self::BookmarkOf => "bookmark-of".to_string(),
Self::MentionOf => "mention-of".to_string(),
Self::Rsvp => "rsvp".to_string(),
}
}
}
impl ToQueryPair<Vec<(String, String)>> for Vec<WebmentionType> {
fn to_query_pair(&self) -> Vec<(String, String)> {
self.iter()
.map(|mention_type| ("wm-property[]".to_string(), mention_type.to_string()))
.collect()
}
}
impl<'a> ToQueryPair<Vec<(String, String)>> for &'a [WebmentionType] {
fn to_query_pair(&self) -> Vec<(String, String)> {
self.iter()
.map(|mention_type| ("wm-property[]".to_string(), mention_type.to_string()))
.collect()
}
}
impl ToQueryPair<(String, String)> for WebmentionType {
fn to_query_pair(&self) -> (String, String) {
("wm-property".to_string(), self.to_string())
}
}
enum NumWebmentionTypes<'a> {
Single(&'a WebmentionType),
Multiple(&'a [WebmentionType]),
Zero,
}
pub(crate) struct GetWebmentionsRequest {
/// If specified, retrieve webmentions since an ID or date/time.
/// If not specified, fetch all possible webmentions from the
/// server.
since: Option<WebmentionsSince>,
/// If specified, fetch only these types of web mentions. An empty
/// vec will result in no webmentions fetched. If not specified,
/// fetch all kinds of webmentions.
types: Option<Vec<WebmentionType>>,
}
impl GetWebmentionsRequest {
fn types(&self) -> Option<NumWebmentionTypes> {
self.types.as_ref().map(|types| {
if types.len() > 1 {
NumWebmentionTypes::Multiple(types.as_slice())
} else if types.len() == 1 {
NumWebmentionTypes::Single(types.first().unwrap())
} else {
NumWebmentionTypes::Zero
}
})
}
}
fn create_querystring(req: &GetWebmentionsRequest) -> Result<String> {
let mut query_pairs: Vec<String> = vec![];
if let Some((key, value)) = req.since.as_ref().map(|s| s.to_query_pair()) {
query_pairs.push(format!("{}={}", &key, &value));
}
if let Some(num_types) = req.types() {
let pairs = match num_types {
NumWebmentionTypes::Multiple(types) => types.to_query_pair(),
NumWebmentionTypes::Single(wm_type) => vec![wm_type.to_query_pair()],
_ => {
return Err(anyhow!(
"Webmention types filter specified, but no types given"
))
}
};
for (key, value) in pairs {
query_pairs.push(format!("{}={}", &key, &value));
}
}
if query_pairs.len() > 1 {
Ok(query_pairs.join("&"))
} else if query_pairs.len() == 1 {
Ok(query_pairs.swap_remove(0))
} else {
Ok("".to_string())
}
}
fn create_request_url(base_url: &Url, req: &GetWebmentionsRequest) -> Result<Url> {
let mut url = base_url.join(WEBMENTIONS_IO_ENDPOINT)?;
let mut querystring = create_querystring(req)?;
url.set_query(Some(&querystring));
Ok(url)
}
pub(crate) struct WebmentionIoClient {
url: Url,
domain: String,
}
impl WebmentionIoClient {
pub async fn get_mentions(params: GetWebmentionsRequest) {
//
}
}
#[cfg(test)]
mod create_querystring_tests {
use super::*;
#[test]
fn create_querystring_with_since_date() -> Result<()> {
let date = DateTime::parse_from_str("2022-03-08T13:05:27-0100", "%FT%T%z")?;
let req = GetWebmentionsRequest {
since: Some(WebmentionsSince::SinceDate(date)),
types: None,
};
let expected = "since=2022-03-08T13:05:27-0100";
let querystring = create_querystring(&req)?;
assert_eq!(querystring.as_str(), expected);
Ok(())
}
#[test]
fn create_querystring_with_since_id() -> Result<()> {
let req = GetWebmentionsRequest {
since: Some(WebmentionsSince::SinceId(12345)),
types: None,
};
let expected = "since_id=12345";
let querystring = create_querystring(&req)?;
assert_eq!(querystring, expected);
Ok(())
}
#[test]
fn create_querystring_with_one_type() -> Result<()> {
let req = GetWebmentionsRequest {
since: None,
types: Some(vec![WebmentionType::InReplyTo]),
};
let expected = "wm-property=in-reply-to";
let querystring = create_querystring(&req)?;
assert_eq!(querystring, expected);
Ok(())
}
#[test]
fn create_querystring_with_since_and_one_type() -> Result<()> {
let req = GetWebmentionsRequest {
since: Some(WebmentionsSince::SinceId(12345)),
types: Some(vec![WebmentionType::InReplyTo]),
};
let expected = "since_id=12345&wm-property=in-reply-to";
let querystring = create_querystring(&req)?;
assert_eq!(querystring, expected);
Ok(())
}
#[test]
fn create_querystring_with_mutiple_types() -> Result<()> {
let req = GetWebmentionsRequest {
since: None,
types: Some(vec![WebmentionType::InReplyTo, WebmentionType::BookmarkOf]),
};
let expected = "wm-property[]=in-reply-to&wm-property[]=bookmark-of";
let querystring = create_querystring(&req)?;
assert_eq!(querystring, expected);
Ok(())
}
#[test]
fn create_querystring_with_since_and_mutiple_types() -> Result<()> {
let req = GetWebmentionsRequest {
since: Some(WebmentionsSince::SinceId(12345)),
types: Some(vec![WebmentionType::InReplyTo, WebmentionType::BookmarkOf]),
};
let expected = "since_id=12345&wm-property[]=in-reply-to&wm-property[]=bookmark-of";
let querystring = create_querystring(&req)?;
assert_eq!(querystring, expected);
Ok(())
}
#[test]
fn create_querystring_with_no_types_in_filter() -> Result<()> {
let req = GetWebmentionsRequest {
since: None,
types: Some(vec![]),
};
let querystring = create_querystring(&req);
assert!(matches!(querystring, Err(_)));
Ok(())
}
}
#[cfg(test)]
mod create_request_url_tests {
use super::*;
#[test]
fn test_create_url_with_since_date() -> Result<()> {
let base_url = Url::parse("https://webmention.io")?;
let date = DateTime::parse_from_str("2022-03-08T13:05:27-0100", "%FT%T%z")?;
let req = GetWebmentionsRequest {
since: Some(WebmentionsSince::SinceDate(date)),
types: None,
};
let expected = "https://webmention.io/api/mentions.jf2?since=2022-03-08T13:05:27-0100";
let api_url = create_request_url(&base_url, &req)?;
assert_eq!(api_url.as_str(), expected);
Ok(())
}
}