dodil/erp-brick-contracts

tests/test_flow.py

"""The whole story once, through the doors: draft → send (no mail provider: a manual task) → copy the signing link →
the counterparty signs through the public door → our director signs in the app → the executed copy and its
certificate. The other test files take each rule apart."""
import base64
import hashlib
import io
import re

from conftest import ADMIN, headers
from erp_platform import work

DIRECTOR = headers("director")


def draft_nda(api, partners, key="F1", **values):
    bp = partners.add(1001, "Studio Nine Ltd", ["supplier"])
    s, c = api("POST", "/contracts", ADMIN, {"type_code": "nda", "bp_id": str(bp), "form_key": key,
                                             "values": {"start_date": "2026-11-01", **values},
                                             "signers": [{"side": "THEM", "full_name": "Sam Nine",
                                                          "email": "sam@studionine.example", "signing_order": 1},
                                                         {"side": "US", "full_name": "Dana Director",
                                                          "email": "director.1@scenario.test", "title": "Director",
                                                          "signing_order": 2}]})
    assert s == 200, c
    return c


def path_of(url):
    return url.split("public.contracts.test", 1)[1]


def test_the_whole_story(library, partners, door):
    api = library
    c = draft_nda(api, partners)
    cid = c["contract_id"]
    assert c["state"] == "DRAFT" and c["missing"] == [] and c["approval_required"] is False, c
    s, sent = api("POST", f"/contracts/{cid}/send", ADMIN, {})
    assert s == 200 and sent["state"] == "OUT_FOR_SIGNATURE" and sent["version"] == 1, sent
    assert sent["deliveries"] == [{"signer_no": 1, "channel": "manual"}]
    s, link = api("POST", f"/contracts/{cid}/signers/1/copy-link", ADMIN, {})
    assert s == 200 and link["url"].startswith("https://public.contracts.test/p/"), link
    s, page = door("GET", path_of(link["url"]))
    assert s == 200 and "Studio Nine Ltd" in page and sent["sha256"] in page, page[:500]
    s, page = door("POST", path_of(link["url"]), form={"action": "sign", "typed_name": "Sam Nine", "consent": "yes",
                                                       "version": "1", "sha256": sent["sha256"]})
    assert s == 200 and "you have signed electronically" in page, page[:600]
    s, todo = api("GET", "/to-sign", DIRECTOR)
    assert s == 200 and [x["contract_id"] for x in todo["to_sign"]] == [cid], todo
    s, out = api("POST", f"/contracts/{cid}/sign", DIRECTOR, {"version": 1, "sha256": sent["sha256"],
                                                                "typed_name": "Dana Director", "consent": True})
    assert s == 200 and out["executed"] is True and out["state"] == "SIGNED", out
    s, cert = api("GET", f"/contracts/{cid}/certificate", ADMIN)
    assert s == 200 and cert["chain"]["valid"] is True, cert
    kinds = [e["kind"] for e in cert["events"]]
    assert kinds.count("SIGNED") == 2 and "OPENED" in kinds and "CONSENTED" in kinds, kinds
    s, ex = api("GET", f"/contracts/{cid}/executed", ADMIN)
    data = base64.b64decode(ex["content_base64"])
    assert hashlib.sha256(data).hexdigest() == ex["sha256"] == cert["executed_sha256"]
    s, v1 = api("GET", f"/contracts/{cid}/versions/1/file", ADMIN)
    v1b = base64.b64decode(v1["content_base64"])
    assert data.startswith(v1b) and hashlib.sha256(v1b).hexdigest() == sent["sha256"]
    from pypdf import PdfReader
    text = PdfReader(io.BytesIO(data)).pages[-1].extract_text()
    assert "Signed electronically" in text and sent["sha256"] in text.replace("\n", "")