1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
from __future__ import annotations
from pygitweb.static_tests.js_runtime import JsPage
from pygitweb.static_tests.pages import MANIFEST, board_shell, card_html, posted_json, requested
def _board(js: JsPage, html: str | None = None) -> None:
js.set_html(
html if html is not None else board_shell(cards_todo=card_html(ref="refs/tags/tasks/task_abcd", title="Ship"))
)
js.load("board-context.js")
def test_task_ids_drop_the_prefix_and_shorten(js: JsPage) -> None:
_board(js, "<div></div>")
assert js.call("board-context.js", "taskDisplayId", "") == ""
assert js.call("board-context.js", "taskDisplayId", "refs/tags/tasks/task_abcd") == "abcd"
assert js.call("board-context.js", "taskDisplayId", "refs/tags/tasks/custom") == "custom"
assert js.call("board-context.js", "taskDisplayIdShort", "") == ""
assert js.call("board-context.js", "taskDisplayIdShort", "ab") == "ab"
assert js.call("board-context.js", "taskDisplayIdShort", "abcdef") == "cdef"
def test_context_comes_from_the_dataset_or_the_url(js: JsPage) -> None:
_board(js)
assert js.call("board-context.js", "getBoardContext") == {"project": "demo", "board": "Tasks"}
js.set_html('<div class="board-columns"></div>')
js.set_location("http://127.0.0.1/project/demo/board/?b=Sprint")
js.load("board-context.js")
assert js.call("board-context.js", "getBoardContext") == {"project": "demo", "board": "Sprint"}
js.set_location("http://127.0.0.1/project/demo/board")
assert js.call("board-context.js", "getBoardContext")["board"] == "Tasks"
def test_find_card_matches_the_task_ref(js: JsPage) -> None:
_board(js)
assert js.call("board-context.js", "findBoardCardByTaskRef", "") is None
assert js.value("__loaded['board-context.js'].findBoardCardByTaskRef('missing')") is None
assert js.value("__loaded['board-context.js'].findBoardCardByTaskRef('refs/tags/tasks/task_abcd') !== null") is True
def test_title_tooltip_uses_the_id_and_falls_back_to_untitled(js: JsPage) -> None:
js.set_html('<div class="board-card"></div>')
js.load("board-context.js")
js.run("__loaded['board-context.js'].syncCardTitleLineTooltip(document.querySelector('.board-card'))")
js.set_html(board_shell(cards_todo=card_html(title=" ")))
js.run("__loaded['board-context.js'].syncCardTitleLineTooltip(document.querySelector('.board-card'))")
assert js.attr(".board-card-title-line", "title") == "Untitled"
js.set_html(board_shell(cards_todo=card_html(ref="refs/tags/tasks/task_abcd", title="Ship")))
js.run(
"__loaded['board-context.js'].setCardTaskRefDisplay("
"document.querySelector('.board-card'), 'refs/tags/tasks/task_abcd', null)"
)
assert js.text(".board-card-task-id") == "abcd"
assert js.text(".board-card-task-ref") == "refs/tags/tasks/task_abcd"
assert js.attr(".board-card-title-line", "title") == "abcd: Ship"
def test_title_line_without_a_title_element_uses_untitled(js: JsPage) -> None:
js.set_html(
'<div class="board-card" data-task-ref="refs/tags/tasks/task_abcd">'
'<div class="board-card-title-line"></div>'
'<span class="board-card-task-id"></span>'
'<div class="board-card-task-ref">old</div></div>'
)
js.load("board-context.js")
js.run("__loaded['board-context.js'].syncCardTitleLineTooltip(document.querySelector('.board-card'))")
assert js.attr(".board-card-title-line", "title") == "abcd: Untitled"
js.run("__loaded['board-context.js'].setCardTaskRefDisplay(document.querySelector('.board-card'), '', 'abcd')")
assert js.text(".board-card-task-ref") == ""
def test_error_hint_replaces_itself_and_expires(js: JsPage) -> None:
_board(js, "<div></div>")
js.call("board-context.js", "showBoardError", "nope")
assert js.count(".board-task-error-hint") == 0
_board(js)
js.call("board-context.js", "showBoardError", "first")
js.call("board-context.js", "showBoardError", "second")
assert js.count(".board-task-error-hint") == 1
assert js.text(".board-task-error-hint") == "second"
js.tick()
assert js.count(".board-task-error-hint") == 0
def test_column_badge_sums_points(js: JsPage) -> None:
html = board_shell(
cards_todo=card_html(ref="a", points="2") + card_html(ref="b", points="3") + card_html(ref="c", points=""),
)
_board(js, html)
js.run("__loaded['board-context.js'].updateColumnBadge(null)")
js.run("__loaded['board-context.js'].updateColumnBadge(document.querySelector('.board-column'))")
assert js.text(".board-column-task-count") == "3"
assert js.text(".board-column-points-total") == "5 pts"
js.set_html('<div class="board-column"></div>')
js.load("board-context.js")
js.run("__loaded['board-context.js'].updateColumnBadge(document.querySelector('.board-column'))")
assert js.count(".board-column-task-count") == 0
def test_field_update_posts_json_and_reports_failures(js: JsPage) -> None:
_board(js, "<div></div>")
assert js.settle("__loaded['board-context.js'].pushTaskFieldUpdate(null, {})") == {"ok": False, "status": 0}
_board(js)
card = "document.querySelector('.board-card')"
js.route("tasks/update", error="offline")
assert js.settle(f"__loaded['board-context.js'].pushTaskFieldUpdate({card}, {{a:1}})") == {
"ok": False,
"status": 0,
}
js.route("tasks/update", status=200)
assert js.settle(f"__loaded['board-context.js'].pushTaskFieldUpdate({card}, {{title:'Ship'}})") == {
"ok": True,
"status": 200,
}
assert posted_json(js, "tasks/update")["title"] == "Ship"
js.route("tasks/update", status=404)
assert js.settle(f"__loaded['board-context.js'].pushTaskFieldUpdate({card}, {{}})")["status"] == 404
js.route("tasks/update", error="offline")
assert js.settle(f"__loaded['board-context.js'].pushTaskFieldUpdate({card}, {{}})") == {"ok": False, "status": 0}
js.set_html('<div class="board-columns"><div class="board-card" data-task-ref="t"></div></div>')
js.load("board-context.js")
assert js.settle("__loaded['board-context.js'].pushTaskFieldUpdate(document.querySelector('.board-card'), {})") == {
"ok": False,
"status": 0,
}
def test_refresh_stores_the_manifest_or_an_empty_one(js: JsPage) -> None:
_board(js, '<div class="board-columns"></div>')
js.set_location("http://127.0.0.1/")
assert js.settle("__loaded['board-context.js'].refreshBoardRefManifest()") is None
js.route("board-ref-manifest", body=MANIFEST)
_board(js)
got = js.settle("__loaded['board-context.js'].refreshBoardRefManifest()")
assert got["commits"][0]["insert"] == "abcd"
assert js.call("board-context.js", "getBoardRefManifest")["refs"][0]["insert"] == "main"
js.route("board-ref-manifest", status=500)
empty = js.settle("__loaded['board-context.js'].refreshBoardRefManifest()")
assert empty == {"commits": [], "refs": []}
js.route("board-ref-manifest", error="offline")
assert js.settle("__loaded['board-context.js'].refreshBoardRefManifest()") == {"commits": [], "refs": []}
assert requested(js, "board-ref-manifest") is True