use std::collections::BTreeMap; use assert2::let_assert; use git_next_config::{ ForgeType, GitDir, Hostname, RepoBranches, RepoConfig, RepoConfigSource, RepoPath, ServerRepoConfig, }; use git_next_git::{self as git, Generation, GitRemote, Repository}; use gix::remote::Direction; use kxio::fs; use pretty_assertions::assert_eq; use crate::gitforge::tests::common; use super::*; type Result = core::result::Result>; #[test] fn load_should_parse_server_config() -> Result<()> { let fs = fs::temp()?; fs.file_write( &fs.base().join("git-next-server.toml"), r#" [http] addr = "0.0.0.0" port = 8080 [webhook] url = "http://localhost:9909/webhook" [storage] path = "/opt/git-next/data" [forge.default] forge_type = "MockForge" hostname = "git.example.net" user = "Bob" token = "API-Token" [forge.default.repos] hello = { repo = "user/hello", branch = "main", gitdir = "/opt/git/user/hello.git" } world = { repo = "user/world", branch = "master", main = "main", next = "next", dev = "dev" } [forge.default.repos.sam] repo = "user/sam" branch = "main" main = "master" next = "upcoming" dev = "sam-dev" "#, ) ?; let_assert!(Ok(config) = ServerConfig::load(&fs)); let expected = ServerConfig { http: Http { addr: "0.0.0.0".to_string(), port: 8080, }, webhook: Webhook { url: "http://localhost:9909/webhook".to_string(), }, storage: ServerStorage { path: "/opt/git-next/data".into(), }, forge: HashMap::from([( "default".to_string(), ForgeConfig::new( ForgeType::MockForge, "git.example.net".to_string(), "Bob".to_string(), "API-Token".to_string(), BTreeMap::from([ ( "hello".to_string(), ServerRepoConfig::new( "user/hello".to_string(), "main".to_string(), Some("/opt/git/user/hello.git".into()), None, None, None, ), ), ( "world".to_string(), ServerRepoConfig::new( "user/world".to_string(), "master".to_string(), None, Some("main".to_string()), Some("next".to_string()), Some("dev".to_string()), ), ), ( "sam".to_string(), ServerRepoConfig::new( "user/sam".to_string(), "main".to_string(), None, Some("master".to_string()), Some("upcoming".to_string()), Some("sam-dev".to_string()), ), ), ]), ), )]), }; assert_eq!(config, expected, "ServerConfig"); if let Some(forge) = config.forge.get("world") { if let Some(repo) = forge.get_repo("sam") { let repo_config = repo.repo_config(); let expected = Some(RepoConfig::new( RepoBranches::new( "master".to_string(), "upcoming".to_string(), "sam-dev".to_string(), ), RepoConfigSource::Server, )); assert_eq!(repo_config, expected, "RepoConfig"); } } Ok(()) } #[test] fn test_repo_config_load() -> Result<()> { let toml = r#"[branches] main = "main" next = "next" dev = "dev" [options] "#; let config = RepoConfig::load(toml)?; assert_eq!( config, RepoConfig::new( RepoBranches::new("main".to_string(), "next".to_string(), "dev".to_string(),), RepoConfigSource::Repo ) ); Ok(()) } #[test] fn gitdir_should_display_as_pathbuf() { //given let gitdir = GitDir::from("foo/dir"); //when let result = format!("{}", gitdir); //then assert_eq!(result, "foo/dir"); } #[test] // NOTE: this test assumes it is being run in a cloned worktree from the project's home repo: // git.kemitix.net:kemitix/git-next // If the default push remote is something else, then this test will fail fn repo_details_find_default_push_remote_finds_correct_remote() -> Result<()> { let cli_crate_dir = std::env::current_dir().map_err(git::validate::Error::Io)?; let_assert!(Some(Some(root)) = cli_crate_dir.parent().map(|p| p.parent())); let mut repo_details = common::repo_details( 1, Generation::new(), common::forge_details(1, ForgeType::MockForge), None, GitDir::new(root), // Server GitDir - should be ignored ); repo_details.forge = repo_details .forge .with_hostname(Hostname::new("git.kemitix.net")); repo_details.repo_path = RepoPath::new("kemitix/git-next".to_string()); let gitdir = &repo_details.gitdir; let repository = Repository::open(gitdir)?; let found_git_remote = git::validate::find_default_remote(&repository, Direction::Push)?; let config_git_remote = repo_details.git_remote(); assert_eq!( found_git_remote, config_git_remote, "Default Push Remote must match config" ); Ok(()) } #[test] fn gitdir_validate_should_pass_a_valid_git_repo() -> Result<()> { let cli_crate_dir = std::env::current_dir().map_err(git::validate::Error::Io)?; let_assert!(Some(Some(root)) = cli_crate_dir.parent().map(|p| p.parent())); let mut repo_details = common::repo_details( 1, Generation::new(), common::forge_details(1, ForgeType::MockForge), None, GitDir::new(root), // Server GitDir - should be ignored ); repo_details.forge = repo_details .forge .with_hostname(Hostname::new("git.kemitix.net")); repo_details.repo_path = RepoPath::new("kemitix/git-next".to_string()); let gitdir = &repo_details.gitdir; let repository = Repository::open(gitdir)?; git::validate(&repository, &repo_details)?; Ok(()) } #[test] fn gitdir_validate_should_fail_a_git_repo_with_wrong_remote() -> Result<()> { let_assert!(Ok(cli_crate_dir) = std::env::current_dir().map_err(git::validate::Error::Io)); let_assert!(Some(Some(root)) = cli_crate_dir.parent().map(|p| p.parent())); let mut repo_details = common::repo_details( 1, Generation::new(), common::forge_details(1, ForgeType::MockForge), None, GitDir::new(root), // Server GitDir - should be ignored ); repo_details.repo_path = RepoPath::new("hello/world".to_string()); let gitdir = &repo_details.gitdir; let repository = Repository::open(gitdir)?; let_assert!(Err(_) = git::validate(&repository, &repo_details)); Ok(()) } #[test] fn git_remote_to_string_is_as_expected() { let git_remote = GitRemote::new(Hostname::new("foo"), RepoPath::new("bar".to_string())); let as_string = git_remote.to_string(); assert_eq!(as_string, "foo:bar"); }