Files
IdeA/crates/app-tauri/tests/dto_git.rs
Blomios 307ae71857 feat: add main features
Agents for developpement added + frontend add + backend added. Git viewer created + agent and template creator + layout and project creator
2026-06-06 01:27:01 +02:00

263 lines
8.6 KiB
Rust

//! L8 tests for the Git DTO (de)serialisation contract: camelCase on the
//! wire, transparent list shapes, `From<…Output>` conversions, and request
//! DTO deserialisation.
use app_tauri_lib::dto::{
GitBranchesDto, GitCheckoutRequestDto, GitCommitDto, GitCommitListDto, GitCommitRequestDto,
GitFileStatusDto, GitStageRequestDto, GitStatusListDto, GraphCommitDto, GraphCommitListDto,
};
use application::{GitBranchesOutput, GitCommitOutput, GitGraphOutput, GitLogOutput, GitStatusOutput};
use domain::ports::{GitCommitInfo, GitFileStatus, GraphCommit};
use serde_json::json;
use uuid::Uuid;
// ---------------------------------------------------------------------------
// GitFileStatusDto serialisation
// ---------------------------------------------------------------------------
#[test]
fn git_file_status_dto_serialises_camelcase() {
let dto = GitFileStatusDto {
path: "src/main.rs".to_owned(),
staged: true,
};
let v = serde_json::to_value(&dto).unwrap();
assert_eq!(v["path"], "src/main.rs");
assert_eq!(v["staged"], true);
// no snake_case leak — both fields are single words so no renaming needed,
// but verify no extra/unexpected keys.
assert!(v.get("path").is_some());
assert!(v.get("staged").is_some());
}
#[test]
fn git_file_status_from_domain_type() {
let domain = GitFileStatus {
path: "README.md".to_owned(),
staged: false,
};
let dto = GitFileStatusDto::from(domain);
assert_eq!(dto.path, "README.md");
assert!(!dto.staged);
}
// ---------------------------------------------------------------------------
// GitStatusListDto — transparent array
// ---------------------------------------------------------------------------
#[test]
fn git_status_list_dto_is_transparent_array() {
let out = GitStatusOutput {
entries: vec![
GitFileStatus {
path: "a.rs".to_owned(),
staged: true,
},
GitFileStatus {
path: "b.rs".to_owned(),
staged: false,
},
],
};
let dto = GitStatusListDto::from(out);
let v = serde_json::to_value(&dto).unwrap();
let arr = v.as_array().expect("transparent array");
assert_eq!(arr.len(), 2);
assert_eq!(arr[0]["path"], "a.rs");
assert_eq!(arr[0]["staged"], true);
assert_eq!(arr[1]["path"], "b.rs");
assert_eq!(arr[1]["staged"], false);
}
// ---------------------------------------------------------------------------
// GitCommitDto serialisation & From impls
// ---------------------------------------------------------------------------
#[test]
fn git_commit_dto_serialises_camelcase() {
let dto = GitCommitDto {
hash: "abc123".to_owned(),
summary: "feat: add git support".to_owned(),
};
let v = serde_json::to_value(&dto).unwrap();
assert_eq!(v["hash"], "abc123");
assert_eq!(v["summary"], "feat: add git support");
}
#[test]
fn git_commit_dto_from_commit_info() {
let info = GitCommitInfo {
hash: "deadbeef".to_owned(),
summary: "fix: something".to_owned(),
};
let dto = GitCommitDto::from(info);
assert_eq!(dto.hash, "deadbeef");
assert_eq!(dto.summary, "fix: something");
}
#[test]
fn git_commit_dto_from_commit_output() {
let out = GitCommitOutput {
commit: GitCommitInfo {
hash: "cafebabe".to_owned(),
summary: "chore: cleanup".to_owned(),
},
};
let dto = GitCommitDto::from(out);
assert_eq!(dto.hash, "cafebabe");
assert_eq!(dto.summary, "chore: cleanup");
}
// ---------------------------------------------------------------------------
// GitCommitListDto — transparent array
// ---------------------------------------------------------------------------
#[test]
fn git_commit_list_dto_is_transparent_array() {
let out = GitLogOutput {
commits: vec![
GitCommitInfo {
hash: "aaa".to_owned(),
summary: "first".to_owned(),
},
GitCommitInfo {
hash: "bbb".to_owned(),
summary: "second".to_owned(),
},
],
};
let dto = GitCommitListDto::from(out);
let v = serde_json::to_value(&dto).unwrap();
let arr = v.as_array().expect("transparent array");
assert_eq!(arr.len(), 2);
assert_eq!(arr[0]["hash"], "aaa");
assert_eq!(arr[0]["summary"], "first");
}
// ---------------------------------------------------------------------------
// GitBranchesDto serialisation (incl. current: null)
// ---------------------------------------------------------------------------
#[test]
fn git_branches_dto_serialises_with_current() {
let out = GitBranchesOutput {
branches: vec!["main".to_owned(), "feature/x".to_owned()],
current: Some("main".to_owned()),
};
let dto = GitBranchesDto::from(out);
let v = serde_json::to_value(&dto).unwrap();
assert_eq!(v["branches"][0], "main");
assert_eq!(v["branches"][1], "feature/x");
assert_eq!(v["current"], "main");
}
#[test]
fn git_branches_dto_serialises_null_current() {
let out = GitBranchesOutput {
branches: vec![],
current: None,
};
let dto = GitBranchesDto::from(out);
let v = serde_json::to_value(&dto).unwrap();
assert!(v["current"].is_null(), "current must be null when None");
}
// ---------------------------------------------------------------------------
// GraphCommitDto serialisation & From impls
// ---------------------------------------------------------------------------
#[test]
fn graph_commit_dto_serialises_camelcase() {
let commit = GraphCommit {
hash: "abc123".to_owned(),
summary: "feat: graph".to_owned(),
parents: vec!["deadbeef".to_owned()],
refs: vec!["main".to_owned(), "tag: v1.0".to_owned()],
author: "Alice".to_owned(),
timestamp: 1_700_000_000,
};
let dto = GraphCommitDto::from(commit);
let v = serde_json::to_value(&dto).unwrap();
assert_eq!(v["hash"], "abc123");
assert_eq!(v["summary"], "feat: graph");
assert_eq!(v["parents"][0], "deadbeef");
assert_eq!(v["refs"][0], "main");
assert_eq!(v["refs"][1], "tag: v1.0");
assert_eq!(v["author"], "Alice");
assert_eq!(v["timestamp"], 1_700_000_000_i64);
// No snake_case leaks for multi-word fields — none here but verify shape.
assert!(v.get("hash").is_some());
}
#[test]
fn graph_commit_list_dto_is_transparent_array() {
let out = GitGraphOutput {
commits: vec![
GraphCommit {
hash: "aaa".to_owned(),
summary: "first".to_owned(),
parents: vec![],
refs: vec!["main".to_owned()],
author: "Bob".to_owned(),
timestamp: 1000,
},
GraphCommit {
hash: "bbb".to_owned(),
summary: "second".to_owned(),
parents: vec!["aaa".to_owned()],
refs: vec![],
author: "Bob".to_owned(),
timestamp: 999,
},
],
};
let dto = GraphCommitListDto::from(out);
let v = serde_json::to_value(&dto).unwrap();
let arr = v.as_array().expect("transparent array");
assert_eq!(arr.len(), 2);
assert_eq!(arr[0]["hash"], "aaa");
assert_eq!(arr[0]["refs"][0], "main");
assert_eq!(arr[1]["hash"], "bbb");
assert!(arr[1]["parents"][0] == "aaa");
}
// ---------------------------------------------------------------------------
// Request DTO deserialisation (camelCase)
// ---------------------------------------------------------------------------
#[test]
fn git_stage_request_deserialises_camelcase() {
let project_id = Uuid::from_u128(1).to_string();
let raw = json!({
"projectId": project_id,
"path": "src/lib.rs"
});
let dto: GitStageRequestDto = serde_json::from_value(raw).unwrap();
assert_eq!(dto.project_id, project_id);
assert_eq!(dto.path, "src/lib.rs");
}
#[test]
fn git_commit_request_deserialises_camelcase() {
let project_id = Uuid::from_u128(2).to_string();
let raw = json!({
"projectId": project_id,
"message": "feat: initial commit"
});
let dto: GitCommitRequestDto = serde_json::from_value(raw).unwrap();
assert_eq!(dto.project_id, project_id);
assert_eq!(dto.message, "feat: initial commit");
}
#[test]
fn git_checkout_request_deserialises_camelcase() {
let project_id = Uuid::from_u128(3).to_string();
let raw = json!({
"projectId": project_id,
"branch": "feature/awesome"
});
let dto: GitCheckoutRequestDto = serde_json::from_value(raw).unwrap();
assert_eq!(dto.project_id, project_id);
assert_eq!(dto.branch, "feature/awesome");
}