upleb.uk

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

summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/git_remote_helper.rs169
1 files changed, 166 insertions, 3 deletions
diff --git a/tests/git_remote_helper.rs b/tests/git_remote_helper.rs
index 66a0be5..00f9be3 100644
--- a/tests/git_remote_helper.rs
+++ b/tests/git_remote_helper.rs
@@ -1,9 +1,9 @@
1use std::collections::HashSet; 1use std::{collections::HashSet, env::current_dir};
2 2
3use anyhow::{Context, Result}; 3use anyhow::{Context, Result};
4use futures::join; 4use futures::join;
5use nostr::nips::nip01::Coordinate; 5use nostr::nips::nip01::Coordinate;
6use nostr_sdk::{Kind, ToBech32}; 6use nostr_sdk::{secp256k1::rand, Kind, ToBech32};
7use relay::Relay; 7use relay::Relay;
8use serial_test::serial; 8use serial_test::serial;
9use test_utils::{git::GitTestRepo, *}; 9use test_utils::{git::GitTestRepo, *};
@@ -39,6 +39,21 @@ fn prep_git_repo() -> Result<GitTestRepo> {
39 Ok(test_repo) 39 Ok(test_repo)
40} 40}
41 41
42fn clone_git_repo_with_nostr_url() -> Result<GitTestRepo> {
43 let path = current_dir()?.join(format!("tmpgit-clone{}", rand::random::<u64>()));
44 std::fs::create_dir(path.clone())?;
45 CliTester::new_git_with_remote_helper_from_dir(&path, ["clone", &get_nostr_remote_url()?, "."])
46 .expect_end_eventually_and_print()?;
47 let test_repo = GitTestRepo::open(&path)?;
48 let mut config = test_repo
49 .git_repo
50 .config()
51 .context("cannot open git config")?;
52 config.set_str("nostr.nsec", TEST_KEY_1_NSEC)?;
53 config.set_str("nostr.npub", TEST_KEY_1_NPUB)?;
54 Ok(test_repo)
55}
56
42fn prep_git_repo_minus_1_commit() -> Result<GitTestRepo> { 57fn prep_git_repo_minus_1_commit() -> Result<GitTestRepo> {
43 let test_repo = GitTestRepo::without_repo_in_git_config(); 58 let test_repo = GitTestRepo::without_repo_in_git_config();
44 let mut config = test_repo 59 let mut config = test_repo
@@ -58,10 +73,15 @@ fn cli_tester(git_repo: &GitTestRepo) -> CliTester {
58 73
59fn cli_tester_after_fetch(git_repo: &GitTestRepo) -> Result<CliTester> { 74fn cli_tester_after_fetch(git_repo: &GitTestRepo) -> Result<CliTester> {
60 let mut p = cli_tester(git_repo); 75 let mut p = cli_tester(git_repo);
76 cli_expect_nostr_fetch(&mut p)?;
77 Ok(p)
78}
79
80fn cli_expect_nostr_fetch(p: &mut CliTester) -> Result<()> {
61 p.expect("nostr: fetching...\r\n")?; 81 p.expect("nostr: fetching...\r\n")?;
62 p.expect_eventually("updates")?; // some updates 82 p.expect_eventually("updates")?; // some updates
63 p.expect_eventually("\r\n")?; 83 p.expect_eventually("\r\n")?;
64 Ok(p) 84 Ok(())
65} 85}
66 86
67/// git runs `list for-push` before `push`. in `push` we use the git server 87/// git runs `list for-push` before `push`. in `push` we use the git server
@@ -793,6 +813,8 @@ mod fetch {
793 813
794mod push { 814mod push {
795 815
816 use nostr_sdk::Event;
817
796 use super::*; 818 use super::*;
797 819
798 #[tokio::test] 820 #[tokio::test]
@@ -1692,4 +1714,145 @@ mod push {
1692 1714
1693 Ok(()) 1715 Ok(())
1694 } 1716 }
1717
1718 #[tokio::test]
1719 #[serial]
1720 async fn push_2_commits_to_existing_proposal() -> Result<()> {
1721 let (events, source_git_repo) = prep_source_repo_and_events_including_proposals().await?;
1722 let source_path = source_git_repo.dir.to_str().unwrap().to_string();
1723
1724 let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = (
1725 Relay::new(8051, None, None),
1726 Relay::new(8052, None, None),
1727 Relay::new(8053, None, None),
1728 Relay::new(8055, None, None),
1729 Relay::new(8056, None, None),
1730 Relay::new(8057, None, None),
1731 );
1732 r51.events = events.clone();
1733 r55.events = events.clone();
1734
1735 let before = r55.events.iter().cloned().collect::<HashSet<Event>>();
1736
1737 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
1738 let branch_name = get_proposal_branch_name_from_events(&events, FEATURE_BRANCH_NAME_1)?;
1739
1740 let git_repo = clone_git_repo_with_nostr_url()?;
1741 git_repo.checkout_remote_branch(&branch_name)?;
1742
1743 std::fs::write(git_repo.dir.join("new.md"), "some content")?;
1744 git_repo.stage_and_commit("new.md")?;
1745
1746 std::fs::write(git_repo.dir.join("new2.md"), "some content")?;
1747 git_repo.stage_and_commit("new2.md")?;
1748
1749 let mut p = CliTester::new_git_with_remote_helper_from_dir(&git_repo.dir, ["push"]);
1750 cli_expect_nostr_fetch(&mut p)?;
1751 p.expect(format!("fetching refs list: {}...\r\n\r", source_path).as_str())?;
1752 p.expect(format!("To {}\r\n", get_nostr_remote_url()?).as_str())?;
1753 p.expect_end_with(
1754 format!(" eb5d678..7de5e41 {branch_name} -> {branch_name}\r\n").as_str(),
1755 )?;
1756
1757 for p in [51, 52, 53, 55, 56, 57] {
1758 relay::shutdown_relay(8000 + p)?;
1759 }
1760
1761 Ok(())
1762 });
1763 // launch relays
1764 let _ = join!(
1765 r51.listen_until_close(),
1766 r52.listen_until_close(),
1767 r53.listen_until_close(),
1768 r55.listen_until_close(),
1769 r56.listen_until_close(),
1770 r57.listen_until_close(),
1771 );
1772
1773 cli_tester_handle.join().unwrap()?;
1774
1775 // TODO source repo doesn't have proposal branch
1776 // TODO
1777 let new_events = r55
1778 .events
1779 .iter()
1780 .cloned()
1781 .collect::<HashSet<Event>>()
1782 .difference(&before)
1783 .cloned()
1784 .collect::<Vec<Event>>();
1785 assert_eq!(new_events.len(), 2);
1786 let first_new_patch = new_events
1787 .iter()
1788 .find(|e| e.content.contains("new.md"))
1789 .unwrap();
1790 let second_new_patch = new_events
1791 .iter()
1792 .find(|e| e.content.contains("new2.md"))
1793 .unwrap();
1794 assert!(
1795 first_new_patch.content.contains("[PATCH 3/4]"),
1796 "first patch labeled with [PATCH 3/4]"
1797 );
1798 assert!(
1799 second_new_patch.content.contains("[PATCH 4/4]"),
1800 "second patch labeled with [PATCH 4/4]"
1801 );
1802
1803 let proposal = r55
1804 .events
1805 .iter()
1806 .find(|e| {
1807 e.iter_tags()
1808 .find(|t| t.as_vec()[0].eq("branch-name"))
1809 .is_some_and(|t| t.as_vec()[1].eq(FEATURE_BRANCH_NAME_1))
1810 })
1811 .unwrap();
1812
1813 assert_eq!(
1814 proposal.id().to_string(),
1815 first_new_patch
1816 .tags
1817 .iter()
1818 .find(|t| t.is_root())
1819 .unwrap()
1820 .as_vec()[1],
1821 "first patch sets proposal id as root"
1822 );
1823
1824 assert_eq!(
1825 first_new_patch.id().to_string(),
1826 second_new_patch
1827 .tags
1828 .iter()
1829 .find(|t| t.is_reply())
1830 .unwrap()
1831 .as_vec()[1],
1832 "second new patch replies to the first new patch"
1833 );
1834
1835 let previous_proposal_tip_event = r55
1836 .events
1837 .iter()
1838 .find(|e| {
1839 e.iter_tags()
1840 .any(|t| t.as_vec()[1].eq(&proposal.id().to_string()))
1841 && e.content.contains("[PATCH 2/2]")
1842 })
1843 .unwrap();
1844
1845 assert_eq!(
1846 previous_proposal_tip_event.id().to_string(),
1847 first_new_patch
1848 .tags
1849 .iter()
1850 .find(|t| t.is_reply())
1851 .unwrap()
1852 .as_vec()[1],
1853 "first patch replies to the previous tip of proposal"
1854 );
1855
1856 Ok(())
1857 }
1695} 1858}