Files
gitea-pr-review/tests/normalize_tests.rs
T

306 lines
10 KiB
Rust

use gitea_pr_review::gitea::dto::*;
use gitea_pr_review::normalize::normalize_bundle;
#[test]
fn normalize_groups_replies_and_sorts_threads_by_time() {
let bundle = PullBundleDto {
pull: PullDto {
number: 42,
title: "Fix parser".into(),
state: "open".into(),
body: Some("desc".into()),
user: UserDto {
login: "alice".into(),
},
base: PullBranchDto {
ref_name: "main".into(),
},
head: PullBranchDto {
ref_name: "feature/x".into(),
},
created_at: "2026-04-08T10:00:00Z".into(),
updated_at: "2026-04-08T11:00:00Z".into(),
merged_at: None,
additions: Some(99),
deletions: Some(33),
changed_files: Some(7),
},
reviews: vec![
ReviewDto {
id: 8,
state: "APPROVED".into(),
user: UserDto {
login: "carol".into(),
},
submitted_at: Some("2026-04-08T13:00:00Z".into()),
},
ReviewDto {
id: 7,
state: "COMMENT".into(),
user: UserDto {
login: "bob".into(),
},
submitted_at: Some("2026-04-08T12:00:00Z".into()),
},
],
comments: vec![
ReviewCommentDto {
id: 2,
body: "reply".into(),
created_at: "2026-04-08T12:02:00Z".into(),
updated_at: Some("2026-04-08T12:03:00Z".into()),
user: UserDto {
login: "bob".into(),
},
path: Some("src/main.rs".into()),
line: Some(10),
pull_request_review_id: Some(7),
in_reply_to: Some(1),
original_position: Some(10),
position: Some(10),
commit_id: Some("abc123".into()),
original_commit_id: Some("abc123".into()),
diff_hunk: Some("@@ -1 +1 @@".into()),
},
ReviewCommentDto {
id: 1,
body: "root".into(),
created_at: "2026-04-08T12:01:00Z".into(),
updated_at: Some("2026-04-08T12:02:00Z".into()),
user: UserDto {
login: "bob".into(),
},
path: Some("src/main.rs".into()),
line: Some(10),
pull_request_review_id: Some(7),
in_reply_to: None,
original_position: Some(10),
position: Some(10),
commit_id: Some("abc123".into()),
original_commit_id: Some("abc123".into()),
diff_hunk: Some("@@ -1 +1 @@".into()),
},
ReviewCommentDto {
id: 3,
body: "other thread".into(),
created_at: "2026-04-08T11:59:00Z".into(),
updated_at: None,
user: UserDto {
login: "dave".into(),
},
path: Some("src/lib.rs".into()),
line: Some(22),
pull_request_review_id: Some(8),
in_reply_to: None,
original_position: Some(22),
position: Some(22),
commit_id: Some("def456".into()),
original_commit_id: Some("def456".into()),
diff_hunk: Some("@@ -2 +2 @@".into()),
},
],
commits: vec![
CommitDto {
sha: "bbbbbbbccccccc".into(),
commit: RepoCommitDto {
message: "fix: later commit\n\nbody".into(),
author: Some(CommitUserDto {
name: "Bob".into(),
date: "2026-04-08T12:30:00Z".into(),
}),
},
},
CommitDto {
sha: "aaaaaaabbbbbbb".into(),
commit: RepoCommitDto {
message: "feat: earlier commit".into(),
author: Some(CommitUserDto {
name: "Alice".into(),
date: "2026-04-08T11:30:00Z".into(),
}),
},
},
],
files: vec![
ChangedFileDto {
filename: "src/main.rs".into(),
additions: 5,
deletions: 1,
changes: Some(6),
status: Some("modified".into()),
previous_filename: None,
},
ChangedFileDto {
filename: "src/lib.rs".into(),
additions: 3,
deletions: 2,
changes: Some(5),
status: Some("modified".into()),
previous_filename: None,
},
],
};
let doc = normalize_bundle("org/repo", "2026-04-08T12:34:56Z".into(), bundle);
assert_eq!(doc.meta.repo, "org/repo");
assert_eq!(doc.meta.pr_index, 42);
assert_eq!(doc.meta.fetched_at, "2026-04-08T12:34:56Z");
assert_eq!(doc.meta.base_branch, "main");
assert_eq!(doc.meta.head_branch, "feature/x");
assert_eq!(doc.commits.len(), 2);
assert_eq!(doc.commits[0].title, "feat: earlier commit");
assert_eq!(doc.commits[0].author, "Alice");
assert_eq!(doc.commits[1].title, "fix: later commit");
assert_eq!(doc.reviews.len(), 2);
assert_eq!(doc.reviews[0].id, 7);
assert_eq!(doc.reviews[1].id, 8);
assert_eq!(doc.diff_stat.files_changed, 2);
assert_eq!(doc.diff_stat.additions, 8);
assert_eq!(doc.diff_stat.deletions, 3);
assert_eq!(doc.diff_stat.files[0].path, "src/main.rs");
assert_eq!(doc.diff_stat.files[1].path, "src/lib.rs");
assert_eq!(doc.threads.len(), 2);
assert_eq!(doc.threads[0].root_comment.id, 3);
assert_eq!(doc.threads[0].file_path.as_deref(), Some("src/lib.rs"));
assert_eq!(doc.threads[0].line, Some(22));
assert_eq!(doc.threads[1].root_comment.id, 1);
assert_eq!(doc.threads[1].replies.len(), 1);
assert_eq!(doc.threads[1].replies[0].id, 2);
assert_eq!(doc.threads[1].file_path.as_deref(), Some("src/main.rs"));
assert_eq!(doc.threads[1].line, Some(10));
}
#[test]
fn normalize_does_not_merge_unrelated_comments_on_same_file() {
let bundle = PullBundleDto {
pull: PullDto {
number: 100,
title: "T".into(),
state: "open".into(),
body: None,
user: UserDto {
login: "alice".into(),
},
base: PullBranchDto {
ref_name: "main".into(),
},
head: PullBranchDto {
ref_name: "feature/y".into(),
},
created_at: "2026-04-08T10:00:00Z".into(),
updated_at: "2026-04-08T10:00:00Z".into(),
merged_at: None,
additions: None,
deletions: None,
changed_files: None,
},
reviews: vec![],
comments: vec![
ReviewCommentDto {
id: 10,
body: "first line comment".into(),
created_at: "2026-04-08T12:01:00Z".into(),
updated_at: None,
user: UserDto {
login: "bob".into(),
},
path: Some("src/main.rs".into()),
line: Some(10),
pull_request_review_id: Some(1),
in_reply_to: None,
original_position: Some(10),
position: Some(10),
commit_id: Some("abc123".into()),
original_commit_id: Some("abc123".into()),
diff_hunk: None,
},
ReviewCommentDto {
id: 11,
body: "second line comment".into(),
created_at: "2026-04-08T12:02:00Z".into(),
updated_at: None,
user: UserDto {
login: "bob".into(),
},
path: Some("src/main.rs".into()),
line: Some(20),
pull_request_review_id: Some(1),
in_reply_to: None,
original_position: Some(20),
position: Some(20),
commit_id: Some("abc123".into()),
original_commit_id: Some("abc123".into()),
diff_hunk: None,
},
],
commits: vec![],
files: vec![],
};
let doc = normalize_bundle("org/repo", "2026-04-08T12:34:56Z".into(), bundle);
assert_eq!(doc.threads.len(), 2);
assert_eq!(doc.threads[0].root_comment.id, 10);
assert_eq!(doc.threads[0].replies.len(), 0);
assert_eq!(doc.threads[1].root_comment.id, 11);
assert_eq!(doc.threads[1].replies.len(), 0);
}
#[test]
fn normalize_uses_non_zero_position_when_line_is_missing() {
let bundle = PullBundleDto {
pull: PullDto {
number: 101,
title: "T".into(),
state: "open".into(),
body: None,
user: UserDto {
login: "alice".into(),
},
base: PullBranchDto {
ref_name: "main".into(),
},
head: PullBranchDto {
ref_name: "feature/z".into(),
},
created_at: "2026-04-08T10:00:00Z".into(),
updated_at: "2026-04-08T10:00:00Z".into(),
merged_at: None,
additions: None,
deletions: None,
changed_files: None,
},
reviews: vec![],
comments: vec![ReviewCommentDto {
id: 1001,
body: "position based comment".into(),
created_at: "2026-04-08T12:00:00Z".into(),
updated_at: None,
user: UserDto {
login: "bob".into(),
},
path: Some("src/main.rs".into()),
line: None,
pull_request_review_id: Some(1),
in_reply_to: None,
original_position: Some(42),
position: Some(41),
commit_id: Some("abc123".into()),
original_commit_id: Some("abc123".into()),
diff_hunk: None,
}],
commits: vec![],
files: vec![],
};
let doc = normalize_bundle("org/repo", "2026-04-08T12:34:56Z".into(), bundle);
assert_eq!(doc.threads.len(), 1);
assert_eq!(doc.threads[0].root_comment.path.as_deref(), Some("src/main.rs"));
assert_eq!(doc.threads[0].root_comment.line, Some(41));
}