Skip to content

Commit 361c31e

Browse files
authored
Extend tests for rest of receive module (payjoin#632)
2 parents f98899b + 9be9dc2 commit 361c31e

File tree

7 files changed

+109
-6
lines changed

7 files changed

+109
-6
lines changed

.cargo/mutants.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
additional_cargo_args = ["--all-features"]
2-
examine_globs = ["payjoin/src/uri/*.rs", "payjoin/src/receive/v1/**/*.rs"]
2+
examine_globs = ["payjoin/src/uri/*.rs", "payjoin/src/receive/**/*.rs"]
33
exclude_globs = []
44
exclude_re = [
55
"impl Debug",

payjoin-cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ reqwest = { version = "0.12", default-features = false }
4343
rustls = { version = "0.22.4", optional = true }
4444
serde = { version = "1.0.160", features = ["derive"] }
4545
sled = "0.34"
46-
tokio = { version = "1.12.0", features = ["full"] }
46+
tokio = { version = "1.38.1", features = ["full"] }
4747
tokio-rustls = { version = "0.25", features = ["ring"], default-features = false, optional = true }
4848
url = { version = "2.3.1", features = ["serde"] }
4949

payjoin-test-utils/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ rustls = "0.22"
2424
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls"] }
2525
testcontainers = "0.15.0"
2626
testcontainers-modules = { version = "0.3.7", features = ["redis"] }
27-
tokio = { version = "1.12.0", features = ["full"] }
27+
tokio = { version = "1.38.1", features = ["full"] }
2828
tracing = "0.1.40"
2929
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
3030
url = "2.2.2"

payjoin/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ serde_json = { version = "1.0.108", optional = true }
4545
bitcoind = { version = "0.36.0", features = ["0_21_2"] }
4646
payjoin-test-utils = { path = "../payjoin-test-utils" }
4747
once_cell = "1"
48-
tokio = { version = "1.12.0", features = ["full"] }
48+
tokio = { version = "1.38.1", features = ["full"] }
4949
tracing = "0.1.40"
5050

5151
[package.metadata.docs.rs]

payjoin/src/receive/multiparty/mod.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,64 @@ impl FinalizedProposal {
248248

249249
pub fn v2(&self) -> &[v2::UncheckedProposal] { &self.v2_proposals }
250250
}
251+
252+
#[cfg(test)]
253+
mod test {
254+
255+
use std::any::{Any, TypeId};
256+
257+
use payjoin_test_utils::{BoxError, PARSED_ORIGINAL_PSBT};
258+
259+
use super::{v1, v2, FinalizedProposal, UncheckedProposalBuilder, SUPPORTED_VERSIONS};
260+
use crate::receive::optional_parameters::Params;
261+
use crate::receive::v2::test::SHARED_CONTEXT;
262+
263+
fn multiparty_proposal_from_test_vector() -> v1::UncheckedProposal {
264+
let pairs = url::form_urlencoded::parse("v=2&optimisticmerge=true".as_bytes());
265+
let params = Params::from_query_pairs(pairs, SUPPORTED_VERSIONS)
266+
.expect("Could not parse from query pairs");
267+
v1::UncheckedProposal { psbt: PARSED_ORIGINAL_PSBT.clone(), params }
268+
}
269+
270+
#[test]
271+
fn test_build_multiparty() -> Result<(), BoxError> {
272+
let proposal_one = v2::UncheckedProposal {
273+
v1: multiparty_proposal_from_test_vector(),
274+
context: SHARED_CONTEXT.clone(),
275+
};
276+
let proposal_two = v2::UncheckedProposal {
277+
v1: multiparty_proposal_from_test_vector(),
278+
context: SHARED_CONTEXT.clone(),
279+
};
280+
let mut multiparty = UncheckedProposalBuilder::new();
281+
multiparty.add(proposal_one)?;
282+
multiparty.add(proposal_two)?;
283+
let unchecked_proposal = multiparty.build();
284+
assert!(unchecked_proposal?.contexts.len() == 2);
285+
Ok(())
286+
}
287+
288+
#[test]
289+
fn finalize_multiparty() -> Result<(), BoxError> {
290+
use crate::psbt::PsbtExt;
291+
let proposal_one = v2::UncheckedProposal {
292+
v1: multiparty_proposal_from_test_vector(),
293+
context: SHARED_CONTEXT.clone(),
294+
};
295+
let proposal_two = v2::UncheckedProposal {
296+
v1: multiparty_proposal_from_test_vector(),
297+
context: SHARED_CONTEXT.clone(),
298+
};
299+
let mut finalized_multiparty = FinalizedProposal::new();
300+
finalized_multiparty.add(proposal_one.clone())?;
301+
assert_eq!(finalized_multiparty.v2()[0].type_id(), TypeId::of::<v2::UncheckedProposal>());
302+
303+
finalized_multiparty.add(proposal_two)?;
304+
assert_eq!(finalized_multiparty.v2()[1].type_id(), TypeId::of::<v2::UncheckedProposal>());
305+
306+
let multiparty_psbt =
307+
finalized_multiparty.combine().expect("could not create PSBT from finalized proposal");
308+
assert!(multiparty_psbt.validate_input_utxos().is_ok());
309+
Ok(())
310+
}
311+
}

payjoin/src/receive/optional_parameters.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,25 @@ impl fmt::Display for Error {
133133
impl std::error::Error for Error {
134134
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
135135
}
136+
137+
#[cfg(test)]
138+
pub(crate) mod test {
139+
use bitcoin::Amount;
140+
141+
use super::*;
142+
143+
#[test]
144+
fn test_parse_params() {
145+
use bitcoin::FeeRate;
146+
147+
let pairs = url::form_urlencoded::parse(b"maxadditionalfeecontribution=182&additionalfeeoutputindex=0&minfeerate=1&disableoutputsubstitution=true&optimisticmerge=true");
148+
let params =
149+
Params::from_query_pairs(pairs, &[1]).expect("Could not parse params from query pairs");
150+
assert_eq!(params.v, 1);
151+
assert_eq!(params.output_substitution, OutputSubstitution::Disabled);
152+
assert_eq!(params.additional_fee_contribution, Some((Amount::from_sat(182), 0)));
153+
assert_eq!(params.min_fee_rate, FeeRate::BROADCAST_MIN);
154+
#[cfg(feature = "_multiparty")]
155+
assert!(params.optimistic_merge)
156+
}
157+
}

payjoin/src/receive/v2/mod.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -655,15 +655,16 @@ fn id(s: &HpkeKeyPair) -> ShortId {
655655
}
656656

657657
#[cfg(test)]
658-
mod test {
658+
pub mod test {
659659
use std::str::FromStr;
660660

661661
use once_cell::sync::Lazy;
662662
use payjoin_test_utils::{BoxError, EXAMPLE_URL, KEM, KEY_ID, SYMMETRIC};
663+
use persist::Value;
663664

664665
use super::*;
665666

666-
static SHARED_CONTEXT: Lazy<SessionContext> = Lazy::new(|| SessionContext {
667+
pub(crate) static SHARED_CONTEXT: Lazy<SessionContext> = Lazy::new(|| SessionContext {
667668
address: Address::from_str("tb1q6d3a2w975yny0asuvd9a67ner4nks58ff0q8g4")
668669
.expect("valid address")
669670
.assume_checked(),
@@ -707,9 +708,28 @@ mod test {
707708
Ok(())
708709
}
709710

711+
#[test]
712+
fn default_expiry() {
713+
let now = SystemTime::now();
714+
715+
let session = NewReceiver::new(
716+
SHARED_CONTEXT.address.clone(),
717+
SHARED_CONTEXT.directory.clone(),
718+
SHARED_CONTEXT.ohttp_keys.clone(),
719+
None,
720+
);
721+
let session_expiry = session.unwrap().context.expiry.duration_since(now).unwrap().as_secs();
722+
let default_expiry = Duration::from_secs(86400);
723+
if let Some(expected_expiry) = now.checked_add(default_expiry) {
724+
assert_eq!(TWENTY_FOUR_HOURS_DEFAULT_EXPIRY, default_expiry);
725+
assert_eq!(session_expiry, expected_expiry.duration_since(now).unwrap().as_secs());
726+
}
727+
}
728+
710729
#[test]
711730
fn receiver_ser_de_roundtrip() -> Result<(), serde_json::Error> {
712731
let session = Receiver { context: SHARED_CONTEXT.clone() };
732+
assert_eq!(session.key().as_ref(), session.key().0.as_bytes());
713733
let serialized = serde_json::to_string(&session)?;
714734
let deserialized: Receiver = serde_json::from_str(&serialized)?;
715735
assert_eq!(session, deserialized);

0 commit comments

Comments
 (0)