add support for reporting the closest task that is in a signed MoU
[utils.git] / src / budget_sync / test / test_write_budget_markdown.py
index c6dba2f8b8e7f1a441cbaf58461fb228e70114fe..0a8b5dc8f84b17e23810b353ba90d6603c2c00e5 100644 (file)
@@ -1,7 +1,7 @@
 import unittest
 from budget_sync.config import Config
 from budget_sync.test.mock_bug import MockBug
-from budget_sync.test.mock_path import MockPath, DIR
+from budget_sync.test.mock_path import MockFilesystem, MockPath, DIR
 from budget_sync.test.test_mock_path import make_filesystem_and_report_if_error
 from budget_sync.budget_graph import BudgetGraph
 from budget_sync.write_budget_markdown import (
@@ -20,6 +20,38 @@ class TestWriteBudgetMarkdown(unittest.TestCase):
         self.assertEqual(markdown_escape("abc * def_k < &k"),
                          r"abc \* def\_k &lt; &amp;k")
 
+    def format_files_dict(self, files):
+        assert isinstance(files, dict)
+        files_list: "list[str]" = []
+        for path, contents in files.items():
+            assert isinstance(path, str)
+            if contents is DIR:
+                files_list.append(f"    {path!r}: DIR,")
+                continue
+            assert isinstance(contents, bytes)
+            lines: "list[str]" = []
+            for line in contents.splitlines(keepends=True):
+                lines.append(f"        {line!r}")
+            if len(lines) == 0:
+                files_list.append(f"    {path!r}: b'',")
+            else:
+                lines_str = '\n'.join(lines)
+                files_list.append(f"    {path!r}: (\n{lines_str}\n    ),")
+        if len(files_list) == 0:
+            return "{}"
+        return "{\n" + "\n".join(files_list) + "\n}"
+
+    def assertFiles(self, expected_files, filesystem: MockFilesystem):
+        files = filesystem.files
+        self.assertIsInstance(expected_files, dict)
+        if files == expected_files:
+            return
+        files_str = self.format_files_dict(files)
+        expected_files_str = self.format_files_dict(expected_files)
+        self.assertEqual(
+            files, expected_files,
+            msg=f"\nfiles:\n{files_str}\nexpected:\n{expected_files_str}")
+
     def test(self):
         config = Config.from_str(
             """
@@ -45,16 +77,133 @@ class TestWriteBudgetMarkdown(unittest.TestCase):
         with make_filesystem_and_report_if_error(self) as filesystem:
             output_dir = MockPath("/output_dir/", filesystem=filesystem)
             write_budget_markdown(budget_graph, output_dir)
-            self.assertEqual({
-                "/": DIR,
-                "/output_dir": DIR,
-                '/output_dir/person1.mdwn': b'<!-- autogenerated by '
-                b'budget-sync -->\n\n# Person One (person1)\n\n\n\n#'
-                b' Status Tracking\n\n',
-                '/output_dir/person2.mdwn': b'<!-- autogenerated by '
-                b'budget-sync -->\n\n# Person Two (person2)\n\n\n\n#'
-                b' Status Tracking\n\n',
-            }, filesystem.files)
+            self.assertFiles({
+                '/': DIR,
+                '/output_dir': DIR,
+                '/output_dir/person1.mdwn': (
+                    b'<!-- autogenerated by budget-sync -->\n'
+                    b'\n'
+                    b'# Person One (person1)\n'
+                    b'\n'
+                    b'\n'
+                    b'\n'
+                    b'# Status Tracking\n'
+                    b'\n'
+                ),
+                '/output_dir/person2.mdwn': (
+                    b'<!-- autogenerated by budget-sync -->\n'
+                    b'\n'
+                    b'# Person Two (person2)\n'
+                    b'\n'
+                    b'\n'
+                    b'\n'
+                    b'# Status Tracking\n'
+                    b'\n'
+                ),
+            }, filesystem)
+
+    def test2(self):
+        config = Config.from_str(
+            """
+            bugzilla_url = "https://bugzilla.example.com/"
+            [milestones]
+            "milestone 1" = { canonical_bug_id = 1 }
+            [people."person1"]
+            email = "person1@example.com"
+            full_name = "Person One"
+            [people."person2"]
+            full_name = "Person Two"
+            """)
+        budget_graph = BudgetGraph([
+            MockBug(bug_id=1,
+                    cf_budget_parent=None,
+                    cf_budget="700",
+                    cf_total_budget="1000",
+                    cf_nlnet_milestone="milestone 1",
+                    cf_payees_list="",
+                    summary="",
+                    assigned_to="person1@example.com",
+                    cf_is_in_nlnet_mou2="Yes"),
+            MockBug(bug_id=2,
+                    cf_budget_parent=1,
+                    cf_budget="100",
+                    cf_total_budget="300",
+                    cf_nlnet_milestone="milestone 1",
+                    cf_payees_list="person2 = 100",
+                    summary="",
+                    assigned_to="person1@example.com",
+                    cf_is_in_nlnet_mou2="Yes"),
+            MockBug(bug_id=3,
+                    cf_budget_parent=2,
+                    cf_budget="100",
+                    cf_total_budget="200",
+                    cf_nlnet_milestone="milestone 1",
+                    cf_payees_list="person1 = 100",
+                    summary="",
+                    assigned_to="person1@example.com"),
+            MockBug(bug_id=4,
+                    cf_budget_parent=3,
+                    cf_budget="100",
+                    cf_total_budget="100",
+                    cf_nlnet_milestone="milestone 1",
+                    cf_payees_list="person2 = 100",
+                    summary="",
+                    assigned_to="person1@example.com"),
+        ], config)
+        self.assertEqual([], budget_graph.get_errors())
+        with make_filesystem_and_report_if_error(self) as filesystem:
+            output_dir = MockPath("/output_dir/", filesystem=filesystem)
+            write_budget_markdown(budget_graph, output_dir)
+            self.assertFiles({
+                '/': DIR,
+                '/output_dir': DIR,
+                '/output_dir/person1.mdwn': (
+                    b'<!-- autogenerated by budget-sync -->\n'
+                    b'\n'
+                    b'# Person One (person1)\n'
+                    b'\n'
+                    b'\n'
+                    b'\n'
+                    b'# Status Tracking\n'
+                    b'\n'
+                    b'\n'
+                    b'## Payment not yet submitted\n'
+                    b'\n'
+                    b'\n'
+                    b'### milestone 1\n'
+                    b'\n'
+                    b'* [Bug #3](https://bugzilla.example.com/show_bug.cgi?id=3):\n'
+                    b'  \n'
+                    b'    * &euro;100 which is the total amount\n'
+                    b'    * the closest parent task which is in the MoU is\n'
+                    b'      [Bug #2](https://bugzilla.example.com/show_bug.cgi?id=2)\n'
+                ),
+                '/output_dir/person2.mdwn': (
+                    b'<!-- autogenerated by budget-sync -->\n'
+                    b'\n'
+                    b'# Person Two (person2)\n'
+                    b'\n'
+                    b'\n'
+                    b'\n'
+                    b'# Status Tracking\n'
+                    b'\n'
+                    b'\n'
+                    b'## Payment not yet submitted\n'
+                    b'\n'
+                    b'\n'
+                    b'### milestone 1\n'
+                    b'\n'
+                    b'* [Bug #2](https://bugzilla.example.com/show_bug.cgi?id=2):\n'
+                    b'  \n'
+                    b'    * &euro;100 which is the total amount\n'
+                    b'    * this task is in the MoU\n'
+                    b'* [Bug #4](https://bugzilla.example.com/show_bug.cgi?id=4):\n'
+                    b'  \n'
+                    b'    * &euro;100 which is the total amount\n'
+                    b'    * the closest parent task which is in the MoU is\n'
+                    b'      [Bug #2](https://bugzilla.example.com/show_bug.cgi?id=2)\n'
+                ),
+            }, filesystem)
     # TODO: add more test cases