use secfinding::*;
use secfinding::reportable::*;
use super::*;
use crate::{Finding, Severity};
#[test]
fn finding_implements_reportable() {
let f = Finding::new("scanner", "target", Severity::High, "Title", "Detail").unwrap();
assert_eq!(Reportable::scanner(&f), "scanner");
assert_eq!(Reportable::target(&f), "target");
assert_eq!(Reportable::severity(&f), Severity::High);
assert_eq!(Reportable::title(&f), "Title");
assert_eq!(Reportable::detail(&f), "Detail");
}
#[test]
fn custom_type_implements_reportable() {
struct CustomFinding {
name: String,
}
impl Reportable for CustomFinding {
fn scanner(&self) -> &'static str {
"custom"
}
fn target(&self) -> &'static str {
"custom-target"
}
fn severity(&self) -> Severity {
Severity::Critical
}
fn title(&self) -> &str {
&self.name
}
fn cwe_ids(&self) -> &[String] {
&[]
}
fn cve_ids(&self) -> &[String] {
&[]
}
fn tags(&self) -> &[String] {
&[]
}
}
let f = CustomFinding { name: "XSS".into() };
assert_eq!(f.scanner(), "custom");
assert_eq!(f.severity(), Severity::Critical);
assert_eq!(f.detail(), ""); assert!(f.tags().is_empty()); assert!(f.rule_id().contains("xss"));
}
#[test]
fn reportable_defaults_are_sensible() {
struct Minimal;
impl Reportable for Minimal {
fn scanner(&self) -> &'static str {
"s"
}
fn target(&self) -> &'static str {
"t"
}
fn severity(&self) -> Severity {
Severity::Info
}
fn title(&self) -> &'static str {
"minimal"
}
fn cwe_ids(&self) -> &[String] {
&[]
}
fn cve_ids(&self) -> &[String] {
&[]
}
fn tags(&self) -> &[String] {
&[]
}
}
let m = Minimal;
assert_eq!(m.detail(), "");
assert!(m.cwe_ids().is_empty());
assert!(m.cve_ids().is_empty());
assert!(m.tags().is_empty());
assert_eq!(m.confidence(), None);
assert_eq!(m.exploit_hint(), None);
assert_eq!(m.rule_id(), "s/minimal");
}
#[test]
fn reportable_custom_sarif_level() {
struct CustomSev;
impl Reportable for CustomSev {
fn scanner(&self) -> &'static str {
"s"
}
fn target(&self) -> &'static str {
"t"
}
fn severity(&self) -> Severity {
Severity::Critical
}
fn title(&self) -> &'static str {
"t"
}
fn cwe_ids(&self) -> &[String] {
&[]
}
fn cve_ids(&self) -> &[String] {
&[]
}
fn tags(&self) -> &[String] {
&[]
}
}
let f = CustomSev;
assert_eq!(f.sarif_level(), "error");
}
#[test]
fn reportable_custom_rule_id() {
struct CustomRuleId;
impl Reportable for CustomRuleId {
fn scanner(&self) -> &'static str {
"scanner"
}
fn target(&self) -> &'static str {
"target"
}
fn severity(&self) -> Severity {
Severity::Info
}
fn title(&self) -> &'static str {
"MY custom TITLE!"
}
fn rule_id(&self) -> String {
"CUSTOM-RULE-ID".to_string()
}
fn cwe_ids(&self) -> &[String] {
&[]
}
fn cve_ids(&self) -> &[String] {
&[]
}
fn tags(&self) -> &[String] {
&[]
}
}
let f = CustomRuleId;
assert_eq!(f.rule_id(), "CUSTOM-RULE-ID");
}
#[test]
fn reportable_default_rule_id_formatting() {
struct Spaces;
impl Reportable for Spaces {
fn scanner(&self) -> &'static str {
"scan"
}
fn target(&self) -> &'static str {
"target"
}
fn severity(&self) -> Severity {
Severity::Info
}
fn title(&self) -> &'static str {
"Some spaces here"
}
fn cwe_ids(&self) -> &[String] {
&[]
}
fn cve_ids(&self) -> &[String] {
&[]
}
fn tags(&self) -> &[String] {
&[]
}
}
let f = Spaces;
assert_eq!(f.rule_id(), "scan/some-spaces-here");
}