Files
rustdesk/src/update_metadata/offline_tests.rs
T
RustDeskandClaude Opus 5.5 9997b7a3b8 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>
2026-10-14 14:45:22 +08:00

86 lines
2.8 KiB
Rust

use super::*;
use crate::update_metadata::offline::{
verify_offline_update_metadata_with_options, OfflineVerificationOptions,
};
fn verify_offline(fixture: &Fixture, local_file_name: &str) -> ResultType<VerifiedUpdateArtifact> {
verify_offline_for_package(fixture, local_file_name, PUBLIC_UPDATE_PACKAGE_ID)
}
fn verify_offline_for_package(
fixture: &Fixture,
local_file_name: &str,
expected_package_id: &str,
) -> ResultType<VerifiedUpdateArtifact> {
let trusted_keys = [key(fixture.public_key)];
verify_offline_update_metadata_with_options(
&fixture.metadata,
&fixture.signature,
OfflineVerificationOptions {
requirements: OfflineUpdateMetadataRequirements {
local_file_name,
expected_package_id,
artifact: query(),
},
trusted_keys: &trusted_keys,
},
)
}
#[test]
fn offline_metadata_requires_the_expected_package_identity() {
const CUSTOM_PACKAGE_ID: &str = "com.example.rustdesk-custom";
let mut custom_metadata = metadata();
custom_metadata["package_id"] = json!(CUSTOM_PACKAGE_ID);
let fixture = sign_fixture(custom_metadata, KEY_ID);
assert!(
verify_offline_for_package(&fixture, "rustdesk-1.4.6-x86_64.exe", CUSTOM_PACKAGE_ID)
.is_ok()
);
assert!(verify_offline(&fixture, "rustdesk-1.4.6-x86_64.exe").is_err());
}
#[test]
fn accepts_signed_offline_artifact_from_custom_https_release() {
let mut custom_metadata = metadata();
custom_metadata["artifacts"][0]["url"] =
json!("https://updates.example.com/releases/v1.4.6/rustdesk-1.4.6-x86_64.exe");
let fixture = sign_fixture(custom_metadata, KEY_ID);
let artifact = verify_offline(&fixture, "rustdesk-1.4.6-x86_64.exe")
.expect("verified custom HTTPS artifact");
assert_eq!("rustdesk-1.4.6-x86_64.exe", artifact.file_name);
}
#[test]
fn rejects_signed_offline_artifact_from_unsafe_url() {
for url in [
"http://updates.example.com/rustdesk-1.4.6-x86_64.exe",
"https://user@updates.example.com/rustdesk-1.4.6-x86_64.exe",
] {
let mut invalid_metadata = metadata();
invalid_metadata["artifacts"][0]["url"] = json!(url);
let fixture = sign_fixture(invalid_metadata, KEY_ID);
assert!(
verify_offline(&fixture, "rustdesk-1.4.6-x86_64.exe").is_err(),
"{url}"
);
}
}
#[test]
fn rejects_offline_artifact_name_or_release_mismatch() {
assert!(verify_offline(&valid_fixture(), "renamed-update.exe").is_err());
let mut invalid_metadata = metadata();
invalid_metadata["version"] = json!("1.4.7");
assert!(verify_offline(
&sign_fixture(invalid_metadata, KEY_ID),
"rustdesk-1.4.6-x86_64.exe"
)
.is_err());
}