minor refactor and fix tests

This commit is contained in:
GyulyVGC 2026-01-24 21:48:09 +01:00
parent 158ade0fc5
commit 0f691588ef
5 changed files with 183 additions and 151 deletions

View file

@ -126,8 +126,10 @@ mod tests {
data_notification: Default::default(),
favorite_notification: Default::default(),
remote_notifications: Default::default(),
ip_blacklist_notification: Default::default(),
},
style: StyleType::DraculaDark,
ip_blacklist: "some-path".to_string(),
},
device: ConfigDevice {
device_name: "hey-hey".to_string(),

View file

@ -11,11 +11,12 @@ use crate::gui::styles::style_constants::FONT_SIZE_FOOTER;
use crate::gui::styles::types::style_type::StyleType;
use crate::gui::types::message::Message;
use crate::networking::types::data_representation::DataRepr;
use crate::networking::types::host::{Host, ThumbnailHost};
use crate::networking::types::host::ThumbnailHost;
use crate::networking::types::info_traffic::InfoTraffic;
use crate::report::get_report_entries::{get_host_entries, get_service_entries};
use crate::report::types::sort_type::SortType;
use crate::translations::types::language::Language;
use crate::utils::formatted_strings::clip_text;
const MAX_ENTRIES: usize = 4;
const MAX_CHARS_HOST: usize = 26;
@ -95,12 +96,9 @@ fn host_col<'a>(
let mut thumbnail_hosts = Vec::new();
for (host, data_info_host) in &hosts {
let text = host_text(host);
let country = host.country;
let thumbnail_host = ThumbnailHost {
country,
text: text.clone(),
};
let thumbnail_host = ThumbnailHost::from_host(host, MAX_CHARS_HOST);
let country = thumbnail_host.country;
let text = thumbnail_host.text.clone();
if thumbnail_hosts.contains(&thumbnail_host) {
continue;
@ -139,120 +137,3 @@ fn service_col<'a>(
}
service_col
}
fn host_text(host: &Host) -> String {
clip_text(host.to_host_thumbnail_string(), MAX_CHARS_HOST)
}
fn clip_text(text: &str, max_chars: usize) -> String {
let text = text.trim();
let chars = text.chars().collect::<Vec<char>>();
let tot_len = chars.len();
let slice_len = min(max_chars, tot_len);
let suspensions = if tot_len > max_chars { "" } else { "" };
let slice = if tot_len > max_chars {
&chars[..slice_len - 2]
} else {
&chars[..slice_len]
}
.iter()
.collect::<String>();
[slice.trim(), suspensions].concat()
}
#[cfg(test)]
mod tests {
use crate::gui::pages::thumbnail_page::{
MAX_CHARS_HOST, MAX_CHARS_SERVICE, clip_text, host_text,
};
use crate::networking::types::asn::Asn;
use crate::networking::types::host::Host;
fn host_for_tests(domain: &str, asn: &str) -> Host {
Host {
domain: domain.to_string(),
asn: Asn {
name: asn.to_string(),
code: "512".to_string(),
},
country: Default::default(),
}
}
#[test]
fn test_clip_text() {
assert_eq!(
clip_text("iphone-di-doofenshmirtz.local", MAX_CHARS_HOST),
"iphone-di-doofenshmirtz.…"
);
assert_eq!(clip_text("github.com", MAX_CHARS_HOST), "github.com");
assert_eq!(clip_text("https6789012", MAX_CHARS_SERVICE), "https6789012");
assert_eq!(
clip_text("https67890123", MAX_CHARS_SERVICE),
"https67890123"
);
assert_eq!(
clip_text("https678901234", MAX_CHARS_SERVICE),
"https678901…"
);
assert_eq!(
clip_text("https6789012345", MAX_CHARS_SERVICE),
"https678901…"
);
assert_eq!(
clip_text("protocol with space", MAX_CHARS_SERVICE),
"protocol wi…"
);
assert_eq!(
clip_text("protocol90 23456", MAX_CHARS_SERVICE),
"protocol90…"
);
assert_eq!(
clip_text(" \n\t sniffnet.net ", MAX_CHARS_HOST),
"sniffnet.net"
);
assert_eq!(
clip_text(" protocol90 23456 \n ", MAX_CHARS_SERVICE),
"protocol90…"
);
assert_eq!(
clip_text(" protocol90 23456 ", MAX_CHARS_HOST),
"protocol90 23456"
);
}
#[test]
fn test_host_text() {
let host = host_for_tests("iphone-di-doofenshmirtz.local", "AS1234");
assert_eq!(host_text(&host), "iphone-di-doofenshmirtz.…");
let host = host_for_tests("", "");
assert_eq!(host_text(&host), "");
let host = host_for_tests("192.168.1.113", "AS1234");
assert_eq!(host_text(&host), "AS1234");
let host = host_for_tests("192.168.1.113", "");
assert_eq!(host_text(&host), "192.168.1.113");
let host = host_for_tests("", "FASTLY");
assert_eq!(host_text(&host), "FASTLY");
let host = host_for_tests("::", "GOOGLE");
assert_eq!(host_text(&host), "GOOGLE");
let host = host_for_tests("::f", "AKAMAI-TECHNOLOGIES-INCORPORATED");
assert_eq!(host_text(&host), "AKAMAI-TECHNOLOGIES-INCO…");
let host = host_for_tests("::g", "GOOGLE");
assert_eq!(host_text(&host), "::g");
let host = host_for_tests(" ", "GOOGLE");
assert_eq!(host_text(&host), "GOOGLE");
}
}

View file

@ -1366,7 +1366,7 @@ mod tests {
DataThresholdExceeded, LoggedNotification,
};
use crate::notifications::types::notifications::{
DataNotification, FavoriteNotification, Notification, Notifications,
DataNotification, Notification, Notifications, SimpleNotification,
};
use crate::notifications::types::sound::Sound;
use crate::report::types::sort_type::SortType;
@ -1874,14 +1874,24 @@ mod tests {
previous_threshold: 800_000,
};
let fav_notification_init = FavoriteNotification {
notify_on_favorite: false,
let fav_notification_init = SimpleNotification {
is_active: false,
sound: Sound::Pop,
};
let fav_notification_new = SimpleNotification {
is_active: true,
sound: Sound::Pop,
};
let blacklist_notification_init = SimpleNotification {
is_active: false,
sound: Sound::Swhoosh,
};
let fav_notification_new = FavoriteNotification {
notify_on_favorite: true,
sound: Sound::Pop,
let blacklist_notification_new = SimpleNotification {
is_active: true,
sound: Sound::Gulp,
};
// initial default state
@ -1894,6 +1904,14 @@ mod tests {
sniffer.conf.settings.notifications.favorite_notification,
fav_notification_init
);
assert_eq!(
sniffer
.conf
.settings
.notifications
.ip_blacklist_notification,
blacklist_notification_init
);
// change volume
sniffer.update(Message::ChangeVolume(95));
@ -1907,14 +1925,13 @@ mod tests {
sniffer.conf.settings.notifications.favorite_notification,
fav_notification_init,
);
assert_eq!(
sniffer.conf.settings.notifications.data_notification,
bytes_notification_init
);
assert_eq!(
sniffer.conf.settings.notifications.favorite_notification,
fav_notification_init
sniffer
.conf
.settings
.notifications
.ip_blacklist_notification,
blacklist_notification_init
);
// Toggle on bytes notifications
@ -1952,6 +1969,14 @@ mod tests {
sniffer.conf.settings.notifications.favorite_notification,
fav_notification_init,
);
assert_eq!(
sniffer
.conf
.settings
.notifications
.ip_blacklist_notification,
blacklist_notification_init,
);
// change favorite notifications
sniffer.update(Message::UpdateNotificationSettings(
@ -1976,6 +2001,21 @@ mod tests {
sniffer.conf.settings.notifications.favorite_notification,
fav_notification_new
);
// change favorite notifications
sniffer.update(Message::UpdateNotificationSettings(
Notification::IpBlacklist(blacklist_notification_new),
true,
));
assert_eq!(
sniffer
.conf
.settings
.notifications
.ip_blacklist_notification,
blacklist_notification_new,
);
}
#[test]
@ -2129,6 +2169,7 @@ mod tests {
sniffer.update(Message::SetPcapImport("/test.pcap".to_string()));
sniffer.update(Message::ChangeRunningPage(RunningPage::Notifications));
sniffer.update(Message::DataReprSelection(DataRepr::Bits));
sniffer.update(Message::LoadIpBlacklist("blacklist_file.csv".to_string()));
// force saving configs by quitting the app
sniffer.welcome = Some((false, 0));
@ -2153,11 +2194,10 @@ mod tests {
),
notifications: Notifications {
volume: 100,
data_notification: Default::default(),
favorite_notification: Default::default(),
remote_notifications: Default::default(),
..Notifications::default()
},
style: StyleType::DraculaDark,
ip_blacklist: "blacklist_file.csv".to_string(),
},
window: ConfigWindow::new((1000.0, 999.0), (-5.0, 277.5), (20.0, 20.0)),
device: ConfigDevice::default(),

View file

@ -1,6 +1,7 @@
use crate::countries::types::country::Country;
use crate::networking::types::asn::Asn;
use crate::networking::types::data_info_host::DataInfoHost;
use crate::utils::formatted_strings::clip_text;
use std::net::IpAddr;
/// Struct to represent a network host
@ -26,17 +27,6 @@ impl Host {
ret_val
}
/// Used in the thumbnail
pub fn to_host_thumbnail_string(&self) -> &str {
let domain = &self.domain;
let asn = &self.asn.name;
if asn.is_empty() || (!domain.trim().is_empty() && domain.parse::<IpAddr>().is_err()) {
domain
} else {
asn
}
}
/// Used in the blacklist notifications
pub fn to_host_blacklist_string(&self) -> String {
let domain = &self.domain;
@ -74,6 +64,24 @@ pub struct ThumbnailHost {
pub text: String,
}
impl ThumbnailHost {
/// Constructor from a Host
pub fn from_host(host: &Host, max_text_chars: usize) -> Self {
let domain = &host.domain;
let asn = &host.asn.name;
let unclipped =
if asn.is_empty() || (!domain.trim().is_empty() && domain.parse::<IpAddr>().is_err()) {
domain
} else {
asn
};
Self {
country: host.country.clone(),
text: clip_text(unclipped, max_text_chars),
}
}
}
#[derive(Clone, Debug)]
pub struct HostMessage {
pub host: Host,
@ -81,3 +89,56 @@ pub struct HostMessage {
pub address_to_lookup: IpAddr,
pub rdns: String,
}
#[cfg(test)]
mod tests {
use crate::networking::types::asn::Asn;
use crate::networking::types::host::{Host, ThumbnailHost};
fn host_for_tests(domain: &str, asn: &str) -> Host {
Host {
domain: domain.to_string(),
asn: Asn {
name: asn.to_string(),
code: "512".to_string(),
},
country: Default::default(),
}
}
#[test]
fn test_thumbnail_host_text() {
let host = host_for_tests("iphone-di-doofenshmirtz.local", "AS1234");
assert_eq!(
ThumbnailHost::from_host(&host, 26).text,
"iphone-di-doofenshmirtz.…"
);
let host = host_for_tests("", "");
assert_eq!(ThumbnailHost::from_host(&host, 26).text, "");
let host = host_for_tests("192.168.1.113", "AS1234");
assert_eq!(ThumbnailHost::from_host(&host, 26).text, "AS1234");
let host = host_for_tests("192.168.1.113", "");
assert_eq!(ThumbnailHost::from_host(&host, 26).text, "192.168.1.113");
let host = host_for_tests("", "FASTLY");
assert_eq!(ThumbnailHost::from_host(&host, 26).text, "FASTLY");
let host = host_for_tests("::", "GOOGLE");
assert_eq!(ThumbnailHost::from_host(&host, 26).text, "GOOGLE");
let host = host_for_tests("::f", "AKAMAI-TECHNOLOGIES-INCORPORATED");
assert_eq!(
ThumbnailHost::from_host(&host, 26).text,
"AKAMAI-TECHNOLOGIES-INCO…"
);
let host = host_for_tests("::g", "GOOGLE");
assert_eq!(ThumbnailHost::from_host(&host, 26).text, "::g");
let host = host_for_tests(" ", "GOOGLE");
assert_eq!(ThumbnailHost::from_host(&host, 26).text, "GOOGLE");
}
}

View file

@ -137,6 +137,24 @@ pub fn redirect_stdout_stderr_to_file()
None
}
pub fn clip_text(text: &str, max_chars: usize) -> String {
let text = text.trim();
let chars = text.chars().collect::<Vec<char>>();
let tot_len = chars.len();
let slice_len = min(max_chars, tot_len);
let suspensions = if tot_len > max_chars { "" } else { "" };
let slice = if tot_len > max_chars {
&chars[..slice_len - 2]
} else {
&chars[..slice_len]
}
.iter()
.collect::<String>();
[slice.trim(), suspensions].concat()
}
#[cfg(test)]
mod tests {
use super::*;
@ -209,4 +227,34 @@ mod tests {
assert_eq!(f("..."), "..");
assert_eq!(f("no_dots_in_this"), "no_dots_in_this");
}
#[test]
fn test_clip_text() {
assert_eq!(
clip_text("iphone-di-doofenshmirtz.local", 26),
"iphone-di-doofenshmirtz.…"
);
assert_eq!(clip_text("github.com", 26), "github.com");
assert_eq!(clip_text("https6789012", 13), "https6789012");
assert_eq!(clip_text("https67890123", 13), "https67890123");
assert_eq!(clip_text("https678901234", 13), "https678901…");
assert_eq!(clip_text("https6789012345", 13), "https678901…");
assert_eq!(clip_text("protocol with space", 13), "protocol wi…");
assert_eq!(clip_text("protocol90 23456", 13), "protocol90…");
assert_eq!(
clip_text(" \n\t sniffnet.net ", 26),
"sniffnet.net"
);
assert_eq!(
clip_text(" protocol90 23456 \n ", 12),
"protocol90…"
);
assert_eq!(
clip_text(" protocol90 23456 ", 26),
"protocol90 23456"
);
}
}