80 lines
2.5 KiB
Python
80 lines
2.5 KiB
Python
"""Integration tests against the real Raycast.app, if present.
|
|
|
|
These tests are gated on `RAYCAST_APP_PATH` (or, as a developer convenience,
|
|
the `Raycast Beta.app` sitting next to the repo). They prove that discovery
|
|
gives us the same signing_secret HANDOFF.md documents — i.e. that the AST
|
|
patterns we match against survive on the actual minified bundle, not just the
|
|
synthetic fixture.
|
|
|
|
Skipped automatically if no app is found, so CI without an .app stays green.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from raycast_api.config import Config
|
|
|
|
EXPECTED_SECRET = "6bc455473576ce2cd6f70426caff867aabbe3f7291c1a79681af5e8ce0ca1408"
|
|
|
|
|
|
def _app_path() -> Path | None:
|
|
env = os.environ.get("RAYCAST_APP_PATH")
|
|
candidates: list[Path] = []
|
|
if env:
|
|
candidates.append(Path(env))
|
|
candidates.extend(
|
|
[
|
|
Path(__file__).resolve().parents[2] / "Raycast Beta.app",
|
|
Path("/Applications/Raycast Beta.app"),
|
|
Path("/Applications/Raycast.app"),
|
|
]
|
|
)
|
|
for p in candidates:
|
|
if p.is_dir():
|
|
return p
|
|
return None
|
|
|
|
|
|
pytestmark = pytest.mark.local_app
|
|
|
|
|
|
@pytest.fixture
|
|
def real_app() -> Path:
|
|
app = _app_path()
|
|
if app is None:
|
|
pytest.skip("No local Raycast.app found (set RAYCAST_APP_PATH to override)")
|
|
raise AssertionError("unreachable")
|
|
return app
|
|
|
|
|
|
def test_discover_secret(real_app: Path, isolated_cache: Path) -> None:
|
|
cfg = Config.discover_from_app(real_app)
|
|
assert len(cfg.signature_secret) == 64
|
|
assert all(c in "0123456789abcdef" for c in cfg.signature_secret)
|
|
if cfg.signature_secret != EXPECTED_SECRET:
|
|
pytest.skip(
|
|
f"Local Raycast secret ({cfg.signature_secret[-8:]}) doesn't match HANDOFF "
|
|
f"({EXPECTED_SECRET[-8:]}) — likely a different Raycast version. Discovery shape OK."
|
|
)
|
|
|
|
|
|
def test_discover_signing_spec_shape(real_app: Path, isolated_cache: Path) -> None:
|
|
cfg = Config.discover_from_app(real_app)
|
|
spec = cfg.signing_spec
|
|
assert spec.join_char == "."
|
|
assert spec.body_hash_algorithm == "SHA-256"
|
|
assert spec.hmac_algorithm == "SHA-256"
|
|
assert spec.key_encoding == "utf-8"
|
|
ranges = {(r.start, r.end, r.shift) for r in spec.rot_ranges}
|
|
assert ranges == {(65, 90, 13), (97, 122, 13), (48, 57, 5)}
|
|
|
|
|
|
def test_app_version_and_ua(real_app: Path, isolated_cache: Path) -> None:
|
|
cfg = Config.discover_from_app(real_app)
|
|
assert cfg.app_version
|
|
assert cfg.user_agent.startswith(f"Raycast/{cfg.app_version} (x-macOS Version ")
|