//! Integration test for a compositions+lane suite reaching the lanes (WOR-1512).
//!
//! A suite that declares `compositions:` plus a capability lane (here
//! `compliance:`) but no `tools:`/`agents:` used to short-circuit right after
//! the compositions ran, so the declared lane never executed and silently
//! contributed nothing to the result. The run now falls through to the lanes
//! whenever the suite declares one. Offline and key-free: the built-in mock.

use assert_cmd::Command;
use predicates::prelude::*;

fn mcptest() -> Command {
    Command::cargo_bin("mcptest").expect("binary builds")
}

fn mcptest_bin() -> &'static str {
    env!("CARGO_BIN_EXE_mcptest")
}

/// Write a clean mock manifest exposing one `echo` tool: the tool the
/// composition node calls and the server the compliance check probes.
fn write_manifest(dir: &std::path::Path) -> std::path::PathBuf {
    let manifest = r#"mock_server:
  name: echo
  tools:
    - name: echo
      description: "Echo a fixed line."
      input_schema:
        type: object
      response:
        isError: false
        content:
          - type: text
            text: "hello"
"#;
    let path = dir.join("echo.yaml");
    std::fs::write(&path, manifest).expect("write mock manifest");
    path
}

/// A `compositions:` + `compliance:` suite has no tool or agent tests, so the
/// old `composition_only` short-circuit returned after running the composition
/// and never reached the compliance lane. The run must now execute both: the
/// composition row AND the `compliance/PROTO-002` row appear, and the run exits
/// 0 because both pass.
#[test]
fn a_compositions_plus_lane_suite_still_runs_the_lane() {
    let dir = tempfile::tempdir().unwrap();
    let manifest = write_manifest(dir.path());
    let suite = format!(
        r#"servers:
  mock:
    command: ['{bin}', 'mock', '--tools-from', '{manifest}']
compositions:
  - name: echo-once
    nodes:
      - id: e
        tool: echo
        mock:
          result:
            ok: true
    output: e
    expect:
      - target: "composition.ran"
        matcher:
          exact: true
      - target: "nodes.e.status"
        matcher:
          exact: "ok"
compliance:
  - name: PROTO-002 initialize returns capabilities
    server: mock
    check: initialize
    expect:
      - target: result.capabilities
        matcher:
          schema: {{ type: object }}
"#,
        bin = mcptest_bin(),
        manifest = manifest.display(),
    );
    let path = dir.path().join("suite.yml");
    std::fs::write(&path, suite).expect("write suite");
    mcptest()
        .args(["run", "--config", path.to_str().unwrap()])
        .assert()
        .success()
        .stdout(predicate::str::contains("compliance/PROTO-002"));
}
