upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--flake.nix2
-rw-r--r--src/bin/git_remote_nostr/push.rs36
-rw-r--r--src/bin/git_remote_nostr/utils.rs13
-rw-r--r--src/bin/ngit/sub_commands/list.rs13
-rw-r--r--src/bin/ngit/sub_commands/send.rs7
-rw-r--r--src/lib/client.rs132
-rw-r--r--src/lib/git/identify_ahead_behind.rs8
-rw-r--r--src/lib/git/mod.rs83
-rw-r--r--src/lib/git_events.rs16
-rw-r--r--src/lib/login/mod.rs14
-rw-r--r--src/lib/repo_ref.rs13
-rw-r--r--src/lib/repo_state.rs7
-rw-r--r--test_utils/src/lib.rs204
-rw-r--r--test_utils/src/relay.rs8
-rw-r--r--tests/git_remote_nostr/push.rs30
-rw-r--r--tests/ngit_init.rs36
-rw-r--r--tests/ngit_list.rs366
-rw-r--r--tests/ngit_login.rs350
-rw-r--r--tests/ngit_send.rs246
19 files changed, 951 insertions, 633 deletions
diff --git a/flake.nix b/flake.nix
index ff528e5..9ca8a7d 100644
--- a/flake.nix
+++ b/flake.nix
@@ -19,7 +19,7 @@
19 # ideally this wouldn't be pinned to a specific nightly version but 19 # ideally this wouldn't be pinned to a specific nightly version but
20 # selectLatestNightlyWith isn't support with mixed toolchains 20 # selectLatestNightlyWith isn't support with mixed toolchains
21 # https://github.com/oxalica/rust-overlay/issues/136 21 # https://github.com/oxalica/rust-overlay/issues/136
22 (lib.hiPrio rust-bin.nightly."2024-12-15".rustfmt) 22 (lib.hiPrio rust-bin.nightly."2025-07-16".rustfmt)
23 # (rust-bin.stable.latest.override { extensions = [ "rust-analyzer" ]; }) 23 # (rust-bin.stable.latest.override { extensions = [ "rust-analyzer" ]; })
24 rust-bin.stable.latest.default 24 rust-bin.stable.latest.default
25 ]; 25 ];
diff --git a/src/bin/git_remote_nostr/push.rs b/src/bin/git_remote_nostr/push.rs
index 04fc4d8..9ff8af0 100644
--- a/src/bin/git_remote_nostr/push.rs
+++ b/src/bin/git_remote_nostr/push.rs
@@ -1049,10 +1049,13 @@ async fn get_merged_status_events(
1049 let (ahead, _) = 1049 let (ahead, _) =
1050 git_repo.get_commits_ahead_behind(&tip_of_remote_branch, &tip_of_pushed_branch)?; 1050 git_repo.get_commits_ahead_behind(&tip_of_remote_branch, &tip_of_pushed_branch)?;
1051 1051
1052 let commit_events = get_events_from_local_cache(git_repo.get_path()?, vec![ 1052 let commit_events = get_events_from_local_cache(
1053 nostr::Filter::default().kind(nostr::Kind::GitPatch), 1053 git_repo.get_path()?,
1054 // TODO: limit by repo_ref 1054 vec![
1055 ]) 1055 nostr::Filter::default().kind(nostr::Kind::GitPatch),
1056 // TODO: limit by repo_ref
1057 ],
1058 )
1056 .await?; 1059 .await?;
1057 1060
1058 let merged_proposals_info = 1061 let merged_proposals_info =
@@ -1129,9 +1132,12 @@ async fn get_merged_proposals_info(
1129 proposals.entry(proposal_id).or_default(); 1132 proposals.entry(proposal_id).or_default();
1130 // ignore revisions without all the merged commits 1133 // ignore revisions without all the merged commits
1131 if entry_revision_id == &revision_id { 1134 if entry_revision_id == &revision_id {
1132 merged_patches.insert(*commit_hash, MergedPRCommitType::PatchCommit { 1135 merged_patches.insert(
1133 event_id: patch_event.id, 1136 *commit_hash,
1134 }); 1137 MergedPRCommitType::PatchCommit {
1138 event_id: patch_event.id,
1139 },
1140 );
1135 } 1141 }
1136 } 1142 }
1137 } 1143 }
@@ -1156,9 +1162,12 @@ async fn get_merged_proposals_info(
1156 proposals.entry(proposal_id).or_default(); 1162 proposals.entry(proposal_id).or_default();
1157 // ignore revisions without all the applied commits 1163 // ignore revisions without all the applied commits
1158 if entry_revision_id == &revision_id { 1164 if entry_revision_id == &revision_id {
1159 merged_patches.insert(*commit_hash, MergedPRCommitType::PatchApplied { 1165 merged_patches.insert(
1160 event_id: patch_event.id, 1166 *commit_hash,
1161 }); 1167 MergedPRCommitType::PatchApplied {
1168 event_id: patch_event.id,
1169 },
1170 );
1162 } 1171 }
1163 } 1172 }
1164 } 1173 }
@@ -1405,9 +1414,10 @@ async fn get_proposal_and_revision_root_from_patch(
1405 .clone(), 1414 .clone(),
1406 )?; 1415 )?;
1407 1416
1408 get_events_from_local_cache(git_repo.get_path()?, vec![ 1417 get_events_from_local_cache(
1409 nostr::Filter::default().id(proposal_or_revision_id), 1418 git_repo.get_path()?,
1410 ]) 1419 vec![nostr::Filter::default().id(proposal_or_revision_id)],
1420 )
1411 .await? 1421 .await?
1412 .first() 1422 .first()
1413 .unwrap() 1423 .unwrap()
diff --git a/src/bin/git_remote_nostr/utils.rs b/src/bin/git_remote_nostr/utils.rs
index f7e688e..dc75872 100644
--- a/src/bin/git_remote_nostr/utils.rs
+++ b/src/bin/git_remote_nostr/utils.rs
@@ -108,11 +108,14 @@ pub async fn get_open_or_draft_proposals(
108 .collect(); 108 .collect();
109 109
110 let statuses: Vec<nostr::Event> = { 110 let statuses: Vec<nostr::Event> = {
111 let mut statuses = get_events_from_local_cache(git_repo_path, vec![ 111 let mut statuses = get_events_from_local_cache(
112 nostr::Filter::default() 112 git_repo_path,
113 .kinds(status_kinds().clone()) 113 vec![
114 .events(proposals.iter().map(|e| e.id)), 114 nostr::Filter::default()
115 ]) 115 .kinds(status_kinds().clone())
116 .events(proposals.iter().map(|e| e.id)),
117 ],
118 )
116 .await?; 119 .await?;
117 statuses.sort_by_key(|e| e.created_at); 120 statuses.sort_by_key(|e| e.created_at);
118 statuses.reverse(); 121 statuses.reverse();
diff --git a/src/bin/ngit/sub_commands/list.rs b/src/bin/ngit/sub_commands/list.rs
index 2c91e66..0330be1 100644
--- a/src/bin/ngit/sub_commands/list.rs
+++ b/src/bin/ngit/sub_commands/list.rs
@@ -49,11 +49,14 @@ pub async fn launch() -> Result<()> {
49 } 49 }
50 50
51 let statuses: Vec<nostr::Event> = { 51 let statuses: Vec<nostr::Event> = {
52 let mut statuses = get_events_from_local_cache(git_repo_path, vec![ 52 let mut statuses = get_events_from_local_cache(
53 nostr::Filter::default() 53 git_repo_path,
54 .kinds(status_kinds().clone()) 54 vec![
55 .events(proposals_and_revisions.iter().map(|e| e.id)), 55 nostr::Filter::default()
56 ]) 56 .kinds(status_kinds().clone())
57 .events(proposals_and_revisions.iter().map(|e| e.id)),
58 ],
59 )
57 .await?; 60 .await?;
58 statuses.sort_by_key(|e| e.created_at); 61 statuses.sort_by_key(|e| e.created_at);
59 statuses.reverse(); 62 statuses.reverse();
diff --git a/src/bin/ngit/sub_commands/send.rs b/src/bin/ngit/sub_commands/send.rs
index 5a5acc8..c84e339 100644
--- a/src/bin/ngit/sub_commands/send.rs
+++ b/src/bin/ngit/sub_commands/send.rs
@@ -378,9 +378,10 @@ async fn get_root_proposal_id_and_mentions_from_in_reply_to(
378 public_key: _, 378 public_key: _,
379 uppercase: false, 379 uppercase: false,
380 }) => { 380 }) => {
381 let events = get_events_from_local_cache(git_repo_path, vec![ 381 let events = get_events_from_local_cache(
382 nostr::Filter::new().id(*event_id), 382 git_repo_path,
383 ]) 383 vec![nostr::Filter::new().id(*event_id)],
384 )
384 .await?; 385 .await?;
385 386
386 if let Some(first) = events.iter().find(|e| e.id.eq(event_id)) { 387 if let Some(first) = events.iter().find(|e| e.id.eq(event_id)) {
diff --git a/src/lib/client.rs b/src/lib/client.rs
index 16cfe30..9253022 100644
--- a/src/lib/client.rs
+++ b/src/lib/client.rs
@@ -1103,16 +1103,18 @@ pub async fn get_state_from_cache(
1103) -> Result<RepoState> { 1103) -> Result<RepoState> {
1104 if let Some(git_repo_path) = git_repo_path { 1104 if let Some(git_repo_path) = git_repo_path {
1105 RepoState::try_from( 1105 RepoState::try_from(
1106 get_events_from_local_cache(git_repo_path, vec![get_filter_state_events( 1106 get_events_from_local_cache(
1107 &repo_ref.coordinates(), 1107 git_repo_path,
1108 )]) 1108 vec![get_filter_state_events(&repo_ref.coordinates())],
1109 )
1109 .await?, 1110 .await?,
1110 ) 1111 )
1111 } else { 1112 } else {
1112 RepoState::try_from( 1113 RepoState::try_from(
1113 get_event_from_global_cache(git_repo_path, vec![get_filter_state_events( 1114 get_event_from_global_cache(
1114 &repo_ref.coordinates(), 1115 git_repo_path,
1115 )]) 1116 vec![get_filter_state_events(&repo_ref.coordinates())],
1117 )
1116 .await?, 1118 .await?,
1117 ) 1119 )
1118 } 1120 }
@@ -1178,17 +1180,20 @@ async fn create_relays_request(
1178 } 1180 }
1179 1181
1180 if let Some(git_repo_path) = git_repo_path { 1182 if let Some(git_repo_path) = git_repo_path {
1181 for event in &get_events_from_local_cache(git_repo_path, vec![ 1183 for event in &get_events_from_local_cache(
1182 nostr::Filter::default() 1184 git_repo_path,
1183 .kinds(vec![Kind::GitPatch]) 1185 vec![
1184 .custom_tags( 1186 nostr::Filter::default()
1185 SingleLetterTag::lowercase(nostr_sdk::Alphabet::A), 1187 .kinds(vec![Kind::GitPatch])
1186 repo_coordinates_without_relays 1188 .custom_tags(
1187 .iter() 1189 SingleLetterTag::lowercase(nostr_sdk::Alphabet::A),
1188 .map(|c| c.coordinate.to_string()) 1190 repo_coordinates_without_relays
1189 .collect::<Vec<String>>(), 1191 .iter()
1190 ), 1192 .map(|c| c.coordinate.to_string())
1191 ]) 1193 .collect::<Vec<String>>(),
1194 ),
1195 ],
1196 )
1192 .await? 1197 .await?
1193 { 1198 {
1194 if event_is_patch_set_root(event) || event_is_revision_root(event) { 1199 if event_is_patch_set_root(event) || event_is_revision_root(event) {
@@ -1198,11 +1203,11 @@ async fn create_relays_request(
1198 } 1203 }
1199 } 1204 }
1200 1205
1201 let profile_events = 1206 let profile_events = get_event_from_global_cache(
1202 get_event_from_global_cache(git_repo_path, vec![get_filter_contributor_profiles( 1207 git_repo_path,
1203 contributors.clone(), 1208 vec![get_filter_contributor_profiles(contributors.clone())],
1204 )]) 1209 )
1205 .await?; 1210 .await?;
1206 for c in &contributors { 1211 for c in &contributors {
1207 if let Some(event) = profile_events 1212 if let Some(event) = profile_events
1208 .iter() 1213 .iter()
@@ -1768,17 +1773,20 @@ pub async fn get_proposals_and_revisions_from_cache(
1768 git_repo_path: &Path, 1773 git_repo_path: &Path,
1769 repo_coordinates: HashSet<Nip19Coordinate>, 1774 repo_coordinates: HashSet<Nip19Coordinate>,
1770) -> Result<Vec<nostr::Event>> { 1775) -> Result<Vec<nostr::Event>> {
1771 let mut proposals = get_events_from_local_cache(git_repo_path, vec![ 1776 let mut proposals = get_events_from_local_cache(
1772 nostr::Filter::default() 1777 git_repo_path,
1773 .kind(nostr::Kind::GitPatch) 1778 vec![
1774 .custom_tags( 1779 nostr::Filter::default()
1775 nostr::SingleLetterTag::lowercase(nostr_sdk::Alphabet::A), 1780 .kind(nostr::Kind::GitPatch)
1776 repo_coordinates 1781 .custom_tags(
1777 .iter() 1782 nostr::SingleLetterTag::lowercase(nostr_sdk::Alphabet::A),
1778 .map(|c| c.coordinate.to_string()) 1783 repo_coordinates
1779 .collect::<Vec<String>>(), 1784 .iter()
1780 ), 1785 .map(|c| c.coordinate.to_string())
1781 ]) 1786 .collect::<Vec<String>>(),
1787 ),
1788 ],
1789 )
1782 .await? 1790 .await?
1783 .iter() 1791 .iter()
1784 .filter(|e| event_is_patch_set_root(e)) 1792 .filter(|e| event_is_patch_set_root(e))
@@ -1794,23 +1802,29 @@ pub async fn get_all_proposal_patch_events_from_cache(
1794 repo_ref: &RepoRef, 1802 repo_ref: &RepoRef,
1795 proposal_id: &nostr::EventId, 1803 proposal_id: &nostr::EventId,
1796) -> Result<Vec<nostr::Event>> { 1804) -> Result<Vec<nostr::Event>> {
1797 let mut commit_events = get_events_from_local_cache(git_repo_path, vec![ 1805 let mut commit_events = get_events_from_local_cache(
1798 nostr::Filter::default() 1806 git_repo_path,
1799 .kind(nostr::Kind::GitPatch) 1807 vec![
1800 .event(*proposal_id), 1808 nostr::Filter::default()
1801 nostr::Filter::default() 1809 .kind(nostr::Kind::GitPatch)
1802 .kind(nostr::Kind::GitPatch) 1810 .event(*proposal_id),
1803 .id(*proposal_id), 1811 nostr::Filter::default()
1804 ]) 1812 .kind(nostr::Kind::GitPatch)
1813 .id(*proposal_id),
1814 ],
1815 )
1805 .await?; 1816 .await?;
1806 1817
1807 let permissioned_users: HashSet<PublicKey> = [repo_ref.maintainers.clone(), vec![ 1818 let permissioned_users: HashSet<PublicKey> = [
1808 commit_events 1819 repo_ref.maintainers.clone(),
1809 .iter() 1820 vec![
1810 .find(|e| e.id.eq(proposal_id)) 1821 commit_events
1811 .context("proposal not in cache")? 1822 .iter()
1812 .pubkey, 1823 .find(|e| e.id.eq(proposal_id))
1813 ]] 1824 .context("proposal not in cache")?
1825 .pubkey,
1826 ],
1827 ]
1814 .concat() 1828 .concat()
1815 .iter() 1829 .iter()
1816 .copied() 1830 .copied()
@@ -1824,12 +1838,15 @@ pub async fn get_all_proposal_patch_events_from_cache(
1824 .collect(); 1838 .collect();
1825 1839
1826 if !revision_roots.is_empty() { 1840 if !revision_roots.is_empty() {
1827 for event in get_events_from_local_cache(git_repo_path, vec![ 1841 for event in get_events_from_local_cache(
1828 nostr::Filter::default() 1842 git_repo_path,
1829 .kind(nostr::Kind::GitPatch) 1843 vec![
1830 .events(revision_roots) 1844 nostr::Filter::default()
1831 .authors(permissioned_users.clone()), 1845 .kind(nostr::Kind::GitPatch)
1832 ]) 1846 .events(revision_roots)
1847 .authors(permissioned_users.clone()),
1848 ],
1849 )
1833 .await? 1850 .await?
1834 { 1851 {
1835 commit_events.push(event); 1852 commit_events.push(event);
@@ -1844,9 +1861,10 @@ pub async fn get_all_proposal_patch_events_from_cache(
1844} 1861}
1845 1862
1846pub async fn get_event_from_cache_by_id(git_repo: &Repo, event_id: &EventId) -> Result<Event> { 1863pub async fn get_event_from_cache_by_id(git_repo: &Repo, event_id: &EventId) -> Result<Event> {
1847 Ok(get_events_from_local_cache(git_repo.get_path()?, vec![ 1864 Ok(get_events_from_local_cache(
1848 nostr::Filter::default().id(*event_id), 1865 git_repo.get_path()?,
1849 ]) 1866 vec![nostr::Filter::default().id(*event_id)],
1867 )
1850 .await? 1868 .await?
1851 .first() 1869 .first()
1852 .context("failed to find event in cache")? 1870 .context("failed to find event in cache")?
diff --git a/src/lib/git/identify_ahead_behind.rs b/src/lib/git/identify_ahead_behind.rs
index baea687..d736522 100644
--- a/src/lib/git/identify_ahead_behind.rs
+++ b/src/lib/git/identify_ahead_behind.rs
@@ -184,10 +184,10 @@ mod tests {
184 identify_ahead_behind(&git_repo, &Some("feature".to_string()), &None)?; 184 identify_ahead_behind(&git_repo, &Some("feature".to_string()), &None)?;
185 185
186 assert_eq!(from_branch, "feature"); 186 assert_eq!(from_branch, "feature");
187 assert_eq!(ahead, vec![ 187 assert_eq!(
188 oid_to_sha1(&feature_oid), 188 ahead,
189 oid_to_sha1(&dev_oid_first) 189 vec![oid_to_sha1(&feature_oid), oid_to_sha1(&dev_oid_first)]
190 ]); 190 );
191 assert_eq!(to_branch, "main"); 191 assert_eq!(to_branch, "main");
192 assert_eq!(behind, vec![]); 192 assert_eq!(behind, vec![]);
193 193
diff --git a/src/lib/git/mod.rs b/src/lib/git/mod.rs
index 464990b..d4bf2f5 100644
--- a/src/lib/git/mod.rs
+++ b/src/lib/git/mod.rs
@@ -1490,10 +1490,10 @@ mod tests {
1490 &oid_to_sha1(&feature_oid), 1490 &oid_to_sha1(&feature_oid),
1491 )?; 1491 )?;
1492 assert_eq!(ahead, vec![]); 1492 assert_eq!(ahead, vec![]);
1493 assert_eq!(behind, vec![ 1493 assert_eq!(
1494 oid_to_sha1(&behind_2_oid), 1494 behind,
1495 oid_to_sha1(&behind_1_oid), 1495 vec![oid_to_sha1(&behind_2_oid), oid_to_sha1(&behind_1_oid),],
1496 ],); 1496 );
1497 Ok(()) 1497 Ok(())
1498 } 1498 }
1499 1499
@@ -1515,10 +1515,10 @@ mod tests {
1515 &oid_to_sha1(&main_oid), 1515 &oid_to_sha1(&main_oid),
1516 &oid_to_sha1(&ahead_2_oid), 1516 &oid_to_sha1(&ahead_2_oid),
1517 )?; 1517 )?;
1518 assert_eq!(ahead, vec![ 1518 assert_eq!(
1519 oid_to_sha1(&ahead_2_oid), 1519 ahead,
1520 oid_to_sha1(&ahead_1_oid), 1520 vec![oid_to_sha1(&ahead_2_oid), oid_to_sha1(&ahead_1_oid),],
1521 ],); 1521 );
1522 assert_eq!(behind, vec![]); 1522 assert_eq!(behind, vec![]);
1523 Ok(()) 1523 Ok(())
1524 } 1524 }
@@ -1547,14 +1547,14 @@ mod tests {
1547 &oid_to_sha1(&behind_2_oid), 1547 &oid_to_sha1(&behind_2_oid),
1548 &oid_to_sha1(&ahead_2_oid), 1548 &oid_to_sha1(&ahead_2_oid),
1549 )?; 1549 )?;
1550 assert_eq!(ahead, vec![ 1550 assert_eq!(
1551 oid_to_sha1(&ahead_2_oid), 1551 ahead,
1552 oid_to_sha1(&ahead_1_oid) 1552 vec![oid_to_sha1(&ahead_2_oid), oid_to_sha1(&ahead_1_oid)],
1553 ],); 1553 );
1554 assert_eq!(behind, vec![ 1554 assert_eq!(
1555 oid_to_sha1(&behind_2_oid), 1555 behind,
1556 oid_to_sha1(&behind_1_oid) 1556 vec![oid_to_sha1(&behind_2_oid), oid_to_sha1(&behind_1_oid)],
1557 ],); 1557 );
1558 Ok(()) 1558 Ok(())
1559 } 1559 }
1560 } 1560 }
@@ -2209,9 +2209,10 @@ mod tests {
2209 test_repo.populate_with_test_branch()?; 2209 test_repo.populate_with_test_branch()?;
2210 test_repo.checkout("main")?; 2210 test_repo.checkout("main")?;
2211 2211
2212 assert_eq!(git_repo.parse_starting_commits("HEAD~1")?, vec![ 2212 assert_eq!(
2213 str_to_sha1("431b84edc0d2fa118d63faa3c2db9c73d630a5ae")? 2213 git_repo.parse_starting_commits("HEAD~1")?,
2214 ],); 2214 vec![str_to_sha1("431b84edc0d2fa118d63faa3c2db9c73d630a5ae")?],
2215 );
2215 Ok(()) 2216 Ok(())
2216 } 2217 }
2217 2218
@@ -2221,9 +2222,10 @@ mod tests {
2221 let git_repo = Repo::from_path(&test_repo.dir)?; 2222 let git_repo = Repo::from_path(&test_repo.dir)?;
2222 test_repo.populate_with_test_branch()?; 2223 test_repo.populate_with_test_branch()?;
2223 2224
2224 assert_eq!(git_repo.parse_starting_commits("HEAD~1")?, vec![ 2225 assert_eq!(
2225 str_to_sha1("82ff2bcc9aa94d1bd8faee723d4c8cc190d6061c")? 2226 git_repo.parse_starting_commits("HEAD~1")?,
2226 ],); 2227 vec![str_to_sha1("82ff2bcc9aa94d1bd8faee723d4c8cc190d6061c")?],
2228 );
2227 Ok(()) 2229 Ok(())
2228 } 2230 }
2229 } 2231 }
@@ -2237,10 +2239,13 @@ mod tests {
2237 test_repo.populate_with_test_branch()?; 2239 test_repo.populate_with_test_branch()?;
2238 test_repo.checkout("main")?; 2240 test_repo.checkout("main")?;
2239 2241
2240 assert_eq!(git_repo.parse_starting_commits("HEAD~2")?, vec![ 2242 assert_eq!(
2241 str_to_sha1("431b84edc0d2fa118d63faa3c2db9c73d630a5ae")?, 2243 git_repo.parse_starting_commits("HEAD~2")?,
2242 str_to_sha1("af474d8d271490e5c635aad337abdc050034b16a")?, 2244 vec![
2243 ],); 2245 str_to_sha1("431b84edc0d2fa118d63faa3c2db9c73d630a5ae")?,
2246 str_to_sha1("af474d8d271490e5c635aad337abdc050034b16a")?,
2247 ],
2248 );
2244 Ok(()) 2249 Ok(())
2245 } 2250 }
2246 } 2251 }
@@ -2253,11 +2258,14 @@ mod tests {
2253 let git_repo = Repo::from_path(&test_repo.dir)?; 2258 let git_repo = Repo::from_path(&test_repo.dir)?;
2254 test_repo.populate_with_test_branch()?; 2259 test_repo.populate_with_test_branch()?;
2255 2260
2256 assert_eq!(git_repo.parse_starting_commits("HEAD~3")?, vec![ 2261 assert_eq!(
2257 str_to_sha1("82ff2bcc9aa94d1bd8faee723d4c8cc190d6061c")?, 2262 git_repo.parse_starting_commits("HEAD~3")?,
2258 str_to_sha1("a23e6b05aaeb7d1471b4a838b51f337d5644eeb0")?, 2263 vec![
2259 str_to_sha1("7ab82116068982671a8111f27dc10599172334b2")?, 2264 str_to_sha1("82ff2bcc9aa94d1bd8faee723d4c8cc190d6061c")?,
2260 ],); 2265 str_to_sha1("a23e6b05aaeb7d1471b4a838b51f337d5644eeb0")?,
2266 str_to_sha1("7ab82116068982671a8111f27dc10599172334b2")?,
2267 ],
2268 );
2261 Ok(()) 2269 Ok(())
2262 } 2270 }
2263 } 2271 }
@@ -2271,11 +2279,14 @@ mod tests {
2271 test_repo.populate_with_test_branch()?; 2279 test_repo.populate_with_test_branch()?;
2272 test_repo.checkout("main")?; 2280 test_repo.checkout("main")?;
2273 2281
2274 assert_eq!(git_repo.parse_starting_commits("af474d8..a23e6b0")?, vec![ 2282 assert_eq!(
2275 str_to_sha1("a23e6b05aaeb7d1471b4a838b51f337d5644eeb0")?, 2283 git_repo.parse_starting_commits("af474d8..a23e6b0")?,
2276 str_to_sha1("7ab82116068982671a8111f27dc10599172334b2")?, 2284 vec![
2277 str_to_sha1("431b84edc0d2fa118d63faa3c2db9c73d630a5ae")?, 2285 str_to_sha1("a23e6b05aaeb7d1471b4a838b51f337d5644eeb0")?,
2278 ],); 2286 str_to_sha1("7ab82116068982671a8111f27dc10599172334b2")?,
2287 str_to_sha1("431b84edc0d2fa118d63faa3c2db9c73d630a5ae")?,
2288 ],
2289 );
2279 Ok(()) 2290 Ok(())
2280 } 2291 }
2281 } 2292 }
diff --git a/src/lib/git_events.rs b/src/lib/git_events.rs
index 3ce7637..69406c1 100644
--- a/src/lib/git_events.rs
+++ b/src/lib/git_events.rs
@@ -134,14 +134,15 @@ pub async fn generate_patch_event(
134 // code that makes it into the main branch, assuming 134 // code that makes it into the main branch, assuming
135 // the commit id is correct 135 // the commit id is correct
136 Tag::from_standardized(TagStandard::Reference(commit.to_string())), 136 Tag::from_standardized(TagStandard::Reference(commit.to_string())),
137 Tag::custom(TagKind::Custom(std::borrow::Cow::Borrowed("alt")), vec![ 137 Tag::custom(
138 format!( 138 TagKind::Custom(std::borrow::Cow::Borrowed("alt")),
139 vec![format!(
139 "git patch: {}", 140 "git patch: {}",
140 git_repo 141 git_repo
141 .get_commit_message_summary(commit) 142 .get_commit_message_summary(commit)
142 .unwrap_or_default() 143 .unwrap_or_default()
143 ), 144 )],
144 ]), 145 ),
145 ], 146 ],
146 if let Some(thread_event_id) = thread_event_id { 147 if let Some(thread_event_id) = thread_event_id {
147 vec![Tag::from_standardized(nostr_sdk::TagStandard::Event { 148 vec![Tag::from_standardized(nostr_sdk::TagStandard::Event {
@@ -205,9 +206,10 @@ pub async fn generate_patch_event(
205 .collect(), 206 .collect(),
206 vec![ 207 vec![
207 // a fallback is now in place to extract this from the patch 208 // a fallback is now in place to extract this from the patch
208 Tag::custom(TagKind::Custom(std::borrow::Cow::Borrowed("commit")), vec![ 209 Tag::custom(
209 commit.to_string(), 210 TagKind::Custom(std::borrow::Cow::Borrowed("commit")),
210 ]), 211 vec![commit.to_string()],
212 ),
211 // this is required as patches cannot be relied upon to include the 'base 213 // this is required as patches cannot be relied upon to include the 'base
212 // commit' 214 // commit'
213 Tag::custom( 215 Tag::custom(
diff --git a/src/lib/login/mod.rs b/src/lib/login/mod.rs
index bfc7328..3fcd755 100644
--- a/src/lib/login/mod.rs
+++ b/src/lib/login/mod.rs
@@ -79,11 +79,15 @@ fn print_logged_in_as(
79 "failed to find your relay list. consider using another nostr client to create one to enhance your nostr experience." 79 "failed to find your relay list. consider using another nostr client to create one to enhance your nostr experience."
80 ); 80 );
81 } 81 }
82 eprintln!("logged in as {}{}", user_ref.metadata.name, match source { 82 eprintln!(
83 SignerInfoSource::CommandLineArguments => " via cli arguments", 83 "logged in as {}{}",
84 SignerInfoSource::GitLocal => " to local repository", 84 user_ref.metadata.name,
85 SignerInfoSource::GitGlobal => "", 85 match source {
86 }); 86 SignerInfoSource::CommandLineArguments => " via cli arguments",
87 SignerInfoSource::GitLocal => " to local repository",
88 SignerInfoSource::GitGlobal => "",
89 }
90 );
87 Ok(()) 91 Ok(())
88} 92}
89 93
diff --git a/src/lib/repo_ref.rs b/src/lib/repo_ref.rs
index c1fc288..0236e34 100644
--- a/src/lib/repo_ref.rs
+++ b/src/lib/repo_ref.rs
@@ -578,11 +578,14 @@ pub fn save_repo_config_to_yaml(
578 .context("failed to convert public key into npub")?, 578 .context("failed to convert public key into npub")?,
579 ); 579 );
580 } 580 }
581 serde_yaml::to_writer(file, &RepoConfigYaml { 581 serde_yaml::to_writer(
582 identifier: Some(identifier), 582 file,
583 maintainers: maintainers_npubs, 583 &RepoConfigYaml {
584 relays, 584 identifier: Some(identifier),
585 }) 585 maintainers: maintainers_npubs,
586 relays,
587 },
588 )
586 .context("failed to write maintainers to maintainers.yaml file serde_yaml") 589 .context("failed to write maintainers to maintainers.yaml file serde_yaml")
587} 590}
588 591
diff --git a/src/lib/repo_state.rs b/src/lib/repo_state.rs
index 04f3cf2..345f05c 100644
--- a/src/lib/repo_state.rs
+++ b/src/lib/repo_state.rs
@@ -56,9 +56,10 @@ impl RepoState {
56 add_head(&mut state); 56 add_head(&mut state);
57 let mut tags = vec![Tag::identifier(identifier.clone())]; 57 let mut tags = vec![Tag::identifier(identifier.clone())];
58 for (name, value) in &state { 58 for (name, value) in &state {
59 tags.push(Tag::custom(nostr_sdk::TagKind::Custom(name.into()), vec![ 59 tags.push(Tag::custom(
60 value.clone(), 60 nostr_sdk::TagKind::Custom(name.into()),
61 ])); 61 vec![value.clone()],
62 ));
62 } 63 }
63 let event = sign_event( 64 let event = sign_event(
64 EventBuilder::new(STATE_KIND, "").tags(tags), 65 EventBuilder::new(STATE_KIND, "").tags(tags),
diff --git a/test_utils/src/lib.rs b/test_utils/src/lib.rs
index 1312610..7d79cff 100644
--- a/test_utils/src/lib.rs
+++ b/test_utils/src/lib.rs
@@ -544,10 +544,14 @@ impl CliTesterConfirmPrompt<'_> {
544 let mut s = String::new(); 544 let mut s = String::new();
545 self.tester 545 self.tester
546 .formatter 546 .formatter
547 .format_confirm_prompt_selection(&mut s, self.prompt.as_str(), match input { 547 .format_confirm_prompt_selection(
548 None => self.default, 548 &mut s,
549 Some(_) => input, 549 self.prompt.as_str(),
550 }) 550 match input {
551 None => self.default,
552 Some(_) => input,
553 },
554 )
551 .expect("diagluer theme formatter should succeed"); 555 .expect("diagluer theme formatter should succeed");
552 if !s.contains(self.prompt.as_str()) { 556 if !s.contains(self.prompt.as_str()) {
553 panic!("dialoguer must be broken as formatted prompt success doesnt contain prompt"); 557 panic!("dialoguer must be broken as formatted prompt success doesnt contain prompt");
@@ -1017,10 +1021,13 @@ where
1017 cmd.env("RUST_BACKTRACE", "0"); 1021 cmd.env("RUST_BACKTRACE", "0");
1018 cmd.args(args); 1022 cmd.args(args);
1019 // using branch for PR https://github.com/rust-cli/rexpect/pull/103 to strip ansi escape codes 1023 // using branch for PR https://github.com/rust-cli/rexpect/pull/103 to strip ansi escape codes
1020 rexpect::session::spawn_with_options(cmd, Options { 1024 rexpect::session::spawn_with_options(
1021 timeout_ms: Some(timeout_ms), 1025 cmd,
1022 strip_ansi_escape_codes: true, 1026 Options {
1023 }) 1027 timeout_ms: Some(timeout_ms),
1028 strip_ansi_escape_codes: true,
1029 },
1030 )
1024} 1031}
1025 1032
1026pub fn rexpect_with_from_dir<I, S>( 1033pub fn rexpect_with_from_dir<I, S>(
@@ -1038,10 +1045,13 @@ where
1038 cmd.current_dir(dir); 1045 cmd.current_dir(dir);
1039 cmd.args(args); 1046 cmd.args(args);
1040 // using branch for PR https://github.com/rust-cli/rexpect/pull/103 to strip ansi escape codes 1047 // using branch for PR https://github.com/rust-cli/rexpect/pull/103 to strip ansi escape codes
1041 rexpect::session::spawn_with_options(cmd, Options { 1048 rexpect::session::spawn_with_options(
1042 timeout_ms: Some(timeout_ms), 1049 cmd,
1043 strip_ansi_escape_codes: true, 1050 Options {
1044 }) 1051 timeout_ms: Some(timeout_ms),
1052 strip_ansi_escape_codes: true,
1053 },
1054 )
1045} 1055}
1046 1056
1047pub fn remote_helper_rexpect_with_from_dir( 1057pub fn remote_helper_rexpect_with_from_dir(
@@ -1056,10 +1066,13 @@ pub fn remote_helper_rexpect_with_from_dir(
1056 cmd.current_dir(dir); 1066 cmd.current_dir(dir);
1057 cmd.args([dir.as_os_str().to_str().unwrap(), nostr_remote_url]); 1067 cmd.args([dir.as_os_str().to_str().unwrap(), nostr_remote_url]);
1058 // using branch for PR https://github.com/rust-cli/rexpect/pull/103 to strip ansi escape codes 1068 // using branch for PR https://github.com/rust-cli/rexpect/pull/103 to strip ansi escape codes
1059 rexpect::session::spawn_with_options(cmd, Options { 1069 rexpect::session::spawn_with_options(
1060 timeout_ms: Some(timeout_ms), 1070 cmd,
1061 strip_ansi_escape_codes: true, 1071 Options {
1062 }) 1072 timeout_ms: Some(timeout_ms),
1073 strip_ansi_escape_codes: true,
1074 },
1075 )
1063} 1076}
1064 1077
1065pub fn git_with_remote_helper_rexpect_with_from_dir<I, S>( 1078pub fn git_with_remote_helper_rexpect_with_from_dir<I, S>(
@@ -1103,10 +1116,13 @@ where
1103 cmd.current_dir(dir); 1116 cmd.current_dir(dir);
1104 cmd.args(args); 1117 cmd.args(args);
1105 // using branch for PR https://github.com/rust-cli/rexpect/pull/103 to strip ansi escape codes 1118 // using branch for PR https://github.com/rust-cli/rexpect/pull/103 to strip ansi escape codes
1106 rexpect::session::spawn_with_options(cmd, Options { 1119 rexpect::session::spawn_with_options(
1107 timeout_ms: Some(timeout_ms), 1120 cmd,
1108 strip_ansi_escape_codes: true, 1121 Options {
1109 }) 1122 timeout_ms: Some(timeout_ms),
1123 strip_ansi_escape_codes: true,
1124 },
1125 )
1110 .context("spawning failed") 1126 .context("spawning failed")
1111} 1127}
1112 1128
@@ -1145,11 +1161,14 @@ pub fn get_proposal_branch_name(
1145 test_repo: &GitTestRepo, 1161 test_repo: &GitTestRepo,
1146 branch_name_in_event: &str, 1162 branch_name_in_event: &str,
1147) -> Result<String> { 1163) -> Result<String> {
1148 let events = block_on(get_events_from_cache(&test_repo.dir, vec![ 1164 let events = block_on(get_events_from_cache(
1149 nostr::Filter::default() 1165 &test_repo.dir,
1150 .kind(nostr_sdk::Kind::GitPatch) 1166 vec![
1151 .hashtag("root"), 1167 nostr::Filter::default()
1152 ]))?; 1168 .kind(nostr_sdk::Kind::GitPatch)
1169 .hashtag("root"),
1170 ],
1171 ))?;
1153 get_proposal_branch_name_from_events(&events, branch_name_in_event) 1172 get_proposal_branch_name_from_events(&events, branch_name_in_event)
1154} 1173}
1155 1174
@@ -1303,45 +1322,54 @@ pub fn cli_tester_create_proposal(
1303 create_and_populate_branch(test_repo, branch_name, prefix, false, None)?; 1322 create_and_populate_branch(test_repo, branch_name, prefix, false, None)?;
1304 std::thread::sleep(std::time::Duration::from_millis(1000)); 1323 std::thread::sleep(std::time::Duration::from_millis(1000));
1305 if let Some(in_reply_to) = in_reply_to { 1324 if let Some(in_reply_to) = in_reply_to {
1306 let mut p = CliTester::new_from_dir(&test_repo.dir, [ 1325 let mut p = CliTester::new_from_dir(
1307 "--nsec", 1326 &test_repo.dir,
1308 TEST_KEY_1_NSEC, 1327 [
1309 "--password", 1328 "--nsec",
1310 TEST_PASSWORD, 1329 TEST_KEY_1_NSEC,
1311 "--disable-cli-spinners", 1330 "--password",
1312 "send", 1331 TEST_PASSWORD,
1313 "HEAD~2", 1332 "--disable-cli-spinners",
1314 "--no-cover-letter", 1333 "send",
1315 "--in-reply-to", 1334 "HEAD~2",
1316 in_reply_to.as_str(), 1335 "--no-cover-letter",
1317 ]); 1336 "--in-reply-to",
1337 in_reply_to.as_str(),
1338 ],
1339 );
1318 p.expect_end_eventually()?; 1340 p.expect_end_eventually()?;
1319 } else if let Some((title, description)) = cover_letter_title_and_description { 1341 } else if let Some((title, description)) = cover_letter_title_and_description {
1320 let mut p = CliTester::new_from_dir(&test_repo.dir, [ 1342 let mut p = CliTester::new_from_dir(
1321 "--nsec", 1343 &test_repo.dir,
1322 TEST_KEY_1_NSEC, 1344 [
1323 "--password", 1345 "--nsec",
1324 TEST_PASSWORD, 1346 TEST_KEY_1_NSEC,
1325 "--disable-cli-spinners", 1347 "--password",
1326 "send", 1348 TEST_PASSWORD,
1327 "HEAD~2", 1349 "--disable-cli-spinners",
1328 "--title", 1350 "send",
1329 format!("\"{title}\"").as_str(), 1351 "HEAD~2",
1330 "--description", 1352 "--title",
1331 format!("\"{description}\"").as_str(), 1353 format!("\"{title}\"").as_str(),
1332 ]); 1354 "--description",
1355 format!("\"{description}\"").as_str(),
1356 ],
1357 );
1333 p.expect_end_eventually()?; 1358 p.expect_end_eventually()?;
1334 } else { 1359 } else {
1335 let mut p = CliTester::new_from_dir(&test_repo.dir, [ 1360 let mut p = CliTester::new_from_dir(
1336 "--nsec", 1361 &test_repo.dir,
1337 TEST_KEY_1_NSEC, 1362 [
1338 "--password", 1363 "--nsec",
1339 TEST_PASSWORD, 1364 TEST_KEY_1_NSEC,
1340 "--disable-cli-spinners", 1365 "--password",
1341 "send", 1366 TEST_PASSWORD,
1342 "HEAD~2", 1367 "--disable-cli-spinners",
1343 "--no-cover-letter", 1368 "send",
1344 ]); 1369 "HEAD~2",
1370 "--no-cover-letter",
1371 ],
1372 );
1345 p.expect_end_eventually()?; 1373 p.expect_end_eventually()?;
1346 } 1374 }
1347 Ok(()) 1375 Ok(())
@@ -1373,11 +1401,14 @@ pub fn use_ngit_list_to_download_and_checkout_proposal_branch(
1373 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]); 1401 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
1374 p.expect("fetching updates...\r\n")?; 1402 p.expect("fetching updates...\r\n")?;
1375 p.expect_eventually("\r\n")?; // some updates listed here 1403 p.expect_eventually("\r\n")?; // some updates listed here
1376 let mut c = p.expect_choice("all proposals", vec![ 1404 let mut c = p.expect_choice(
1377 format!("\"{PROPOSAL_TITLE_3}\""), 1405 "all proposals",
1378 format!("\"{PROPOSAL_TITLE_2}\""), 1406 vec![
1379 format!("\"{PROPOSAL_TITLE_1}\""), 1407 format!("\"{PROPOSAL_TITLE_3}\""),
1380 ])?; 1408 format!("\"{PROPOSAL_TITLE_2}\""),
1409 format!("\"{PROPOSAL_TITLE_1}\""),
1410 ],
1411 )?;
1381 c.succeeds_with( 1412 c.succeeds_with(
1382 if proposal_number == 3 { 1413 if proposal_number == 3 {
1383 0 1414 0
@@ -1389,12 +1420,15 @@ pub fn use_ngit_list_to_download_and_checkout_proposal_branch(
1389 true, 1420 true,
1390 None, 1421 None,
1391 )?; 1422 )?;
1392 let mut c = p.expect_choice("", vec![ 1423 let mut c = p.expect_choice(
1393 format!("create and checkout proposal branch (2 ahead 0 behind 'main')"), 1424 "",
1394 format!("apply to current branch with `git am`"), 1425 vec![
1395 format!("download to ./patches"), 1426 format!("create and checkout proposal branch (2 ahead 0 behind 'main')"),
1396 format!("back"), 1427 format!("apply to current branch with `git am`"),
1397 ])?; 1428 format!("download to ./patches"),
1429 format!("back"),
1430 ],
1431 )?;
1398 c.succeeds_with(0, true, Some(0))?; 1432 c.succeeds_with(0, true, Some(0))?;
1399 p.expect_end_eventually()?; 1433 p.expect_end_eventually()?;
1400 Ok(()) 1434 Ok(())
@@ -1466,9 +1500,10 @@ fn get_first_proposal_event_id() -> Result<nostr::EventId> {
1466 client.fetch_events( 1500 client.fetch_events(
1467 nostr::Filter::default() 1501 nostr::Filter::default()
1468 .kind(nostr::Kind::GitPatch) 1502 .kind(nostr::Kind::GitPatch)
1469 .custom_tags(nostr::SingleLetterTag::lowercase(nostr::Alphabet::T), vec![ 1503 .custom_tags(
1470 "root", 1504 nostr::SingleLetterTag::lowercase(nostr::Alphabet::T),
1471 ]), 1505 vec!["root"],
1506 ),
1472 Duration::from_millis(500), 1507 Duration::from_millis(500),
1473 ), 1508 ),
1474 )? 1509 )?
@@ -1496,15 +1531,18 @@ pub fn create_proposals_with_first_revised_and_repo_with_unrevised_proposal_chec
1496 1531
1497 amend_last_commit(&originating_repo, "add some ammended-commit.md")?; 1532 amend_last_commit(&originating_repo, "add some ammended-commit.md")?;
1498 1533
1499 let mut p = CliTester::new_from_dir(&originating_repo.dir, [ 1534 let mut p = CliTester::new_from_dir(
1500 "--nsec", 1535 &originating_repo.dir,
1501 TEST_KEY_1_NSEC, 1536 [
1502 "--password", 1537 "--nsec",
1503 TEST_PASSWORD, 1538 TEST_KEY_1_NSEC,
1504 "--disable-cli-spinners", 1539 "--password",
1505 "push", 1540 TEST_PASSWORD,
1506 "--force", 1541 "--disable-cli-spinners",
1507 ]); 1542 "push",
1543 "--force",
1544 ],
1545 );
1508 p.expect_end_eventually()?; 1546 p.expect_end_eventually()?;
1509 1547
1510 Ok((originating_repo, test_repo)) 1548 Ok((originating_repo, test_repo))
diff --git a/test_utils/src/relay.rs b/test_utils/src/relay.rs
index 14778d9..b14f532 100644
--- a/test_utils/src/relay.rs
+++ b/test_utils/src/relay.rs
@@ -161,9 +161,11 @@ impl<'a> Relay<'a> {
161 if let Some(listner) = self.req_listener { 161 if let Some(listner) = self.req_listener {
162 listner(self, client_id, subscription_id, vec![filter.clone()])?; 162 listner(self, client_id, subscription_id, vec![filter.clone()])?;
163 } else { 163 } else {
164 self.respond_standard_req(client_id, &subscription_id, &[ 164 self.respond_standard_req(
165 filter.clone() 165 client_id,
166 ])?; 166 &subscription_id,
167 &[filter.clone()],
168 )?;
167 // self.respond_eose(client_id, subscription_id)?; 169 // self.respond_eose(client_id, subscription_id)?;
168 } 170 }
169 // respond with events 171 // respond with events
diff --git a/tests/git_remote_nostr/push.rs b/tests/git_remote_nostr/push.rs
index 9f5f492..5912543 100644
--- a/tests/git_remote_nostr/push.rs
+++ b/tests/git_remote_nostr/push.rs
@@ -969,12 +969,10 @@ async fn proposal_three_way_merge_commit_pushed_to_main_leads_to_status_event_is
969 std::fs::write(git_repo.dir.join("new.md"), "some content")?; 969 std::fs::write(git_repo.dir.join("new.md"), "some content")?;
970 git_repo.stage_and_commit("new.md")?; 970 git_repo.stage_and_commit("new.md")?;
971 971
972 CliTester::new_git_with_remote_helper_from_dir(&git_repo.dir, [ 972 CliTester::new_git_with_remote_helper_from_dir(
973 "merge", 973 &git_repo.dir,
974 &branch_name, 974 ["merge", &branch_name, "-m", "proposal merge commit message"],
975 "-m", 975 )
976 "proposal merge commit message",
977 ])
978 .expect_end_eventually_and_print()?; 976 .expect_end_eventually_and_print()?;
979 977
980 let oid = git_repo.get_tip_of_local_branch("main")?; 978 let oid = git_repo.get_tip_of_local_branch("main")?;
@@ -1125,12 +1123,10 @@ async fn proposal_fast_forward_merge_commits_pushed_to_main_leads_to_status_even
1125 git_repo.checkout_remote_branch(&branch_name)?; 1123 git_repo.checkout_remote_branch(&branch_name)?;
1126 git_repo.checkout("refs/heads/main")?; 1124 git_repo.checkout("refs/heads/main")?;
1127 1125
1128 CliTester::new_git_with_remote_helper_from_dir(&git_repo.dir, [ 1126 CliTester::new_git_with_remote_helper_from_dir(
1129 "merge", 1127 &git_repo.dir,
1130 &branch_name, 1128 ["merge", &branch_name, "-m", "proposal merge commit message"],
1131 "-m", 1129 )
1132 "proposal merge commit message",
1133 ])
1134 .expect_end_eventually_and_print()?; 1130 .expect_end_eventually_and_print()?;
1135 1131
1136 let oid = git_repo.get_tip_of_local_branch("main")?; 1132 let oid = git_repo.get_tip_of_local_branch("main")?;
@@ -1784,12 +1780,10 @@ async fn push_new_pr_branch_creates_proposal() -> Result<()> {
1784 std::fs::write(git_repo.dir.join("new2.md"), "some content")?; 1780 std::fs::write(git_repo.dir.join("new2.md"), "some content")?;
1785 git_repo.stage_and_commit("new2.md")?; 1781 git_repo.stage_and_commit("new2.md")?;
1786 1782
1787 let mut p = CliTester::new_git_with_remote_helper_from_dir(&git_repo.dir, [ 1783 let mut p = CliTester::new_git_with_remote_helper_from_dir(
1788 "push", 1784 &git_repo.dir,
1789 "-u", 1785 ["push", "-u", "origin", branch_name],
1790 "origin", 1786 );
1791 branch_name,
1792 ]);
1793 cli_expect_nostr_fetch(&mut p)?; 1787 cli_expect_nostr_fetch(&mut p)?;
1794 p.expect(format!("fetching {source_path} ref list over filesystem...\r\n").as_str())?; 1788 p.expect(format!("fetching {source_path} ref list over filesystem...\r\n").as_str())?;
1795 p.expect("list: connecting...\r\n\r\r\r")?; 1789 p.expect("list: connecting...\r\n\r\r\r")?;
diff --git a/tests/ngit_init.rs b/tests/ngit_init.rs
index e49dbdd..1a23177 100644
--- a/tests/ngit_init.rs
+++ b/tests/ngit_init.rs
@@ -75,10 +75,14 @@ mod when_repo_not_previously_claimed {
75 8051, 75 8051,
76 None, 76 None,
77 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 77 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
78 relay.respond_events(client_id, &subscription_id, &vec![ 78 relay.respond_events(
79 generate_test_key_1_metadata_event("fred"), 79 client_id,
80 generate_test_key_1_relay_list_event(), 80 &subscription_id,
81 ])?; 81 &vec![
82 generate_test_key_1_metadata_event("fred"),
83 generate_test_key_1_relay_list_event(),
84 ],
85 )?;
82 Ok(()) 86 Ok(())
83 }), 87 }),
84 ), 88 ),
@@ -197,10 +201,14 @@ mod when_repo_not_previously_claimed {
197 8051, 201 8051,
198 None, 202 None,
199 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 203 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
200 relay.respond_events(client_id, &subscription_id, &vec![ 204 relay.respond_events(
201 generate_test_key_1_metadata_event("fred"), 205 client_id,
202 generate_test_key_1_relay_list_event(), 206 &subscription_id,
203 ])?; 207 &vec![
208 generate_test_key_1_metadata_event("fred"),
209 generate_test_key_1_relay_list_event(),
210 ],
211 )?;
204 Ok(()) 212 Ok(())
205 }), 213 }),
206 ), 214 ),
@@ -454,10 +462,14 @@ mod when_repo_not_previously_claimed {
454 8051, 462 8051,
455 None, 463 None,
456 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 464 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
457 relay.respond_events(client_id, &subscription_id, &vec![ 465 relay.respond_events(
458 generate_test_key_1_metadata_event("fred"), 466 client_id,
459 generate_test_key_1_relay_list_event(), 467 &subscription_id,
460 ])?; 468 &vec![
469 generate_test_key_1_metadata_event("fred"),
470 generate_test_key_1_relay_list_event(),
471 ],
472 )?;
461 Ok(()) 473 Ok(())
462 }), 474 }),
463 ), 475 ),
diff --git a/tests/ngit_list.rs b/tests/ngit_list.rs
index c8f761a..0547ad4 100644
--- a/tests/ngit_list.rs
+++ b/tests/ngit_list.rs
@@ -201,11 +201,14 @@ mod when_main_branch_is_uptodate {
201 201
202 p.expect("fetching updates...\r\n")?; 202 p.expect("fetching updates...\r\n")?;
203 p.expect_eventually("\r\n")?; // some updates listed here 203 p.expect_eventually("\r\n")?; // some updates listed here
204 let mut c = p.expect_choice("all proposals", vec![ 204 let mut c = p.expect_choice(
205 format!("\"{PROPOSAL_TITLE_3}\""), 205 "all proposals",
206 format!("\"{PROPOSAL_TITLE_2}\""), 206 vec![
207 format!("\"{PROPOSAL_TITLE_1}\""), 207 format!("\"{PROPOSAL_TITLE_3}\""),
208 ])?; 208 format!("\"{PROPOSAL_TITLE_2}\""),
209 format!("\"{PROPOSAL_TITLE_1}\""),
210 ],
211 )?;
209 c.succeeds_with(2, true, None)?; 212 c.succeeds_with(2, true, None)?;
210 let mut c = p.expect_choice("", vec![ 213 let mut c = p.expect_choice("", vec![
211 format!( 214 format!(
@@ -317,11 +320,14 @@ mod when_main_branch_is_uptodate {
317 320
318 p.expect("fetching updates...\r\n")?; 321 p.expect("fetching updates...\r\n")?;
319 p.expect_eventually("\r\n")?; // some updates listed here 322 p.expect_eventually("\r\n")?; // some updates listed here
320 let mut c = p.expect_choice("all proposals", vec![ 323 let mut c = p.expect_choice(
321 format!("\"{PROPOSAL_TITLE_3}\""), 324 "all proposals",
322 format!("\"{PROPOSAL_TITLE_2}\""), 325 vec![
323 format!("\"{PROPOSAL_TITLE_1}\""), 326 format!("\"{PROPOSAL_TITLE_3}\""),
324 ])?; 327 format!("\"{PROPOSAL_TITLE_2}\""),
328 format!("\"{PROPOSAL_TITLE_1}\""),
329 ],
330 )?;
325 c.succeeds_with(0, true, None)?; 331 c.succeeds_with(0, true, None)?;
326 let mut c = p.expect_choice("", vec![ 332 let mut c = p.expect_choice("", vec![
327 format!( 333 format!(
@@ -436,12 +442,15 @@ mod when_main_branch_is_uptodate {
436 442
437 p.expect("fetching updates...\r\n")?; 443 p.expect("fetching updates...\r\n")?;
438 p.expect_eventually("\r\n")?; // some updates listed here 444 p.expect_eventually("\r\n")?; // some updates listed here
439 let mut c = p.expect_choice("all proposals", vec![ 445 let mut c = p.expect_choice(
440 format!("add d3.md"), // commit msg title 446 "all proposals",
441 format!("\"{PROPOSAL_TITLE_3}\""), 447 vec![
442 format!("\"{PROPOSAL_TITLE_2}\""), 448 format!("add d3.md"), // commit msg title
443 format!("\"{PROPOSAL_TITLE_1}\""), 449 format!("\"{PROPOSAL_TITLE_3}\""),
444 ])?; 450 format!("\"{PROPOSAL_TITLE_2}\""),
451 format!("\"{PROPOSAL_TITLE_1}\""),
452 ],
453 )?;
445 c.succeeds_with(0, true, None)?; 454 c.succeeds_with(0, true, None)?;
446 let mut c = p.expect_choice("", vec![ 455 let mut c = p.expect_choice("", vec![
447 format!( 456 format!(
@@ -511,12 +520,15 @@ mod when_main_branch_is_uptodate {
511 520
512 p.expect("fetching updates...\r\n")?; 521 p.expect("fetching updates...\r\n")?;
513 p.expect_eventually("\r\n")?; // some updates listed here 522 p.expect_eventually("\r\n")?; // some updates listed here
514 let mut c = p.expect_choice("all proposals", vec![ 523 let mut c = p.expect_choice(
515 format!("add d3.md"), // commit msg title 524 "all proposals",
516 format!("\"{PROPOSAL_TITLE_3}\""), 525 vec![
517 format!("\"{PROPOSAL_TITLE_2}\""), 526 format!("add d3.md"), // commit msg title
518 format!("\"{PROPOSAL_TITLE_1}\""), 527 format!("\"{PROPOSAL_TITLE_3}\""),
519 ])?; 528 format!("\"{PROPOSAL_TITLE_2}\""),
529 format!("\"{PROPOSAL_TITLE_1}\""),
530 ],
531 )?;
520 c.succeeds_with(0, true, None)?; 532 c.succeeds_with(0, true, None)?;
521 let mut c = p.expect_choice("", vec![ 533 let mut c = p.expect_choice("", vec![
522 format!( 534 format!(
@@ -630,11 +642,14 @@ mod when_main_branch_is_uptodate {
630 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]); 642 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
631 p.expect("fetching updates...\r\n")?; 643 p.expect("fetching updates...\r\n")?;
632 p.expect_eventually("\r\n")?; // some updates listed here 644 p.expect_eventually("\r\n")?; // some updates listed here
633 let mut c = p.expect_choice("all proposals", vec![ 645 let mut c = p.expect_choice(
634 format!("\"{PROPOSAL_TITLE_3}\""), 646 "all proposals",
635 format!("\"{PROPOSAL_TITLE_2}\""), 647 vec![
636 format!("\"{PROPOSAL_TITLE_1}\""), 648 format!("\"{PROPOSAL_TITLE_3}\""),
637 ])?; 649 format!("\"{PROPOSAL_TITLE_2}\""),
650 format!("\"{PROPOSAL_TITLE_1}\""),
651 ],
652 )?;
638 c.succeeds_with(2, true, None)?; 653 c.succeeds_with(2, true, None)?;
639 let mut c = p.expect_choice("", vec![ 654 let mut c = p.expect_choice("", vec![
640 format!( 655 format!(
@@ -652,18 +667,24 @@ mod when_main_branch_is_uptodate {
652 p = CliTester::new_from_dir(&test_repo.dir, ["list"]); 667 p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
653 p.expect("fetching updates...\r\n")?; 668 p.expect("fetching updates...\r\n")?;
654 p.expect_eventually("\r\n")?; // some updates listed here 669 p.expect_eventually("\r\n")?; // some updates listed here
655 let mut c = p.expect_choice("all proposals", vec![ 670 let mut c = p.expect_choice(
656 format!("\"{PROPOSAL_TITLE_3}\""), 671 "all proposals",
657 format!("\"{PROPOSAL_TITLE_2}\""), 672 vec![
658 format!("\"{PROPOSAL_TITLE_1}\""), 673 format!("\"{PROPOSAL_TITLE_3}\""),
659 ])?; 674 format!("\"{PROPOSAL_TITLE_2}\""),
675 format!("\"{PROPOSAL_TITLE_1}\""),
676 ],
677 )?;
660 c.succeeds_with(2, true, None)?; 678 c.succeeds_with(2, true, None)?;
661 let mut c = p.expect_choice("", vec![ 679 let mut c = p.expect_choice(
662 format!("checkout proposal branch (2 ahead 0 behind 'main')"), 680 "",
663 format!("apply to current branch with `git am`"), 681 vec![
664 format!("download to ./patches"), 682 format!("checkout proposal branch (2 ahead 0 behind 'main')"),
665 format!("back"), 683 format!("apply to current branch with `git am`"),
666 ])?; 684 format!("download to ./patches"),
685 format!("back"),
686 ],
687 )?;
667 c.succeeds_with(0, true, Some(0))?; 688 c.succeeds_with(0, true, Some(0))?;
668 p.expect_end_eventually_and_print()?; 689 p.expect_end_eventually_and_print()?;
669 690
@@ -717,11 +738,14 @@ mod when_main_branch_is_uptodate {
717 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]); 738 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
718 p.expect("fetching updates...\r\n")?; 739 p.expect("fetching updates...\r\n")?;
719 p.expect_eventually("\r\n")?; // some updates listed here 740 p.expect_eventually("\r\n")?; // some updates listed here
720 let mut c = p.expect_choice("all proposals", vec![ 741 let mut c = p.expect_choice(
721 format!("\"{PROPOSAL_TITLE_3}\""), 742 "all proposals",
722 format!("\"{PROPOSAL_TITLE_2}\""), 743 vec![
723 format!("\"{PROPOSAL_TITLE_1}\""), 744 format!("\"{PROPOSAL_TITLE_3}\""),
724 ])?; 745 format!("\"{PROPOSAL_TITLE_2}\""),
746 format!("\"{PROPOSAL_TITLE_1}\""),
747 ],
748 )?;
725 c.succeeds_with(2, true, None)?; 749 c.succeeds_with(2, true, None)?;
726 let mut c = p.expect_choice("", vec![ 750 let mut c = p.expect_choice("", vec![
727 format!( 751 format!(
@@ -739,18 +763,24 @@ mod when_main_branch_is_uptodate {
739 p = CliTester::new_from_dir(&test_repo.dir, ["list"]); 763 p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
740 p.expect("fetching updates...\r\n")?; 764 p.expect("fetching updates...\r\n")?;
741 p.expect_eventually("\r\n")?; // some updates listed here 765 p.expect_eventually("\r\n")?; // some updates listed here
742 let mut c = p.expect_choice("all proposals", vec![ 766 let mut c = p.expect_choice(
743 format!("\"{PROPOSAL_TITLE_3}\""), 767 "all proposals",
744 format!("\"{PROPOSAL_TITLE_2}\""), 768 vec![
745 format!("\"{PROPOSAL_TITLE_1}\""), 769 format!("\"{PROPOSAL_TITLE_3}\""),
746 ])?; 770 format!("\"{PROPOSAL_TITLE_2}\""),
771 format!("\"{PROPOSAL_TITLE_1}\""),
772 ],
773 )?;
747 c.succeeds_with(2, true, None)?; 774 c.succeeds_with(2, true, None)?;
748 let mut c = p.expect_choice("", vec![ 775 let mut c = p.expect_choice(
749 format!("checkout proposal branch (2 ahead 0 behind 'main')"), 776 "",
750 format!("apply to current branch with `git am`"), 777 vec![
751 format!("download to ./patches"), 778 format!("checkout proposal branch (2 ahead 0 behind 'main')"),
752 format!("back"), 779 format!("apply to current branch with `git am`"),
753 ])?; 780 format!("download to ./patches"),
781 format!("back"),
782 ],
783 )?;
754 c.succeeds_with(0, true, Some(0))?; 784 c.succeeds_with(0, true, Some(0))?;
755 p.expect(format!( 785 p.expect(format!(
756 "checked out proposal as 'pr/{FEATURE_BRANCH_NAME_1}(", 786 "checked out proposal as 'pr/{FEATURE_BRANCH_NAME_1}(",
@@ -823,18 +853,24 @@ mod when_main_branch_is_uptodate {
823 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]); 853 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
824 p.expect("fetching updates...\r\n")?; 854 p.expect("fetching updates...\r\n")?;
825 p.expect_eventually("\r\n")?; // some updates listed here 855 p.expect_eventually("\r\n")?; // some updates listed here
826 let mut c = p.expect_choice("all proposals", vec![ 856 let mut c = p.expect_choice(
827 format!("\"{PROPOSAL_TITLE_3}\""), 857 "all proposals",
828 format!("\"{PROPOSAL_TITLE_2}\""), 858 vec![
829 format!("\"{PROPOSAL_TITLE_1}\""), 859 format!("\"{PROPOSAL_TITLE_3}\""),
830 ])?; 860 format!("\"{PROPOSAL_TITLE_2}\""),
861 format!("\"{PROPOSAL_TITLE_1}\""),
862 ],
863 )?;
831 c.succeeds_with(2, true, None)?; 864 c.succeeds_with(2, true, None)?;
832 let mut c = p.expect_choice("", vec![ 865 let mut c = p.expect_choice(
833 format!("checkout proposal branch and apply 1 appendments"), 866 "",
834 format!("apply to current branch with `git am`"), 867 vec![
835 format!("download to ./patches"), 868 format!("checkout proposal branch and apply 1 appendments"),
836 format!("back"), 869 format!("apply to current branch with `git am`"),
837 ])?; 870 format!("download to ./patches"),
871 format!("back"),
872 ],
873 )?;
838 c.succeeds_with(0, true, Some(0))?; 874 c.succeeds_with(0, true, Some(0))?;
839 p.expect("checked out proposal branch and applied 1 appendments (2 ahead 0 behind 'main')\r\n")?; 875 p.expect("checked out proposal branch and applied 1 appendments (2 ahead 0 behind 'main')\r\n")?;
840 p.expect_end()?; 876 p.expect_end()?;
@@ -893,18 +929,24 @@ mod when_main_branch_is_uptodate {
893 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]); 929 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
894 p.expect("fetching updates...\r\n")?; 930 p.expect("fetching updates...\r\n")?;
895 p.expect_eventually("\r\n")?; // some updates listed here 931 p.expect_eventually("\r\n")?; // some updates listed here
896 let mut c = p.expect_choice("all proposals", vec![ 932 let mut c = p.expect_choice(
897 format!("\"{PROPOSAL_TITLE_3}\""), 933 "all proposals",
898 format!("\"{PROPOSAL_TITLE_2}\""), 934 vec![
899 format!("\"{PROPOSAL_TITLE_1}\""), 935 format!("\"{PROPOSAL_TITLE_3}\""),
900 ])?; 936 format!("\"{PROPOSAL_TITLE_2}\""),
937 format!("\"{PROPOSAL_TITLE_1}\""),
938 ],
939 )?;
901 c.succeeds_with(2, true, None)?; 940 c.succeeds_with(2, true, None)?;
902 let mut c = p.expect_choice("", vec![ 941 let mut c = p.expect_choice(
903 format!("checkout proposal branch and apply 1 appendments"), 942 "",
904 format!("apply to current branch with `git am`"), 943 vec![
905 format!("download to ./patches"), 944 format!("checkout proposal branch and apply 1 appendments"),
906 format!("back"), 945 format!("apply to current branch with `git am`"),
907 ])?; 946 format!("download to ./patches"),
947 format!("back"),
948 ],
949 )?;
908 c.succeeds_with(0, true, Some(0))?; 950 c.succeeds_with(0, true, Some(0))?;
909 p.expect("checked out proposal branch and applied 1 appendments (2 ahead 0 behind 'main')\r\n")?; 951 p.expect("checked out proposal branch and applied 1 appendments (2 ahead 0 behind 'main')\r\n")?;
910 p.expect_end()?; 952 p.expect_end()?;
@@ -1000,21 +1042,29 @@ mod when_main_branch_is_uptodate {
1000 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]); 1042 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
1001 p.expect("fetching updates...\r\n")?; 1043 p.expect("fetching updates...\r\n")?;
1002 p.expect_eventually("\r\n")?; // some updates listed here 1044 p.expect_eventually("\r\n")?; // some updates listed here
1003 let mut c = p.expect_choice("all proposals", vec![ 1045 let mut c = p.expect_choice(
1004 format!("\"{PROPOSAL_TITLE_3}\""), 1046 "all proposals",
1005 format!("\"{PROPOSAL_TITLE_2}\""), 1047 vec![
1006 format!("\"{PROPOSAL_TITLE_1}\""), 1048 format!("\"{PROPOSAL_TITLE_3}\""),
1007 ])?; 1049 format!("\"{PROPOSAL_TITLE_2}\""),
1050 format!("\"{PROPOSAL_TITLE_1}\""),
1051 ],
1052 )?;
1008 c.succeeds_with(2, true, None)?; 1053 c.succeeds_with(2, true, None)?;
1009 p.expect_eventually("--force`\r\n")?; 1054 p.expect_eventually("--force`\r\n")?;
1010 1055
1011 let mut c = p.expect_choice("", vec![ 1056 let mut c = p.expect_choice(
1012 format!("checkout local branch with unpublished changes"), 1057 "",
1013 format!("discard unpublished changes and checkout new revision"), 1058 vec![
1014 format!("apply to current branch with `git am`"), 1059 format!("checkout local branch with unpublished changes"),
1015 format!("download to ./patches"), 1060 format!(
1016 "back".to_string(), 1061 "discard unpublished changes and checkout new revision"
1017 ])?; 1062 ),
1063 format!("apply to current branch with `git am`"),
1064 format!("download to ./patches"),
1065 "back".to_string(),
1066 ],
1067 )?;
1018 c.succeeds_with(1, true, Some(0))?; 1068 c.succeeds_with(1, true, Some(0))?;
1019 1069
1020 p.expect_end_eventually_and_print()?; 1070 p.expect_end_eventually_and_print()?;
@@ -1071,11 +1121,14 @@ mod when_main_branch_is_uptodate {
1071 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]); 1121 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
1072 p.expect("fetching updates...\r\n")?; 1122 p.expect("fetching updates...\r\n")?;
1073 p.expect_eventually("\r\n")?; // some updates listed here 1123 p.expect_eventually("\r\n")?; // some updates listed here
1074 let mut c = p.expect_choice("all proposals", vec![ 1124 let mut c = p.expect_choice(
1075 format!("\"{PROPOSAL_TITLE_3}\""), 1125 "all proposals",
1076 format!("\"{PROPOSAL_TITLE_2}\""), 1126 vec![
1077 format!("\"{PROPOSAL_TITLE_1}\""), 1127 format!("\"{PROPOSAL_TITLE_3}\""),
1078 ])?; 1128 format!("\"{PROPOSAL_TITLE_2}\""),
1129 format!("\"{PROPOSAL_TITLE_1}\""),
1130 ],
1131 )?;
1079 c.succeeds_with(2, true, None)?; 1132 c.succeeds_with(2, true, None)?;
1080 p.expect("you have an amended/rebase version the proposal that is unpublished\r\n")?; 1133 p.expect("you have an amended/rebase version the proposal that is unpublished\r\n")?;
1081 p.expect("you have previously applied the latest version of the proposal (2 ahead 0 behind 'main') but your local proposal branch has amended or rebased it (2 ahead 0 behind 'main')\r\n")?; 1134 p.expect("you have previously applied the latest version of the proposal (2 ahead 0 behind 'main') but your local proposal branch has amended or rebased it (2 ahead 0 behind 'main')\r\n")?;
@@ -1084,13 +1137,18 @@ mod when_main_branch_is_uptodate {
1084 p.expect(" 2) run `ngit list` and checkout the latest published version of this proposal\r\n")?; 1137 p.expect(" 2) run `ngit list` and checkout the latest published version of this proposal\r\n")?;
1085 p.expect("if you are confident in your changes consider running `ngit push --force`\r\n")?; 1138 p.expect("if you are confident in your changes consider running `ngit push --force`\r\n")?;
1086 1139
1087 let mut c = p.expect_choice("", vec![ 1140 let mut c = p.expect_choice(
1088 format!("checkout local branch with unpublished changes"), 1141 "",
1089 format!("discard unpublished changes and checkout new revision"), 1142 vec![
1090 format!("apply to current branch with `git am`"), 1143 format!("checkout local branch with unpublished changes"),
1091 format!("download to ./patches"), 1144 format!(
1092 "back".to_string(), 1145 "discard unpublished changes and checkout new revision"
1093 ])?; 1146 ),
1147 format!("apply to current branch with `git am`"),
1148 format!("download to ./patches"),
1149 "back".to_string(),
1150 ],
1151 )?;
1094 c.succeeds_with(1, true, Some(1))?; 1152 c.succeeds_with(1, true, Some(1))?;
1095 p.expect_end_with("checked out latest version of proposal (2 ahead 0 behind 'main'), replacing unpublished version (2 ahead 0 behind 'main')\r\n")?; 1153 p.expect_end_with("checked out latest version of proposal (2 ahead 0 behind 'main'), replacing unpublished version (2 ahead 0 behind 'main')\r\n")?;
1096 1154
@@ -1168,20 +1226,26 @@ mod when_main_branch_is_uptodate {
1168 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]); 1226 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
1169 p.expect("fetching updates...\r\n")?; 1227 p.expect("fetching updates...\r\n")?;
1170 p.expect_eventually("\r\n")?; // some updates listed here 1228 p.expect_eventually("\r\n")?; // some updates listed here
1171 let mut c = p.expect_choice("all proposals", vec![ 1229 let mut c = p.expect_choice(
1172 format!("\"{PROPOSAL_TITLE_3}\""), 1230 "all proposals",
1173 format!("\"{PROPOSAL_TITLE_2}\""), 1231 vec![
1174 format!("\"{PROPOSAL_TITLE_1}\""), 1232 format!("\"{PROPOSAL_TITLE_3}\""),
1175 ])?; 1233 format!("\"{PROPOSAL_TITLE_2}\""),
1234 format!("\"{PROPOSAL_TITLE_1}\""),
1235 ],
1236 )?;
1176 c.succeeds_with(2, true, None)?; 1237 c.succeeds_with(2, true, None)?;
1177 p.expect( 1238 p.expect(
1178 "local proposal branch exists with 1 unpublished commits on top of the most up-to-date version of the proposal (3 ahead 0 behind 'main')\r\n", 1239 "local proposal branch exists with 1 unpublished commits on top of the most up-to-date version of the proposal (3 ahead 0 behind 'main')\r\n",
1179 )?; 1240 )?;
1180 1241
1181 let mut c = p.expect_choice("", vec![ 1242 let mut c = p.expect_choice(
1182 format!("checkout proposal branch with 1 unpublished commits"), 1243 "",
1183 format!("back"), 1244 vec![
1184 ])?; 1245 format!("checkout proposal branch with 1 unpublished commits"),
1246 format!("back"),
1247 ],
1248 )?;
1185 c.succeeds_with(0, true, Some(0))?; 1249 c.succeeds_with(0, true, Some(0))?;
1186 p.expect("checked out proposal branch with 1 unpublished commits (3 ahead 0 behind 'main')\r\n")?; 1250 p.expect("checked out proposal branch with 1 unpublished commits (3 ahead 0 behind 'main')\r\n")?;
1187 p.expect_end()?; 1251 p.expect_end()?;
@@ -1244,20 +1308,26 @@ mod when_main_branch_is_uptodate {
1244 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]); 1308 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
1245 p.expect("fetching updates...\r\n")?; 1309 p.expect("fetching updates...\r\n")?;
1246 p.expect_eventually("\r\n")?; // some updates listed here 1310 p.expect_eventually("\r\n")?; // some updates listed here
1247 let mut c = p.expect_choice("all proposals", vec![ 1311 let mut c = p.expect_choice(
1248 format!("\"{PROPOSAL_TITLE_3}\""), 1312 "all proposals",
1249 format!("\"{PROPOSAL_TITLE_2}\""), 1313 vec![
1250 format!("\"{PROPOSAL_TITLE_1}\""), 1314 format!("\"{PROPOSAL_TITLE_3}\""),
1251 ])?; 1315 format!("\"{PROPOSAL_TITLE_2}\""),
1316 format!("\"{PROPOSAL_TITLE_1}\""),
1317 ],
1318 )?;
1252 c.succeeds_with(2, true, None)?; 1319 c.succeeds_with(2, true, None)?;
1253 p.expect( 1320 p.expect(
1254 "local proposal branch exists with 1 unpublished commits on top of the most up-to-date version of the proposal (3 ahead 0 behind 'main')\r\n", 1321 "local proposal branch exists with 1 unpublished commits on top of the most up-to-date version of the proposal (3 ahead 0 behind 'main')\r\n",
1255 )?; 1322 )?;
1256 1323
1257 let mut c = p.expect_choice("", vec![ 1324 let mut c = p.expect_choice(
1258 format!("checkout proposal branch with 1 unpublished commits"), 1325 "",
1259 format!("back"), 1326 vec![
1260 ])?; 1327 format!("checkout proposal branch with 1 unpublished commits"),
1328 format!("back"),
1329 ],
1330 )?;
1261 c.succeeds_with(0, true, Some(0))?; 1331 c.succeeds_with(0, true, Some(0))?;
1262 p.expect("checked out proposal branch with 1 unpublished commits (3 ahead 0 behind 'main')\r\n")?; 1332 p.expect("checked out proposal branch with 1 unpublished commits (3 ahead 0 behind 'main')\r\n")?;
1263 p.expect_end()?; 1333 p.expect_end()?;
@@ -1340,20 +1410,26 @@ mod when_main_branch_is_uptodate {
1340 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]); 1410 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
1341 p.expect("fetching updates...\r\n")?; 1411 p.expect("fetching updates...\r\n")?;
1342 p.expect_eventually("\r\n")?; // some updates listed here 1412 p.expect_eventually("\r\n")?; // some updates listed here
1343 let mut c = p.expect_choice("all proposals", vec![ 1413 let mut c = p.expect_choice(
1344 format!("\"{PROPOSAL_TITLE_3}\""), 1414 "all proposals",
1345 format!("\"{PROPOSAL_TITLE_2}\""), 1415 vec![
1346 format!("\"{PROPOSAL_TITLE_1}\""), 1416 format!("\"{PROPOSAL_TITLE_3}\""),
1347 ])?; 1417 format!("\"{PROPOSAL_TITLE_2}\""),
1418 format!("\"{PROPOSAL_TITLE_1}\""),
1419 ],
1420 )?;
1348 c.succeeds_with(2, true, None)?; 1421 c.succeeds_with(2, true, None)?;
1349 p.expect("updated proposal available (2 ahead 0 behind 'main'). existing version is 2 ahead 1 behind 'main'\r\n")?; 1422 p.expect("updated proposal available (2 ahead 0 behind 'main'). existing version is 2 ahead 1 behind 'main'\r\n")?;
1350 let mut c = p.expect_choice("", vec![ 1423 let mut c = p.expect_choice(
1351 format!("checkout and overwrite existing proposal branch"), 1424 "",
1352 format!("checkout existing outdated proposal branch"), 1425 vec![
1353 format!("apply to current branch with `git am`"), 1426 format!("checkout and overwrite existing proposal branch"),
1354 format!("download to ./patches"), 1427 format!("checkout existing outdated proposal branch"),
1355 format!("back"), 1428 format!("apply to current branch with `git am`"),
1356 ])?; 1429 format!("download to ./patches"),
1430 format!("back"),
1431 ],
1432 )?;
1357 c.succeeds_with(0, true, Some(0))?; 1433 c.succeeds_with(0, true, Some(0))?;
1358 p.expect("checked out new version of proposal (2 ahead 0 behind 'main'), replacing old version (2 ahead 1 behind 'main')\r\n")?; 1434 p.expect("checked out new version of proposal (2 ahead 0 behind 'main'), replacing old version (2 ahead 1 behind 'main')\r\n")?;
1359 p.expect_end()?; 1435 p.expect_end()?;
@@ -1407,20 +1483,26 @@ mod when_main_branch_is_uptodate {
1407 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]); 1483 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
1408 p.expect("fetching updates...\r\n")?; 1484 p.expect("fetching updates...\r\n")?;
1409 p.expect_eventually("\r\n")?; // some updates listed here 1485 p.expect_eventually("\r\n")?; // some updates listed here
1410 let mut c = p.expect_choice("all proposals", vec![ 1486 let mut c = p.expect_choice(
1411 format!("\"{PROPOSAL_TITLE_3}\""), 1487 "all proposals",
1412 format!("\"{PROPOSAL_TITLE_2}\""), 1488 vec![
1413 format!("\"{PROPOSAL_TITLE_1}\""), 1489 format!("\"{PROPOSAL_TITLE_3}\""),
1414 ])?; 1490 format!("\"{PROPOSAL_TITLE_2}\""),
1491 format!("\"{PROPOSAL_TITLE_1}\""),
1492 ],
1493 )?;
1415 c.succeeds_with(2, true, None)?; 1494 c.succeeds_with(2, true, None)?;
1416 p.expect("updated proposal available (2 ahead 0 behind 'main'). existing version is 2 ahead 1 behind 'main'\r\n")?; 1495 p.expect("updated proposal available (2 ahead 0 behind 'main'). existing version is 2 ahead 1 behind 'main'\r\n")?;
1417 let mut c = p.expect_choice("", vec![ 1496 let mut c = p.expect_choice(
1418 format!("checkout and overwrite existing proposal branch"), 1497 "",
1419 format!("checkout existing outdated proposal branch"), 1498 vec![
1420 format!("apply to current branch with `git am`"), 1499 format!("checkout and overwrite existing proposal branch"),
1421 format!("download to ./patches"), 1500 format!("checkout existing outdated proposal branch"),
1422 format!("back"), 1501 format!("apply to current branch with `git am`"),
1423 ])?; 1502 format!("download to ./patches"),
1503 format!("back"),
1504 ],
1505 )?;
1424 c.succeeds_with(0, true, Some(0))?; 1506 c.succeeds_with(0, true, Some(0))?;
1425 p.expect("checked out new version of proposal (2 ahead 0 behind 'main'), replacing old version (2 ahead 1 behind 'main')\r\n")?; 1507 p.expect("checked out new version of proposal (2 ahead 0 behind 'main'), replacing old version (2 ahead 1 behind 'main')\r\n")?;
1426 p.expect_end()?; 1508 p.expect_end()?;
diff --git a/tests/ngit_login.rs b/tests/ngit_login.rs
index 09e40f1..9e708dc 100644
--- a/tests/ngit_login.rs
+++ b/tests/ngit_login.rs
@@ -6,21 +6,27 @@ use test_utils::*;
6static EXPECTED_NSEC_PROMPT: &str = "nsec"; 6static EXPECTED_NSEC_PROMPT: &str = "nsec";
7 7
8fn show_first_time_login_choices(p: &mut CliTester) -> Result<CliTesterChoicePrompt> { 8fn show_first_time_login_choices(p: &mut CliTester) -> Result<CliTesterChoicePrompt> {
9 p.expect_choice("login to nostr", vec![ 9 p.expect_choice(
10 "secret key (nsec / ncryptsec)".to_string(), 10 "login to nostr",
11 "nostr connect (remote signer)".to_string(), 11 vec![
12 "create account".to_string(), 12 "secret key (nsec / ncryptsec)".to_string(),
13 "help".to_string(), 13 "nostr connect (remote signer)".to_string(),
14 ]) 14 "create account".to_string(),
15 "help".to_string(),
16 ],
17 )
15} 18}
16 19
17fn first_time_login_choices_succeeds_with_nsec(p: &mut CliTester, nsec: &str) -> Result<()> { 20fn first_time_login_choices_succeeds_with_nsec(p: &mut CliTester, nsec: &str) -> Result<()> {
18 p.expect_choice("login to nostr", vec![ 21 p.expect_choice(
19 "secret key (nsec / ncryptsec)".to_string(), 22 "login to nostr",
20 "nostr connect (remote signer)".to_string(), 23 vec![
21 "create account".to_string(), 24 "secret key (nsec / ncryptsec)".to_string(),
22 "help".to_string(), 25 "nostr connect (remote signer)".to_string(),
23 ])? 26 "create account".to_string(),
27 "help".to_string(),
28 ],
29 )?
24 .succeeds_with(0, false, Some(0))?; 30 .succeeds_with(0, false, Some(0))?;
25 31
26 p.expect_input(EXPECTED_NSEC_PROMPT)? 32 p.expect_input(EXPECTED_NSEC_PROMPT)?
@@ -129,17 +135,25 @@ mod with_relays {
129 async fn when_latest_metadata_and_relay_list_on_all_relays() -> Result<()> { 135 async fn when_latest_metadata_and_relay_list_on_all_relays() -> Result<()> {
130 run_test_displays_correct_name( 136 run_test_displays_correct_name(
131 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 137 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
132 relay.respond_events(client_id, &subscription_id, &vec![ 138 relay.respond_events(
133 generate_test_key_1_metadata_event("fred"), 139 client_id,
134 generate_test_key_1_relay_list_event_same_as_fallback(), 140 &subscription_id,
135 ])?; 141 &vec![
142 generate_test_key_1_metadata_event("fred"),
143 generate_test_key_1_relay_list_event_same_as_fallback(),
144 ],
145 )?;
136 Ok(()) 146 Ok(())
137 }), 147 }),
138 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 148 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
139 relay.respond_events(client_id, &subscription_id, &vec![ 149 relay.respond_events(
140 generate_test_key_1_metadata_event("fred"), 150 client_id,
141 generate_test_key_1_relay_list_event_same_as_fallback(), 151 &subscription_id,
142 ])?; 152 &vec![
153 generate_test_key_1_metadata_event("fred"),
154 generate_test_key_1_relay_list_event_same_as_fallback(),
155 ],
156 )?;
143 Ok(()) 157 Ok(())
144 }), 158 }),
145 ) 159 )
@@ -154,14 +168,18 @@ mod with_relays {
154 async fn when_metadata_contains_only_display_name() -> Result<()> { 168 async fn when_metadata_contains_only_display_name() -> Result<()> {
155 run_test_displays_correct_name( 169 run_test_displays_correct_name(
156 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 170 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
157 relay.respond_events(client_id, &subscription_id, &vec![ 171 relay.respond_events(
158 nostr::event::EventBuilder::metadata( 172 client_id,
159 &nostr::Metadata::new().display_name("fred"), 173 &subscription_id,
160 ) 174 &vec![
161 .sign_with_keys(&TEST_KEY_1_KEYS) 175 nostr::event::EventBuilder::metadata(
162 .unwrap(), 176 &nostr::Metadata::new().display_name("fred"),
163 generate_test_key_1_relay_list_event_same_as_fallback(), 177 )
164 ])?; 178 .sign_with_keys(&TEST_KEY_1_KEYS)
179 .unwrap(),
180 generate_test_key_1_relay_list_event_same_as_fallback(),
181 ],
182 )?;
165 Ok(()) 183 Ok(())
166 }), 184 }),
167 None, 185 None,
@@ -187,14 +205,19 @@ mod with_relays {
187 205
188 run_test_displays_correct_name( 206 run_test_displays_correct_name(
189 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 207 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
190 relay.respond_events(client_id, &subscription_id, &vec![ 208 relay.respond_events(
191 nostr::event::EventBuilder::metadata( 209 client_id,
192 &nostr::Metadata::new().custom_field("displayName", "fred"), 210 &subscription_id,
193 ) 211 &vec![
194 .sign_with_keys(&TEST_KEY_1_KEYS) 212 nostr::event::EventBuilder::metadata(
195 .unwrap(), 213 &nostr::Metadata::new()
196 generate_test_key_1_relay_list_event_same_as_fallback(), 214 .custom_field("displayName", "fred"),
197 ])?; 215 )
216 .sign_with_keys(&TEST_KEY_1_KEYS)
217 .unwrap(),
218 generate_test_key_1_relay_list_event_same_as_fallback(),
219 ],
220 )?;
198 Ok(()) 221 Ok(())
199 }), 222 }),
200 None, 223 None,
@@ -208,14 +231,18 @@ mod with_relays {
208 -> Result<()> { 231 -> Result<()> {
209 run_test_displays_fallback_to_npub( 232 run_test_displays_fallback_to_npub(
210 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 233 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
211 relay.respond_events(client_id, &subscription_id, &vec![ 234 relay.respond_events(
212 nostr::event::EventBuilder::metadata( 235 client_id,
213 &nostr::Metadata::new().about("other info in metadata"), 236 &subscription_id,
214 ) 237 &vec![
215 .sign_with_keys(&TEST_KEY_1_KEYS) 238 nostr::event::EventBuilder::metadata(
216 .unwrap(), 239 &nostr::Metadata::new().about("other info in metadata"),
217 generate_test_key_1_relay_list_event_same_as_fallback(), 240 )
218 ])?; 241 .sign_with_keys(&TEST_KEY_1_KEYS)
242 .unwrap(),
243 generate_test_key_1_relay_list_event_same_as_fallback(),
244 ],
245 )?;
219 Ok(()) 246 Ok(())
220 }), 247 }),
221 None, 248 None,
@@ -230,10 +257,14 @@ mod with_relays {
230 -> Result<()> { 257 -> Result<()> {
231 run_test_displays_correct_name( 258 run_test_displays_correct_name(
232 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 259 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
233 relay.respond_events(client_id, &subscription_id, &vec![ 260 relay.respond_events(
234 generate_test_key_1_metadata_event("fred"), 261 client_id,
235 generate_test_key_1_relay_list_event_same_as_fallback(), 262 &subscription_id,
236 ])?; 263 &vec![
264 generate_test_key_1_metadata_event("fred"),
265 generate_test_key_1_relay_list_event_same_as_fallback(),
266 ],
267 )?;
237 Ok(()) 268 Ok(())
238 }), 269 }),
239 None, 270 None,
@@ -247,15 +278,19 @@ mod with_relays {
247 { 278 {
248 run_test_displays_correct_name( 279 run_test_displays_correct_name(
249 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 280 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
250 relay.respond_events(client_id, &subscription_id, &vec![ 281 relay.respond_events(
251 generate_test_key_1_metadata_event("fred"), 282 client_id,
252 ])?; 283 &subscription_id,
284 &vec![generate_test_key_1_metadata_event("fred")],
285 )?;
253 Ok(()) 286 Ok(())
254 }), 287 }),
255 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 288 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
256 relay.respond_events(client_id, &subscription_id, &vec![ 289 relay.respond_events(
257 generate_test_key_1_relay_list_event_same_as_fallback(), 290 client_id,
258 ])?; 291 &subscription_id,
292 &vec![generate_test_key_1_relay_list_event_same_as_fallback()],
293 )?;
259 Ok(()) 294 Ok(())
260 }), 295 }),
261 ) 296 )
@@ -267,16 +302,22 @@ mod with_relays {
267 async fn when_some_relays_return_old_metadata_event() -> Result<()> { 302 async fn when_some_relays_return_old_metadata_event() -> Result<()> {
268 run_test_displays_correct_name( 303 run_test_displays_correct_name(
269 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 304 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
270 relay.respond_events(client_id, &subscription_id, &vec![ 305 relay.respond_events(
271 generate_test_key_1_metadata_event("fred"), 306 client_id,
272 generate_test_key_1_relay_list_event_same_as_fallback(), 307 &subscription_id,
273 ])?; 308 &vec![
309 generate_test_key_1_metadata_event("fred"),
310 generate_test_key_1_relay_list_event_same_as_fallback(),
311 ],
312 )?;
274 Ok(()) 313 Ok(())
275 }), 314 }),
276 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 315 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
277 relay.respond_events(client_id, &subscription_id, &vec![ 316 relay.respond_events(
278 generate_test_key_1_metadata_event_old("fred old"), 317 client_id,
279 ])?; 318 &subscription_id,
319 &vec![generate_test_key_1_metadata_event_old("fred old")],
320 )?;
280 Ok(()) 321 Ok(())
281 }), 322 }),
282 ) 323 )
@@ -288,16 +329,22 @@ mod with_relays {
288 async fn when_some_relays_return_other_users_metadata() -> Result<()> { 329 async fn when_some_relays_return_other_users_metadata() -> Result<()> {
289 run_test_displays_correct_name( 330 run_test_displays_correct_name(
290 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 331 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
291 relay.respond_events(client_id, &subscription_id, &vec![ 332 relay.respond_events(
292 generate_test_key_2_metadata_event("carole"), 333 client_id,
293 ])?; 334 &subscription_id,
335 &vec![generate_test_key_2_metadata_event("carole")],
336 )?;
294 Ok(()) 337 Ok(())
295 }), 338 }),
296 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 339 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
297 relay.respond_events(client_id, &subscription_id, &vec![ 340 relay.respond_events(
298 generate_test_key_1_metadata_event_old("fred"), 341 client_id,
299 generate_test_key_1_relay_list_event_same_as_fallback(), 342 &subscription_id,
300 ])?; 343 &vec![
344 generate_test_key_1_metadata_event_old("fred"),
345 generate_test_key_1_relay_list_event_same_as_fallback(),
346 ],
347 )?;
301 Ok(()) 348 Ok(())
302 }), 349 }),
303 ) 350 )
@@ -310,16 +357,22 @@ mod with_relays {
310 run_test_displays_correct_name( 357 run_test_displays_correct_name(
311 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 358 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
312 let event = generate_test_key_1_kind_event(nostr::Kind::TextNote); 359 let event = generate_test_key_1_kind_event(nostr::Kind::TextNote);
313 relay.respond_events(client_id, &subscription_id, &vec![ 360 relay.respond_events(
314 make_event_old_or_change_user(event, &TEST_KEY_1_KEYS, 0), 361 client_id,
315 ])?; 362 &subscription_id,
363 &vec![make_event_old_or_change_user(event, &TEST_KEY_1_KEYS, 0)],
364 )?;
316 Ok(()) 365 Ok(())
317 }), 366 }),
318 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 367 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
319 relay.respond_events(client_id, &subscription_id, &vec![ 368 relay.respond_events(
320 generate_test_key_1_metadata_event_old("fred"), 369 client_id,
321 generate_test_key_1_relay_list_event_same_as_fallback(), 370 &subscription_id,
322 ])?; 371 &vec![
372 generate_test_key_1_metadata_event_old("fred"),
373 generate_test_key_1_relay_list_event_same_as_fallback(),
374 ],
375 )?;
323 Ok(()) 376 Ok(())
324 }), 377 }),
325 ) 378 )
@@ -334,10 +387,14 @@ mod with_relays {
334 async fn displays_correct_name() -> Result<()> { 387 async fn displays_correct_name() -> Result<()> {
335 run_test_when_specifying_command_line_nsec_only_displays_correct_name( 388 run_test_when_specifying_command_line_nsec_only_displays_correct_name(
336 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 389 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
337 relay.respond_events(client_id, &subscription_id, &vec![ 390 relay.respond_events(
338 generate_test_key_1_metadata_event("fred"), 391 client_id,
339 generate_test_key_1_relay_list_event_same_as_fallback(), 392 &subscription_id,
340 ])?; 393 &vec![
394 generate_test_key_1_metadata_event("fred"),
395 generate_test_key_1_relay_list_event_same_as_fallback(),
396 ],
397 )?;
341 Ok(()) 398 Ok(())
342 }), 399 }),
343 None, 400 None,
@@ -355,12 +412,10 @@ mod with_relays {
355 412
356 let cli_tester_handle = std::thread::spawn(move || -> Result<()> { 413 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
357 let test_repo = GitTestRepo::default(); 414 let test_repo = GitTestRepo::default();
358 let mut p = CliTester::new_from_dir(&test_repo.dir, [ 415 let mut p = CliTester::new_from_dir(
359 "account", 416 &test_repo.dir,
360 "login", 417 ["account", "login", "--nsec", TEST_KEY_1_NSEC],
361 "--nsec", 418 );
362 TEST_KEY_1_NSEC,
363 ]);
364 419
365 p.expect("saved login details to local git config. you are only logged in to this local repository.\r\n")?; 420 p.expect("saved login details to local git config. you are only logged in to this local repository.\r\n")?;
366 421
@@ -432,9 +487,11 @@ mod with_relays {
432 async fn warm_user_and_displays_name() -> Result<()> { 487 async fn warm_user_and_displays_name() -> Result<()> {
433 run_test_when_no_relay_list_found_warns_user_and_uses_npub( 488 run_test_when_no_relay_list_found_warns_user_and_uses_npub(
434 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 489 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
435 relay.respond_events(client_id, &subscription_id, &vec![ 490 relay.respond_events(
436 generate_test_key_1_metadata_event("fred"), 491 client_id,
437 ])?; 492 &subscription_id,
493 &vec![generate_test_key_1_metadata_event("fred")],
494 )?;
438 Ok(()) 495 Ok(())
439 }), 496 }),
440 None, 497 None,
@@ -525,17 +582,25 @@ mod with_relays {
525 async fn displays_correct_name() -> Result<()> { 582 async fn displays_correct_name() -> Result<()> {
526 run_test_displays_correct_name( 583 run_test_displays_correct_name(
527 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 584 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
528 relay.respond_events(client_id, &subscription_id, &vec![ 585 relay.respond_events(
529 generate_test_key_1_metadata_event_old("Fred"), 586 client_id,
530 generate_test_key_1_relay_list_event(), 587 &subscription_id,
531 ])?; 588 &vec![
589 generate_test_key_1_metadata_event_old("Fred"),
590 generate_test_key_1_relay_list_event(),
591 ],
592 )?;
532 Ok(()) 593 Ok(())
533 }), 594 }),
534 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 595 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
535 relay.respond_events(client_id, &subscription_id, &vec![ 596 relay.respond_events(
536 generate_test_key_1_metadata_event("fred"), 597 client_id,
537 generate_test_key_1_relay_list_event(), 598 &subscription_id,
538 ])?; 599 &vec![
600 generate_test_key_1_metadata_event("fred"),
601 generate_test_key_1_relay_list_event(),
602 ],
603 )?;
539 Ok(()) 604 Ok(())
540 }), 605 }),
541 ) 606 )
@@ -607,10 +672,10 @@ mod with_offline_flag {
607 true, 672 true,
608 )?; 673 )?;
609 674
610 p.expect_choice("login to nostr", vec![ 675 p.expect_choice(
611 "try again with nsec".to_string(), 676 "login to nostr",
612 "back".to_string(), 677 vec!["try again with nsec".to_string(), "back".to_string()],
613 ])? 678 )?
614 .succeeds_with(0, false, Some(0))?; 679 .succeeds_with(0, false, Some(0))?;
615 } 680 }
616 681
@@ -630,13 +695,10 @@ mod with_offline_flag {
630 #[test] 695 #[test]
631 fn valid_nsec_param_succeeds_without_prompts() -> Result<()> { 696 fn valid_nsec_param_succeeds_without_prompts() -> Result<()> {
632 let test_repo = GitTestRepo::default(); 697 let test_repo = GitTestRepo::default();
633 let mut p = CliTester::new_from_dir(&test_repo.dir, [ 698 let mut p = CliTester::new_from_dir(
634 "account", 699 &test_repo.dir,
635 "login", 700 ["account", "login", "--offline", "--nsec", TEST_KEY_1_NSEC],
636 "--offline", 701 );
637 "--nsec",
638 TEST_KEY_1_NSEC,
639 ]);
640 702
641 p.expect("saved login details to local git config. you are only logged in to this local repository.\r\n")?; 703 p.expect("saved login details to local git config. you are only logged in to this local repository.\r\n")?;
642 704
@@ -648,13 +710,10 @@ mod with_offline_flag {
648 #[test] 710 #[test]
649 fn invalid_nsec_param_fails_without_prompts() -> Result<()> { 711 fn invalid_nsec_param_fails_without_prompts() -> Result<()> {
650 let test_repo = GitTestRepo::default(); 712 let test_repo = GitTestRepo::default();
651 let mut p = CliTester::new_from_dir(&test_repo.dir, [ 713 let mut p = CliTester::new_from_dir(
652 "account", 714 &test_repo.dir,
653 "login", 715 ["account", "login", "--offline", "--nsec", TEST_INVALID_NSEC],
654 "--offline", 716 );
655 "--nsec",
656 TEST_INVALID_NSEC,
657 ]);
658 717
659 p.expect_end_with( 718 p.expect_end_with(
660 "Error: invalid nsec parameter\r\n\r\nCaused by:\r\n Invalid secret key\r\n", 719 "Error: invalid nsec parameter\r\n\r\nCaused by:\r\n Invalid secret key\r\n",
@@ -668,15 +727,18 @@ mod with_offline_flag {
668 #[test] 727 #[test]
669 fn valid_nsec_param_succeeds_without_prompts() -> Result<()> { 728 fn valid_nsec_param_succeeds_without_prompts() -> Result<()> {
670 let test_repo = GitTestRepo::default(); 729 let test_repo = GitTestRepo::default();
671 let mut p = CliTester::new_from_dir(&test_repo.dir, [ 730 let mut p = CliTester::new_from_dir(
672 "account", 731 &test_repo.dir,
673 "login", 732 [
674 "--offline", 733 "account",
675 "--nsec", 734 "login",
676 TEST_KEY_1_NSEC, 735 "--offline",
677 "--password", 736 "--nsec",
678 TEST_PASSWORD, 737 TEST_KEY_1_NSEC,
679 ]); 738 "--password",
739 TEST_PASSWORD,
740 ],
741 );
680 p.expect("saved login details to local git config. you are only logged in to this local repository.\r\n")?; 742 p.expect("saved login details to local git config. you are only logged in to this local repository.\r\n")?;
681 743
682 p.expect_end_with( 744 p.expect_end_with(
@@ -687,15 +749,18 @@ mod with_offline_flag {
687 #[test] 749 #[test]
688 fn parameters_can_be_called_globally() -> Result<()> { 750 fn parameters_can_be_called_globally() -> Result<()> {
689 let test_repo = GitTestRepo::default(); 751 let test_repo = GitTestRepo::default();
690 let mut p = CliTester::new_from_dir(&test_repo.dir, [ 752 let mut p = CliTester::new_from_dir(
691 "--nsec", 753 &test_repo.dir,
692 TEST_KEY_1_NSEC, 754 [
693 "--password", 755 "--nsec",
694 TEST_PASSWORD, 756 TEST_KEY_1_NSEC,
695 "account", 757 "--password",
696 "login", 758 TEST_PASSWORD,
697 "--offline", 759 "account",
698 ]); 760 "login",
761 "--offline",
762 ],
763 );
699 p.expect("saved login details to local git config. you are only logged in to this local repository.\r\n")?; 764 p.expect("saved login details to local git config. you are only logged in to this local repository.\r\n")?;
700 765
701 p.expect_end_with( 766 p.expect_end_with(
@@ -710,15 +775,18 @@ mod with_offline_flag {
710 fn valid_nsec_param_succeeds_without_prompts_and_logs_in() -> Result<()> { 775 fn valid_nsec_param_succeeds_without_prompts_and_logs_in() -> Result<()> {
711 standard_first_time_login_with_nsec()?.exit()?; 776 standard_first_time_login_with_nsec()?.exit()?;
712 let test_repo = GitTestRepo::default(); 777 let test_repo = GitTestRepo::default();
713 let mut p = CliTester::new_from_dir(&test_repo.dir, [ 778 let mut p = CliTester::new_from_dir(
714 "account", 779 &test_repo.dir,
715 "login", 780 [
716 "--offline", 781 "account",
717 "--nsec", 782 "login",
718 TEST_KEY_2_NSEC, 783 "--offline",
719 "--password", 784 "--nsec",
720 TEST_PASSWORD, 785 TEST_KEY_2_NSEC,
721 ]); 786 "--password",
787 TEST_PASSWORD,
788 ],
789 );
722 p.expect("saved login details to local git config. you are only logged in to this local repository.\r\n")?; 790 p.expect("saved login details to local git config. you are only logged in to this local repository.\r\n")?;
723 791
724 p.expect_end_with( 792 p.expect_end_with(
diff --git a/tests/ngit_send.rs b/tests/ngit_send.rs
index 5cc5291..2cd5956 100644
--- a/tests/ngit_send.rs
+++ b/tests/ngit_send.rs
@@ -181,10 +181,14 @@ async fn prep_run_create_proposal(
181 8051, 181 8051,
182 None, 182 None,
183 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 183 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
184 relay.respond_events(client_id, &subscription_id, &vec![ 184 relay.respond_events(
185 generate_test_key_1_metadata_event("fred"), 185 client_id,
186 generate_test_key_1_relay_list_event(), 186 &subscription_id,
187 ])?; 187 &vec![
188 generate_test_key_1_metadata_event("fred"),
189 generate_test_key_1_relay_list_event(),
190 ],
191 )?;
188 Ok(()) 192 Ok(())
189 }), 193 }),
190 ), 194 ),
@@ -194,9 +198,11 @@ async fn prep_run_create_proposal(
194 8055, 198 8055,
195 None, 199 None,
196 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 200 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
197 relay.respond_events(client_id, &subscription_id, &vec![ 201 relay.respond_events(
198 generate_repo_ref_event(), 202 client_id,
199 ])?; 203 &subscription_id,
204 &vec![generate_repo_ref_event()],
205 )?;
200 Ok(()) 206 Ok(())
201 }), 207 }),
202 ), 208 ),
@@ -762,10 +768,14 @@ mod when_cover_letter_details_specified_with_range_of_head_2_sends_cover_letter_
762 8051, 768 8051,
763 None, 769 None,
764 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 770 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
765 relay.respond_events(client_id, &subscription_id, &vec![ 771 relay.respond_events(
766 generate_test_key_1_metadata_event("fred"), 772 client_id,
767 generate_test_key_1_relay_list_event(), 773 &subscription_id,
768 ])?; 774 &vec![
775 generate_test_key_1_metadata_event("fred"),
776 generate_test_key_1_relay_list_event(),
777 ],
778 )?;
769 Ok(()) 779 Ok(())
770 }), 780 }),
771 ), 781 ),
@@ -775,9 +785,11 @@ mod when_cover_letter_details_specified_with_range_of_head_2_sends_cover_letter_
775 8055, 785 8055,
776 None, 786 None,
777 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 787 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
778 relay.respond_events(client_id, &subscription_id, &vec![ 788 relay.respond_events(
779 generate_repo_ref_event(), 789 client_id,
780 ])?; 790 &subscription_id,
791 &vec![generate_repo_ref_event()],
792 )?;
781 Ok(()) 793 Ok(())
782 }), 794 }),
783 ), 795 ),
@@ -836,10 +848,14 @@ mod when_cover_letter_details_specified_with_range_of_head_2_sends_cover_letter_
836 8051, 848 8051,
837 None, 849 None,
838 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 850 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
839 relay.respond_events(client_id, &subscription_id, &vec![ 851 relay.respond_events(
840 generate_test_key_1_metadata_event("fred"), 852 client_id,
841 generate_test_key_1_relay_list_event(), 853 &subscription_id,
842 ])?; 854 &vec![
855 generate_test_key_1_metadata_event("fred"),
856 generate_test_key_1_relay_list_event(),
857 ],
858 )?;
843 Ok(()) 859 Ok(())
844 }), 860 }),
845 ), 861 ),
@@ -849,9 +865,11 @@ mod when_cover_letter_details_specified_with_range_of_head_2_sends_cover_letter_
849 8055, 865 8055,
850 None, 866 None,
851 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 867 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
852 relay.respond_events(client_id, &subscription_id, &vec![ 868 relay.respond_events(
853 generate_repo_ref_event(), 869 client_id,
854 ])?; 870 &subscription_id,
871 &vec![generate_repo_ref_event()],
872 )?;
855 Ok(()) 873 Ok(())
856 }), 874 }),
857 ), 875 ),
@@ -904,10 +922,14 @@ mod when_cover_letter_details_specified_with_range_of_head_2_sends_cover_letter_
904 8051, 922 8051,
905 None, 923 None,
906 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 924 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
907 relay.respond_events(client_id, &subscription_id, &vec![ 925 relay.respond_events(
908 generate_test_key_1_metadata_event("fred"), 926 client_id,
909 generate_test_key_1_relay_list_event(), 927 &subscription_id,
910 ])?; 928 &vec![
929 generate_test_key_1_metadata_event("fred"),
930 generate_test_key_1_relay_list_event(),
931 ],
932 )?;
911 Ok(()) 933 Ok(())
912 }), 934 }),
913 ), 935 ),
@@ -917,9 +939,11 @@ mod when_cover_letter_details_specified_with_range_of_head_2_sends_cover_letter_
917 8055, 939 8055,
918 None, 940 None,
919 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 941 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
920 relay.respond_events(client_id, &subscription_id, &vec![ 942 relay.respond_events(
921 generate_repo_ref_event(), 943 client_id,
922 ])?; 944 &subscription_id,
945 &vec![generate_repo_ref_event()],
946 )?;
923 Ok(()) 947 Ok(())
924 }), 948 }),
925 ), 949 ),
@@ -992,10 +1016,14 @@ mod when_no_cover_letter_flag_set_with_range_of_head_2_sends_2_patches_without_c
992 8051, 1016 8051,
993 None, 1017 None,
994 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 1018 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
995 relay.respond_events(client_id, &subscription_id, &vec![ 1019 relay.respond_events(
996 generate_test_key_1_metadata_event("fred"), 1020 client_id,
997 generate_test_key_1_relay_list_event(), 1021 &subscription_id,
998 ])?; 1022 &vec![
1023 generate_test_key_1_metadata_event("fred"),
1024 generate_test_key_1_relay_list_event(),
1025 ],
1026 )?;
999 Ok(()) 1027 Ok(())
1000 }), 1028 }),
1001 ), 1029 ),
@@ -1005,9 +1033,11 @@ mod when_no_cover_letter_flag_set_with_range_of_head_2_sends_2_patches_without_c
1005 8055, 1033 8055,
1006 None, 1034 None,
1007 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 1035 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
1008 relay.respond_events(client_id, &subscription_id, &vec![ 1036 relay.respond_events(
1009 generate_repo_ref_event(), 1037 client_id,
1010 ])?; 1038 &subscription_id,
1039 &vec![generate_repo_ref_event()],
1040 )?;
1011 Ok(()) 1041 Ok(())
1012 }), 1042 }),
1013 ), 1043 ),
@@ -1174,13 +1204,16 @@ mod when_range_ommited_prompts_for_selection_defaulting_ahead_of_main {
1174 fn expect_msgs_first(p: &mut CliTester) -> Result<()> { 1204 fn expect_msgs_first(p: &mut CliTester) -> Result<()> {
1175 p.expect("fetching updates...\r\n")?; 1205 p.expect("fetching updates...\r\n")?;
1176 p.expect_eventually("\r\n")?; // may be 'no updates' or some updates 1206 p.expect_eventually("\r\n")?; // may be 'no updates' or some updates
1177 let mut selector = p.expect_multi_select("select commits for proposal", vec![ 1207 let mut selector = p.expect_multi_select(
1178 "(Joe Bloggs) add t4.md [feature] fe973a8".to_string(), 1208 "select commits for proposal",
1179 "(Joe Bloggs) add t3.md 232efb3".to_string(), 1209 vec![
1180 "(Joe Bloggs) add t2.md [main] 431b84e".to_string(), 1210 "(Joe Bloggs) add t4.md [feature] fe973a8".to_string(),
1181 "(Joe Bloggs) add t1.md af474d8".to_string(), 1211 "(Joe Bloggs) add t3.md 232efb3".to_string(),
1182 "(Joe Bloggs) Initial commit 9ee507f".to_string(), 1212 "(Joe Bloggs) add t2.md [main] 431b84e".to_string(),
1183 ])?; 1213 "(Joe Bloggs) add t1.md af474d8".to_string(),
1214 "(Joe Bloggs) Initial commit 9ee507f".to_string(),
1215 ],
1216 )?;
1184 selector.succeeds_with(vec![0, 1], false, vec![0, 1])?; 1217 selector.succeeds_with(vec![0, 1], false, vec![0, 1])?;
1185 p.expect("creating proposal from 2 commits:\r\n")?; 1218 p.expect("creating proposal from 2 commits:\r\n")?;
1186 p.expect("fe973a8 add t4.md\r\n")?; 1219 p.expect("fe973a8 add t4.md\r\n")?;
@@ -1205,10 +1238,14 @@ mod when_range_ommited_prompts_for_selection_defaulting_ahead_of_main {
1205 8051, 1238 8051,
1206 None, 1239 None,
1207 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 1240 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
1208 relay.respond_events(client_id, &subscription_id, &vec![ 1241 relay.respond_events(
1209 generate_test_key_1_metadata_event("fred"), 1242 client_id,
1210 generate_test_key_1_relay_list_event(), 1243 &subscription_id,
1211 ])?; 1244 &vec![
1245 generate_test_key_1_metadata_event("fred"),
1246 generate_test_key_1_relay_list_event(),
1247 ],
1248 )?;
1212 Ok(()) 1249 Ok(())
1213 }), 1250 }),
1214 ), 1251 ),
@@ -1218,9 +1255,11 @@ mod when_range_ommited_prompts_for_selection_defaulting_ahead_of_main {
1218 8055, 1255 8055,
1219 None, 1256 None,
1220 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 1257 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
1221 relay.respond_events(client_id, &subscription_id, &vec![ 1258 relay.respond_events(
1222 generate_repo_ref_event(), 1259 client_id,
1223 ])?; 1260 &subscription_id,
1261 &vec![generate_repo_ref_event()],
1262 )?;
1224 Ok(()) 1263 Ok(())
1225 }), 1264 }),
1226 ), 1265 ),
@@ -1262,10 +1301,14 @@ mod when_range_ommited_prompts_for_selection_defaulting_ahead_of_main {
1262 8051, 1301 8051,
1263 None, 1302 None,
1264 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 1303 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
1265 relay.respond_events(client_id, &subscription_id, &vec![ 1304 relay.respond_events(
1266 generate_test_key_1_metadata_event("fred"), 1305 client_id,
1267 generate_test_key_1_relay_list_event(), 1306 &subscription_id,
1268 ])?; 1307 &vec![
1308 generate_test_key_1_metadata_event("fred"),
1309 generate_test_key_1_relay_list_event(),
1310 ],
1311 )?;
1269 Ok(()) 1312 Ok(())
1270 }), 1313 }),
1271 ), 1314 ),
@@ -1275,9 +1318,11 @@ mod when_range_ommited_prompts_for_selection_defaulting_ahead_of_main {
1275 8055, 1318 8055,
1276 None, 1319 None,
1277 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 1320 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
1278 relay.respond_events(client_id, &subscription_id, &vec![ 1321 relay.respond_events(
1279 generate_repo_ref_event(), 1322 client_id,
1280 ])?; 1323 &subscription_id,
1324 &vec![generate_repo_ref_event()],
1325 )?;
1281 Ok(()) 1326 Ok(())
1282 }), 1327 }),
1283 ), 1328 ),
@@ -1393,11 +1438,15 @@ mod root_proposal_specified_using_in_reply_to_with_range_of_head_2_and_cover_let
1393 8051, 1438 8051,
1394 None, 1439 None,
1395 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 1440 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
1396 relay.respond_events(client_id, &subscription_id, &vec![ 1441 relay.respond_events(
1397 generate_test_key_1_metadata_event("fred"), 1442 client_id,
1398 generate_test_key_1_relay_list_event(), 1443 &subscription_id,
1399 get_pretend_proposal_root_event(), 1444 &vec![
1400 ])?; 1445 generate_test_key_1_metadata_event("fred"),
1446 generate_test_key_1_relay_list_event(),
1447 get_pretend_proposal_root_event(),
1448 ],
1449 )?;
1401 Ok(()) 1450 Ok(())
1402 }), 1451 }),
1403 ), 1452 ),
@@ -1407,10 +1456,11 @@ mod root_proposal_specified_using_in_reply_to_with_range_of_head_2_and_cover_let
1407 8055, 1456 8055,
1408 None, 1457 None,
1409 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 1458 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
1410 relay.respond_events(client_id, &subscription_id, &vec![ 1459 relay.respond_events(
1411 generate_repo_ref_event(), 1460 client_id,
1412 get_pretend_proposal_root_event(), 1461 &subscription_id,
1413 ])?; 1462 &vec![generate_repo_ref_event(), get_pretend_proposal_root_event()],
1463 )?;
1414 Ok(()) 1464 Ok(())
1415 }), 1465 }),
1416 ), 1466 ),
@@ -1451,11 +1501,15 @@ mod root_proposal_specified_using_in_reply_to_with_range_of_head_2_and_cover_let
1451 8051, 1501 8051,
1452 None, 1502 None,
1453 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 1503 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
1454 relay.respond_events(client_id, &subscription_id, &vec![ 1504 relay.respond_events(
1455 generate_test_key_1_metadata_event("fred"), 1505 client_id,
1456 generate_test_key_1_relay_list_event(), 1506 &subscription_id,
1457 get_pretend_proposal_root_event(), 1507 &vec![
1458 ])?; 1508 generate_test_key_1_metadata_event("fred"),
1509 generate_test_key_1_relay_list_event(),
1510 get_pretend_proposal_root_event(),
1511 ],
1512 )?;
1459 Ok(()) 1513 Ok(())
1460 }), 1514 }),
1461 ), 1515 ),
@@ -1465,10 +1519,11 @@ mod root_proposal_specified_using_in_reply_to_with_range_of_head_2_and_cover_let
1465 8055, 1519 8055,
1466 None, 1520 None,
1467 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 1521 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
1468 relay.respond_events(client_id, &subscription_id, &vec![ 1522 relay.respond_events(
1469 generate_repo_ref_event(), 1523 client_id,
1470 get_pretend_proposal_root_event(), 1524 &subscription_id,
1471 ])?; 1525 &vec![generate_repo_ref_event(), get_pretend_proposal_root_event()],
1526 )?;
1472 Ok(()) 1527 Ok(())
1473 }), 1528 }),
1474 ), 1529 ),
@@ -1645,11 +1700,15 @@ mod in_reply_to_mentions_issue {
1645 8051, 1700 8051,
1646 None, 1701 None,
1647 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 1702 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
1648 relay.respond_events(client_id, &subscription_id, &vec![ 1703 relay.respond_events(
1649 generate_test_key_1_metadata_event("fred"), 1704 client_id,
1650 generate_test_key_1_relay_list_event(), 1705 &subscription_id,
1651 get_pretend_issue_event(), 1706 &vec![
1652 ])?; 1707 generate_test_key_1_metadata_event("fred"),
1708 generate_test_key_1_relay_list_event(),
1709 get_pretend_issue_event(),
1710 ],
1711 )?;
1653 Ok(()) 1712 Ok(())
1654 }), 1713 }),
1655 ), 1714 ),
@@ -1659,10 +1718,11 @@ mod in_reply_to_mentions_issue {
1659 8055, 1718 8055,
1660 None, 1719 None,
1661 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 1720 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
1662 relay.respond_events(client_id, &subscription_id, &vec![ 1721 relay.respond_events(
1663 generate_repo_ref_event(), 1722 client_id,
1664 get_pretend_issue_event(), 1723 &subscription_id,
1665 ])?; 1724 &vec![generate_repo_ref_event(), get_pretend_issue_event()],
1725 )?;
1666 Ok(()) 1726 Ok(())
1667 }), 1727 }),
1668 ), 1728 ),
@@ -1764,10 +1824,14 @@ mod in_reply_to_mentions_npub_and_nprofile_which_get_mentioned_in_proposal_root
1764 8051, 1824 8051,
1765 None, 1825 None,
1766 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 1826 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
1767 relay.respond_events(client_id, &subscription_id, &vec![ 1827 relay.respond_events(
1768 generate_test_key_1_metadata_event("fred"), 1828 client_id,
1769 generate_test_key_1_relay_list_event(), 1829 &subscription_id,
1770 ])?; 1830 &vec![
1831 generate_test_key_1_metadata_event("fred"),
1832 generate_test_key_1_relay_list_event(),
1833 ],
1834 )?;
1771 Ok(()) 1835 Ok(())
1772 }), 1836 }),
1773 ), 1837 ),
@@ -1777,9 +1841,11 @@ mod in_reply_to_mentions_npub_and_nprofile_which_get_mentioned_in_proposal_root
1777 8055, 1841 8055,
1778 None, 1842 None,
1779 Some(&|relay, client_id, subscription_id, _| -> Result<()> { 1843 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
1780 relay.respond_events(client_id, &subscription_id, &vec![ 1844 relay.respond_events(
1781 generate_repo_ref_event(), 1845 client_id,
1782 ])?; 1846 &subscription_id,
1847 &vec![generate_repo_ref_event()],
1848 )?;
1783 Ok(()) 1849 Ok(())
1784 }), 1850 }),
1785 ), 1851 ),