File size: 3,637 Bytes
d2d1903
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
"""
Tests for Stage 70 β€” bundle CLI.

  python -m delivery.bundle create DIR [--out PATH]
  python -m delivery.bundle verify  ZIP

Recipient who got a bundle.zip in an email can verify in one shell
command. Exit-code contract:
  0 β€” create succeeded OR verify passed (manifest intact)
  1 β€” verify failed (sha256 mismatch on at least one file)
  2 β€” bad args / file not found / not a zip
"""
import json
import zipfile

from delivery.bundle import _cli, bundle_pilot_output


def _populate(tmp_path):
    src = tmp_path / "pilot_out"
    src.mkdir()
    (src / "report.html").write_text("<h1>R</h1>", encoding="utf-8")
    (src / "queue.html").write_text("<h1>Q</h1>", encoding="utf-8")
    return src


def _run(capsys, *args):
    capsys.readouterr()
    rc = _cli(list(args))
    out, err = capsys.readouterr()
    body = json.loads(out) if out.strip() else None
    err_body = json.loads(err) if err.strip() else None
    return rc, body, err_body


# --- create ----------------------------------------------------------

def test_create_emits_bundle_path_and_writes_zip(tmp_path, capsys):
    src = _populate(tmp_path)
    rc, body, _ = _run(capsys, "create", str(src))
    assert rc == 0
    assert "bundle_path" in body
    zip_path = tmp_path / "pilot_out.zip"
    assert zip_path.exists()


def test_create_with_explicit_out(tmp_path, capsys):
    src = _populate(tmp_path)
    out = tmp_path / "custom.zip"
    rc, body, _ = _run(capsys, "create", str(src), "--out", str(out))
    assert rc == 0
    assert body["bundle_path"] == str(out.resolve())
    assert out.exists()


def test_create_missing_dir_exits_2(tmp_path, capsys):
    rc, _, err = _run(capsys, "create", str(tmp_path / "nope"))
    assert rc == 2
    assert "does not exist" in err["error"]


# --- verify ----------------------------------------------------------

def test_verify_intact_bundle_exits_0(tmp_path, capsys):
    src = _populate(tmp_path)
    zip_path = bundle_pilot_output(src)
    rc, body, _ = _run(capsys, "verify", str(zip_path))
    assert rc == 0
    assert body["ok"] is True
    assert body["n_mismatches"] == 0


def test_verify_tampered_bundle_exits_1(tmp_path, capsys):
    """The recipient's smoking gun β€” if anyone modified a file in the
    bundle, verify returns exit 1 + ok=false + the mismatching paths
    in the JSON. Cron-friendly: pipe to ``jq .ok`` and gate on it."""
    src = _populate(tmp_path)
    src_zip = bundle_pilot_output(src)
    tampered = tmp_path / "tampered.zip"
    with zipfile.ZipFile(src_zip, "r") as zin, \
            zipfile.ZipFile(tampered, "w", zipfile.ZIP_DEFLATED) as zout:
        for name in zin.namelist():
            data = zin.read(name)
            if name == "report.html":
                data = b"<h1>EVIL</h1>"
            zout.writestr(name, data)
    rc, body, _ = _run(capsys, "verify", str(tampered))
    assert rc == 1
    assert body["ok"] is False
    assert body["n_mismatches"] == 1
    assert body["mismatches"][0]["path"] == "report.html"


def test_verify_missing_file_exits_2(tmp_path, capsys):
    rc, _, err = _run(capsys, "verify", str(tmp_path / "no_such.zip"))
    assert rc == 2
    assert "error" in err


def test_verify_non_zip_exits_2(tmp_path, capsys):
    """A path that exists but isn't a zip β€” exit 2 with a clear
    'not a valid zip' message. Operator pointing at the wrong file
    sees the right error, not a Python traceback."""
    bad = tmp_path / "not_a_zip.txt"
    bad.write_text("plain text not a zip", encoding="utf-8")
    rc, _, err = _run(capsys, "verify", str(bad))
    assert rc == 2
    assert "not a valid zip" in err["error"]