""" Tests for ip_utils.write_caddyfile — this function is called on every ip_range / domain / cell_name change and was previously untested. """ import os import sys import tempfile import unittest sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'api')) from ip_utils import write_caddyfile, get_service_ips class TestWriteCaddyfile(unittest.TestCase): def setUp(self): self.tmp = tempfile.mkdtemp() self.path = os.path.join(self.tmp, 'caddy', 'Caddyfile') def _write(self, ip_range='172.20.0.0/16', cell_name='mycell', domain='cell'): ok = write_caddyfile(ip_range, cell_name, domain, self.path) self.assertTrue(ok, "write_caddyfile returned False") with open(self.path) as f: return f.read() def test_creates_file_in_subdirectory(self): self._write() self.assertTrue(os.path.isfile(self.path)) def test_cell_domain_vhost_present(self): content = self._write(cell_name='mycell', domain='cell') self.assertIn('http://mycell.cell', content) def test_custom_domain_used(self): content = self._write(cell_name='pic0', domain='dev') self.assertIn('http://pic0.dev', content) self.assertNotIn('mycell', content) self.assertNotIn('.cell', content) def test_service_subdomains_use_domain(self): content = self._write(domain='mynet') self.assertIn('http://calendar.mynet', content) self.assertIn('http://files.mynet', content) self.assertIn('http://mail.mynet', content) self.assertIn('http://webdav.mynet', content) def test_virtual_ips_match_ip_range(self): ip_range = '10.0.0.0/16' content = self._write(ip_range=ip_range) ips = get_service_ips(ip_range) self.assertIn(ips['vip_calendar'], content) self.assertIn(ips['vip_files'], content) self.assertIn(ips['vip_mail'], content) self.assertIn(ips['vip_webdav'], content) def test_reverse_proxy_targets_are_internal_ports(self): content = self._write() self.assertIn('reverse_proxy cell-radicale:5232', content) self.assertIn('reverse_proxy cell-filegator:8080', content) self.assertIn('reverse_proxy cell-rainloop:8888', content) self.assertIn('reverse_proxy cell-webdav:80', content) def test_api_proxy_present(self): content = self._write() self.assertIn('reverse_proxy cell-api:3000', content) def test_overwrite_on_second_call(self): self._write(cell_name='first', domain='cell') content = self._write(cell_name='second', domain='cell') self.assertIn('second.cell', content) self.assertNotIn('first.cell', content) def test_different_ip_ranges_produce_different_vips(self): c1 = self._write(ip_range='10.0.0.0/16') os.remove(self.path) c2 = self._write(ip_range='192.168.1.0/24') self.assertNotEqual(c1, c2) def test_auto_https_off(self): content = self._write() self.assertIn('auto_https off', content) def test_catchall_block_present(self): content = self._write() self.assertIn(':80 {', content) def test_invalid_ip_range_returns_false(self): result = write_caddyfile('not-a-cidr', 'cell', 'cell', self.path) self.assertFalse(result) def test_file_is_not_empty(self): self._write() self.assertGreater(os.path.getsize(self.path), 100) def tearDown(self): import shutil shutil.rmtree(self.tmp, ignore_errors=True) if __name__ == '__main__': unittest.main()