test: remove tests that do not pin user-visible behavior (#16539)

* test: remove tests that do not pin user-visible behavior

Apply the AGENTS.md test rules to the existing Rust and Flutter suites.
A test is kept when it is the only coverage of user- or API-visible
behavior, the regression test of a reported or fixed bug, a security
boundary (one test per rejection class), or a check against an external
reference. Tests that assert private state or the order of internal
steps, pin review-round corner cases, or repeat what a kept test already
covers are removed.

Rust: 679 -> 298 tests. Dart: 118 -> 45 tests.

Test-only helpers left without callers go with them
(applyLastOnlineStateForTesting, terminalKeyboardRowWidth,
debugBufferedInputCount, tokio's test-util dev feature), and cfg gates
and visibility that existed only for the deleted tests are narrowed.
Runtime behavior is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WS1HTjp6UQuG43KEcQPq1R

* test: keep tests that pin security and user-visible behavior

Restore six tests that review showed are the only coverage of their
behavior:

- update metadata rejects an artifact file name with path components;
- ICE candidates from another session are dropped;
- KCP delivers every multi-segment frame queued before a close;
- set_files rejects an empty name in a multi-file transfer;
- a lopsided elongated cursor keeps its centre hotspot (#16242);
- toggling Show hidden during a pending same-path read issues a new read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WS1HTjp6UQuG43KEcQPq1R

* test: keep offline update and key-exchange downgrade rejections

Restore three tests that are the only coverage of their rejection class:

- offline update metadata rejects a signed artifact with an http or
  credential-bearing URL;
- offline verification rejects a renamed local file and a version that
  does not match the release;
- a key-exchange pick lowered in transit leaves both sides unable to
  decrypt, so a v0 fallback after a failed v1 decrypt cannot pass
  unnoticed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WS1HTjp6UQuG43KEcQPq1R

* test: keep the decomposed-grapheme and reconnect-cancel tests

Each catches a plausible wrong change that passes every kept test:
mapping the first scalar under a locked Ctrl turns é into \x05,
and a reconnect that does not fail pending reads leaves them hanging
until the 30 s timeout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WS1HTjp6UQuG43KEcQPq1R

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
RustDeskandClaude Opus 5.5 authored and GitHub committed 2026-10-14 14:45:22 +08:00
1 parent 76ab280ae9
commit 9997b7a3b8
94 files changed
+66 -9405

No files matched your search

+1 -84
View File
@@ -2767,7 +2767,7 @@ impl<T: InvokeUiSession> Remote<T> {
/// A shape that decoded, still compressed, under the id the UI knows it by. Copied once it
/// decoded: the message's colors may be a slice of a larger received buffer, which a clone
/// would keep alive.
#[cfg(any(feature = "flutter", test))]
#[cfg(feature = "flutter")]
fn cursor_shape(id: u64, cd: &CursorData, compressed: &[u8]) -> CursorData {
CursorData {
id,
@@ -3022,74 +3022,6 @@ mod cursor_dedupe_tests {
assert_eq!(dedupe.id(2), first);
assert_eq!(dedupe.id(1), first);
}
#[test]
fn the_hotspot_is_part_of_the_shape() {
let a = CursorDedupe::name(&shape(1, 0, b"arrow"));
let b = CursorDedupe::name(&shape(2, 1, b"arrow"));
assert_ne!(a, b);
}
#[test]
fn a_reused_handle_names_its_latest_shape() {
let mut dedupe = CursorDedupe::default();
dedupe.record(1, CursorDedupe::name(&shape(1, 0, b"arrow")));
let beam = CursorDedupe::name(&shape(1, 0, b"beam"));
dedupe.record(1, beam);
assert_eq!(dedupe.id(1), beam);
}
#[test]
fn a_rejected_shape_names_its_handle_and_is_never_decoded() {
let mut dedupe = CursorDedupe::default();
let arrow = CursorDedupe::name(&shape(7, 0, b"arrow"));
dedupe.record(7, arrow);
let beam = CursorDedupe::name(&shape(8, 0, b"beam"));
dedupe.record(8, beam);
let broken = CursorDedupe::name(&shape(7, 0, b"broken"));
assert_eq!(
dedupe.rejected(7, broken),
broken,
"not the shape it named before"
);
assert_eq!(
dedupe.id(7),
broken,
"nor when the handle is selected again"
);
assert_eq!(dedupe.id(8), beam, "another handle keeps its shape");
assert!(!dedupe.has_decoded(broken));
assert!(
dedupe.has_decoded(arrow),
"kept for a handle that brings it again"
);
dedupe.record(7, arrow);
assert_eq!(dedupe.id(7), arrow);
}
#[test]
fn a_shape_rejected_under_handles_never_seen_files_nothing() {
let mut dedupe = CursorDedupe::default();
let broken = CursorDedupe::name(&shape(0, 0, b"broken"));
for handle in 0..1000 {
assert_eq!(dedupe.rejected(handle, broken), broken);
}
assert!(dedupe.ids.is_empty());
assert!(!dedupe.has_decoded(broken));
}
#[test]
fn an_id_the_peer_never_sent_is_passed_on() {
assert_eq!(CursorDedupe::default().id(7), 7);
}
#[test]
fn peers_from_1_5_0_name_cursors_by_content() {
use hbb_common::get_version_number as v;
assert!(!crate::is_peer_naming_cursors_by_content(v("1.4.9")));
assert!(crate::is_peer_naming_cursors_by_content(v("1.5.0")));
assert!(crate::is_peer_naming_cursors_by_content(v("1.5.1")));
}
}
#[cfg(test)]
@@ -3107,21 +3039,6 @@ mod kept_cursor_tests {
}
}
#[test]
fn a_kept_shape_is_a_copy_under_the_ui_id() {
let mut cd = compressed(4, 4);
cd.hotx = 1;
let kept = cursor_shape(42, &cd, &cd.colors);
assert_eq!(kept.id, 42);
assert_eq!((kept.hotx, kept.width, kept.height), (1, 4, 4));
assert_eq!(kept.colors, cd.colors);
assert_ne!(
kept.colors.as_ptr(),
cd.colors.as_ptr(),
"not a view of the received buffer"
);
}
#[test]
fn a_kept_shape_is_checked_again_when_it_is_read() {
assert_eq!(kept_cursor_rgba(compressed(4, 4)).unwrap().colors.len(), 64);