use super::*;
#[derive(Boilerplate)]
pub(crate) struct OutputHtml {
pub(crate) chain: Chain,
pub(crate) confirmations: u32,
pub(crate) inscriptions: Option<Vec<InscriptionId>>,
pub(crate) outpoint: OutPoint,
pub(crate) output: TxOut,
pub(crate) runes: Option<BTreeMap<SpacedRune, Pile>>,
pub(crate) sat_ranges: Option<Vec<(u64, u64)>>,
pub(crate) spent: bool,
}
impl PageContent for OutputHtml {
fn title(&self) -> String {
format!("Output {}", self.outpoint)
}
}
#[cfg(test)]
mod tests {
use {
super::*,
bitcoin::{PubkeyHash, blockdata::script},
};
#[test]
fn unspent_output() {
assert_regex_match!(
OutputHtml {
chain: Chain::Mainnet,
confirmations: 6,
inscriptions: Some(Vec::new()),
outpoint: outpoint(1),
output: TxOut { value: Amount::from_sat(3), script_pubkey: ScriptBuf::new_p2pkh(&PubkeyHash::all_zeros()), },
runes: Some(BTreeMap::new()),
sat_ranges: Some(vec![(0, 1), (1, 3)]),
spent: false,
},
"
<h1>Output <span class=monospace>1{64}:1</span></h1>
<dl>
<dt>value</dt><dd>3</dd>
<dt>script pubkey</dt><dd class=monospace>OP_DUP OP_HASH160 OP_PUSHBYTES_20 0{40} OP_EQUALVERIFY OP_CHECKSIG</dd>
<dt>address</dt><dd><a class=collapse href=/address/1111111111111111111114oLvT2>1111111111111111111114oLvT2</a></dd>
<dt>transaction</dt><dd><a class=collapse href=/tx/1{64}>1{64}</a></dd>
<dt>confirmations</dt><dd>6</dd>
<dt>spent</dt><dd>false</dd>
</dl>
<h2>2 Sat Ranges</h2>
<ul class=monospace>
<li><a href=/sat/0 class=mythic>0</a></li>
<li><a href=/sat/1 class=common>1</a>-<a href=/sat/2 class=common>2</a> \\(2 sats\\)</li>
</ul>
"
.unindent()
);
}
#[test]
fn spent_output() {
assert_regex_match!(
OutputHtml {
chain: Chain::Mainnet,
confirmations: 10,
inscriptions: None,
outpoint: outpoint(1),
output: TxOut {
value: Amount::from_sat(1),
script_pubkey: script::Builder::new().push_int(0).into_script(),
},
runes: None,
sat_ranges: None,
spent: true,
},
"
<h1>Output <span class=monospace>1{64}:1</span></h1>
<dl>
<dt>value</dt><dd>1</dd>
<dt>script pubkey</dt><dd class=monospace>OP_0</dd>
<dt>transaction</dt><dd><a class=collapse href=/tx/1{64}>1{64}</a></dd>
<dt>confirmations</dt><dd>10</dd>
<dt>spent</dt><dd>true</dd>
</dl>
"
.unindent()
);
}
#[test]
fn spent_output_with_ranges() {
assert_regex_match!(
OutputHtml {
chain: Chain::Mainnet,
confirmations: 6,
inscriptions: None,
outpoint: outpoint(1),
output: TxOut { value: Amount::from_sat(3), script_pubkey: ScriptBuf::new_p2pkh(&PubkeyHash::all_zeros()), },
runes: None,
sat_ranges: Some(vec![(0, 1), (1, 3)]),
spent: true,
},
"
<h1>Output <span class=monospace>1{64}:1</span></h1>
<dl>
<dt>value</dt><dd>3</dd>
<dt>script pubkey</dt><dd class=monospace>OP_DUP OP_HASH160 OP_PUSHBYTES_20 0{40} OP_EQUALVERIFY OP_CHECKSIG</dd>
<dt>address</dt><dd><a class=collapse href=/address/1111111111111111111114oLvT2>1111111111111111111114oLvT2</a></dd>
<dt>transaction</dt><dd><a class=collapse href=/tx/1{64}>1{64}</a></dd>
<dt>confirmations</dt><dd>6</dd>
<dt>spent</dt><dd>true</dd>
</dl>
<h2>2 Sat Ranges</h2>
<ul class=monospace>
<li><a href=/sat/0 class=mythic>0</a></li>
<li><a href=/sat/1 class=common>1</a>-<a href=/sat/2 class=common>2</a> \\(2 sats\\)</li>
</ul>
"
.unindent()
);
}
#[test]
fn no_list() {
assert_regex_match!(
OutputHtml {
chain: Chain::Mainnet,
confirmations: 6,
inscriptions: None,
outpoint: outpoint(1),
output: TxOut { value: Amount::from_sat(3), script_pubkey: ScriptBuf::new_p2pkh(&PubkeyHash::all_zeros()), },
runes: None,
sat_ranges: None,
spent: false,
}
.to_string(),
"
<h1>Output <span class=monospace>1{64}:1</span></h1>
<dl>
<dt>value</dt><dd>3</dd>
<dt>script pubkey</dt><dd class=monospace>OP_DUP OP_HASH160 OP_PUSHBYTES_20 0{40} OP_EQUALVERIFY OP_CHECKSIG</dd>
<dt>address</dt><dd><a class=collapse href=/address/1111111111111111111114oLvT2>1111111111111111111114oLvT2</a></dd>
<dt>transaction</dt><dd><a class=collapse href=/tx/1{64}>1{64}</a></dd>
<dt>confirmations</dt><dd>6</dd>
<dt>spent</dt><dd>false</dd>
</dl>
"
.unindent()
);
}
#[test]
fn with_inscriptions() {
assert_regex_match!(
OutputHtml {
chain: Chain::Mainnet,
confirmations: 6,
inscriptions: Some(vec![inscription_id(1)]),
outpoint: outpoint(1),
output: TxOut {
value: Amount::from_sat(3),
script_pubkey: ScriptBuf::new_p2pkh(&PubkeyHash::all_zeros()),
},
runes: None,
sat_ranges: None,
spent: false,
},
"
<h1>Output <span class=monospace>1{64}:1</span></h1>
<dl>
<dt>inscriptions</dt>
<dd class=thumbnails>
<a href=/inscription/1{64}i1><iframe .* src=/preview/1{64}i1></iframe></a>
</dd>
.*
</dl>
"
.unindent()
);
}
#[test]
fn with_runes() {
assert_regex_match!(
OutputHtml {
chain: Chain::Mainnet,
confirmations: 6,
inscriptions: None,
outpoint: outpoint(1),
output: TxOut {
value: Amount::from_sat(3),
script_pubkey: ScriptBuf::new_p2pkh(&PubkeyHash::all_zeros()),
},
runes: Some(
vec![(
SpacedRune {
rune: Rune(26),
spacers: 1
},
Pile {
amount: 11,
divisibility: 1,
symbol: None,
}
)]
.into_iter()
.collect()
),
sat_ranges: None,
spent: false,
},
"
<h1>Output <span class=monospace>1{64}:1</span></h1>
<dl>
<dt>runes</dt>
<dd>
<table>
<tr>
<th>rune</th>
<th>balance</th>
</tr>
<tr>
<td><a href=/rune/A•A>A•A</a></td>
<td>1.1\u{A0}¤</td>
</tr>
</table>
</dd>
.*
</dl>
"
.unindent()
);
}
}