acecalisto3 commited on
Commit
f4ffc94
·
verified ·
1 Parent(s): 7e113aa

editor: ship the four modules the last push left behind

Browse files
Files changed (1) hide show
  1. editor/test_admin.py +128 -0
editor/test_admin.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """The updater drives a page it does not own, so pin the two things that are
2
+ actually ours: which rows get ticked, and finding a toolbar button across three
3
+ Joomla generations. The browser itself is faked — this is about the logic, and
4
+ a real run against a live site is a dry run away.
5
+ """
6
+ import admin
7
+ import mesh
8
+ import pytest
9
+
10
+
11
+ class Loc:
12
+ """The slice of Playwright's Locator this module uses."""
13
+
14
+ def __init__(self, items=(), text=""):
15
+ self.items = list(items)
16
+ self.text = text
17
+ self.checked = False
18
+ self.clicked = 0
19
+
20
+ # a locator is both a set and, via .first/.nth, its members
21
+ def count(self):
22
+ return len(self.items) if self.items else (1 if self.text else 0)
23
+
24
+ def all(self):
25
+ return self.items
26
+
27
+ def nth(self, i):
28
+ return self.items[i]
29
+
30
+ @property
31
+ def first(self):
32
+ return self.items[0] if self.items else self
33
+
34
+ def inner_text(self):
35
+ return self.text
36
+
37
+ def check(self):
38
+ self.checked = True
39
+
40
+ def click(self):
41
+ self.clicked += 1
42
+
43
+ def get_attribute(self, _):
44
+ return self.text
45
+
46
+ def locator(self, sel):
47
+ return self.sub[sel]
48
+
49
+
50
+ def _row(cid, name):
51
+ cb = Loc(text=cid)
52
+ cells = Loc([Loc(text="")] * 1 + [Loc(text=f"{name}\nhttps://update.example/x.xml")])
53
+ tr = Loc(text=name)
54
+ tr.sub = {"td, th": cells}
55
+ cb.sub = {"xpath=ancestor::tr[1]": tr}
56
+ return cb
57
+
58
+
59
+ class Page:
60
+ def __init__(self, rows=(), buttons=(), alerts=()):
61
+ self.rows = {r.text: r for r in rows}
62
+ self.buttons = dict(buttons)
63
+ self.alerts = list(alerts)
64
+ self.waited = []
65
+
66
+ def locator(self, sel):
67
+ if sel == 'input[name="cid[]"]':
68
+ return Loc(list(self.rows.values()))
69
+ if sel.startswith('input[name="cid[]"][value='):
70
+ return Loc([self.rows[sel.split('"')[3]]])
71
+ if sel == "#system-message-container .alert":
72
+ return Loc([Loc(text=a) for a in self.alerts])
73
+ return self.buttons.get(sel, Loc())
74
+
75
+ def wait_for_load_state(self, *a, **kw):
76
+ self.waited.append(a)
77
+
78
+
79
+ ROWS = [_row("101", "Regular Labs - Snippets"), _row("102", "YOOtheme - Joomla Template")]
80
+ MODERN = 'joomla-toolbar-button[task="update.update"] button'
81
+ ANCIENT = 'button[onclick*="update.update"]'
82
+
83
+
84
+ def test_only_the_named_rows_are_ticked():
85
+ page = Page(ROWS, {MODERN: Loc([Loc(text="btn")])}, alerts=["Update completed."])
86
+ picked, messages = admin.apply_updates(page, only=["yootheme"])
87
+
88
+ assert [p["label"] for p in picked] == ["YOOtheme - Joomla Template"]
89
+ assert page.rows["102"].checked is True
90
+ assert page.rows["101"].checked is False # the one we did not ask for
91
+ assert messages == ["Update completed."]
92
+
93
+
94
+ def test_no_filter_means_every_pending_row():
95
+ page = Page(ROWS, {MODERN: Loc([Loc(text="btn")])})
96
+ picked, _ = admin.apply_updates(page)
97
+ assert len(picked) == 2 and all(r.checked for r in page.rows.values())
98
+
99
+
100
+ def test_a_joomla_3_toolbar_is_still_found():
101
+ page = Page(ROWS, {ANCIENT: Loc([Loc(text="btn")])})
102
+ admin.apply_updates(page)
103
+ assert page.buttons[ANCIENT].items[0].clicked == 1
104
+
105
+
106
+ def test_no_update_button_is_an_error_not_a_silent_no_op():
107
+ page = Page(ROWS)
108
+ with pytest.raises(admin.AdminError):
109
+ admin.apply_updates(page)
110
+
111
+
112
+ def test_nothing_pending_never_presses_update():
113
+ page = Page([], {MODERN: Loc([Loc(text="btn")])})
114
+ picked, messages = admin.apply_updates(page)
115
+ assert picked == [] and messages == []
116
+ assert page.buttons[MODERN].items[0].clicked == 0
117
+
118
+
119
+ def test_typed_credentials_beat_the_stored_ones(monkeypatch):
120
+ monkeypatch.setattr(mesh, "env", lambda site=None: {
121
+ "ADMIN_USER": "stored", "ADMIN_PASS": "storedpw"})
122
+ assert admin.credentials("x") == ("stored", "storedpw")
123
+ assert admin.credentials("x", "typed", "typedpw") == ("typed", "typedpw")
124
+
125
+
126
+ def test_sign_in_without_credentials_refuses_before_opening_the_site():
127
+ with pytest.raises(admin.AdminError):
128
+ admin.sign_in(None, "https://x.test", "", "")