#![allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::panic,
clippy::indexing_slicing,
reason = "test code"
)]
use accounting::playback::{Report, Verdict};
use kernel::B3Hash;
use serde_json::json;
use super::super::exit::Exit;
use super::super::grammar::{Invocation, parse};
use super::super::verbs::Verb;
use super::{Refused, outcome, request_of};
fn refusal_of(line: &[&str]) -> Option<&'static str> {
let words: Vec<String> = line.iter().map(|word| (*word).to_owned()).collect();
let Ok(Invocation::Run(Verb::PlaybackExport, read)) = parse(&words) else {
panic!("{line:?} did not parse as playback export");
};
match request_of(&read) {
Ok(_) => None,
Err(Refused::Line(_)) => Some("line"),
Err(Refused::Selection(_)) => Some("selection"),
}
}
#[test]
fn a_range_or_a_building_that_does_not_read_is_a_command_line_refusal() {
assert_eq!(
[
refusal_of(&["playback export", "c", "--from", "5", "--through", "2"]),
refusal_of(&["playback export", "c", "--building", "a:b"]),
refusal_of(&["playback export", "c", "--from", "two"]),
refusal_of(&["playback export", "c", "--from", "2", "--through", "5"]),
],
[Some("selection"), Some("line"), Some("line"), None]
);
}
#[test]
fn a_day_that_does_not_read_or_crosses_since_to_nothing_is_a_selection_refusal() {
assert_eq!(
[
refusal_of(&["playback export", "c", "--day", "2026-02-30"]),
refusal_of(&[
"playback export",
"c",
"--day",
"2026-05-14",
"--since",
"2026-05-15T00:00:00Z"
]),
refusal_of(&["playback export", "c", "--since", "2026-05-14T09:00:00"]),
refusal_of(&[
"playback export",
"c",
"--day",
"2026-05-14",
"--since",
"2026-05-14T09:00:00Z"
]),
],
[
Some("selection"),
Some("selection"),
Some("selection"),
None
]
);
}
fn report(source: Verdict, browser: Verdict) -> Report {
Report {
file: B3Hash::digest(b"page"),
digest: Some(B3Hash::digest(b"bundle")),
events: Some(3),
structure: Verdict::Passed,
bundle: Verdict::Unasked {
why: "no other bundle was given",
},
source,
offline: Verdict::Passed,
browser,
covered: vec!["load".to_owned()],
}
}
#[test]
fn a_check_exits_refused_on_a_failed_item_or_one_asked_for_and_not_done() {
let (file, digest) = (
B3Hash::digest(b"page").to_string(),
B3Hash::digest(b"bundle").to_string(),
);
let unasked = || Verdict::Unasked {
why: "no browser observation was given; the product does not run the page",
};
assert_eq!(
[
outcome(&report(Verdict::Passed, Verdict::Passed)),
outcome(&report(
Verdict::Failed {
found: "differs from its recomputation first in `costs`".to_owned()
},
unasked()
)),
outcome(&report(
Verdict::Unable {
why: "the city's ledger ends at seq 1, before the cutoff 4".to_owned()
},
unasked()
)),
],
[
(
json!({
"file": file,
"digest": digest,
"events": "3",
"structure": {"status": "passed"},
"bundle": {"status": "unchecked", "why": "no other bundle was given"},
"source": {"status": "passed"},
"offline": {"status": "passed"},
"browser": {"status": "passed", "covered": ["load"]},
}),
Exit::Done
),
(
json!({
"file": file,
"digest": digest,
"events": "3",
"structure": {"status": "passed"},
"bundle": {"status": "unchecked", "why": "no other bundle was given"},
"source": {"status": "failed", "found": "differs from its recomputation first in `costs`"},
"offline": {"status": "passed"},
"browser": {"status": "unchecked", "why": "no browser observation was given; the product does not run the page"},
}),
Exit::Refused
),
(
json!({
"file": file,
"digest": digest,
"events": "3",
"structure": {"status": "passed"},
"bundle": {"status": "unchecked", "why": "no other bundle was given"},
"source": {"status": "unchecked", "why": "the city's ledger ends at seq 1, before the cutoff 4"},
"offline": {"status": "passed"},
"browser": {"status": "unchecked", "why": "no browser observation was given; the product does not run the page"},
}),
Exit::Refused
),
]
);
}