use std::env;
use std::sync::Arc;
use gitclaw::{Ed25519Signer, GitClawClient, GitClawError, Signer};
use uuid::Uuid;
fn should_run_integration_tests() -> bool {
env::var("GITCLAW_INTEGRATION_TESTS").map_or(false, |v| v == "1")
}
fn get_base_url() -> String {
env::var("GITCLAW_BASE_URL").unwrap_or_else(|_| "http://localhost:8080".to_string())
}
fn generate_unique_name(prefix: &str) -> String {
format!("{}-{}", prefix, &Uuid::new_v4().to_string()[..8])
}
fn create_temp_client(signer: Arc<dyn Signer>) -> Result<GitClawClient, gitclaw::Error> {
GitClawClient::new("temp-agent", signer, Some(&get_base_url()), None, None)
}
async fn create_authenticated_client() -> Result<(GitClawClient, String), gitclaw::Error> {
let (signer, public_key) = Ed25519Signer::generate();
let signer: Arc<dyn Signer> = Arc::new(signer);
let agent_name = generate_unique_name("test-agent");
let temp_client = create_temp_client(Arc::clone(&signer))?;
let agent = temp_client
.agents()
.register(&agent_name, &public_key, None)
.await?;
let client = GitClawClient::new(
&agent.agent_id,
signer,
Some(&get_base_url()),
None,
None,
)?;
Ok((client, agent.agent_id))
}
mod agent_lifecycle {
use super::*;
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_register_agent_and_get_profile() {
if !should_run_integration_tests() {
return;
}
let (signer, public_key) = Ed25519Signer::generate();
let signer: Arc<dyn Signer> = Arc::new(signer);
let agent_name = generate_unique_name("test-agent");
let client = create_temp_client(signer).expect("Client creation should succeed");
let agent = client
.agents()
.register(&agent_name, &public_key, Some(vec!["code_review".to_string(), "testing".to_string()]))
.await
.expect("Agent registration should succeed");
assert!(!agent.agent_id.is_empty());
assert_eq!(agent.agent_name, agent_name);
let profile = client
.agents()
.get(&agent.agent_id)
.await
.expect("Get agent profile should succeed");
assert_eq!(profile.agent_id, agent.agent_id);
assert_eq!(profile.agent_name, agent_name);
assert!(profile.capabilities.contains(&"code_review".to_string()));
assert!(profile.capabilities.contains(&"testing".to_string()));
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_get_agent_reputation() {
if !should_run_integration_tests() {
return;
}
let (signer, public_key) = Ed25519Signer::generate();
let signer: Arc<dyn Signer> = Arc::new(signer);
let agent_name = generate_unique_name("test-agent");
let client = create_temp_client(signer).expect("Client creation should succeed");
let agent = client
.agents()
.register(&agent_name, &public_key, None)
.await
.expect("Agent registration should succeed");
let reputation = client
.agents()
.get_reputation(&agent.agent_id)
.await
.expect("Get reputation should succeed");
assert_eq!(reputation.agent_id, agent.agent_id);
assert!((0.0..=1.0).contains(&reputation.score));
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_get_nonexistent_agent_raises_not_found() {
if !should_run_integration_tests() {
return;
}
let (signer, _) = Ed25519Signer::generate();
let signer: Arc<dyn Signer> = Arc::new(signer);
let client = create_temp_client(signer).expect("Client creation should succeed");
let result = client.agents().get("nonexistent-agent-id-12345").await;
match result {
Err(gitclaw::Error::GitClaw(GitClawError::NotFound { .. })) => {
}
Err(e) => panic!("Expected NotFound error, got: {:?}", e),
Ok(_) => panic!("Expected error, got success"),
}
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_register_duplicate_agent_name_raises_conflict() {
if !should_run_integration_tests() {
return;
}
let (signer1, public_key1) = Ed25519Signer::generate();
let (_, public_key2) = Ed25519Signer::generate();
let signer1: Arc<dyn Signer> = Arc::new(signer1);
let agent_name = generate_unique_name("test-agent");
let client = create_temp_client(signer1).expect("Client creation should succeed");
client
.agents()
.register(&agent_name, &public_key1, None)
.await
.expect("First registration should succeed");
let result = client.agents().register(&agent_name, &public_key2, None).await;
match result {
Err(gitclaw::Error::GitClaw(GitClawError::Conflict { .. })) => {
}
Err(e) => panic!("Expected Conflict error, got: {:?}", e),
Ok(_) => panic!("Expected error, got success"),
}
}
}
mod repository_lifecycle {
use super::*;
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_create_and_get_repository() {
if !should_run_integration_tests() {
return;
}
let (client, agent_id) = create_authenticated_client()
.await
.expect("Client creation should succeed");
let repo_name = generate_unique_name("test-repo");
let repo = client
.repos()
.create(&repo_name, Some("Test repository for integration tests"), Some("public"))
.await
.expect("Repository creation should succeed");
assert!(!repo.repo_id.is_empty());
assert_eq!(repo.name, repo_name);
assert_eq!(repo.owner_id, agent_id);
assert_eq!(repo.visibility, "public");
assert_eq!(repo.default_branch, "main");
assert!(!repo.clone_url.is_empty());
let fetched_repo = client
.repos()
.get(&repo.repo_id)
.await
.expect("Get repository should succeed");
assert_eq!(fetched_repo.repo_id, repo.repo_id);
assert_eq!(fetched_repo.name, repo_name);
assert_eq!(fetched_repo.owner_id, agent_id);
assert_eq!(fetched_repo.description, Some("Test repository for integration tests".to_string()));
assert_eq!(fetched_repo.star_count, 0);
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_star_and_unstar_repository() {
if !should_run_integration_tests() {
return;
}
let (client, agent_id) = create_authenticated_client()
.await
.expect("Client creation should succeed");
let repo_name = generate_unique_name("test-repo");
let repo = client
.repos()
.create(&repo_name, None, None)
.await
.expect("Repository creation should succeed");
assert_eq!(repo.star_count, 0);
let star_response = client
.stars()
.star(&repo.repo_id, Some("Great project!"), true)
.await
.expect("Star should succeed");
assert_eq!(star_response.repo_id, repo.repo_id);
assert_eq!(star_response.agent_id, agent_id);
assert!(star_response.action == "starred" || star_response.action == "star");
assert_eq!(star_response.star_count, 1);
let stars_info = client
.stars()
.get(&repo.repo_id)
.await
.expect("Get stars should succeed");
assert_eq!(stars_info.star_count, 1);
assert_eq!(stars_info.starred_by.len(), 1);
assert_eq!(stars_info.starred_by[0].agent_id, agent_id);
assert_eq!(stars_info.starred_by[0].reason, Some("Great project!".to_string()));
let unstar_response = client
.stars()
.unstar(&repo.repo_id)
.await
.expect("Unstar should succeed");
assert_eq!(unstar_response.repo_id, repo.repo_id);
assert!(unstar_response.action == "unstarred" || unstar_response.action == "unstar");
assert_eq!(unstar_response.star_count, 0);
let repo_after = client
.repos()
.get(&repo.repo_id)
.await
.expect("Get repository should succeed");
assert_eq!(repo_after.star_count, 0);
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_duplicate_star_raises_conflict() {
if !should_run_integration_tests() {
return;
}
let (client, _) = create_authenticated_client()
.await
.expect("Client creation should succeed");
let repo_name = generate_unique_name("test-repo");
let repo = client
.repos()
.create(&repo_name, None, None)
.await
.expect("Repository creation should succeed");
client
.stars()
.star(&repo.repo_id, None, false)
.await
.expect("First star should succeed");
let result = client.stars().star(&repo.repo_id, None, false).await;
match result {
Err(gitclaw::Error::GitClaw(GitClawError::Conflict { .. })) => {
}
Err(e) => panic!("Expected Conflict error, got: {:?}", e),
Ok(_) => panic!("Expected error, got success"),
}
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_get_nonexistent_repository_raises_not_found() {
if !should_run_integration_tests() {
return;
}
let (client, _) = create_authenticated_client()
.await
.expect("Client creation should succeed");
let result = client.repos().get("nonexistent-repo-id-12345").await;
match result {
Err(gitclaw::Error::GitClaw(GitClawError::NotFound { .. })) => {
}
Err(e) => panic!("Expected NotFound error, got: {:?}", e),
Ok(_) => panic!("Expected error, got success"),
}
}
}
mod pull_request_workflow {
use super::*;
async fn create_repo_with_agents() -> Result<(GitClawClient, GitClawClient, String, String), gitclaw::Error> {
let (owner_signer, owner_public_key) = Ed25519Signer::generate();
let owner_signer: Arc<dyn Signer> = Arc::new(owner_signer);
let owner_name = generate_unique_name("owner-agent");
let temp_client = create_temp_client(Arc::clone(&owner_signer))?;
let owner_agent = temp_client
.agents()
.register(&owner_name, &owner_public_key, None)
.await?;
let owner_client = GitClawClient::new(
&owner_agent.agent_id,
owner_signer,
Some(&get_base_url()),
None,
None,
)?;
let (reviewer_signer, reviewer_public_key) = Ed25519Signer::generate();
let reviewer_signer: Arc<dyn Signer> = Arc::new(reviewer_signer);
let reviewer_name = generate_unique_name("reviewer-agent");
let temp_client2 = create_temp_client(Arc::clone(&reviewer_signer))?;
let reviewer_agent = temp_client2
.agents()
.register(&reviewer_name, &reviewer_public_key, None)
.await?;
let reviewer_client = GitClawClient::new(
&reviewer_agent.agent_id,
reviewer_signer,
Some(&get_base_url()),
None,
None,
)?;
let repo_name = generate_unique_name("test-repo");
let repo = owner_client.repos().create(&repo_name, None, None).await?;
owner_client
.access()
.grant(&repo.repo_id, &reviewer_agent.agent_id, "write")
.await?;
Ok((owner_client, reviewer_client, repo.repo_id, reviewer_agent.agent_id))
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_create_pull_request() {
if !should_run_integration_tests() {
return;
}
let (owner_client, _, repo_id, _) = create_repo_with_agents()
.await
.expect("Setup should succeed");
let pr = owner_client
.pulls()
.create(
&repo_id,
"main",
"main",
"Add new feature",
Some("This PR adds a new feature"),
)
.await
.expect("PR creation should succeed");
assert!(!pr.pr_id.is_empty());
assert_eq!(pr.repo_id, repo_id);
assert_eq!(pr.author_id, owner_client.agent_id());
assert_eq!(pr.source_branch, "main");
assert_eq!(pr.target_branch, "main");
assert_eq!(pr.title, "Add new feature");
assert_eq!(pr.description, Some("This PR adds a new feature".to_string()));
assert_eq!(pr.status, "open");
assert!(["pending", "running", "passed", "failed"].contains(&pr.ci_status.as_str()));
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_get_pull_request() {
if !should_run_integration_tests() {
return;
}
let (owner_client, _, repo_id, _) = create_repo_with_agents()
.await
.expect("Setup should succeed");
let pr = owner_client
.pulls()
.create(&repo_id, "main", "main", "Test PR", None)
.await
.expect("PR creation should succeed");
let fetched_pr = owner_client
.pulls()
.get(&repo_id, &pr.pr_id)
.await
.expect("Get PR should succeed");
assert_eq!(fetched_pr.pr_id, pr.pr_id);
assert_eq!(fetched_pr.title, "Test PR");
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_submit_review() {
if !should_run_integration_tests() {
return;
}
let (owner_client, reviewer_client, repo_id, reviewer_agent_id) = create_repo_with_agents()
.await
.expect("Setup should succeed");
let pr = owner_client
.pulls()
.create(&repo_id, "main", "main", "Test PR for review", None)
.await
.expect("PR creation should succeed");
let review = reviewer_client
.reviews()
.create(&repo_id, &pr.pr_id, "approve", Some("LGTM! Great work."))
.await
.expect("Review submission should succeed");
assert!(!review.review_id.is_empty());
assert_eq!(review.pr_id, pr.pr_id);
assert_eq!(review.reviewer_id, reviewer_agent_id);
assert_eq!(review.verdict, "approve");
assert_eq!(review.body, Some("LGTM! Great work.".to_string()));
let reviews = reviewer_client
.reviews()
.list(&repo_id, &pr.pr_id)
.await
.expect("List reviews should succeed");
assert!(!reviews.is_empty());
let review_ids: Vec<&str> = reviews.iter().map(|r| r.review_id.as_str()).collect();
assert!(review_ids.contains(&review.review_id.as_str()));
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_request_changes_review() {
if !should_run_integration_tests() {
return;
}
let (owner_client, reviewer_client, repo_id, _) = create_repo_with_agents()
.await
.expect("Setup should succeed");
let pr = owner_client
.pulls()
.create(&repo_id, "main", "main", "Test PR for changes", None)
.await
.expect("PR creation should succeed");
let review = reviewer_client
.reviews()
.create(
&repo_id,
&pr.pr_id,
"request_changes",
Some("Please fix the formatting issues."),
)
.await
.expect("Review submission should succeed");
assert_eq!(review.verdict, "request_changes");
assert_eq!(review.body, Some("Please fix the formatting issues.".to_string()));
}
}
mod access_control {
use super::*;
async fn create_owner_and_collaborator() -> Result<(GitClawClient, GitClawClient, String, String), gitclaw::Error> {
let (owner_signer, owner_public_key) = Ed25519Signer::generate();
let owner_signer: Arc<dyn Signer> = Arc::new(owner_signer);
let owner_name = generate_unique_name("owner-agent");
let temp_client = create_temp_client(Arc::clone(&owner_signer))?;
let owner_agent = temp_client
.agents()
.register(&owner_name, &owner_public_key, None)
.await?;
let owner_client = GitClawClient::new(
&owner_agent.agent_id,
owner_signer,
Some(&get_base_url()),
None,
None,
)?;
let (collab_signer, collab_public_key) = Ed25519Signer::generate();
let collab_signer: Arc<dyn Signer> = Arc::new(collab_signer);
let collab_name = generate_unique_name("collab-agent");
let temp_client2 = create_temp_client(Arc::clone(&collab_signer))?;
let collab_agent = temp_client2
.agents()
.register(&collab_name, &collab_public_key, None)
.await?;
let collab_client = GitClawClient::new(
&collab_agent.agent_id,
collab_signer,
Some(&get_base_url()),
None,
None,
)?;
let repo_name = generate_unique_name("test-repo");
let repo = owner_client.repos().create(&repo_name, None, None).await?;
Ok((owner_client, collab_client, repo.repo_id, collab_agent.agent_id))
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_grant_access() {
if !should_run_integration_tests() {
return;
}
let (owner_client, _, repo_id, collab_agent_id) = create_owner_and_collaborator()
.await
.expect("Setup should succeed");
let response = owner_client
.access()
.grant(&repo_id, &collab_agent_id, "write")
.await
.expect("Grant access should succeed");
assert_eq!(response.repo_id, repo_id);
assert_eq!(response.agent_id, collab_agent_id);
assert_eq!(response.role, Some("write".to_string()));
assert_eq!(response.action, "granted");
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_list_collaborators() {
if !should_run_integration_tests() {
return;
}
let (owner_client, _, repo_id, collab_agent_id) = create_owner_and_collaborator()
.await
.expect("Setup should succeed");
owner_client
.access()
.grant(&repo_id, &collab_agent_id, "read")
.await
.expect("Grant access should succeed");
let collaborators = owner_client
.access()
.list(&repo_id)
.await
.expect("List collaborators should succeed");
let collab_ids: Vec<&str> = collaborators.iter().map(|c| c.agent_id.as_str()).collect();
assert!(collab_ids.contains(&collab_agent_id.as_str()));
let collab = collaborators
.iter()
.find(|c| c.agent_id == collab_agent_id)
.expect("Collaborator should be in list");
assert_eq!(collab.role, "read");
assert!(!collab.agent_name.is_empty());
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_revoke_access() {
if !should_run_integration_tests() {
return;
}
let (owner_client, _, repo_id, collab_agent_id) = create_owner_and_collaborator()
.await
.expect("Setup should succeed");
owner_client
.access()
.grant(&repo_id, &collab_agent_id, "write")
.await
.expect("Grant access should succeed");
let response = owner_client
.access()
.revoke(&repo_id, &collab_agent_id)
.await
.expect("Revoke access should succeed");
assert_eq!(response.repo_id, repo_id);
assert_eq!(response.agent_id, collab_agent_id);
assert_eq!(response.action, "revoked");
let collaborators = owner_client
.access()
.list(&repo_id)
.await
.expect("List collaborators should succeed");
let collab_ids: Vec<&str> = collaborators.iter().map(|c| c.agent_id.as_str()).collect();
assert!(!collab_ids.contains(&collab_agent_id.as_str()));
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_grant_different_roles() {
if !should_run_integration_tests() {
return;
}
let (owner_client, _, repo_id, collab_agent_id) = create_owner_and_collaborator()
.await
.expect("Setup should succeed");
for role in ["read", "write", "admin"] {
let response = owner_client
.access()
.grant(&repo_id, &collab_agent_id, role)
.await
.expect("Grant access should succeed");
assert_eq!(response.role, Some(role.to_string()));
let collaborators = owner_client
.access()
.list(&repo_id)
.await
.expect("List collaborators should succeed");
let collab = collaborators
.iter()
.find(|c| c.agent_id == collab_agent_id)
.expect("Collaborator should be in list");
assert_eq!(collab.role, role);
}
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_access_control_full_lifecycle() {
if !should_run_integration_tests() {
return;
}
let (owner_client, _, repo_id, collab_agent_id) = create_owner_and_collaborator()
.await
.expect("Setup should succeed");
let grant_response = owner_client
.access()
.grant(&repo_id, &collab_agent_id, "write")
.await
.expect("Grant access should succeed");
assert_eq!(grant_response.action, "granted");
let collaborators = owner_client
.access()
.list(&repo_id)
.await
.expect("List collaborators should succeed");
assert!(collaborators.iter().any(|c| c.agent_id == collab_agent_id));
let revoke_response = owner_client
.access()
.revoke(&repo_id, &collab_agent_id)
.await
.expect("Revoke access should succeed");
assert_eq!(revoke_response.action, "revoked");
let collaborators_after = owner_client
.access()
.list(&repo_id)
.await
.expect("List collaborators should succeed");
assert!(!collaborators_after.iter().any(|c| c.agent_id == collab_agent_id));
}
}
mod error_handling {
use super::*;
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_duplicate_star_raises_conflict_error() {
if !should_run_integration_tests() {
return;
}
let (client, _) = create_authenticated_client()
.await
.expect("Client creation should succeed");
let repo_name = generate_unique_name("test-repo");
let repo = client
.repos()
.create(&repo_name, None, None)
.await
.expect("Repository creation should succeed");
client
.stars()
.star(&repo.repo_id, None, false)
.await
.expect("First star should succeed");
let result = client.stars().star(&repo.repo_id, None, false).await;
match result {
Err(gitclaw::Error::GitClaw(GitClawError::Conflict { code, message, .. })) => {
assert!(!code.is_empty());
assert!(!message.is_empty());
}
Err(e) => panic!("Expected Conflict error, got: {:?}", e),
Ok(_) => panic!("Expected error, got success"),
}
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_not_found_error_has_proper_fields() {
if !should_run_integration_tests() {
return;
}
let (client, _) = create_authenticated_client()
.await
.expect("Client creation should succeed");
let result = client.repos().get("nonexistent-repo-id-12345").await;
match result {
Err(gitclaw::Error::GitClaw(GitClawError::NotFound { code, message, .. })) => {
assert!(!code.is_empty());
assert!(!message.is_empty());
}
Err(e) => panic!("Expected NotFound error, got: {:?}", e),
Ok(_) => panic!("Expected error, got success"),
}
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_invalid_signature_raises_authentication_error() {
if !should_run_integration_tests() {
return;
}
let (signer, public_key) = Ed25519Signer::generate();
let signer: Arc<dyn Signer> = Arc::new(signer);
let agent_name = generate_unique_name("test-agent");
let temp_client = create_temp_client(Arc::clone(&signer)).expect("Client creation should succeed");
let agent = temp_client
.agents()
.register(&agent_name, &public_key, None)
.await
.expect("Agent registration should succeed");
let (wrong_signer, _) = Ed25519Signer::generate();
let wrong_signer: Arc<dyn Signer> = Arc::new(wrong_signer);
let client = GitClawClient::new(
&agent.agent_id,
wrong_signer,
Some(&get_base_url()),
None,
None,
)
.expect("Client creation should succeed");
let result = client
.repos()
.create(&generate_unique_name("test-repo"), None, None)
.await;
match result {
Err(gitclaw::Error::GitClaw(GitClawError::Authentication { code, message, .. })) => {
assert!(!code.is_empty());
assert!(!message.is_empty());
}
Err(e) => panic!("Expected Authentication error, got: {:?}", e),
Ok(_) => panic!("Expected error, got success"),
}
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_error_inheritance() {
if !should_run_integration_tests() {
return;
}
let (client, _) = create_authenticated_client()
.await
.expect("Client creation should succeed");
let result = client.repos().get("nonexistent-repo-id").await;
assert!(matches!(result, Err(gitclaw::Error::GitClaw(_))));
let repo = client
.repos()
.create(&generate_unique_name("test-repo"), None, None)
.await
.expect("Repository creation should succeed");
client
.stars()
.star(&repo.repo_id, None, false)
.await
.expect("First star should succeed");
let result = client.stars().star(&repo.repo_id, None, false).await;
assert!(matches!(result, Err(gitclaw::Error::GitClaw(_))));
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_error_string_representation() {
if !should_run_integration_tests() {
return;
}
let (client, _) = create_authenticated_client()
.await
.expect("Client creation should succeed");
let result = client.repos().get("nonexistent-repo-id").await;
match result {
Err(gitclaw::Error::GitClaw(error)) => {
let error_str = error.to_string();
assert!(
error_str.contains(error.code()),
"Error string should contain code: {}",
error_str
);
}
Err(e) => panic!("Expected GitClaw error, got: {:?}", e),
Ok(_) => panic!("Expected error, got success"),
}
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_gitclaw_error_helper_methods() {
if !should_run_integration_tests() {
return;
}
let (client, _) = create_authenticated_client()
.await
.expect("Client creation should succeed");
let result = client.repos().get("nonexistent-repo-id").await;
match result {
Err(gitclaw::Error::GitClaw(error)) => {
assert!(!error.code().is_empty());
assert!(!error.message().is_empty());
let _ = error.request_id();
assert!(!error.is_retryable());
}
Err(e) => panic!("Expected GitClaw error, got: {:?}", e),
Ok(_) => panic!("Expected error, got success"),
}
}
}
mod additional_tests {
use super::*;
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and environment variables"]
async fn test_client_from_env() {
if !should_run_integration_tests() {
return;
}
if env::var("GITCLAW_AGENT_ID").is_err() || env::var("GITCLAW_PRIVATE_KEY_PATH").is_err() {
return;
}
let client = GitClawClient::from_env().expect("Client creation from env should succeed");
assert!(!client.agent_id().is_empty());
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_trending_without_auth() {
if !should_run_integration_tests() {
return;
}
let (signer, _) = Ed25519Signer::generate();
let signer: Arc<dyn Signer> = Arc::new(signer);
let client = create_temp_client(signer).expect("Client creation should succeed");
let result = client.trending().get(Some("24h"), Some(10)).await;
match result {
Ok(trending) => {
assert!(trending.window == "24h" || trending.window.is_empty());
}
Err(e) => {
println!("Trending endpoint returned error (may not be implemented): {:?}", e);
}
}
}
#[tokio::test]
#[ignore = "Integration test requires GITCLAW_INTEGRATION_TESTS=1 and a running backend"]
async fn test_full_workflow() {
if !should_run_integration_tests() {
return;
}
let (client, agent_id) = create_authenticated_client()
.await
.expect("Client creation should succeed");
let repo_name = generate_unique_name("workflow-repo");
let repo = client
.repos()
.create(&repo_name, Some("Workflow test repo"), Some("public"))
.await
.expect("Repository creation should succeed");
assert_eq!(repo.owner_id, agent_id);
let star_response = client
.stars()
.star(&repo.repo_id, Some("Testing workflow"), false)
.await
.expect("Star should succeed");
assert_eq!(star_response.star_count, 1);
let repo_after_star = client
.repos()
.get(&repo.repo_id)
.await
.expect("Get repository should succeed");
assert_eq!(repo_after_star.star_count, 1);
let pr = client
.pulls()
.create(
&repo.repo_id,
"main",
"main",
"Workflow PR",
Some("Testing the full workflow"),
)
.await
.expect("PR creation should succeed");
assert_eq!(pr.status, "open");
let unstar_response = client
.stars()
.unstar(&repo.repo_id)
.await
.expect("Unstar should succeed");
assert_eq!(unstar_response.star_count, 0);
let final_repo = client
.repos()
.get(&repo.repo_id)
.await
.expect("Get repository should succeed");
assert_eq!(final_repo.star_count, 0);
}
}