# retoor import hashlib import pytest from devplacepy import config @pytest.fixture def artifacts(tmp_path, monkeypatch): monkeypatch.setattr(config, "NODE_CLIENTS_DIR", tmp_path) (tmp_path / "devplace-node-linux-amd64").write_bytes(b"binary-bytes") (tmp_path / "manifest.json").write_text('[{"version": "0.3.0"}]') (tmp_path / "bad name.txt").write_text("x") return tmp_path def test_client_version_lists_artifacts_with_checksums(client, artifacts): body = client.get("/nodes/client-version").json() assert body["version"] == "0.3.0" and body["protocol"] >= 1 names = [item["name"] for item in body["artifacts"]] assert names == ["devplace-node-linux-amd64"] assert body["artifacts"][0]["sha256"] == hashlib.sha256(b"binary-bytes").hexdigest() def test_download_serves_the_file_with_its_checksum(client, artifacts): response = client.get("/nodes/download/devplace-node-linux-amd64") assert response.status_code == 200 and response.content == b"binary-bytes" assert response.headers["x-content-sha256"] == hashlib.sha256(b"binary-bytes").hexdigest() @pytest.mark.parametrize("name", ["manifest.json", "missing", "..%2Fsecret", "bad%20name.txt", ".hidden"]) def test_download_refuses_everything_else(client, artifacts, name): assert client.get(f"/nodes/download/{name}").status_code in (404, 422) def test_download_refuses_a_symlink(client, artifacts): outside = artifacts.parent / "outside.bin" outside.write_bytes(b"secret") (artifacts / "link").symlink_to(outside) assert client.get("/nodes/download/link").status_code == 404 def test_empty_directory_is_an_empty_list(client, tmp_path, monkeypatch): monkeypatch.setattr(config, "NODE_CLIENTS_DIR", tmp_path / "absent") assert client.get("/nodes/client-version").json()["artifacts"] == []