added unit tests for sender and receiver
This commit is contained in:
parent
97d1ff9323
commit
a362d8ce5c
5 changed files with 323 additions and 31 deletions
4
.github/workflows/publish.yml
vendored
4
.github/workflows/publish.yml
vendored
|
|
@ -15,8 +15,8 @@ jobs:
|
|||
include:
|
||||
- name: linux
|
||||
os: ubuntu-latest
|
||||
artifact_name: caesar
|
||||
asset_name: caesar-linux-amd64
|
||||
artifact_name: target/release/caesar
|
||||
asset_name: caesar-linux
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
|
|
|||
|
|
@ -606,3 +606,156 @@ pub async fn start(socket: Socket, fragment: &str) {
|
|||
// Wait for either future to complete
|
||||
future::select(incoming_handler, outgoing_handler).await;
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use aes_gcm::KeyInit;
|
||||
use tokio_tungstenite::tungstenite::Message as WebSocketMessage;
|
||||
|
||||
#[test]
|
||||
fn test_on_join_room_valid_size() {
|
||||
assert_eq!(on_join_room(Some(10)), Status::Continue());
|
||||
}
|
||||
#[test]
|
||||
fn test_on_join_room_invalid_size() {
|
||||
assert_eq!(
|
||||
on_join_room(None),
|
||||
Status::Err("Invalid join room packet.".into())
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn test_on_error_with_message() {
|
||||
assert_eq!(
|
||||
on_error("Error message".to_string()),
|
||||
Status::Err("Error message".to_string())
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn test_on_leave_room() {
|
||||
let (sender, _) = flume::bounded(1000);
|
||||
let mut context = Context {
|
||||
hmac: vec![],
|
||||
sender: sender,
|
||||
key: EphemeralSecret::random(&mut OsRng),
|
||||
shared_key: None,
|
||||
files: vec![
|
||||
File {
|
||||
name: "file1.txt".to_string(),
|
||||
size: 100,
|
||||
progress: 100,
|
||||
handle: fs::File::create("file1.txt").unwrap(),
|
||||
},
|
||||
File {
|
||||
name: "file2.txt".to_string(),
|
||||
size: 100,
|
||||
progress: 50,
|
||||
handle: fs::File::create("file2.txt").unwrap(),
|
||||
},
|
||||
],
|
||||
sequence: 0,
|
||||
index: 0,
|
||||
progress: 0,
|
||||
length: 0,
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
on_leave_room(&mut context, 0),
|
||||
Status::Err("Transfer was interrupted because the host left the room.".into())
|
||||
);
|
||||
context.files[1].progress = 100;
|
||||
assert_eq!(on_leave_room(&mut context, 0), Status::Exit());
|
||||
}
|
||||
#[test]
|
||||
fn test_on_message_text_join() {
|
||||
let (sender, _) = flume::bounded(1000);
|
||||
let mut context = Context {
|
||||
hmac: vec![],
|
||||
sender: sender,
|
||||
key: EphemeralSecret::random(&mut OsRng),
|
||||
shared_key: None,
|
||||
files: vec![],
|
||||
sequence: 0,
|
||||
index: 0,
|
||||
progress: 0,
|
||||
length: 0,
|
||||
};
|
||||
|
||||
let text_message = WebSocketMessage::Text(r#"{"type":"join","size":10}"#.to_string());
|
||||
assert_eq!(on_message(&mut context, text_message), Status::Continue());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_on_chunk() {
|
||||
let (sender, _) = flume::bounded(1000);
|
||||
// let mut context = Context {
|
||||
// hmac: vec![],
|
||||
// sender: sender.clone(),
|
||||
// key: EphemeralSecret::random(&mut OsRng),
|
||||
// shared_key: Some(Aes128Gcm::new(Key::<Aes128Gcm>::from_slice(&[0u8; 16]))),
|
||||
// files: vec![File {
|
||||
// name: "file1.txt".to_string(),
|
||||
// size: 100,
|
||||
// progress: 0,
|
||||
// handle: fs::File::create("file1.txt").unwrap(),
|
||||
// }],
|
||||
// sequence: 0,
|
||||
// index: 0,
|
||||
// progress: 0,
|
||||
// length: 0,
|
||||
// };
|
||||
|
||||
// let chunk_packet = ChunkPacket {
|
||||
// sequence: 0,
|
||||
// chunk: b"Hello, world!".to_vec(),
|
||||
// };
|
||||
// assert_eq!(on_chunk(&mut context, chunk_packet), Status::Continue());
|
||||
// assert_eq!(context.sequence, 1);
|
||||
// assert_eq!(context.length, 14);
|
||||
// assert_eq!(context.progress, 14);
|
||||
|
||||
// let chunk_packet = ChunkPacket {
|
||||
// sequence: 1,
|
||||
// chunk: b"Hello, world!".to_vec(),
|
||||
// };
|
||||
// assert_eq!(
|
||||
// on_chunk(&mut context, chunk_packet),
|
||||
// Status::Err("Expected sequence 1, but got 1.".into())
|
||||
// );
|
||||
|
||||
// context.files.clear();
|
||||
// let chunk_packet = ChunkPacket {
|
||||
// sequence: 0,
|
||||
// chunk: b"Hello, world!".to_vec(),
|
||||
// };
|
||||
// assert_eq!(
|
||||
// on_chunk(&mut context, chunk_packet),
|
||||
// Status::Err("Invalid file index.".into())
|
||||
// );
|
||||
|
||||
// Test a chunk packet with no shared key
|
||||
let mut context = Context {
|
||||
hmac: vec![],
|
||||
sender: sender,
|
||||
key: EphemeralSecret::random(&mut OsRng),
|
||||
shared_key: None,
|
||||
files: vec![File {
|
||||
name: "file1.txt".to_string(),
|
||||
size: 100,
|
||||
progress: 0,
|
||||
handle: fs::File::create("file1.txt").unwrap(),
|
||||
}],
|
||||
sequence: 0,
|
||||
index: 0,
|
||||
progress: 0,
|
||||
length: 0,
|
||||
};
|
||||
let chunk_packet = ChunkPacket {
|
||||
sequence: 0,
|
||||
chunk: b"Hello, world!".to_vec(),
|
||||
};
|
||||
assert_eq!(
|
||||
on_chunk(&mut context, chunk_packet),
|
||||
Status::Err("Invalid chunk packet: no shared key established".into())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -704,3 +704,170 @@ pub async fn start(socket: Socket, paths: Vec<String>) {
|
|||
// `outgoing_handler` completes, return the result of the `outgoing_handler`.
|
||||
future::select(incoming_handler, outgoing_handler).await;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use aes_gcm::KeyInit;
|
||||
|
||||
#[test]
|
||||
fn test_on_chunk() {
|
||||
let (sender, _) = flume::bounded(1000);
|
||||
let mut context = Context {
|
||||
hmac: vec![],
|
||||
sender: sender,
|
||||
key: EphemeralSecret::random(&mut OsRng),
|
||||
shared_key: None,
|
||||
files: vec![
|
||||
File {
|
||||
name: "file1.txt".to_string(),
|
||||
size: 100,
|
||||
path: "file1.txt".to_string(),
|
||||
},
|
||||
File {
|
||||
name: "file2.txt".to_string(),
|
||||
size: 100,
|
||||
path: "file2.txt".to_string(),
|
||||
},
|
||||
],
|
||||
task: None,
|
||||
};
|
||||
}
|
||||
#[test]
|
||||
fn test_on_progress() {
|
||||
let (sender, _) = flume::bounded(1000);
|
||||
let mut context = Context {
|
||||
hmac: vec![],
|
||||
sender: sender,
|
||||
key: EphemeralSecret::random(&mut OsRng),
|
||||
shared_key: Some(Aes128Gcm::new(Key::<Aes128Gcm>::from_slice(&[0u8; 16]))),
|
||||
files: vec![
|
||||
File {
|
||||
name: "file1.txt".to_string(),
|
||||
size: 100,
|
||||
path: "file1.txt".to_string(),
|
||||
},
|
||||
File {
|
||||
name: "file2.txt".to_string(),
|
||||
size: 100,
|
||||
path: "file2.txt".to_string(),
|
||||
},
|
||||
],
|
||||
task: None,
|
||||
};
|
||||
assert_eq!(on_progress(&context, ProgressPacket { index: 0, progress: 50 }), Status::Continue());
|
||||
}
|
||||
#[test]
|
||||
fn test_on_create_room() {
|
||||
let (sender, _) = flume::bounded(1000);
|
||||
let mut context = Context {
|
||||
hmac: vec![],
|
||||
sender: sender,
|
||||
key: EphemeralSecret::random(&mut OsRng),
|
||||
shared_key: None,
|
||||
files: vec![
|
||||
File {
|
||||
name: "file1.txt".to_string(),
|
||||
size: 100,
|
||||
path: "file1.txt".to_string(),
|
||||
},
|
||||
File {
|
||||
name: "file2.txt".to_string(),
|
||||
size: 100,
|
||||
path: "file2.txt".to_string(),
|
||||
},
|
||||
],
|
||||
task: None,
|
||||
};
|
||||
assert_eq!(
|
||||
on_create_room(
|
||||
&context,
|
||||
"b531e87d-e51a-4507-94f4-335cbe2d32f3-Nc5skZReq7qJN7INwckyAZLWEEbxsrFfH/692tUNgkM="
|
||||
.to_string()
|
||||
),
|
||||
Status::Continue()
|
||||
);
|
||||
}
|
||||
// #[test]
|
||||
// fn test_on_join_room(){
|
||||
// let (sender, _) = flume::bounded(1000);
|
||||
// let mut context = Context {
|
||||
// hmac: vec![],
|
||||
// sender: sender,
|
||||
// key: EphemeralSecret::random(&mut OsRng),
|
||||
// shared_key: None,
|
||||
// files: vec![
|
||||
// File {
|
||||
// name: "file1.txt".to_string(),
|
||||
// size: 100,
|
||||
// path: "file1.txt".to_string(),
|
||||
// },
|
||||
// File {
|
||||
// name: "file2.txt".to_string(),
|
||||
// size: 100,
|
||||
// path: "file2.txt".to_string(),
|
||||
// },
|
||||
// ],
|
||||
// task: None,
|
||||
// };
|
||||
// assert_eq!(on_join_room(&context, None), Status::Continue());
|
||||
// }
|
||||
#[test]
|
||||
fn test_on_error() {
|
||||
assert_eq!(
|
||||
on_error("Error message".to_string()),
|
||||
Status::Err("Error message".to_string())
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn test_on_leave_room() {
|
||||
let (sender, _) = flume::bounded(1000);
|
||||
let mut context = Context {
|
||||
hmac: vec![],
|
||||
sender: sender,
|
||||
key: EphemeralSecret::random(&mut OsRng),
|
||||
shared_key: None,
|
||||
files: vec![
|
||||
File {
|
||||
name: "file1.txt".to_string(),
|
||||
size: 100,
|
||||
path: "file1.txt".to_string(),
|
||||
},
|
||||
File {
|
||||
name: "file2.txt".to_string(),
|
||||
size: 100,
|
||||
path: "file2.txt".to_string(),
|
||||
},
|
||||
],
|
||||
task: None,
|
||||
};
|
||||
assert_eq!(on_leave_room(&mut context, 5), Status::Continue());
|
||||
}
|
||||
#[test]
|
||||
fn test_on_message() {
|
||||
let (sender, _) = flume::bounded(1000);
|
||||
let mut context = Context {
|
||||
hmac: vec![],
|
||||
sender: sender,
|
||||
key: EphemeralSecret::random(&mut OsRng),
|
||||
shared_key: None,
|
||||
files: vec![
|
||||
File {
|
||||
name: "file1.txt".to_string(),
|
||||
size: 100,
|
||||
path: "file1.txt".to_string(),
|
||||
},
|
||||
File {
|
||||
name: "file2.txt".to_string(),
|
||||
size: 100,
|
||||
path: "file2.txt".to_string(),
|
||||
},
|
||||
],
|
||||
task: None,
|
||||
};
|
||||
assert_eq!(on_message(&mut context, WebSocketMessage::Text(r#"{"type":"leave","index":5}"#.to_string())), Status::Continue());
|
||||
assert_eq!(on_message(&mut context, WebSocketMessage::Text(r#"{"type":"create","id":"b531e87d-e51a-4507-94f4-335cbe2d32f3-Nc5skZReq7qJN7INwckyAZLWEEbxsrFfH/692tUNgkM="}"#.to_string())), Status::Continue());
|
||||
assert_eq!(on_message(&mut context, WebSocketMessage::Text(r#"{"type":"error","message":"Error Message: Test"}"#.to_string())), Status::Err("Error Message: Test".to_string()));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,40 +63,11 @@ pub async fn start_sender(relay: &str, files: &[String]) {
|
|||
}
|
||||
Err(e) => {
|
||||
error!("Error: Failed to connect with error: {e}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Error: failed to create request with reason: {e:?}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
// let Ok(mut request) = relay.into_client_request() else {
|
||||
// println!("Error: Failed to create request.");
|
||||
// return;
|
||||
// };
|
||||
|
||||
// request
|
||||
// .headers_mut()
|
||||
// .insert("Origin", HeaderValue::from_str(relay).unwrap());
|
||||
|
||||
// debug!("Attempting to connect to {relay}...");
|
||||
|
||||
// match connect_async(request).await {
|
||||
// Ok((socket, _)) => {
|
||||
// let paths = files.to_vec();
|
||||
// sender::start(socket, paths).await;
|
||||
// }
|
||||
// Err(e) => {
|
||||
// error!("Error: Failed to connect with error: {e}");
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// let Ok((socket, _)) = connect_async(request).await else {
|
||||
// error!("Error: Failed to connect.");
|
||||
// return;
|
||||
// };
|
||||
// let paths = files.to_vec();
|
||||
// sender::start(socket, paths).await
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ pub enum JsonPacketResponse {
|
|||
/// written from the perspective of the user and should give the user enough
|
||||
/// information to understand what went wrong and how they might be able to
|
||||
/// fix the problem.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Status {
|
||||
/// Indicates that the event loop should continue processing events.
|
||||
Continue(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue