mirror of
https://github.com/usestrix/strix.git
synced 2026-08-21 18:52:47 +02:00
105 lines
3.2 KiB
Python
105 lines
3.2 KiB
Python
"""Tests for ``--workspace-file`` parsing and delivery."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING
|
|
|
|
import pytest
|
|
|
|
from strix.core.inputs import build_root_task
|
|
from strix.interface.utils import (
|
|
WORKSPACE_FILES_MAX_TOTAL_BYTES,
|
|
read_workspace_files,
|
|
resolve_workspace_files,
|
|
)
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
from pathlib import Path
|
|
|
|
|
|
def test_a_bare_path_lands_on_the_file_name(tmp_path: Path) -> None:
|
|
source = tmp_path / "wordlist.txt"
|
|
source.write_text("admin\n", encoding="utf-8")
|
|
|
|
resolved = resolve_workspace_files([str(source)])
|
|
|
|
assert resolved == [
|
|
{"source_path": str(source.resolve()), "workspace_path": "/workspace/wordlist.txt"}
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"dest",
|
|
["specs/openapi.yaml", "/workspace/specs/openapi.yaml"],
|
|
)
|
|
def test_a_declared_destination_is_taken_relative_to_the_workspace(
|
|
tmp_path: Path, dest: str
|
|
) -> None:
|
|
source = tmp_path / "openapi.yaml"
|
|
source.write_text("openapi: 3.1.0\n", encoding="utf-8")
|
|
|
|
resolved = resolve_workspace_files([f"{source}:{dest}"])
|
|
|
|
assert resolved[0]["workspace_path"] == "/workspace/specs/openapi.yaml"
|
|
|
|
|
|
def test_a_missing_file_is_rejected(tmp_path: Path) -> None:
|
|
with pytest.raises(ValueError, match="not an existing file"):
|
|
resolve_workspace_files([str(tmp_path / "nope.txt")])
|
|
|
|
|
|
def test_a_directory_is_rejected(tmp_path: Path) -> None:
|
|
with pytest.raises(ValueError, match="not an existing file"):
|
|
resolve_workspace_files([str(tmp_path)])
|
|
|
|
|
|
@pytest.mark.parametrize("dest", ["../escape.txt", "notes/../../escape.txt", "/etc/passwd"])
|
|
def test_a_destination_outside_the_workspace_is_rejected(tmp_path: Path, dest: str) -> None:
|
|
source = tmp_path / "notes.md"
|
|
source.write_text("x", encoding="utf-8")
|
|
|
|
with pytest.raises(ValueError):
|
|
resolve_workspace_files([f"{source}:{dest}"])
|
|
|
|
|
|
def test_two_files_cannot_claim_one_destination(tmp_path: Path) -> None:
|
|
first = tmp_path / "a.txt"
|
|
second = tmp_path / "b.txt"
|
|
first.write_text("a", encoding="utf-8")
|
|
second.write_text("b", encoding="utf-8")
|
|
|
|
with pytest.raises(ValueError, match="Two workspace files target"):
|
|
resolve_workspace_files([f"{first}:notes.txt", f"{second}:notes.txt"])
|
|
|
|
|
|
def test_the_total_size_is_capped(tmp_path: Path) -> None:
|
|
source = tmp_path / "big.bin"
|
|
source.write_bytes(b"0" * (WORKSPACE_FILES_MAX_TOTAL_BYTES + 1))
|
|
|
|
with pytest.raises(ValueError, match="total limit"):
|
|
resolve_workspace_files([str(source)])
|
|
|
|
|
|
def test_resolved_files_are_read_into_engine_entries(tmp_path: Path) -> None:
|
|
source = tmp_path / "wordlist.txt"
|
|
source.write_bytes(b"admin\n")
|
|
|
|
entries = read_workspace_files(resolve_workspace_files([str(source)]))
|
|
|
|
assert entries == [{"workspace_path": "/workspace/wordlist.txt", "content": b"admin\n"}]
|
|
|
|
|
|
def test_the_task_lists_workspace_files_apart_from_the_targets() -> None:
|
|
task = build_root_task(
|
|
{
|
|
"targets": [],
|
|
"user_instructions": "Use the wordlist",
|
|
"workspace_files": [{"workspace_path": "/workspace/wordlist.txt"}],
|
|
}
|
|
)
|
|
|
|
assert "Files Provided By The User:" in task
|
|
assert "/workspace/wordlist.txt" in task
|
|
assert "not targets to assess" in task
|