use super::*; use crate::core::db::{create_connection, run_migrations}; use std::path::Path; fn setup() -> Connection { let conn = create_connection(Path::new(":memory:")).unwrap(); run_migrations(&conn).unwrap(); // Insert a test project conn.execute( "INSERT INTO projects (gitlab_project_id, path_with_namespace, web_url) VALUES (1, 'group/repo', 'https://gitlab.com/group/repo')", [], ).unwrap(); // Insert a test MR conn.execute( "INSERT INTO merge_requests (gitlab_id, iid, project_id, title, state, draft, source_branch, target_branch, author_username, created_at, updated_at, last_seen_at) \ VALUES (100, 1, 1, 'Test MR', 'merged', 0, 'feature', 'main', 'testuser', 1000, 2000, 3000)", [], ).unwrap(); conn } #[test] fn test_derive_change_type_added() { let diff = GitLabMrDiff { old_path: String::new(), new_path: "src/new.rs".to_string(), new_file: true, renamed_file: false, deleted_file: false, }; assert_eq!(derive_change_type(&diff), "added"); } #[test] fn test_derive_change_type_renamed() { let diff = GitLabMrDiff { old_path: "src/old.rs".to_string(), new_path: "src/new.rs".to_string(), new_file: false, renamed_file: true, deleted_file: false, }; assert_eq!(derive_change_type(&diff), "renamed"); } #[test] fn test_derive_change_type_deleted() { let diff = GitLabMrDiff { old_path: "src/gone.rs".to_string(), new_path: "src/gone.rs".to_string(), new_file: false, renamed_file: false, deleted_file: true, }; assert_eq!(derive_change_type(&diff), "deleted"); } #[test] fn test_derive_change_type_modified() { let diff = GitLabMrDiff { old_path: "src/lib.rs".to_string(), new_path: "src/lib.rs".to_string(), new_file: false, renamed_file: false, deleted_file: false, }; assert_eq!(derive_change_type(&diff), "modified"); } #[test] fn test_upsert_inserts_file_changes() { let conn = setup(); let diffs = [ GitLabMrDiff { old_path: String::new(), new_path: "src/new.rs".to_string(), new_file: true, renamed_file: false, deleted_file: false, }, GitLabMrDiff { old_path: "src/lib.rs".to_string(), new_path: "src/lib.rs".to_string(), new_file: false, renamed_file: false, deleted_file: false, }, ]; let inserted = upsert_mr_file_changes(&conn, 1, 1, &diffs).unwrap(); assert_eq!(inserted, 2); let count: i64 = conn .query_row( "SELECT COUNT(*) FROM mr_file_changes WHERE merge_request_id = 1", [], |r| r.get(0), ) .unwrap(); assert_eq!(count, 2); } #[test] fn test_upsert_replaces_existing() { let conn = setup(); let diffs_v1 = [GitLabMrDiff { old_path: String::new(), new_path: "src/old.rs".to_string(), new_file: true, renamed_file: false, deleted_file: false, }]; upsert_mr_file_changes(&conn, 1, 1, &diffs_v1).unwrap(); let diffs_v2 = [ GitLabMrDiff { old_path: "src/a.rs".to_string(), new_path: "src/a.rs".to_string(), new_file: false, renamed_file: false, deleted_file: false, }, GitLabMrDiff { old_path: "src/b.rs".to_string(), new_path: "src/b.rs".to_string(), new_file: false, renamed_file: false, deleted_file: false, }, ]; let inserted = upsert_mr_file_changes(&conn, 1, 1, &diffs_v2).unwrap(); assert_eq!(inserted, 2); let count: i64 = conn .query_row( "SELECT COUNT(*) FROM mr_file_changes WHERE merge_request_id = 1", [], |r| r.get(0), ) .unwrap(); assert_eq!(count, 2); // The old "src/old.rs" should be gone let old_count: i64 = conn .query_row( "SELECT COUNT(*) FROM mr_file_changes WHERE new_path = 'src/old.rs'", [], |r| r.get(0), ) .unwrap(); assert_eq!(old_count, 0); } #[test] fn test_renamed_stores_old_path() { let conn = setup(); let diffs = [GitLabMrDiff { old_path: "src/old_name.rs".to_string(), new_path: "src/new_name.rs".to_string(), new_file: false, renamed_file: true, deleted_file: false, }]; upsert_mr_file_changes(&conn, 1, 1, &diffs).unwrap(); let (old_path, change_type): (Option, String) = conn .query_row( "SELECT old_path, change_type FROM mr_file_changes WHERE new_path = 'src/new_name.rs'", [], |r| Ok((r.get(0)?, r.get(1)?)), ) .unwrap(); assert_eq!(old_path.as_deref(), Some("src/old_name.rs")); assert_eq!(change_type, "renamed"); } #[test] fn test_non_renamed_has_null_old_path() { let conn = setup(); let diffs = [GitLabMrDiff { old_path: "src/lib.rs".to_string(), new_path: "src/lib.rs".to_string(), new_file: false, renamed_file: false, deleted_file: false, }]; upsert_mr_file_changes(&conn, 1, 1, &diffs).unwrap(); let old_path: Option = conn .query_row( "SELECT old_path FROM mr_file_changes WHERE new_path = 'src/lib.rs'", [], |r| r.get(0), ) .unwrap(); assert!(old_path.is_none()); }