diff options
Diffstat (limited to 'tests/test_init.py')
| -rw-r--r-- | tests/test_init.py | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/tests/test_init.py b/tests/test_init.py index 619d6ba..46b1a26 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -59,6 +59,144 @@ class TestBuildConfig(unittest.TestCase): "cases": 'x" \ntrusted_relays = ["0.0.0.0/0"]\n#'}) +class TestReporterSection(unittest.TestCase): + def test_the_identity_becomes_a_reporter_table(self): + text = init.build({ + "trusted_relays": ["192.0.2.0/24"], + "reporter_name": "A Reporter", + "reporter_org": "Example Ltd", + "reporter_email": "abuse@example.org", + }) + parsed = tomllib.loads(text) + self.assertEqual(parsed["reporter"], { + "name": "A Reporter", + "org": "Example Ltd", + "email": "abuse@example.org", + }) + + def test_a_fully_skipped_identity_emits_no_table_at_all(self): + # Not an empty [reporter]: an empty table reads as configured, and + # the reader would then report an identity of nothing rather than + # saying plainly that none is set. + text = init.build({ + "trusted_relays": ["192.0.2.0/24"], + "reporter_name": "", + "reporter_org": "", + "reporter_email": "", + }) + self.assertNotIn("[reporter]", text) + self.assertNotIn("reporter", tomllib.loads(text)) + + def test_a_skipped_answer_is_absent_not_empty(self): + # Same rule as the cases path: "" reads as configured-and-broken. + text = init.build({ + "trusted_relays": ["192.0.2.0/24"], + "reporter_name": "A Reporter", + "reporter_org": "", + "reporter_email": " ", + }) + reporter = tomllib.loads(text)["reporter"] + self.assertEqual(reporter, {"name": "A Reporter"}) + + def test_values_are_written_stripped(self): + # config.load() strips on read, so writing unstripped would make the + # file disagree with what every consumer sees. + text = init.build({ + "trusted_relays": ["192.0.2.0/24"], + "reporter_name": " A Reporter ", + }) + self.assertEqual(tomllib.loads(text)["reporter"]["name"], "A Reporter") + + def test_a_quote_in_an_identity_cannot_break_out_of_the_toml(self): + with self.assertRaises(ValueError): + init.build({ + "trusted_relays": ["192.0.2.0/24"], + "reporter_name": 'x"\nemail = "attacker@example.invalid"', + }) + + def test_the_identity_loads_back_through_config(self): + # The seam report.build() consumes: what init writes must arrive as + # the dict shape the reader hands over, keys and all. + with tempfile.TemporaryDirectory() as tmp: + path = pathlib.Path(tmp) / "config.toml" + path.write_text(init.build({ + "trusted_relays": ["192.0.2.0/24"], + "reporter_name": "A Reporter", + "reporter_org": "Example Ltd", + "reporter_email": "abuse@example.org", + }), encoding="utf-8") + self.assertEqual(config.load(path).reporter, { + "name": "A Reporter", + "org": "Example Ltd", + "email": "abuse@example.org", + }) + + def test_a_partial_identity_loads_back_with_only_what_was_given(self): + with tempfile.TemporaryDirectory() as tmp: + path = pathlib.Path(tmp) / "config.toml" + path.write_text(init.build({ + "trusted_relays": ["192.0.2.0/24"], + "reporter_email": "abuse@example.org", + }), encoding="utf-8") + self.assertEqual(config.load(path).reporter, + {"email": "abuse@example.org"}) + + +class TestReporterCarryAcross(unittest.TestCase): + def test_an_identity_set_by_hand_survives_a_relays_only_rewrite(self): + # AGENTS.md: sections build() does not produce are carried across + # verbatim. Skipping all three answers must not delete an identity + # the user set earlier; there would be no warning that it went. + with tempfile.TemporaryDirectory() as tmp: + path = pathlib.Path(tmp) / "config.toml" + path.write_text( + '[general]\ntrusted_relays = ["10.0.0.0/8"]\n\n' + '[reporter]\nname = "A Reporter"\nemail = "abuse@example.org"\n', + encoding="utf-8", + ) + init.write(path, {"trusted_relays": ["192.0.2.0/24"]}, force=True) + self.assertEqual(config.load(path).reporter, + {"name": "A Reporter", "email": "abuse@example.org"}) + + def test_a_new_identity_replaces_the_old_one_without_duplicating_it(self): + # A section the builder DOES produce must not also be carried across: + # two [reporter] tables in one file is not merely untidy, tomllib + # refuses the whole file and the config becomes unreadable. + with tempfile.TemporaryDirectory() as tmp: + path = pathlib.Path(tmp) / "config.toml" + path.write_text( + '[general]\ntrusted_relays = ["10.0.0.0/8"]\n\n' + '[reporter]\nname = "Old Name"\n', + encoding="utf-8", + ) + init.write(path, { + "trusted_relays": ["192.0.2.0/24"], + "reporter_name": "New Name", + }, force=True) + + self.assertEqual(path.read_text().count("[reporter]"), 1) + self.assertEqual(config.load(path).reporter, {"name": "New Name"}) + + def test_an_unrelated_section_still_survives_alongside_an_identity(self): + with tempfile.TemporaryDirectory() as tmp: + path = pathlib.Path(tmp) / "config.toml" + path.write_text( + '[general]\ntrusted_relays = ["10.0.0.0/8"]\n\n' + '[reporter]\nname = "Old Name"\n\n' + '[misp]\napi_key = "kept"\n', + encoding="utf-8", + ) + init.write(path, { + "trusted_relays": ["192.0.2.0/24"], + "reporter_name": "New Name", + }, force=True) + + rewritten = path.read_text() + self.assertIn("kept", rewritten) + self.assertNotIn("Old Name", rewritten) + self.assertEqual(config.load(path).reporter, {"name": "New Name"}) + + class TestProviderTable(unittest.TestCase): def test_a_known_provider_resolves_to_ranges(self): self.assertTrue(init.provider_relays("gmail")) |
