]> Nutra Git (v1) - nutratech/cli.git/commitdiff
cover bugs and arg parse funcs
authorShane Jaroch <chown_tee@proton.me>
Fri, 19 Apr 2024 16:57:06 +0000 (12:57 -0400)
committerShane Jaroch <chown_tee@proton.me>
Fri, 19 Apr 2024 16:57:06 +0000 (12:57 -0400)
ntclient/argparser/funcs.py
ntclient/services/bugs.py
tests/services/test_bug.py
tests/test_cli.py

index 8939410c80c694ca0a97fd75e538bb7406d6e67c..c6e7df4e4f575ae49b288d5136ed64e558e2e4e3 100644 (file)
@@ -350,34 +350,13 @@ def bug_simulate(args: argparse.Namespace) -> tuple:
     raise NotImplementedError("This service intentionally raises an error, for testing")
 
 
-def bugs_list(args: argparse.Namespace) -> tuple:
+def bugs_list(args: argparse.Namespace) -> tuple[int, list]:
     """List bug reports that have been saved"""
-    rows, _ = ntclient.services.bugs.list_bugs()
-    n_bugs_total = len(rows)
-    n_bugs_unsubmitted = len([x for x in rows if not bool(x[-1])])
-
-    print(f"You have: {n_bugs_total} total bugs amassed in your journey.")
-    print(f"Of these, {n_bugs_unsubmitted} require submission/reporting.")
-    print()
-
-    for bug in rows:
-        if not args.show:
-            continue
-        # Skip submitted bugs by default
-        if bool(bug[-1]) and not args.debug:
-            continue
-        # Print all bug properties (except noisy stacktrace)
-        print(", ".join(str(x) for x in bug if "\n" not in str(x)))
-        print()
-
-    if n_bugs_unsubmitted > 0:
-        print("NOTE: You have bugs awaiting submission.  Please run the report command")
-
-    return 0, rows
+    return ntclient.services.bugs.list_bugs(show_all=args.show)
 
 
 # pylint: disable=unused-argument
-def bugs_report(args: argparse.Namespace) -> tuple:
+def bugs_report(args: argparse.Namespace) -> tuple[int, int]:
     """Report bugs"""
     n_submissions = ntclient.services.bugs.submit_bugs()
     return 0, n_submissions
index 050d8af32b518526dcf12fcfda39cee487c9f3d8..c16373cca9c022527c32d81179f015af12a3838c 100644 (file)
@@ -61,30 +61,68 @@ INSERT INTO bug
         )
         if repr(exc) == dupe_bug_insertion_exc:
             print("INFO: bug report already exists")
-        else:
+        else:  # pragma: no cover
             raise
 
 
-def list_bugs() -> tuple[list, list]:
-    """List all bugs, with headers."""
-    rows, headers, _, _ = sql_nt("SELECT * FROM bug")
-    return rows, headers
+def _list_bugs() -> list:
+    """List all bugs, with headers as dict keys."""
+    rows, _, _, _ = sql_nt("SELECT * FROM bug")
+    bugs = [dict(x) for x in rows]
+    return bugs
+
+
+def list_bugs(show_all: bool) -> tuple[int, list]:
+    """List all bugs, with headers.  Returns (exit_code, bugs: list[dict])."""
+
+    bugs = _list_bugs()
+    n_bugs_total = len(bugs)
+    n_bugs_unsubmitted = len([x for x in bugs if not bool(x["submitted"])])
+
+    print(f"You have: {n_bugs_total} total bugs amassed in your journey.")
+    print(f"Of these, {n_bugs_unsubmitted} require submission/reporting.")
+    print()
+
+    for bug in bugs:
+        if not show_all:
+            continue
+        # Skip submitted bugs by default
+        if bool(bug["submitted"]) and not CLI_CONFIG.debug:
+            continue
+        # Print all bug properties (except noisy stacktrace)
+        print(", ".join(str(x) for x in bug if "\n" not in str(x)))
+        print()
+
+    if n_bugs_unsubmitted > 0:
+        print("NOTE: You have bugs awaiting submission.  Please run the report command")
+    return 0, bugs
+
+
+def _list_bugs_unsubmitted() -> list:
+    """List unsubmitted bugs, with headers as dict keys."""
+    rows, _, _, _ = sql_nt("SELECT * FROM bug WHERE submitted = 0")
+    bugs = [dict(x) for x in rows]
+    return bugs
 
 
 def submit_bugs() -> int:
     """Submit bug reports to developer, return n_submitted."""
-    # TODO: mock sql_nt() for testing
-    # Gather bugs for submission
-    rows, _, _, _ = sql_nt("SELECT * FROM bug WHERE submitted = 0")
+    bugs = _list_bugs_unsubmitted()
+
+    if len(bugs) == 0:
+        print("INFO: no unsubmitted bugs found")
+        return 0
+
     api_client = ntclient.services.api.ApiClient()
 
     n_submitted = 0
