diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-08 13:55:04 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-08 13:55:04 +0200 |
| commit | b491b772b9f68c0c61a62597a972b6cc7848466e (patch) | |
| tree | b0e80c555af102430cd45cb5180d58c20f156fd3 /tests | |
| parent | ab8be8e3d58a5c2dd8b351110822063b482311e1 (diff) | |
| download | abusectl-b491b772b9f68c0c61a62597a972b6cc7848466e.tar.gz abusectl-b491b772b9f68c0c61a62597a972b6cc7848466e.zip | |
feat: read and validate the config
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_config.py | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/tests/test_config.py b/tests/test_config.py new file mode 100644 index 0000000..c0a9ac4 --- /dev/null +++ b/tests/test_config.py @@ -0,0 +1,88 @@ +# Copyright (C) 2026 Danilo M. <danix@danix.xyz> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +"""Tests for reading and validating ~/.config/abusectl/config.toml.""" + +import os +import pathlib +import tempfile +import unittest +from unittest import mock + +from abusectl import config + + +class TestConfig(unittest.TestCase): + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.root = pathlib.Path(self._tmp.name) + + def tearDown(self): + self._tmp.cleanup() + + def _write(self, text: str) -> pathlib.Path: + path = self.root / "config.toml" + path.write_text(text, encoding="utf-8") + return path + + def test_trusted_relays_and_cases_are_read(self): + path = self._write( + "[general]\n" + 'cases = "~/cases"\n' + 'trusted_relays = ["192.0.2.0/24"]\n' + ) + loaded = config.load(path) + self.assertEqual(loaded.trusted_relays, ["192.0.2.0/24"]) + self.assertEqual(loaded.cases, pathlib.Path.home() / "cases") + + def test_a_missing_file_is_reported_as_not_configured(self): + with self.assertRaises(config.NotConfigured): + config.load(self.root / "absent.toml") + + def test_an_empty_relay_list_is_not_configured(self): + # Present but empty is the same as absent: parse must refuse either + # way rather than guess, so they are one error. + path = self._write("[general]\ntrusted_relays = []\n") + with self.assertRaises(config.NotConfigured): + config.load(path) + + def test_a_malformed_cidr_is_rejected_at_load(self): + # Reported against the file that holds the typo, not later against a + # message that did nothing wrong. + path = self._write('[general]\ntrusted_relays = ["not-a-network"]\n') + with self.assertRaises(ValueError): + config.load(path) + + def test_the_cases_path_has_a_default(self): + path = self._write('[general]\ntrusted_relays = ["192.0.2.0/24"]\n') + self.assertEqual(config.load(path).cases, config.DEFAULT_CASES) + + def test_malformed_toml_is_not_reported_as_not_configured(self): + # A syntax error is a broken file, which is a different problem from + # an absent one and must not be answered with "run abusectl init". + path = self._write("[general\ntrusted_relays = [") + with self.assertRaises(Exception) as caught: + config.load(path) + self.assertNotIsInstance(caught.exception, config.NotConfigured) + + def test_the_config_path_follows_xdg_config_home(self): + with mock.patch.dict(os.environ, {"XDG_CONFIG_HOME": "/tmp/xdg-probe"}): + self.assertEqual( + config.path(), + pathlib.Path("/tmp/xdg-probe/abusectl/config.toml"), + ) + + +if __name__ == "__main__": + unittest.main() |
