use assert_fs::TempDir; #[cfg(feature = "test-utils")] use jj_cz::{CommitType, Description, MockPrompts, Scope}; use jj_cz::{CommitWorkflow, Error, JjLib}; #[cfg(feature = "test-utils")] use jj_lib::{config::StackedConfig, settings::UserSettings, workspace::Workspace}; /// Helper to initialize a temporary jj repository using jj-lib directly (no CLI required) #[cfg(feature = "test-utils")] async fn init_jj_repo(temp_dir: &TempDir) { let config = StackedConfig::with_defaults(); let settings = UserSettings::from_config(config).expect("Failed to create settings"); Workspace::init_internal_git(&settings, temp_dir.path()) .await .expect("Failed to initialize jj repository"); } #[cfg(feature = "test-utils")] #[tokio::test] async fn test_happy_path_integration() { // T037: Happy path integration test let temp_dir = TempDir::new().unwrap(); init_jj_repo(&temp_dir).await; // Create mock prompts that simulate a successful workflow let mock_prompts = MockPrompts::new() .with_commit_type(CommitType::Feat) .with_scope(Scope::empty()) .with_description(Description::parse("add new feature").unwrap()) .with_confirm(true); // Create a mock executor that tracks calls let executor = JjLib::with_working_dir(temp_dir.path()); let workflow = CommitWorkflow::with_prompts(executor, mock_prompts); let result = workflow.run().await; // The workflow should complete successfully assert!( result.is_ok(), "Workflow should complete successfully: {:?}", result ); } #[tokio::test] async fn test_not_in_repo() { // T038: Not-in-repo integration test let temp_dir = TempDir::new().unwrap(); // Don't initialize jj repo // Create executor with the temp directory (which is not a jj repo) let executor = JjLib::with_working_dir(temp_dir.path()); let workflow = CommitWorkflow::new(executor); let result = workflow.run().await; // Should fail with NotARepository error assert!(matches!(result, Err(Error::NotARepository))); } #[cfg(feature = "test-utils")] #[tokio::test] async fn test_cancellation() { // T039: Cancellation integration test // This is tricky to test directly without a TTY // We'll test the error handling path instead // Create a mock executor that simulates cancellation struct CancelMock; #[async_trait::async_trait(?Send)] impl jj_cz::JjExecutor for CancelMock { async fn is_repository(&self) -> Result { Ok(true) } async fn describe(&self, _message: &str) -> Result<(), Error> { Err(Error::Cancelled) } } let executor = CancelMock; let mock_prompts = MockPrompts::new() .with_commit_type(CommitType::Feat) .with_scope(Scope::empty()) .with_description(Description::parse("test").unwrap()) .with_confirm(true); let workflow = CommitWorkflow::with_prompts(executor, mock_prompts); let result = workflow.run().await; // Should fail with Cancelled error assert!(matches!(result, Err(Error::Cancelled))); }