forked from retoor/devplacepy
98 lines
5.7 KiB
Python
98 lines
5.7 KiB
Python
# retoor <retoor@molodetz.nl>
|
|||
|
|
|
||
|
|
import json
|
||
|
|
|
||
|
|
from devplacepy.database import get_table
|
||
|
|
from devplacepy.services.community.files import files
|
||
|
|
from devplacepy.services.community.store import store
|
||
|
|
from tests.api.admin.communities.index import add_ready, admin, client, fake_world, make_account # noqa: F401
|
||
|
|
|
||
|
|
|
||
|
|
def save(client, admin, schema_text, slug="forum-test"):
|
||
|
|
return client.post(f"/admin/communities/{slug}/schema", data={"schema": schema_text}, headers=admin["headers"])
|
||
|
|
|
||
|
|
|
||
|
|
def test_authz(client, admin, fake_world):
|
||
|
|
add_ready(client, admin)
|
||
|
|
member = make_account()
|
||
|
|
assert client.get("/admin/communities/forum-test/schema", headers={"Accept": "application/json"}).status_code in (401, 303)
|
||
|
|
assert client.get("/admin/communities/forum-test/schema", headers=member["headers"]).status_code == 403
|
||
|
|
assert client.post("/admin/communities/forum-test/schema", data={"schema": "{}"}, headers=member["headers"]).status_code == 403
|
||
|
|
assert client.post("/admin/communities/forum-test/schema/restore", headers=member["headers"]).status_code == 403
|
||
|
|
|
||
|
|
|
||
|
|
def test_the_page_shows_the_schema_and_never_a_credential(client, admin, fake_world):
|
||
|
|
add_ready(client, admin)
|
||
|
|
store.update(store.get("forum-test")["uid"], login_password="topsecret-pw", login_totp_secret="TOTPSECRETVALUE")
|
||
|
|
body = client.get("/admin/communities/forum-test/schema", headers=admin["headers"]).json()
|
||
|
|
assert json.loads(body["schema_text"])["origin"] == "forum.test" and body["has_previous"] is False
|
||
|
|
page = client.get("/admin/communities/forum-test/schema", headers={"X-API-KEY": admin["headers"]["X-API-KEY"]})
|
||
|
|
assert page.status_code == 200 and "community-schema" in page.text
|
||
|
|
assert "topsecret-pw" not in page.text and "TOTPSECRETVALUE" not in page.text
|
||
|
|
assert "Edit schema" in client.get("/admin/communities/forum-test", headers={"X-API-KEY": admin["headers"]["X-API-KEY"]}).text
|
||
|
|
|
||
|
|
|
||
|
|
def test_a_verified_schema_is_stored_regenerated_and_the_old_one_kept(client, admin, fake_world):
|
||
|
|
row = add_ready(client, admin)
|
||
|
|
schema = json.loads(json.dumps(row["schema"]))
|
||
|
|
schema["feeds"][0]["post"]["fields"]["title"] = ["$.title", "$.id"]
|
||
|
|
response = save(client, admin, json.dumps(schema))
|
||
|
|
assert response.status_code == 200, response.text
|
||
|
|
assert response.json()["data"]["posts"] >= 1
|
||
|
|
after = store.get("forum-test")
|
||
|
|
assert after["schema"]["feeds"][0]["post"]["fields"]["title"] == ["$.title", "$.id"]
|
||
|
|
assert after["schema_previous"] == row["schema"] and after["status"] == "ready"
|
||
|
|
assert files.load("forum-test", after["schema"]).SCHEMA["feeds"][0]["post"]["fields"]["title"] == ["$.title", "$.id"]
|
||
|
|
rows = list(get_table("audit_log").find(event_key="admin.community.schema", target_label="forum-test"))
|
||
|
|
assert rows
|
||
|
|
|
||
|
|
|
||
|
|
def test_a_structurally_invalid_schema_is_refused_with_every_reason_and_changes_nothing(client, admin, fake_world):
|
||
|
|
row = add_ready(client, admin)
|
||
|
|
broken = json.loads(json.dumps(row["schema"]))
|
||
|
|
broken["feeds"][0]["type"] = "soap"
|
||
|
|
broken["origin"] = "NOT A HOST"
|
||
|
|
response = save(client, admin, json.dumps(broken))
|
||
|
|
assert response.status_code == 400
|
||
|
|
assert store.get("forum-test")["schema"] == row["schema"]
|
||
|
|
html = client.post("/admin/communities/forum-test/schema", data={"schema": json.dumps(broken)}, headers={"X-API-KEY": admin["headers"]["X-API-KEY"]})
|
||
|
|
assert html.status_code == 400 and "Not saved" in html.text and "feeds[0].type" in html.text and "origin" in html.text
|
||
|
|
assert 'name="schema"' in html.text and "NOT A HOST" in html.text
|
||
|
|
|
||
|
|
|
||
|
|
def test_invalid_json_is_refused(client, admin, fake_world):
|
||
|
|
add_ready(client, admin)
|
||
|
|
html = client.post("/admin/communities/forum-test/schema", data={"schema": "{not json"}, headers={"X-API-KEY": admin["headers"]["X-API-KEY"]})
|
||
|
|
assert html.status_code == 400 and "not valid JSON" in html.text
|
||
|
|
|
||
|
|
|
||
|
|
def test_a_schema_that_collects_nothing_live_is_not_saved(client, admin, fake_world):
|
||
|
|
row = add_ready(client, admin)
|
||
|
|
dead = json.loads(json.dumps(row["schema"]))
|
||
|
|
dead["feeds"][0]["list_path"] = "$.nothing_here"
|
||
|
|
response = client.post("/admin/communities/forum-test/schema", data={"schema": json.dumps(dead)}, headers={"X-API-KEY": admin["headers"]["X-API-KEY"]})
|
||
|
|
assert response.status_code == 422 and "no posts" in response.text and "not saved" in response.text
|
||
|
|
assert store.get("forum-test")["schema"] == row["schema"] and not store.get("forum-test")["schema_previous"]
|
||
|
|
|
||
|
|
|
||
|
|
def test_restore_swaps_back_and_refuses_when_there_is_nothing(client, admin, fake_world):
|
||
|
|
row = add_ready(client, admin)
|
||
|
|
assert client.post("/admin/communities/forum-test/schema/restore", headers=admin["headers"]).status_code == 409
|
||
|
|
changed = json.loads(json.dumps(row["schema"]))
|
||
|
|
changed["feeds"][0]["post"]["fields"]["title"] = ["$.title", "$.id"]
|
||
|
|
assert save(client, admin, json.dumps(changed)).status_code == 200
|
||
|
|
assert client.post("/admin/communities/forum-test/schema/restore", headers=admin["headers"]).status_code == 200
|
||
|
|
restored = store.get("forum-test")
|
||
|
|
assert restored["schema"] == row["schema"] and restored["schema_previous"] == changed
|
||
|
|
assert list(get_table("audit_log").find(event_key="admin.community.schema_restore", target_label="forum-test"))
|
||
|
|
|
||
|
|
|
||
|
|
def test_the_devii_tools_exist_and_the_save_needs_confirmation():
|
||
|
|
from devplacepy.services.devii.actions.catalog.community import COMMUNITY_ACTIONS
|
||
|
|
from devplacepy.services.devii.actions.dispatcher import CONFIRM_REQUIRED
|
||
|
|
|
||
|
|
tools = {action.name: action for action in COMMUNITY_ACTIONS}
|
||
|
|
assert tools["community_schema_get"].requires_admin and tools["community_schema_set"].requires_admin
|
||
|
|
assert "community_schema_set" in CONFIRM_REQUIRED
|
||
|
|
assert any(param.name == "confirm" for param in tools["community_schema_set"].params)
|