"""Yearly plans, the usage-based price of a job, locked results and the automatic proofread (no models, no network).""" import os import tempfile import pytest os.environ.setdefault("USERS_DB", os.path.join(tempfile.gettempdir(), "cs_suite_test_users.db")) app = pytest.importorskip("app") P, D, S, H = app.P, app.D, app.S, app.H TEXT = ("The model was trained on the full dataset of 12,500 images and it reached an accuracy of 96.3% [4]. " "The results were compared with a baseline that used the same data and the same split of the samples.") def _docx(tmp_path, name="paper.docx", text=TEXT): from docx import Document d = Document() d.add_paragraph(text) p = tmp_path / name d.save(str(p)) return str(p) # ---------------------------------------------------------------- yearly plans def test_yearly_is_twelve_months_less_the_discount(): assert P.YEARLY_DISCOUNT == 20 assert P.yearly_amount("scholar", "INR") == 9590 # 12 x 999 x 0.8, to the nearest ten rupees assert P.yearly_amount("pro", "INR") == 28790 assert P.yearly_amount("scholar", "USD") == 134 labels = P.price_buttons("INR") assert len(labels) == len(P.BUY_ITEMS) == 6 assert "₹9,590/year" in labels[4] and "₹28,790/year" in labels[5] assert "a year (save 20%)" in P.pricing_html("INR") # ---------------------------------------------------------------- usage-based price def test_price_is_cost_plus_margin_plus_gst(): p = P.usage_price(300, 0.20) # 5 minutes of GPU, 20 cents of language model assert p["gpu_usd"] == pytest.approx(300 * 0.40 / 3600) assert p["space_usd"] == pytest.approx(p["gpu_usd"] * 4) # idle share of the always-on Space assert p["cost_usd"] == pytest.approx(p["gpu_usd"] * 5 + 0.20) assert p["profit_usd"] == pytest.approx(4 * p["cost_usd"]) # 400% margin: price before tax = 5 x cost assert p["gst_usd"] == pytest.approx(0.18 * 5 * p["cost_usd"]) assert p["inr"] == 184 # $2.164 x 85, rounded up assert P.usage_price(1, 0)["inr"] == P.PRICE_MIN_INR # never below the smallest charge def test_no_credits_means_the_wallet_pays_not_a_block(monkeypatch): free = dict(admin=False, key="free", credits=0, trial_left=0, doc_words=5000, status="free", docs_month=0, used=0, month_end=None) monkeypatch.setattr(P, "state", lambda user: dict(free)) monkeypatch.setattr(P, "docs_available", lambda st: 0) monkeypatch.setattr(P, "_free_rerun", lambda e, fkey: False) assert P.check_doc({"email": "a@b.co"}, 4000, "Smart Humanize") == "wallet" # paid from the prepaid wallet monkeypatch.setattr(P, "PAY_PER_USE", False) with pytest.raises(app.A.Upsell): P.check_doc({"email": "a@b.co"}, 4000, "Smart Humanize") # ---------------------------------------------------------------- charges, the pop-up, unlocking def test_charge_is_locked_until_it_is_settled(tmp_path, monkeypatch): out = _docx(tmp_path, "paper_humanized.docx") tok = app.PAYG_FOR.set("payer@example.com") monkeypatch.setattr(S.G, "spent", lambda book=None: 0.20) try: c = app._payg_lock(out, "Smart Humanize", "paper.docx", 4000, 300, None) finally: app.PAYG_FOR.reset(tok) assert c["status"] == "pending" and c["amount_inr"] == 184 and c["ref"].startswith("CS-") user = {"email": "payer@example.com"} status, file, dl = app.claim_paid(user) assert "not confirmed yet" in status and "Pay now" in status and not isinstance(file, str) ok, msg = P.settle_charge(c["ref"], source="admin") assert ok and "can now download" in msg status, file, dl = app.claim_paid(user) assert "Payment received" in status and file == out and "Download" in dl assert P.settle_charge(c["ref"])[1].endswith("already paid.") assert P.settle_charge("CS-NOPE")[0] is False def test_nothing_is_locked_for_a_job_covered_by_a_plan(tmp_path): assert app.PAYG_FOR.get() is None assert app._payg_lock(_docx(tmp_path), "Smart Humanize", "paper.docx", 4000, 300, None) is None def test_popup_shows_the_price_and_opens_the_payment_page(monkeypatch): c = dict(ref="CS-ABCD1234", name="thesis.docx", words=5120, amount_inr=111.0, tool="Smart Humanize", email="payer@example.com") monkeypatch.setattr(P, "PAY_URL", "https://pay.example.com/p?amount={amount}&ref={ref}&email={email}") h = app.pay_popup_html(c, "smart") assert 'class="cs-upsell' in h and "₹111" in h and "CS-ABCD1234" in h and "18% GST" in h assert 'href="https://pay.example.com/p?amount=111&ref=CS-ABCD1234&email=payer%40example.com"' in h assert 'target="_blank"' in h and 'data-cs-go="cs-go-unlock-smart"' in h monkeypatch.setattr(P, "PAY_URL", "") # no gateway yet: the WhatsApp contact assert "https://wa.me/" in app.pay_popup_html(c, "hum") and "cs-go-unlock-hum" in app.pay_popup_html(c, "hum") def test_pay_per_use_buttons_and_admin_table_are_wired(): cfg = app.demo.get_config_file() ids = {c["props"].get("elem_id"): c["id"] for c in cfg["components"] if c["props"].get("elem_id")} assert {"cs-go-unlock-smart", "cs-go-unlock-hum"} <= set(ids) triggers = {t[0] for d in cfg["dependencies"] for t in d["targets"]} assert ids["cs-go-unlock-smart"] in triggers and ids["cs-go-unlock-hum"] in triggers labels = {str(c["props"].get("value") or "") for c in cfg["components"]} assert any("Mark paid" in x for x in labels) and any("yearly" in x.lower() for x in labels) # ---------------------------------------------------------------- automatic proofread class _Rep: meta = {} def __call__(self, *a, **k): pass def _smart_res(path): blocks = D.classify([D.Block(D._norm(TEXT))], D.PASTE_MIN_WORDS) D.analyse(blocks, scorer=lambda texts: [0.0] * len(texts)) stats = lambda p: dict(pct=p, analysed=30, high=0, moderate=0, all_words=30) return dict(before=stats(90), after=stats(10), log=["Pass 1: AI score 90% → rewrote 2 of 2 flagged sentences"], note="", blocks=blocks, path=path, report=None, orig="The original text.", new=TEXT) def test_a_humanized_document_is_proofread_automatically(tmp_path, monkeypatch): src, hum, proofed = _docx(tmp_path, "in.docx"), _docx(tmp_path, "in_humanized.docx"), \ _docx(tmp_path, "in_proofread.docx", TEXT.replace("reached", "achieved")) monkeypatch.setattr(D, "score_texts", lambda texts: [0.0] * len(texts)) monkeypatch.setattr(S, "smart_docx", lambda *a: _smart_res(hum)) seen = {} def proofread(path, orig, rep, hi, mod, protect_ai=False): seen.update(path=path, orig=orig, protect=protect_ai) return dict(path=proofed, before=dict(pct=10, all_words=30), after=dict(pct=8, all_words=30, analysed=30, high=0, moderate=0), n=1, total=2, note="", notes=[], single=True, limited=False) import proofread as PR monkeypatch.setattr(PR, "proofread_docx", proofread) out = app._smart_docx_core(src, 0, 2, 0.9, "Auto", 0.8, 0.5, False, 0, None, None, app.GOALS[0], _Rep()) assert seen == dict(path=hum, orig=src, protect=True) # the humanized file, with the upload as reference assert "Proofread:" in out[0] and "done automatically, 1 of 2" in out[0] and "90% → 8%" in out[0] assert out[3] == proofed # the customer downloads the proofread file def test_the_humanized_file_is_still_delivered_if_the_proofread_fails(tmp_path, monkeypatch): src, hum = _docx(tmp_path, "in.docx"), _docx(tmp_path, "in_humanized.docx") monkeypatch.setattr(D, "score_texts", lambda texts: [0.0] * len(texts)) monkeypatch.setattr(S, "smart_docx", lambda *a: _smart_res(hum)) import proofread as PR def boom(*a, **k): raise ValueError("layout changed") monkeypatch.setattr(PR, "proofread_docx", boom) out = app._smart_docx_core(src, 0, 2, 0.9, "Auto", 0.8, 0.5, False, 0, None, None, app.GOALS[0], _Rep()) assert out[3] == hum and "could not run this time" in out[0] def test_the_humanizer_skips_its_own_polish_when_the_proofread_follows(monkeypatch): called = [] monkeypatch.setattr(H.G, "available", lambda: True) monkeypatch.setattr(H.G, "polish", lambda *a, **k: called.append("polish") or []) monkeypatch.setattr(H.G, "grammar", lambda s, *a, **k: called.append("grammar") or list(s)) monkeypatch.setattr(H.LT, "MODE", "off") monkeypatch.setattr(H.FL, "scores", lambda texts: [0.9] * len(texts)) tok = H.PROOFREAD_FOLLOWS.set(True) try: H.grammar_fix_sentences(["A rewritten sentence that is perfectly fine here."], frozenset()) finally: H.PROOFREAD_FOLLOWS.reset(tok) assert called == [] # one final check (the proofread), not two def test_pricing_page_shows_pay_per_use_and_monthly_or_yearly(): month = P.pricing_html("INR", "Monthly") assert "Pay per use" in month and "pay only to download" in month and "done automatically" in month assert "₹999" in month and "/month" in month and "Yearly: ₹9,590 a year (save 20%)" in month year = P.pricing_html("INR", P.BILLING[1]) assert "₹9,590" in year and "/year" in year and "₹28,790" in year assert "works out at ₹799/month instead of ₹999" in year and "12 months for the price of 9.6" in year usd = P.pricing_html("USD", P.BILLING[1]) assert "$134" in usd and "/year" in usd def test_a_proofread_that_raises_the_ai_score_is_not_used(tmp_path, monkeypatch): """Live case: humanizing reached 0%, the automatic proofread put the author's wording back and the customer got 100%. The humanized file is delivered instead, and the message says why.""" src, hum, proofed = _docx(tmp_path, "in.docx"), _docx(tmp_path, "in_humanized.docx"), _docx(tmp_path, "in_proofread.docx", TEXT.replace("reached", "achieved")) monkeypatch.setattr(D, "score_texts", lambda texts: [0.0] * len(texts)) monkeypatch.setattr(S, "smart_docx", lambda *a: _smart_res(hum)) import proofread as PR monkeypatch.setattr(PR, "proofread_docx", lambda *a, **k: dict( path=proofed, before=dict(pct=10, all_words=30), after=dict(pct=100, all_words=30, analysed=30, high=30, moderate=0), n=2, total=2, note="", notes=[], single=True, limited=False)) out = app._smart_docx_core(src, 0, 2, 0.9, "Auto", 0.8, 0.5, False, 0, None, None, app.GOALS[0], _Rep()) assert out[3] == hum # the humanized file, not the proofread one assert "would have raised the AI score" in out[0] and "90% → 10%" in out[0] def test_checking_models_stay_on_the_cpu_without_a_dedicated_gpu(monkeypatch): import torch import runtime as RT m = torch.nn.Linear(2, 2) monkeypatch.setattr(RT, "HELPERS_GPU", False) assert RT.to_gpu(m) is m and RT.device_of(m).type == "cpu" monkeypatch.setattr(RT, "HELPERS_GPU", True) # a GPU that fails: the model still works on CPU monkeypatch.setattr(m, "to", lambda *a, **k: (_ for _ in ()).throw(RuntimeError("CUDA out of memory"))) assert RT.to_gpu(m) is m def test_learned_banned_words_are_suppressed_without_the_slow_bad_words_filter(monkeypatch): """5,500 bad_words_ids sequences made every Parrot call take 20-30 s on the Space's GPU. Single-token bans now go through suppress_tokens; longer ones are left to banned_in().""" import adaptive as AD class Tok: ids = {"delve": [7], " delve": [8], "Delve": [9], " Delve": [10], "tapestry": [11, 12]} def __call__(self, form, add_special_tokens=False): return type("E", (), {"input_ids": self.ids.get(form, [99, 98])})() monkeypatch.setattr(AD, "banned", lambda: {"delve", "tapestry"}) AD._bw_cache.clear() assert AD.suppress_ids(Tok()) == [7, 8, 9, 10] monkeypatch.setattr(AD, "banned", lambda: set()) AD._bw_cache.clear() assert AD.suppress_ids(Tok()) is None