git-next-core 0.14.1

core for git-next, the trunk-based development manager
Documentation
use crate::s;

//
use super::*;

// clone - can't test are this required a remote server (git_clone only works with https origins)
// open
// - outside storage path
// - - auth matches
#[test_log::test]
fn open_where_storage_external_auth_matches() -> TestResult {
    //given
    let fs = given::a_filesystem();
    let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::External);
    let repo_details = given::repo_details(&fs).with_gitdir(gitdir);
    let url = repo_details.url();
    let url = url.expose_secret();
    given::a_bare_repo_with_url(fs.base(), url, &fs);
    let factory = git::repository::factory::real();

    //when
    let result = factory.open(&repo_details);

    //then
    tracing::debug!(?result, "open");
    assert!(result.is_ok());
    // verify origin in .git/config matches url
    let config = s!(fs.file(&fs.base().join("config")).reader()?);
    tracing::debug!(config=?config.lines().collect::<Vec<_>>(), "auth");
    assert!(config.lines().any(|line| line.contains(url)));
    Ok(())
}
// - outside storage path
// - - NEW: auth does not match
// - - - do *NOT* change repo config
#[test_log::test]
fn open_where_storage_external_auth_differs_error() -> TestResult {
    //given
    let fs = given::a_filesystem();
    let repo_details = given::repo_details(&fs);
    let original_url = repo_details.url();
    let original_url = original_url.expose_secret();
    given::a_bare_repo_with_url(fs.base(), original_url, &fs);
    let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::External);
    let factory = git::repository::factory::real();
    // create new authentication
    let api_token = ApiToken::new(given::a_name().into());
    let forge_details = repo_details.forge.clone().with_token(api_token);
    let repo_details = repo_details.with_gitdir(gitdir).with_forge(forge_details);

    //when
    let_assert!(Err(err) = factory.open(&repo_details));

    //then
    tracing::debug!(?err, "open");
    assert!(matches!(
        err,
        git::repository::Error::MismatchDefaultFetchRemote {
            found: _,
            expected: _
        }
    ));

    // verify origin in .git/config is unchanged
    let config = s!(fs.file(&fs.base().join("config")).reader()?);
    tracing::debug!(config=?config.lines().collect::<Vec<_>>(), "auth");
    assert!(config.lines().any(|line| line.contains(original_url))); // the original urk
    Ok(())
}
// - in storage path
// - - auth matches
#[test_log::test]
fn open_where_storage_internal_auth_matches() -> TestResult {
    //given
    let fs = given::a_filesystem();
    let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
    let repo_details = given::repo_details(&fs).with_gitdir(gitdir);
    let url = repo_details.url();
    let url = url.expose_secret();
    // create a bare repg with the auth from the forge_config
    given::a_bare_repo_with_url(fs.base(), url, &fs);
    let factory = git::repository::factory::real();

    //when
    let result = factory.open(&repo_details);

    //then
    tracing::debug!(?result, "open");
    assert!(result.is_ok());
    // verify origin in .git/config matches url
    let config = s!(fs.file(&fs.base().join("config")).reader()?);
    tracing::debug!(config=?config.lines().collect::<Vec<_>>(), "auth");
    assert!(
        config.lines().any(|line| line.contains(url)),
        "Mismatched URL should not be updated"
    );
    Ok(())
}
// - in storage path
// - - NEW: auth does not match
// - - - CHANGE repo config to match updated auth
#[test_log::test]
fn open_where_storage_internal_auth_differs_update_config() -> TestResult {
    //given
    let fs = given::a_filesystem();
    let repo_details = given::repo_details(&fs);
    let original_url = repo_details.url();
    let original_url = original_url.expose_secret();
    given::a_bare_repo_with_url(fs.base(), original_url, &fs);
    let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
    let factory = git::repository::factory::real();
    // create new authentication
    let api_token = ApiToken::new(given::a_name().into());
    let forge_details = repo_details.forge.clone().with_token(api_token);
    let repo_details = repo_details.with_gitdir(gitdir).with_forge(forge_details);
    let updated_url = repo_details.url();
    let updated_url = updated_url.expose_secret().to_lowercase();

    //when
    let result = factory.open(&repo_details);

    //then
    assert!(result.is_ok());

    // verify origin in .git/config is unchanged
    let config = s!(fs.file(&fs.base().join("config")).reader()?);
    tracing::debug!(config=?config.lines().collect::<Vec<_>>(), "auth");
    assert!(
        config
            .lines()
            .any(|line| line.to_lowercase().contains(&updated_url)),
        "Updated URL should be written to config file"
    );
    Ok(())
}