aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-10 16:53:54 +0200
committerDanilo M. <danix@danix.xyz>2026-09-10 16:53:54 +0200
commit59106867052157a78b825224500f974f985362de (patch)
treec1caaa8eecb1326c28a9d654b9f127a2a31e58c6 /tests
parent9fce523fd196d7ab71c2b54eeb02071178506045 (diff)
downloadabusectl-59106867052157a78b825224500f974f985362de.tar.gz
abusectl-59106867052157a78b825224500f974f985362de.zip
feat: refuse a half-configured destination at report
A [misp] section with url but no api_key (or vice versa) is configured-and-broken, not skipped. report now refuses it before writing anything, naming the missing key, while parse and contacts stay unaffected since neither reads config.load()'s incomplete set. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0176FYdVfpzUq8S9jecqQqL6
Diffstat (limited to 'tests')
-rw-r--r--tests/test_cli.py46
1 files changed, 46 insertions, 0 deletions
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 3638edd..937a0b7 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -480,6 +480,52 @@ class ReportCommand(unittest.TestCase):
self.assertEqual(code, 0)
self.assertNotIn("no reporting destinations", err)
+ def test_a_misp_url_with_no_key_is_refused_naming_the_missing_key(self):
+ self._write_config(
+ '[reporter]\nemail = "r@example.org"\n'
+ '\n[misp]\nurl = "https://misp.example.invalid"\n'
+ )
+ case_path = self._make_case()
+ code, _, err = self._run(
+ "--config", str(self.config), "report", str(case_path)
+ )
+ self.assertEqual(code, 3)
+ self.assertIn("api_key", err)
+ self.assertIn(str(self.config), err)
+ # A refusal must leave the case as it was: nothing regenerated.
+ self.assertEqual(list((case_path / "bodies").iterdir()), [])
+
+ def test_half_a_pair_does_not_stop_parse(self):
+ # The half that would regress silently. Every subcommand loads this
+ # file; parse reads neither MISP key and must not be refused over
+ # one, nor traceback, since cli catches only NotConfigured.
+ self.config.write_text(
+ '[general]\ntrusted_relays = ["192.0.2.0/24"]\n'
+ f'cases = "{self.root / "cases"}"\n'
+ '\n[misp]\napi_key = "k"\n',
+ encoding="utf-8",
+ )
+ code, _, _ = self._run(
+ "--config", str(self.config), "parse",
+ str(FIXTURES / "forged-chain.eml"),
+ )
+ self.assertEqual(code, 0)
+
+ def test_an_abusedb_section_with_no_key_is_a_skip_not_a_refusal(self):
+ # [abusedb] needs only one key, so it can never be half-filled: an
+ # empty section is absence of the whole thing, which is a skip and
+ # should reach the no-destinations warning, not the refusal.
+ self._write_config(
+ '[reporter]\nemail = "r@example.org"\n'
+ '\n[abusedb]\n'
+ )
+ case_path = self._make_case()
+ code, _, err = self._run(
+ "--config", str(self.config), "report", str(case_path)
+ )
+ self.assertEqual(code, 0)
+ self.assertIn("no reporting destinations", err)
+
if __name__ == "__main__":
unittest.main()