use crate::openspec::{Change, ProposalMetadata};
use super::types::{RemoteChange, RemoteProject};
pub fn remote_change_to_local(remote: &RemoteChange) -> Change {
Change {
id: remote.id.clone(),
completed_tasks: remote.completed_tasks,
total_tasks: remote.total_tasks,
last_modified: remote.last_modified.clone(),
dependencies: Vec::new(), metadata: ProposalMetadata::default(),
}
}
pub fn group_changes_by_project(projects: &[RemoteProject]) -> Vec<Change> {
let mut result = Vec::new();
for project in projects {
for change in &project.changes {
let mut local = remote_change_to_local(change);
local.id = format!("{}::{}/{}", project.id, project.name, change.id);
result.push(local);
}
}
result
}
#[cfg(test)]
mod tests {
use super::*;
use crate::remote::types::{RemoteChange, RemoteProject};
fn make_remote_change(id: &str, project: &str, done: u32, total: u32) -> RemoteChange {
RemoteChange {
id: id.to_string(),
project: project.to_string(),
completed_tasks: done,
total_tasks: total,
last_modified: "2024-01-01T00:00:00Z".to_string(),
status: "applying".to_string(),
iteration_number: None,
selected: true,
}
}
#[test]
fn test_remote_change_to_local() {
let remote = make_remote_change("my-change", "proj-1", 2, 5);
let local = remote_change_to_local(&remote);
assert_eq!(local.id, "my-change");
assert_eq!(local.completed_tasks, 2);
assert_eq!(local.total_tasks, 5);
assert!(local.dependencies.is_empty());
}
#[test]
fn test_group_changes_by_project_prefixes_ids() {
let projects = vec![
RemoteProject {
id: "proj-1".to_string(),
name: "Project One".to_string(),
repo: "Project One".to_string(),
branch: "main".to_string(),
status: "idle".to_string(),
is_busy: false,
error: None,
sync_state: "up_to_date".to_string(),
ahead_count: 0,
behind_count: 0,
sync_required: false,
local_sha: None,
remote_sha: None,
last_remote_check_at: None,
remote_check_error: None,
changes: vec![
make_remote_change("change-a", "proj-1", 1, 3),
make_remote_change("change-b", "proj-1", 0, 2),
],
},
RemoteProject {
id: "proj-2".to_string(),
name: "Project Two".to_string(),
repo: "Project Two".to_string(),
branch: "main".to_string(),
status: "idle".to_string(),
is_busy: false,
error: None,
sync_state: "up_to_date".to_string(),
ahead_count: 0,
behind_count: 0,
sync_required: false,
local_sha: None,
remote_sha: None,
last_remote_check_at: None,
remote_check_error: None,
changes: vec![make_remote_change("change-c", "proj-2", 3, 3)],
},
];
let result = group_changes_by_project(&projects);
assert_eq!(result.len(), 3);
assert_eq!(result[0].id, "proj-1::Project One/change-a");
assert_eq!(result[1].id, "proj-1::Project One/change-b");
assert_eq!(result[2].id, "proj-2::Project Two/change-c");
}
}