Skip to content

Refactor overlapping test coverage for streaming and creative rewrites#661

Open
ChristianPavilonis wants to merge 1 commit intomainfrom
refactor-test-coverage-457-458
Open

Refactor overlapping test coverage for streaming and creative rewrites#661
ChristianPavilonis wants to merge 1 commit intomainfrom
refactor-test-coverage-457-458

Conversation

@ChristianPavilonis
Copy link
Copy Markdown
Collaborator

Summary

  • Refactor overlapping UTF-8 boundary tests in streaming_replacer into shared helpers and consolidated coverage-focused cases.
  • Consolidate repetitive srcset and imagesrcset creative rewrite tests into shared helpers plus table-driven case matrices.
  • Keep runtime behavior unchanged while reducing duplicated test setup and preserving multibyte, emoji, spacing, relative path, and descriptor coverage.

Changes

File Change
crates/trusted-server-core/src/streaming_replacer.rs Added reusable chunk-processing test helpers and replaced overlapping UTF-8 boundary tests with consolidated case-based coverage, including explicit multibyte and emoji boundary splits.
crates/trusted-server-core/src/creative.rs Added shared srcset/imagesrcset test helpers and merged overlapping attribute rewrite tests into compact table-driven cases while keeping integration-specific tests separate.

Closes

Closes #457
Closes #458

Test plan

  • cargo test --workspace
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo fmt --all -- --check
  • JS tests: cd crates/js/lib && npx vitest run
  • JS format: cd crates/js/lib && npm run format
  • Docs format: cd docs && npm run format
  • WASM build: cargo build --package trusted-server-adapter-fastly --release --target wasm32-wasip1
  • Manual testing via fastly compute serve
  • Other: Focused Rust test runs for the new consolidated test cases

Checklist

  • Changes follow CLAUDE.md conventions
  • No unwrap() in production code — use expect("should ...")
  • Uses tracing macros (not println!)
  • New code has tests
  • No secrets or credentials committed

@ChristianPavilonis ChristianPavilonis requested review from aram356 and prk-Jr and removed request for aram356 April 24, 2026 23:44
Copy link
Copy Markdown
Collaborator

@aram356 aram356 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Pure test refactor consolidating overlapping srcset/imagesrcset attribute tests in creative.rs and UTF-8 boundary tests in streaming_replacer.rs. The 1:1 mapping from old tests to new table-driven cases is faithful, and several imagesrcset cases gain stronger assertions (>= 2 rewritten candidates instead of >= 1). Two issues need attention before merge — see inline comments.

Blocking

🔧 wrench

  • Multibyte boundary test still doesn't split mid-character: see inline at streaming_replacer.rs:468. The PR fixes the analogous emoji bug but leaves the multibyte case mis-named.
  • Helper assertion message contradicts its check: see inline at creative.rs:798. >= 2 with message expected two should be == 2.

Non-blocking

🤔 thinking

  • <div><img> element switch in helper: see inline at creative.rs:781. Functionally equivalent given the [imagesrcset] selector, but neither old nor new tests cover the realistic <link rel="preload" as="image" imagesrcset="…"> path. Worth a follow-up issue.
  • Loss of cargo test <single-case> granularity: collapsing 8 standalone tests into 2 table-driven tests means a failing inner case can't be re-run in isolation — only the umbrella test. The case_name in assertion messages mitigates this for log-reading, but bisecting harder failures is more friction. Acceptable tradeoff; flagging as a real downside without a parameterized-test macro (rstest or similar).

📝 note

  • Test-name surface shrinks: cargo test output loses 6 named tests (8 srcset/imagesrcset → 2 umbrellas, plus the streaming consolidation). Any CI dashboard or flake tracker keyed on test names will need to be aware.

CI Status

  • cargo fmt: PASS
  • cargo clippy: PASS
  • cargo test: PASS
  • vitest: PASS
  • format-typescript / format-docs: PASS
  • integration tests / browser integration tests: PASS

let result = process_with_explicit_splits(
create_url_replacer("example.com", "https://example.com", "new.com", "https"),
content,
&[23, content.len()],
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 wrenchtest_process_chunk_boundary_in_multibyte_char still doesn't split mid-multibyte.

Byte 23 falls between ø (bytes 21–22) and r — i.e., on a valid UTF-8 boundary, not mid-character. The test name claims to exercise a split inside a multibyte char, but it doesn't. Since you correctly fixed the analogous emoji case in this same PR (the original test_process_chunk_emoji_boundary never split at all), please apply the same fix here.

The replacer's host-fallback rule (example.comnew.com) keeps the assertion green even when the URL-prefix replacement is severed, so the existing assertion still works.

Fix:

let result = process_with_explicit_splits(
    create_url_replacer("example.com", "https://example.com", "new.com", "https"),
    content,
    &[22, content.len()],
);

(byte 22 is in the middle of ø — first byte was 21).

"case `{}` expected two rewritten {} candidates: {}",
case_name,
attr_name,
out
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 wrench — Assertion message and check are inconsistent.

out.matches("/first-party/proxy?tsurl=").count() >= 2,
"case `{}` expected two rewritten {} candidates: {}",

The message says expected two but the predicate accepts ≥ 2. All current cases produce exactly two rewritten candidates, so tightening the check is the correct fix and would catch any future regression that quietly rewrites a third (e.g., relative-candidate) entry.

Fix:

assert_eq!(
    out.matches("/first-party/proxy?tsurl=").count(),
    2,
    "case `{}` expected exactly two rewritten {} candidates: {}",
    case_name,
    attr_name,
    out
);

fn rewrite_srcset_attr(attr_name: &str, attr_value: &str) -> String {
let settings = crate::test_support::tests::create_test_settings();
let html = format!(r#"<img {}="{}">"#, attr_name, attr_value);
rewrite_creative_html(&settings, &html)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 thinking — The new helper wraps both srcset and imagesrcset in <img>. The old imagesrcset tests used <div>. Both are HTML-spec-illegal placements — imagesrcset belongs on <link rel="preload" as="image"> — but both rely on the element-agnostic [imagesrcset] selector at creative.rs:660, so runtime behavior is identical.

Coverage gap (pre-existing, not introduced here): the realistic <link rel="preload" as="image" imagesrcset="…"> path also flows through the link[href] handler at creative.rs:556-561. Neither the old nor new tests exercise that path. Worth a follow-up issue rather than expanding this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consolidate overlapping srcset attribute tests in creative module Refactor UTF-8 boundary tests in streaming_replacer

2 participants