Files
galaxy/crates/remote_server/src/host_response_tests.rs
T

177 lines
6.3 KiB
Rust

use super::*;
use crate::proto::{
delete_file_response, discard_files_response, save_buffer_response, server_message,
write_file_response, DeleteFileResponse, DeleteFileSuccess, DiscardFilesError,
DiscardFilesResponse, DiscardFilesSuccess, FileOperationError, SaveBufferResponse,
SaveBufferSuccess, ServerMessage, WriteFileResponse, WriteFileSuccess,
};
fn msg(inner: server_message::Message) -> ServerMessage {
ServerMessage {
request_id: "req-1".to_string(),
message: Some(inner),
}
}
#[test]
fn write_file_success_is_ok_empty_is_err() {
let success = msg(server_message::Message::WriteFileResponse(
WriteFileResponse {
result: Some(write_file_response::Result::Success(WriteFileSuccess {})),
},
));
assert!(write_file_result(&success).is_ok());
let empty = msg(server_message::Message::WriteFileResponse(
WriteFileResponse { result: None },
));
assert!(write_file_result(&empty).is_err());
}
#[test]
fn write_file_error_propagates_message() {
let err = msg(server_message::Message::WriteFileResponse(
WriteFileResponse {
result: Some(write_file_response::Result::Error(FileOperationError {
message: "disk full".to_string(),
})),
},
));
assert_eq!(write_file_result(&err).unwrap_err(), "disk full");
}
#[test]
fn write_file_wrong_variant_is_err() {
let wrong = msg(server_message::Message::SaveBufferResponse(
SaveBufferResponse {
result: Some(save_buffer_response::Result::Success(SaveBufferSuccess {})),
},
));
assert!(write_file_result(&wrong).is_err());
}
#[test]
fn save_buffer_success_is_ok_empty_is_err() {
let success = msg(server_message::Message::SaveBufferResponse(
SaveBufferResponse {
result: Some(save_buffer_response::Result::Success(SaveBufferSuccess {})),
},
));
assert!(save_buffer_result(&success).is_ok());
let empty = msg(server_message::Message::SaveBufferResponse(
SaveBufferResponse { result: None },
));
assert!(save_buffer_result(&empty).is_err());
}
#[test]
fn save_buffer_error_propagates_message() {
let err = msg(server_message::Message::SaveBufferResponse(
SaveBufferResponse {
result: Some(save_buffer_response::Result::Error(FileOperationError {
message: "permission denied".to_string(),
})),
},
));
assert_eq!(save_buffer_result(&err).unwrap_err(), "permission denied");
}
#[test]
fn delete_file_success_is_ok_empty_is_err() {
let success = msg(server_message::Message::DeleteFileResponse(
DeleteFileResponse {
result: Some(delete_file_response::Result::Success(DeleteFileSuccess {})),
},
));
assert!(delete_file_result(&success).is_ok());
let empty = msg(server_message::Message::DeleteFileResponse(
DeleteFileResponse { result: None },
));
assert!(delete_file_result(&empty).is_err());
}
#[test]
fn delete_file_error_propagates_message() {
let err = msg(server_message::Message::DeleteFileResponse(
DeleteFileResponse {
result: Some(delete_file_response::Result::Error(FileOperationError {
message: "no such file".to_string(),
})),
},
));
assert_eq!(delete_file_result(&err).unwrap_err(), "no such file");
}
#[test]
fn discard_files_success_is_ok() {
let success = msg(server_message::Message::DiscardFilesResponse(
DiscardFilesResponse {
result: Some(discard_files_response::Result::Success(
DiscardFilesSuccess {},
)),
},
));
assert!(discard_files_result(&success).is_ok());
}
#[test]
fn discard_files_error_propagates_message() {
let err = msg(server_message::Message::DiscardFilesResponse(
DiscardFilesResponse {
result: Some(discard_files_response::Result::Error(DiscardFilesError {
message: "merge conflict".to_string(),
})),
},
));
assert_eq!(discard_files_result(&err).unwrap_err(), "merge conflict");
}
#[test]
fn discard_files_empty_result_is_err() {
let empty = msg(server_message::Message::DiscardFilesResponse(
DiscardFilesResponse { result: None },
));
assert!(discard_files_result(&empty).is_err());
}
/// Guard: every host-scoped request variant must have an explicit, intentional
/// response disposition. This match is exhaustive, so adding a new
/// `host_scoped_request::Message` variant fails to compile until it is
/// classified here — a prompt to add a `host_response` parser (or document why
/// the response is parsed at the manager call site).
#[test]
fn every_host_scoped_request_has_a_response_disposition() {
use crate::proto::host_scoped_request::Message as M;
fn disposition(m: &M) -> &'static str {
match m {
// Parsed via the helpers in this module.
M::WriteFile(_) => "host_response::write_file_result",
M::SaveBuffer(_) => "host_response::save_buffer_result",
M::DeleteFile(_) => "host_response::delete_file_result",
M::DiscardFiles(_) => "host_response::discard_files_result",
// Richer responses parsed at the manager call site.
M::ReadFileContext(_) => "manager::read_file_context",
M::GetFragmentMetadataFromHash(_) => "manager::get_fragment_metadata_from_hash",
M::UploadHandoffSnapshot(_) => "manager::upload_handoff_snapshot",
M::GetBranches(_) => "manager::get_branches",
M::IndexCodebase(_) => "manager::index_codebase",
M::DropCodebaseIndex(_) => "manager::drop_codebase_index",
M::ResyncCodebase(_) => "manager::resync_codebase",
M::ResolveConflict(_) => "manager::resolve_conflict",
M::GitCommitChain(_) => "manager::commit_chain",
M::GitPush(_) => "manager::push",
M::GitCreatePr(_) => "manager::create_pr",
M::GitGenerateCommitMessage(_) => "manager::generate_commit_message",
M::GitGetCommittedBranchFiles(_) => "manager::get_committed_branch_files",
M::RipgrepSearch(_) => "manager::start_ripgrep_search",
M::BackgroundJob(_) => "manager::HostRequestHandle::background_job",
}
}
// Referenced so the exhaustive match is compiled and checked.
let _ = disposition;
}