forked from retoor/devplacepy
Code Farm: per-plot auto-replant pause and crop-lock check; community sync and node work
Continuous Delivery could never be turned off once a crop was planted. Add a one-shot per-plot "stop after harvest" flag (POST /game/plot/stop, Devii tool game_plot_stop, game_plots.stop_after_harvest), cleared by the next plant, autoreplant claim or Refactor. Autoreplant now also respects crop locks through the shared _crop_lock predicate. Plan and measurements in happyplanting.md. Also includes the pending community sync, node network and related work in the tree; the full suite passed (4999) with all of it. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -131,3 +131,44 @@ def test_feeds_listing_the_same_posts_are_learned_once_and_comment_feeds_are_ski
|
||||
def test_generic_probe_paths_are_skipped_when_a_feed_is_advertised():
|
||||
_, fetcher = discover(rss_community(), "https://blog.test/")
|
||||
assert not any(request.endswith("/api/posts") or request.endswith("/rss.xml") for request in fetcher.requests)
|
||||
|
||||
|
||||
def test_a_captcha_on_the_login_wall_is_reported_and_never_attempted():
|
||||
routes = club_community({})
|
||||
captcha_wall = routes["https://club.test/"]().replace("<form", '<div class="g-recaptcha" data-sitekey="k"></div><form', 1)
|
||||
routes["https://club.test/"] = captcha_wall
|
||||
routes["https://club.test/login"] = captcha_wall
|
||||
result, fetcher = discover(routes, "https://club.test/")
|
||||
assert result.status == "login_required" and "captcha" in result.error
|
||||
assert result.schema["login"]["captcha"] is True and fetcher.posts == []
|
||||
result, fetcher = discover(routes, "https://club.test/", {"username": "bob", "password": "pw"})
|
||||
assert result.status == "login_required" and "captcha" in result.error and fetcher.posts == []
|
||||
|
||||
|
||||
def test_a_second_factor_with_a_secret_logs_in_and_without_one_asks_a_human(monkeypatch):
|
||||
from devplacepy.services.community import runtime
|
||||
from tests.unit.services.community.login import OTP_PAGE
|
||||
|
||||
monkeypatch.setattr(runtime, "totp", lambda secret: "123456")
|
||||
state = {}
|
||||
routes = club_community(state)
|
||||
password_step = routes["post:https://club.test/login"]
|
||||
|
||||
def first_step(data):
|
||||
answer = password_step(data)
|
||||
if state.get("in"):
|
||||
state["in"] = False
|
||||
return (200, OTP_PAGE)
|
||||
return answer
|
||||
|
||||
def second_step(data):
|
||||
state["in"] = data.get("otp_code") == "123456"
|
||||
return (200, "welcome" if state["in"] else OTP_PAGE)
|
||||
|
||||
routes["post:https://club.test/login"] = first_step
|
||||
routes["post:https://club.test/2fa"] = second_step
|
||||
result, _ = discover(routes, "https://club.test/", {"username": "bob", "password": "pw", "totp": "JBSWY3DPEHPK3PXP"})
|
||||
assert result.status == "ready", result.error
|
||||
state.clear()
|
||||
result, _ = discover(routes, "https://club.test/", {"username": "bob", "password": "pw"})
|
||||
assert result.status == "login_required" and "authenticator secret" in result.error
|
||||
|
||||
Reference in New Issue
Block a user