feat: add NetBox plugin store
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import unittest
|
||||
|
||||
from support import * # noqa: F403
|
||||
|
||||
from netbox_store_agent.errors import ValidationError
|
||||
from netbox_store_agent.protocol import decode_request, encode_response, parse_request, response
|
||||
|
||||
|
||||
class ProtocolTests(unittest.TestCase):
|
||||
def submit(self, **body_overrides: object) -> dict[str, object]:
|
||||
body: dict[str, object] = {
|
||||
"request_id": "eea17d87-8944-4ee2-a076-363338ab746d",
|
||||
"action": "install",
|
||||
"plugin_slug": "demo-plugin",
|
||||
"version": "1.2.3",
|
||||
"approved_payload_sha256": "c" * 64,
|
||||
"requested_by": "netbox:alice",
|
||||
}
|
||||
body.update(body_overrides)
|
||||
return {
|
||||
"protocol_version": 1,
|
||||
"method": "POST",
|
||||
"path": "/v1/operations",
|
||||
"idempotency_key": "20f4274f-d4e5-42bf-9164-967b1a774481",
|
||||
"body": body,
|
||||
}
|
||||
|
||||
def test_exact_submit_contract_and_opaque_token(self) -> None:
|
||||
request = parse_request(self.submit())
|
||||
self.assertEqual(request.operation.approved_payload_sha256, "c" * 64)
|
||||
|
||||
def test_unknown_top_level_field_rejected(self) -> None:
|
||||
value = self.submit(extra=True)
|
||||
value["unexpected"] = True
|
||||
with self.assertRaises(ValidationError):
|
||||
parse_request(value)
|
||||
|
||||
def test_unknown_body_field_rejected(self) -> None:
|
||||
with self.assertRaises(ValidationError):
|
||||
parse_request(self.submit(extra=True))
|
||||
|
||||
def test_non_lifecycle_fields_must_be_null(self) -> None:
|
||||
with self.assertRaises(ValidationError):
|
||||
parse_request(self.submit(action="disable"))
|
||||
request = parse_request(
|
||||
self.submit(action="disable", version=None, approved_payload_sha256=None)
|
||||
)
|
||||
self.assertEqual(request.operation.action, "disable")
|
||||
|
||||
def test_noncanonical_uuid_rejected(self) -> None:
|
||||
with self.assertRaises(ValidationError):
|
||||
parse_request(self.submit(request_id="EEA17D87-8944-4EE2-A076-363338AB746D"))
|
||||
|
||||
def test_multiple_lines_and_oversize_rejected(self) -> None:
|
||||
raw = json.dumps(self.submit()).encode()
|
||||
with self.assertRaises(ValidationError):
|
||||
decode_request(raw + b"\n{}", 65536)
|
||||
with self.assertRaises(ValidationError):
|
||||
decode_request(b"x" * 10, 9)
|
||||
|
||||
def test_capabilities_and_status_paths(self) -> None:
|
||||
cap = parse_request({"protocol_version": 1, "method": "GET", "path": "/v1/capabilities"})
|
||||
self.assertEqual(cap.path, "/v1/capabilities")
|
||||
status = parse_request(
|
||||
{
|
||||
"protocol_version": 1,
|
||||
"method": "GET",
|
||||
"path": "/v1/operations/20f4274f-d4e5-42bf-9164-967b1a774481",
|
||||
}
|
||||
)
|
||||
self.assertEqual(status.idempotency_key, "20f4274f-d4e5-42bf-9164-967b1a774481")
|
||||
|
||||
def test_response_shape_and_single_line(self) -> None:
|
||||
encoded = encode_response(response(200, {"ok": True}))
|
||||
self.assertEqual(encoded.count(b"\n"), 1)
|
||||
self.assertEqual(set(json.loads(encoded)), {"protocol_version", "status", "body"})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user