-    print(f"submitting {len(rows)} bug reports...")
-    print("_" * len(rows))
+    print(f"submitting {len(bugs)} bug reports...")
+    print("_" * len(bugs))
 
-    for bug in rows:
+    for bug in bugs:
         _res = api_client.post_bug(bug)
-        if CLI_CONFIG.debug:
+
+        if CLI_CONFIG.debug:  # pragma: no cover
             print(_res.json())
 
         # Distinguish bug which are unique vs. duplicates (someone else submitted)
@@ -92,7 +130,7 @@ def submit_bugs() -> int:
             sql_nt("UPDATE bug SET submitted = 1 WHERE id = ?", (bug["id"],))
         elif _res.status_code == 204:
             sql_nt("UPDATE bug SET submitted = 2 WHERE id = ?", (bug["id"],))
-        else:
+        else:  # pragma: no cover
             print("WARN: unknown status [{0}]".format(_res.status_code))
             continue
 
@@ -100,5 +138,4 @@ def submit_bugs() -> int:
         n_submitted += 1
 
     print("submitted: {0} bugs".format(n_submitted))
-
     return n_submitted
index 93b5a693b7ece808160d56794409225a220a7c36..646bfe1bbc6ab4cb4fdea7be83fc47110adf53f1 100644 (file)
@@ -23,14 +23,59 @@ class TestBug(unittest.TestCase):
 
     def test_bug_list(self) -> None:
         """Tests the functions for listing bugs"""
-        bugs.list_bugs()
+        exit_code, _bugs = bugs.list_bugs(show_all=True)
+
+        assert exit_code == 0
+        assert len(_bugs) >= 0
+        # assert len(rows) >= 0
+        # assert len(headers) == 11
+
+    def test_bug_list_unsubmitted(self) -> None:
+        """Tests the functions for listing unsubmitted bugs"""
+        with patch(
+            "ntclient.services.bugs._list_bugs",
+            return_value=[{"submitted": False}],
+        ):
+            exit_code, _bugs = bugs.list_bugs(show_all=False)
+
+        assert exit_code == 0
+        assert len(_bugs) == 1
+        _bug = _bugs[0]
+        assert len(_bug.values()) >= 0
+        assert len(_bug.keys()) == 1
 
     @patch("ntclient.services.api.cache_mirrors", return_value="https://someurl.com")
     @patch(
         "ntclient.services.api.ApiClient.post",
         return_value=MagicMock(status_code=201),
     )
+    @patch("ntclient.services.bugs._list_bugs_unsubmitted", return_value=[{"id": 1}])
+    @patch("ntclient.services.bugs.sql_nt")
     # pylint: disable=unused-argument
     def test_bug_report(self, *args: MagicMock) -> None:
         """Tests the functions for submitting bugs"""
         bugs.submit_bugs()
+
+    @patch("ntclient.services.api.cache_mirrors", return_value="https://someurl.com")
+    @patch(
+        "ntclient.services.api.ApiClient.post",
+        return_value=MagicMock(status_code=204),
+    )
+    @patch("ntclient.services.bugs._list_bugs_unsubmitted", return_value=[{"id": 1}])
+    @patch("ntclient.services.bugs.sql_nt")
+    # pylint: disable=unused-argument
+    def test_bug_report_on_204_status(self, *args: MagicMock) -> None:
+        """Tests the functions for submitting bugs"""
+        bugs.submit_bugs()
+
+    @patch("ntclient.services.api.cache_mirrors", return_value="https://someurl.com")
+    @patch(
+        "ntclient.services.api.ApiClient.post",
+        return_value=MagicMock(status_code=201),
+    )
+    @patch("ntclient.services.bugs._list_bugs_unsubmitted", return_value=[])
+    # pylint: disable=unused-argument
+    def test_bug_report_empty_list(self, *args: MagicMock) -> None:
+        """Tests the functions for submitting bugs"""
+        result = bugs.submit_bugs()
+        assert result == 0
index 9e49710ef2bbdf38dde37c51cfbc65cb66df5db4..b292a2e9cc9cdaeea3f40fe728f78e7ac3c9083c 100644 (file)
@@ -292,6 +292,11 @@ class TestCli(unittest.TestCase):
         assert code == 0
         assert isinstance(result, list)
 
+        args = arg_parser.parse_args(args="bug report".split())
+        code, result = args.func(args)
+        assert code == 0
+        assert isinstance(result, int)
+
     def test_415_invalid_path_day_throws_error(self):
         """Ensures invalid path throws exception in `day` subcommand"""
         invalid_day_csv_path = os.path.join(