Prepare NPM references and mutation API

This commit is contained in:
Lyncoln
2026-09-19 22:52:14 -04:00
parent 8caac79a1e
commit 381119a6b5
6 changed files with 436 additions and 10 deletions
+197 -1
View File
@@ -1,6 +1,6 @@
import os
import unittest
from unittest.mock import patch
from unittest.mock import Mock, patch
from dns_sync.adapters import Endpoint
from dns_sync.config import AppConfig
@@ -71,5 +71,201 @@ class NpmClientEndpointTests(unittest.TestCase):
NpmClient(config, endpoint)
class NpmClientMutationTests(unittest.TestCase):
def client(self):
with patch.dict(
os.environ,
{
"NPM_ENDPOINTS": "192.168.1.3",
"DNS_TARGET_IP": "192.168.1.101",
"NPM_IDENTITY": "test@example.com",
"NPM_SECRET": "not-a-real-secret",
},
clear=True,
):
config = AppConfig.from_env()
return NpmClient(
config,
config.npm_endpoints[0],
)
@staticmethod
def response(data):
response = Mock()
response.json.return_value = data
return response
def test_gets_one_proxy_host_by_endpoint_local_id(self):
client = self.client()
client.get_json = Mock(
return_value={
"id": 12,
"domain_names": ["app.example.com"],
}
)
result = client.proxy_host("12")
client.get_json.assert_called_once_with(
"/nginx/proxy-hosts/12"
)
self.assertEqual(result["id"], 12)
def test_creates_proxy_host_with_json_payload(self):
client = self.client()
payload = {
"domain_names": ["app.example.com"],
"forward_scheme": "http",
"forward_host": "192.168.1.20",
"forward_port": 8080,
"certificate_id": 67,
}
client.request = Mock(
return_value=self.response({"id": 12})
)
result = client.create_proxy_host(payload)
client.request.assert_called_once_with(
"POST",
"/nginx/proxy-hosts",
expected_status=201,
json=payload,
)
self.assertEqual(result["id"], 12)
def test_updates_proxy_host_with_json_payload(self):
client = self.client()
payload = {
"forward_host": "192.168.1.30",
}
client.request = Mock(
return_value=self.response({"id": 12})
)
result = client.update_proxy_host(
"12",
payload,
)
client.request.assert_called_once_with(
"PUT",
"/nginx/proxy-hosts/12",
expected_status=200,
json=payload,
)
self.assertEqual(result["id"], 12)
def test_gets_one_certificate_by_endpoint_local_id(self):
client = self.client()
client.get_json = Mock(
return_value={
"id": 67,
"domain_names": ["app.example.com"],
}
)
result = client.certificate("67")
client.get_json.assert_called_once_with(
"/nginx/certificates/67"
)
self.assertEqual(result["id"], 67)
def test_creates_certificate_metadata_with_json_payload(self):
client = self.client()
payload = {
"provider": "other",
"nice_name": "cluster copy",
"domain_names": ["app.example.com"],
"meta": {
"cluster_managed": True,
},
}
client.request = Mock(
return_value=self.response({"id": 84})
)
result = client.create_certificate(payload)
client.request.assert_called_once_with(
"POST",
"/nginx/certificates",
expected_status=201,
json=payload,
)
self.assertEqual(result["id"], 84)
def test_uploads_certificate_material_as_multipart(self):
client = self.client()
client.request = Mock(
return_value=self.response({"id": 84})
)
result = client.upload_certificate(
"84",
certificate=b"CERTIFICATE",
certificate_key=b"PRIVATE-KEY",
intermediate_certificate=b"INTERMEDIATE",
)
client.request.assert_called_once_with(
"POST",
"/nginx/certificates/84/upload",
expected_status=200,
files={
"certificate": (
"certificate.pem",
b"CERTIFICATE",
),
"certificate_key": (
"certificate_key.pem",
b"PRIVATE-KEY",
),
"intermediate_certificate": (
"intermediate_certificate.pem",
b"INTERMEDIATE",
),
},
)
self.assertEqual(result["id"], 84)
def test_certificate_upload_requires_both_required_parts(self):
client = self.client()
with self.assertRaisesRegex(
RuntimeError,
"requires certificate data",
):
client.upload_certificate(
"84",
certificate=b"",
certificate_key=b"PRIVATE-KEY",
)
with self.assertRaisesRegex(
RuntimeError,
"requires certificate key data",
):
client.upload_certificate(
"84",
certificate=b"CERTIFICATE",
certificate_key=b"",
)
def test_rejects_invalid_endpoint_local_ids(self):
client = self.client()
for local_id in ("", "abc", True, -1):
with self.subTest(local_id=local_id):
with self.assertRaisesRegex(
RuntimeError,
"id is invalid",
):
client.certificate(local_id)
if __name__ == "__main__":
unittest.main()