2 from budget_sync
.config
import Config
3 from budget_sync
.ordered_set
import OrderedSet
4 from budget_sync
.test
.mock_bug
import MockBug
5 from budget_sync
.test
.mock_path
import MockFilesystem
, MockPath
, DIR
6 from budget_sync
.test
.test_mock_path
import make_filesystem_and_report_if_error
7 from budget_sync
.budget_graph
import BudgetGraph
8 from budget_sync
.write_budget_markdown
import (
9 write_budget_markdown
, DisplayStatus
, markdown_escape
, markdown_for_person
)
10 from budget_sync
.util
import BugStatus
13 class TestWriteBudgetMarkdown(unittest
.TestCase
):
16 def test_display_status(self
):
17 for status
in BugStatus
:
18 DisplayStatus
.from_status(status
)
20 def test_markdown_escape(self
):
21 self
.assertEqual(markdown_escape("abc * def_k < &k"),
22 r
"abc \* def\_k < &k")
24 def format_files_dict(self
, files
):
25 assert isinstance(files
, dict)
26 files_list
: "list[str]" = []
27 for path
, contents
in files
.items():
28 assert isinstance(path
, str)
30 files_list
.append(f
" {path!r}: DIR,")
32 assert isinstance(contents
, bytes
)
33 lines
: "list[str]" = []
34 for line
in contents
.splitlines(keepends
=True):
35 lines
.append(f
" {line!r}")
37 files_list
.append(f
" {path!r}: b'',")
39 lines_str
= '\n'.join(lines
)
40 files_list
.append(f
" {path!r}: (\n{lines_str}\n ),")
41 if len(files_list
) == 0:
43 return "{\n" + "\n".join(files_list
) + "\n}"
45 def assertFiles(self
, expected_files
, filesystem
: MockFilesystem
):
46 files
= filesystem
.files
47 self
.assertIsInstance(expected_files
, dict)
48 if files
== expected_files
:
50 files_str
= self
.format_files_dict(files
)
51 expected_files_str
= self
.format_files_dict(expected_files
)
53 files
, expected_files
,
54 msg
=f
"\nfiles:\n{files_str}\nexpected:\n{expected_files_str}")
57 config
= Config
.from_str(
59 bugzilla_url = "https://bugzilla.example.com/"
62 email = "person1@example.com"
63 full_name = "Person One"
65 full_name = "Person Two"
67 budget_graph
= BudgetGraph([
69 cf_budget_parent
=None,
72 cf_nlnet_milestone
=None,
75 assigned_to
="person1@example.com"),
77 self
.assertEqual([], budget_graph
.get_errors())
78 with
make_filesystem_and_report_if_error(self
) as filesystem
:
79 output_dir
= MockPath("/output_dir/", filesystem
=filesystem
)
80 write_budget_markdown(budget_graph
, output_dir
)
84 '/output_dir/person1.mdwn': (
85 b
'<!-- autogenerated by budget-sync -->\n'
87 b
'# Person One (person1)\n'
91 b
'# Status Tracking\n'
94 '/output_dir/person2.mdwn': (
95 b
'<!-- autogenerated by budget-sync -->\n'
97 b
'# Person Two (person2)\n'
101 b
'# Status Tracking\n'
107 config
= Config
.from_str(
109 bugzilla_url = "https://bugzilla.example.com/"
111 "milestone 1" = { canonical_bug_id = 1 }
113 email = "person1@example.com"
114 full_name = "Person One"
116 full_name = "Person Two"
118 budget_graph
= BudgetGraph([
120 cf_budget_parent
=None,
122 cf_total_budget
="1000",
123 cf_nlnet_milestone
="milestone 1",
126 assigned_to
="person1@example.com"),
130 cf_total_budget
="300",
131 cf_nlnet_milestone
="milestone 1",
132 cf_payees_list
="person2 = 100",
134 assigned_to
="person1@example.com"),
138 cf_total_budget
="200",
139 cf_nlnet_milestone
="milestone 1",
140 cf_payees_list
="person1 = 100",
142 assigned_to
="person1@example.com"),
146 cf_total_budget
="100",
147 cf_nlnet_milestone
="milestone 1",
148 cf_payees_list
="person2 = 100",
150 assigned_to
="person1@example.com"),
152 self
.assertEqual([], budget_graph
.get_errors())
153 with
make_filesystem_and_report_if_error(self
) as filesystem
:
154 output_dir
= MockPath("/output_dir/", filesystem
=filesystem
)
155 write_budget_markdown(budget_graph
, output_dir
)
159 '/output_dir/person1.mdwn': (
160 b
'<!-- autogenerated by budget-sync -->\n'
162 b
'# Person One (person1)\n'
166 b
'# Status Tracking\n'
169 b
'## Payment not yet submitted\n'
174 b
'* [Bug #3](https://bugzilla.example.com/show_bug.cgi?id=3):\n'
176 b
' * €100 which is the total amount\n'
177 b
' * this task is part of MoU Milestone\n'
178 b
' [Bug #2](https://bugzilla.example.com/show_bug.cgi?id=2)\n'
180 b
'#### MoU Milestone subtotals for not yet submitted payments\n'
182 b
'* [Bug #2](https://bugzilla.example.com/show_bug.cgi?id=2):\n'
184 b
' * subtotal €100 out of total including subtasks of €300\n'
186 '/output_dir/person2.mdwn': (
187 b
'<!-- autogenerated by budget-sync -->\n'
189 b
'# Person Two (person2)\n'
193 b
'# Status Tracking\n'
196 b
'## Payment not yet submitted\n'
201 b
'* [Bug #2](https://bugzilla.example.com/show_bug.cgi?id=2):\n'
203 b
' * €100 which is the total amount\n'
204 b
' * this task is a MoU Milestone\n'
205 b
'* [Bug #4](https://bugzilla.example.com/show_bug.cgi?id=4):\n'
207 b
' * €100 which is the total amount\n'
208 b
' * this task is part of MoU Milestone\n'
209 b
' [Bug #2](https://bugzilla.example.com/show_bug.cgi?id=2)\n'
211 b
'#### MoU Milestone subtotals for not yet submitted payments\n'
213 b
'* [Bug #2](https://bugzilla.example.com/show_bug.cgi?id=2):\n'
215 b
' * subtotal €200 out of total including subtasks of €300\n'
219 def test_markdown_for_person(self
):
220 config
= Config
.from_str(
222 bugzilla_url = "https://bugzilla.example.com/"
224 "milestone 1" = { canonical_bug_id = 1 }
226 email = "person1@example.com"
227 full_name = "Person One"
229 full_name = "Person Two"
231 budget_graph
= BudgetGraph([
233 cf_budget_parent
=None,
235 cf_total_budget
="1000",
236 cf_nlnet_milestone
="milestone 1",
239 assigned_to
="person1@example.com"),
243 cf_total_budget
="400",
244 cf_nlnet_milestone
="milestone 1",
245 cf_payees_list
="person2 = 100",
247 assigned_to
="person1@example.com"),
251 cf_total_budget
="300",
252 cf_nlnet_milestone
="milestone 1",
253 cf_payees_list
="person1 = 100",
255 assigned_to
="person1@example.com"),
259 cf_total_budget
="100",
260 cf_nlnet_milestone
="milestone 1",
261 cf_payees_list
="person2 = 100",
263 assigned_to
="person1@example.com"),
267 cf_total_budget
="100",
268 cf_nlnet_milestone
="milestone 1",
269 cf_payees_list
="person2 = 100",
271 assigned_to
="person1@example.com"),
273 self
.assertEqual([], budget_graph
.get_errors())
274 person
= config
.all_names
["person2"]
275 nodes_subset
= OrderedSet([budget_graph
.nodes
[2],
276 budget_graph
.nodes
[3],
277 budget_graph
.nodes
[4]])
279 '<!-- autogenerated by budget-sync -->\n',
281 '# Person Two (person2)\n',
285 '# Status Tracking\n',
288 '## Payment not yet submitted\n',
293 '* [Bug #2](https://bugzilla.example.com/show_bug.cgi?id=2):\n',
295 ' * €100 which is the total amount\n',
296 ' * this task is a MoU Milestone\n',
297 '* [Bug #4](https://bugzilla.example.com/show_bug.cgi?id=4):\n',
299 ' * €100 which is the total amount\n',
300 ' * this task is part of MoU Milestone\n',
301 ' [Bug #2](https://bugzilla.example.com/show_bug.cgi?id=2)\n',
303 '#### MoU Milestone subtotals for not yet submitted payments\n',
305 '* [Bug #2](https://bugzilla.example.com/show_bug.cgi?id=2):\n',
307 ' * subtotal €200 out of total including subtasks of €400\n',
309 self
.assertEqual(markdown_for_person(
310 budget_graph
, person
, nodes_subset
).splitlines(keepends
=True),
312 # TODO: add more test cases
315 if __name__
== "__main__":