Skip to content

Commit 86f9208

Browse files
committed
Add additional tests for uri module
This expands the test coverage for the uri module covering all mutants that currently exist. This will likely become the narrowest scope of my mutant ci coverage so that we can start with full coverage and expand the scope out as we catch more mutants.
1 parent f5982cf commit 86f9208

File tree

3 files changed

+88
-11
lines changed

3 files changed

+88
-11
lines changed

payjoin-test-utils/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ pub async fn wait_for_service_ready(
253253
}
254254

255255
pub static EXAMPLE_URL: Lazy<Url> =
256-
Lazy::new(|| Url::parse("https://relay.com").expect("invalid URL"));
256+
Lazy::new(|| Url::parse("https://example.com").expect("invalid URL"));
257257

258258
pub const KEY_ID: KeyId = 1;
259259
pub const KEM: Kem = Kem::K256Sha256;

payjoin/src/uri/mod.rs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ impl bitcoin_uri::de::DeserializationState<'_> for DeserializationState {
207207
mod tests {
208208
use std::convert::TryFrom;
209209

210+
use bitcoin_uri::SerializeParams;
211+
210212
use super::*;
211213

212214
#[test]
@@ -269,10 +271,48 @@ mod tests {
269271

270272
#[test]
271273
fn test_unsupported() {
272-
assert!(!Uri::try_from("bitcoin:12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX")
274+
assert!(
275+
!Uri::try_from("bitcoin:12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX")
276+
.unwrap()
277+
.extras
278+
.pj_is_supported(),
279+
"Uri expected a failure with missing pj extras, but it succeeded"
280+
);
281+
}
282+
283+
#[test]
284+
fn test_supported() {
285+
assert!(
286+
Uri::try_from(
287+
"bitcoin:12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX?amount=0.01\
288+
&pjos=0&pj=HTTPS://EXAMPLE.COM/\
289+
%23OH1QYPM5JXYNS754Y4R45QWE336QFX6ZR8DQGVQCULVZTV20TFVEYDMFQC"
290+
)
273291
.unwrap()
274292
.extras
275-
.pj_is_supported());
293+
.pj_is_supported(),
294+
"Uri expected a success with a well formatted pj extras, but it failed"
295+
);
296+
}
297+
298+
#[test]
299+
fn test_pj_param_unknown() {
300+
use bitcoin_uri::de::DeserializationState as _;
301+
let uri = "bitcoin:12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX?pjos=1&pj=HTTPS://EXAMPLE.COM/\
302+
%23OH1QYPM5JXYNS754Y4R45QWE336QFX6ZR8DQGVQCULVZTV20TFVEYDMFQC";
303+
let pjuri = Uri::try_from(uri).unwrap().assume_checked().check_pj_supported().unwrap();
304+
let serialized_params = pjuri.extras.serialize_params();
305+
let pjos_key = serialized_params.clone().next().expect("Missing pjos key").0;
306+
let pj_key = serialized_params.clone().next().expect("Missing pj key").0;
307+
308+
let state = DeserializationState::default();
309+
310+
assert!(state.is_param_known(pjos_key), "The pjos key should match 'pjos', but it failed");
311+
assert!(state.is_param_known(pj_key), "The pj key should match 'pj', but it failed");
312+
assert!(
313+
!state.is_param_known("unknown_param"),
314+
"An unknown_param should not match 'pj' or 'pjos'"
315+
);
276316
}
277317

278318
#[test]

payjoin/src/uri/url_ext.rs

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -225,26 +225,29 @@ impl std::error::Error for ParseReceiverPubkeyParamError {
225225

226226
#[cfg(test)]
227227
mod tests {
228-
use payjoin_test_utils::BoxError;
228+
use payjoin_test_utils::{BoxError, EXAMPLE_URL};
229229

230230
use super::*;
231231
use crate::{Uri, UriExt};
232232

233233
#[test]
234234
fn test_ohttp_get_set() {
235-
let mut url = Url::parse("https://example.com").unwrap();
235+
let mut url = EXAMPLE_URL.clone();
236236

237237
let serialized = "OH1QYPM5JXYNS754Y4R45QWE336QFX6ZR8DQGVQCULVZTV20TFVEYDMFQC";
238238
let ohttp_keys = OhttpKeys::from_str(serialized).unwrap();
239239
url.set_ohttp(ohttp_keys.clone());
240240

241241
assert_eq!(url.fragment(), Some(serialized));
242-
assert_eq!(url.ohttp().unwrap(), ohttp_keys);
242+
assert_eq!(
243+
url.ohttp().expect("Ohttp keys have been set but are missing on get"),
244+
ohttp_keys
245+
);
243246
}
244247

245248
#[test]
246249
fn test_errors_when_parsing_ohttp() {
247-
let missing_ohttp_url = Url::parse("https://example.com").unwrap();
250+
let missing_ohttp_url = EXAMPLE_URL.clone();
248251
assert!(matches!(
249252
missing_ohttp_url.ohttp(),
250253
Err(ParseOhttpKeysParamError::MissingOhttpKeys)
@@ -261,19 +264,19 @@ mod tests {
261264

262265
#[test]
263266
fn test_exp_get_set() {
264-
let mut url = Url::parse("https://example.com").unwrap();
267+
let mut url = EXAMPLE_URL.clone();
265268

266269
let exp_time =
267270
std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(1720547781);
268271
url.set_exp(exp_time);
269272
assert_eq!(url.fragment(), Some("EX1C4UC6ES"));
270273

271-
assert_eq!(url.exp().unwrap(), exp_time);
274+
assert_eq!(url.exp().expect("Expiry has been set but is missing on get"), exp_time);
272275
}
273276

274277
#[test]
275278
fn test_errors_when_parsing_exp() {
276-
let missing_exp_url = Url::parse("http://example.com").unwrap();
279+
let missing_exp_url = EXAMPLE_URL.clone();
277280
assert!(matches!(missing_exp_url.exp(), Err(ParseExpParamError::MissingExp)));
278281

279282
let invalid_bech32_exp_url =
@@ -290,7 +293,41 @@ mod tests {
290293
// Not enough data to decode into a u32
291294
let invalid_timestamp_exp_url =
292295
Url::parse("http://example.com?pj=https://test-payjoin-url#EX10").unwrap();
293-
assert!(matches!(invalid_timestamp_exp_url.exp(), Err(ParseExpParamError::InvalidExp(_))))
296+
assert!(matches!(invalid_timestamp_exp_url.exp(), Err(ParseExpParamError::InvalidExp(_))));
297+
}
298+
299+
#[test]
300+
fn test_errors_when_parsing_receiver_pubkey() {
301+
let missing_receiver_pubkey_url = EXAMPLE_URL.clone();
302+
assert!(matches!(
303+
missing_receiver_pubkey_url.receiver_pubkey(),
304+
Err(ParseReceiverPubkeyParamError::MissingPubkey)
305+
));
306+
307+
let invalid_bech32_receiver_pubkey_url =
308+
Url::parse("http://example.com?pj=https://test-payjoin-url#RK1invalid_bech_32")
309+
.unwrap();
310+
assert!(matches!(
311+
invalid_bech32_receiver_pubkey_url.receiver_pubkey(),
312+
Err(ParseReceiverPubkeyParamError::DecodeBech32(_))
313+
));
314+
315+
// Since the HRP is everything to the left of the right-most separator, the invalid url in
316+
// this test would have it's HRP being parsed as RK101 instead of the expected RK1
317+
let invalid_hrp_receiver_pubkey_url =
318+
Url::parse("http://example.com?pj=https://test-payjoin-url#RK101").unwrap();
319+
assert!(matches!(
320+
invalid_hrp_receiver_pubkey_url.receiver_pubkey(),
321+
Err(ParseReceiverPubkeyParamError::InvalidHrp(_))
322+
));
323+
324+
// Not enough data to decode into a u32
325+
let invalid_receiver_pubkey_url =
326+
Url::parse("http://example.com?pj=https://test-payjoin-url#RK10").unwrap();
327+
assert!(matches!(
328+
invalid_receiver_pubkey_url.receiver_pubkey(),
329+
Err(ParseReceiverPubkeyParamError::InvalidPubkey(_))
330+
));
294331
}
295332

296333
#[test]

0 commit comments

Comments
 (0)