travelagent-forge-github 1.11.1

GitHub forge backend for travelagent
Documentation
//! Live smoke tests for the GitHub forge backend.
//!
//! All tests are `#[ignore]`d so they stay out of default CI. Two tiers:
//!
//! 1. **github.com public**: `GITHUB_TOKEN` env var. Hits public
//!    repos on the public SaaS instance.
//!
//! 2. **GitHub Enterprise smoke** (ROADMAP #767, GH-side analog):
//!    `TRV_SMOKE_GITHUB_BASE_URL`, `TRV_SMOKE_GITHUB_TOKEN`,
//!    `TRV_SMOKE_GITHUB_OWNER`, `TRV_SMOKE_GITHUB_REPO`, and
//!    `TRV_SMOKE_GITHUB_PR`. Covers the base-URL rewriting that
//!    `api.github.com` doesn't exercise.
//!
//! Run either tier with:
//!
//! ```text
//! cargo test -p travelagent-forge-github --test live_smoke -- --ignored
//! ```
//!
//! See `docs/forge-smoke-tests.md` for the full runbook.

use travelagent_core::forge::*;
use travelagent_forge_github::GitHubForge;

#[tokio::test]
#[ignore] // Requires GITHUB_TOKEN; run with: cargo test -- --ignored
async fn live_github_fetch_ripgrep_pr() {
    let forge = if let Ok(f) = GitHubForge::new() {
        f
    } else {
        eprintln!("Skipping: no GitHub token");
        return;
    };
    let pr_id = PrId {
        owner: "BurntSushi".into(),
        repo: "ripgrep".into(),
        number: 2900,
    };

    let meta = forge.get_pr(&pr_id).await.unwrap();
    assert_eq!(meta.author, "tmccombs");
    assert!(!meta.title.is_empty());

    let files = forge.get_pr_files(&pr_id).await.unwrap();
    assert!(!files.is_empty());

    let commits = forge.get_pr_commits(&pr_id).await.unwrap();
    assert!(!commits.is_empty());

    let comments = forge.get_comments(&pr_id).await.unwrap();
    // May or may not have comments, just verify it doesn't error
    let _ = comments;
}

#[tokio::test]
#[ignore]
async fn live_github_fetch_large_pr() {
    // rust-lang/rust#128440 -- 666 files
    let forge = if let Ok(f) = GitHubForge::new() {
        f
    } else {
        eprintln!("Skipping: no GitHub token");
        return;
    };
    let pr_id = PrId {
        owner: "rust-lang".into(),
        repo: "rust".into(),
        number: 128440,
    };

    let meta = forge.get_pr(&pr_id).await.unwrap();
    assert_eq!(meta.state, PrState::Closed); // This PR was closed

    let files = forge.get_pr_files(&pr_id).await.unwrap();
    assert!(
        files.len() > 100,
        "Expected 600+ files, got {}",
        files.len()
    );

    let commits = forge.get_pr_commits(&pr_id).await.unwrap();
    assert!(commits.len() >= 4);
}

/// GitHub Enterprise smoke harness (ROADMAP #767, GH-side analog of
/// the GitLab self-hosted test).
///
/// Reads the five `TRV_SMOKE_GITHUB_*` env vars and, if all are set,
/// runs `get_pr` → `get_pr_files` → `get_pr_commits` → `get_comments`
/// against the configured PR. Any var unset skips silently so
/// contributors without access can `--ignored` the suite.
#[tokio::test]
#[ignore]
async fn live_github_enterprise_smoke() {
    let (base_url, token, owner, repo, pr) = match (
        std::env::var("TRV_SMOKE_GITHUB_BASE_URL"),
        std::env::var("TRV_SMOKE_GITHUB_TOKEN"),
        std::env::var("TRV_SMOKE_GITHUB_OWNER"),
        std::env::var("TRV_SMOKE_GITHUB_REPO"),
        std::env::var("TRV_SMOKE_GITHUB_PR"),
    ) {
        (Ok(a), Ok(b), Ok(c), Ok(d), Ok(e))
            if !a.is_empty() && !b.is_empty() && !c.is_empty() && !d.is_empty() =>
        {
            (a, b, c, d, e)
        }
        _ => {
            eprintln!(
                "Skipping: TRV_SMOKE_GITHUB_BASE_URL/TOKEN/OWNER/REPO/PR must all be set. \
                 See docs/forge-smoke-tests.md."
            );
            return;
        }
    };
    let number: u64 = pr.parse().expect("TRV_SMOKE_GITHUB_PR must parse as a u64");

    let forge =
        GitHubForge::with_token(&base_url, token).expect("GH Enterprise GitHubForge construction");

    let pr_id = PrId {
        owner,
        repo,
        number,
    };

    let meta = forge.get_pr(&pr_id).await.expect("get_pr");
    assert!(!meta.title.is_empty(), "PR must have a title");

    let files = forge.get_pr_files(&pr_id).await.expect("get_pr_files");
    eprintln!(
        "GH-Enterprise smoke: PR {} has {} changed file(s)",
        pr_id.number,
        files.len()
    );

    let commits = forge.get_pr_commits(&pr_id).await.expect("get_pr_commits");
    assert!(!commits.is_empty(), "PR must have at least one commit");

    let _comments = forge.get_comments(&pr_id).await.expect("get_comments");
}