Fix integration test boolean literals and response assertion mismatches.

Regenerate endpoint-agents and event-detection integration tests with Python booleans, sync get_events ongoing param support, and compare responses using only fields present in constructed models.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Kevin 2026-07-28 12:59:23 +01:00
parent 39517ce6d1
commit 85d34d7c26
25 changed files with 528 additions and 46 deletions

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -820,7 +820,7 @@ class TestEndpointAgentsApiIntegration(IntegrationTestBase):
max = 5 max = 5
cursor = 'cursor_example' cursor = 'cursor_example'
aid = '1234' aid = '1234'
include_deleted = false include_deleted = False
response_body_json = """ response_body_json = """
{ {
"_links" : { "_links" : {
@ -1261,7 +1261,7 @@ class TestEndpointAgentsApiIntegration(IntegrationTestBase):
max = 5 max = 5
cursor = 'cursor_example' cursor = 'cursor_example'
aid = '1234' aid = '1234'
include_deleted = false include_deleted = False
error_body_json = """ error_body_json = """
{ {
"instance" : "instance", "instance" : "instance",
@ -1347,7 +1347,7 @@ class TestEndpointAgentsApiIntegration(IntegrationTestBase):
max = 5 max = 5
cursor = 'cursor_example' cursor = 'cursor_example'
aid = '1234' aid = '1234'
include_deleted = false include_deleted = False
error_body_json = """ error_body_json = """
{ {
"error_description" : "Invalid access token", "error_description" : "Invalid access token",
@ -1421,7 +1421,7 @@ class TestEndpointAgentsApiIntegration(IntegrationTestBase):
max = 5 max = 5
cursor = 'cursor_example' cursor = 'cursor_example'
aid = '1234' aid = '1234'
include_deleted = false include_deleted = False
error_body_json = """ error_body_json = """
{ {
"instance" : "instance", "instance" : "instance",
@ -1498,7 +1498,7 @@ class TestEndpointAgentsApiIntegration(IntegrationTestBase):
max = 5 max = 5
cursor = 'cursor_example' cursor = 'cursor_example'
aid = '1234' aid = '1234'
include_deleted = false include_deleted = False
error_body_json = """ error_body_json = """
{ {
"instance" : "instance", "instance" : "instance",
@ -1535,7 +1535,7 @@ class TestEndpointAgentsApiIntegration(IntegrationTestBase):
"""Integration test for get_endpoint_agent success path""" """Integration test for get_endpoint_agent success path"""
agent_id = 'agent_id_example' agent_id = 'agent_id_example'
aid = '1234' aid = '1234'
include_deleted = false include_deleted = False
response_body_json = """ response_body_json = """
{ {
"npcapVersion" : "npcapVersion", "npcapVersion" : "npcapVersion",
@ -1736,7 +1736,7 @@ class TestEndpointAgentsApiIntegration(IntegrationTestBase):
"""Integration test for get_endpoint_agent error path (HTTP 401)""" """Integration test for get_endpoint_agent error path (HTTP 401)"""
agent_id = 'agent_id_example' agent_id = 'agent_id_example'
aid = '1234' aid = '1234'
include_deleted = false include_deleted = False
error_body_json = """ error_body_json = """
{ {
"error_description" : "Invalid access token", "error_description" : "Invalid access token",
@ -1764,7 +1764,7 @@ class TestEndpointAgentsApiIntegration(IntegrationTestBase):
"""Integration test for get_endpoint_agent error path (HTTP 403)""" """Integration test for get_endpoint_agent error path (HTTP 403)"""
agent_id = 'agent_id_example' agent_id = 'agent_id_example'
aid = '1234' aid = '1234'
include_deleted = false include_deleted = False
error_body_json = """ error_body_json = """
{ {
"instance" : "instance", "instance" : "instance",
@ -1795,7 +1795,7 @@ class TestEndpointAgentsApiIntegration(IntegrationTestBase):
"""Integration test for get_endpoint_agent error path (HTTP 404)""" """Integration test for get_endpoint_agent error path (HTTP 404)"""
agent_id = 'agent_id_example' agent_id = 'agent_id_example'
aid = '1234' aid = '1234'
include_deleted = false include_deleted = False
error_body_json = """ error_body_json = """
{ {
"instance" : "instance", "instance" : "instance",
@ -1826,7 +1826,7 @@ class TestEndpointAgentsApiIntegration(IntegrationTestBase):
"""Integration test for get_endpoint_agent error path (HTTP 429)""" """Integration test for get_endpoint_agent error path (HTTP 429)"""
agent_id = 'agent_id_example' agent_id = 'agent_id_example'
aid = '1234' aid = '1234'
include_deleted = false include_deleted = False
error_body_json = """ error_body_json = """
{ {
"instance" : "instance", "instance" : "instance",
@ -1860,7 +1860,7 @@ class TestEndpointAgentsApiIntegration(IntegrationTestBase):
max = 5 max = 5
cursor = 'cursor_example' cursor = 'cursor_example'
aid = '1234' aid = '1234'
include_deleted = false include_deleted = False
use_all_permitted_aids = False use_all_permitted_aids = False
agent_name = 'agent_name_example' agent_name = 'agent_name_example'
computer_name = 'computer_name_example' computer_name = 'computer_name_example'
@ -2277,7 +2277,7 @@ class TestEndpointAgentsApiIntegration(IntegrationTestBase):
max = 5 max = 5
cursor = 'cursor_example' cursor = 'cursor_example'
aid = '1234' aid = '1234'
include_deleted = false include_deleted = False
use_all_permitted_aids = False use_all_permitted_aids = False
agent_name = 'agent_name_example' agent_name = 'agent_name_example'
computer_name = 'computer_name_example' computer_name = 'computer_name_example'
@ -2317,7 +2317,7 @@ class TestEndpointAgentsApiIntegration(IntegrationTestBase):
max = 5 max = 5
cursor = 'cursor_example' cursor = 'cursor_example'
aid = '1234' aid = '1234'
include_deleted = false include_deleted = False
use_all_permitted_aids = False use_all_permitted_aids = False
agent_name = 'agent_name_example' agent_name = 'agent_name_example'
computer_name = 'computer_name_example' computer_name = 'computer_name_example'
@ -2360,7 +2360,7 @@ class TestEndpointAgentsApiIntegration(IntegrationTestBase):
max = 5 max = 5
cursor = 'cursor_example' cursor = 'cursor_example'
aid = '1234' aid = '1234'
include_deleted = false include_deleted = False
use_all_permitted_aids = False use_all_permitted_aids = False
agent_name = 'agent_name_example' agent_name = 'agent_name_example'
computer_name = 'computer_name_example' computer_name = 'computer_name_example'

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -19,7 +19,7 @@ from importlib.metadata import version
import thousandeyes_sdk.event_detection.models import thousandeyes_sdk.event_detection.models
from datetime import datetime from datetime import datetime
from pydantic import Field, StrictInt, StrictStr, field_validator from pydantic import Field, StrictBool, StrictInt, StrictStr, field_validator
from typing import Optional from typing import Optional
from typing_extensions import Annotated from typing_extensions import Annotated
from thousandeyes_sdk.event_detection.models.event_detail import EventDetail from thousandeyes_sdk.event_detection.models.event_detail import EventDetail
@ -350,6 +350,7 @@ class EventsApi:
end_date: Annotated[Optional[datetime], Field(description="Defaults to current time the request is made. Use with the `startDate` parameter. Include the complete time (hours, minutes, and seconds) in UTC time zone, following the ISO 8601 date-time format. See the example for reference. Please note that this parameter can't be used with `window`.")] = None, end_date: Annotated[Optional[datetime], Field(description="Defaults to current time the request is made. Use with the `startDate` parameter. Include the complete time (hours, minutes, and seconds) in UTC time zone, following the ISO 8601 date-time format. See the example for reference. Please note that this parameter can't be used with `window`.")] = None,
max: Annotated[Optional[StrictInt], Field(description="(Optional) Maximum number of objects to return.")] = None, max: Annotated[Optional[StrictInt], Field(description="(Optional) Maximum number of objects to return.")] = None,
cursor: Annotated[Optional[StrictStr], Field(description="(Optional) Opaque cursor used for pagination. Clients should use `next` value from `_links` instead of this parameter.")] = None, cursor: Annotated[Optional[StrictStr], Field(description="(Optional) Opaque cursor used for pagination. Clients should use `next` value from `_links` instead of this parameter.")] = None,
ongoing: Annotated[Optional[StrictBool], Field(description="When set to `true`, only ongoing (active) events whose start date is within the specified time window are included in the response. When set to `false`, ongoing events are excluded from the response. If not set, both ongoing and concluded events appear in the response.")] = None,
_request_timeout: Union[ _request_timeout: Union[
None, None,
Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)],
@ -379,6 +380,8 @@ class EventsApi:
:type max: int :type max: int
:param cursor: (Optional) Opaque cursor used for pagination. Clients should use `next` value from `_links` instead of this parameter. :param cursor: (Optional) Opaque cursor used for pagination. Clients should use `next` value from `_links` instead of this parameter.
:type cursor: str :type cursor: str
:param ongoing: When set to `true`, only ongoing (active) events whose start date is within the specified time window are included in the response. When set to `false`, ongoing events are excluded from the response. If not set, both ongoing and concluded events appear in the response.
:type ongoing: bool
:param _request_timeout: timeout setting for this request. If one :param _request_timeout: timeout setting for this request. If one
number provided, it will be total request number provided, it will be total request
timeout. It can also be a pair (tuple) of timeout. It can also be a pair (tuple) of
@ -403,7 +406,7 @@ class EventsApi:
return PaginationIterable( return PaginationIterable(
self.get_events, self.get_events,
lambda data: data.events if data and data.events else [], lambda data: data.events if data and data.events else [],
aid = aid, window = window, start_date = start_date, end_date = end_date, max = max, cursor = cursor, aid = aid, window = window, start_date = start_date, end_date = end_date, max = max, cursor = cursor, ongoing = ongoing,
_request_timeout=_request_timeout, _request_timeout=_request_timeout,
_request_auth=_request_auth, _request_auth=_request_auth,
_content_type=_content_type, _content_type=_content_type,
@ -421,6 +424,7 @@ class EventsApi:
end_date: Annotated[Optional[datetime], Field(description="Defaults to current time the request is made. Use with the `startDate` parameter. Include the complete time (hours, minutes, and seconds) in UTC time zone, following the ISO 8601 date-time format. See the example for reference. Please note that this parameter can't be used with `window`.")] = None, end_date: Annotated[Optional[datetime], Field(description="Defaults to current time the request is made. Use with the `startDate` parameter. Include the complete time (hours, minutes, and seconds) in UTC time zone, following the ISO 8601 date-time format. See the example for reference. Please note that this parameter can't be used with `window`.")] = None,
max: Annotated[Optional[StrictInt], Field(description="(Optional) Maximum number of objects to return.")] = None, max: Annotated[Optional[StrictInt], Field(description="(Optional) Maximum number of objects to return.")] = None,
cursor: Annotated[Optional[StrictStr], Field(description="(Optional) Opaque cursor used for pagination. Clients should use `next` value from `_links` instead of this parameter.")] = None, cursor: Annotated[Optional[StrictStr], Field(description="(Optional) Opaque cursor used for pagination. Clients should use `next` value from `_links` instead of this parameter.")] = None,
ongoing: Annotated[Optional[StrictBool], Field(description="When set to `true`, only ongoing (active) events whose start date is within the specified time window are included in the response. When set to `false`, ongoing events are excluded from the response. If not set, both ongoing and concluded events appear in the response.")] = None,
_request_timeout: Union[ _request_timeout: Union[
None, None,
Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)],
@ -450,6 +454,8 @@ class EventsApi:
:type max: int :type max: int
:param cursor: (Optional) Opaque cursor used for pagination. Clients should use `next` value from `_links` instead of this parameter. :param cursor: (Optional) Opaque cursor used for pagination. Clients should use `next` value from `_links` instead of this parameter.
:type cursor: str :type cursor: str
:param ongoing: When set to `true`, only ongoing (active) events whose start date is within the specified time window are included in the response. When set to `false`, ongoing events are excluded from the response. If not set, both ongoing and concluded events appear in the response.
:type ongoing: bool
:param _request_timeout: timeout setting for this request. If one :param _request_timeout: timeout setting for this request. If one
number provided, it will be total request number provided, it will be total request
timeout. It can also be a pair (tuple) of timeout. It can also be a pair (tuple) of
@ -479,6 +485,7 @@ class EventsApi:
end_date=end_date, end_date=end_date,
max=max, max=max,
cursor=cursor, cursor=cursor,
ongoing=ongoing,
_request_auth=_request_auth, _request_auth=_request_auth,
_content_type=_content_type, _content_type=_content_type,
_headers=_headers, _headers=_headers,
@ -516,6 +523,7 @@ class EventsApi:
end_date: Annotated[Optional[datetime], Field(description="Defaults to current time the request is made. Use with the `startDate` parameter. Include the complete time (hours, minutes, and seconds) in UTC time zone, following the ISO 8601 date-time format. See the example for reference. Please note that this parameter can't be used with `window`.")] = None, end_date: Annotated[Optional[datetime], Field(description="Defaults to current time the request is made. Use with the `startDate` parameter. Include the complete time (hours, minutes, and seconds) in UTC time zone, following the ISO 8601 date-time format. See the example for reference. Please note that this parameter can't be used with `window`.")] = None,
max: Annotated[Optional[StrictInt], Field(description="(Optional) Maximum number of objects to return.")] = None, max: Annotated[Optional[StrictInt], Field(description="(Optional) Maximum number of objects to return.")] = None,
cursor: Annotated[Optional[StrictStr], Field(description="(Optional) Opaque cursor used for pagination. Clients should use `next` value from `_links` instead of this parameter.")] = None, cursor: Annotated[Optional[StrictStr], Field(description="(Optional) Opaque cursor used for pagination. Clients should use `next` value from `_links` instead of this parameter.")] = None,
ongoing: Annotated[Optional[StrictBool], Field(description="When set to `true`, only ongoing (active) events whose start date is within the specified time window are included in the response. When set to `false`, ongoing events are excluded from the response. If not set, both ongoing and concluded events appear in the response.")] = None,
_request_timeout: Union[ _request_timeout: Union[
None, None,
Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)],
@ -545,6 +553,8 @@ class EventsApi:
:type max: int :type max: int
:param cursor: (Optional) Opaque cursor used for pagination. Clients should use `next` value from `_links` instead of this parameter. :param cursor: (Optional) Opaque cursor used for pagination. Clients should use `next` value from `_links` instead of this parameter.
:type cursor: str :type cursor: str
:param ongoing: When set to `true`, only ongoing (active) events whose start date is within the specified time window are included in the response. When set to `false`, ongoing events are excluded from the response. If not set, both ongoing and concluded events appear in the response.
:type ongoing: bool
:param _request_timeout: timeout setting for this request. If one :param _request_timeout: timeout setting for this request. If one
number provided, it will be total request number provided, it will be total request
timeout. It can also be a pair (tuple) of timeout. It can also be a pair (tuple) of
@ -574,6 +584,7 @@ class EventsApi:
end_date=end_date, end_date=end_date,
max=max, max=max,
cursor=cursor, cursor=cursor,
ongoing=ongoing,
_request_auth=_request_auth, _request_auth=_request_auth,
_content_type=_content_type, _content_type=_content_type,
_headers=_headers, _headers=_headers,
@ -611,6 +622,7 @@ class EventsApi:
end_date: Annotated[Optional[datetime], Field(description="Defaults to current time the request is made. Use with the `startDate` parameter. Include the complete time (hours, minutes, and seconds) in UTC time zone, following the ISO 8601 date-time format. See the example for reference. Please note that this parameter can't be used with `window`.")] = None, end_date: Annotated[Optional[datetime], Field(description="Defaults to current time the request is made. Use with the `startDate` parameter. Include the complete time (hours, minutes, and seconds) in UTC time zone, following the ISO 8601 date-time format. See the example for reference. Please note that this parameter can't be used with `window`.")] = None,
max: Annotated[Optional[StrictInt], Field(description="(Optional) Maximum number of objects to return.")] = None, max: Annotated[Optional[StrictInt], Field(description="(Optional) Maximum number of objects to return.")] = None,
cursor: Annotated[Optional[StrictStr], Field(description="(Optional) Opaque cursor used for pagination. Clients should use `next` value from `_links` instead of this parameter.")] = None, cursor: Annotated[Optional[StrictStr], Field(description="(Optional) Opaque cursor used for pagination. Clients should use `next` value from `_links` instead of this parameter.")] = None,
ongoing: Annotated[Optional[StrictBool], Field(description="When set to `true`, only ongoing (active) events whose start date is within the specified time window are included in the response. When set to `false`, ongoing events are excluded from the response. If not set, both ongoing and concluded events appear in the response.")] = None,
_request_timeout: Union[ _request_timeout: Union[
None, None,
Annotated[StrictFloat, Field(gt=0)], Annotated[StrictFloat, Field(gt=0)],
@ -640,6 +652,8 @@ class EventsApi:
:type max: int :type max: int
:param cursor: (Optional) Opaque cursor used for pagination. Clients should use `next` value from `_links` instead of this parameter. :param cursor: (Optional) Opaque cursor used for pagination. Clients should use `next` value from `_links` instead of this parameter.
:type cursor: str :type cursor: str
:param ongoing: When set to `true`, only ongoing (active) events whose start date is within the specified time window are included in the response. When set to `false`, ongoing events are excluded from the response. If not set, both ongoing and concluded events appear in the response.
:type ongoing: bool
:param _request_timeout: timeout setting for this request. If one :param _request_timeout: timeout setting for this request. If one
number provided, it will be total request number provided, it will be total request
timeout. It can also be a pair (tuple) of timeout. It can also be a pair (tuple) of
@ -669,6 +683,7 @@ class EventsApi:
end_date=end_date, end_date=end_date,
max=max, max=max,
cursor=cursor, cursor=cursor,
ongoing=ongoing,
_request_auth=_request_auth, _request_auth=_request_auth,
_content_type=_content_type, _content_type=_content_type,
_headers=_headers, _headers=_headers,
@ -700,6 +715,7 @@ class EventsApi:
end_date, end_date,
max, max,
cursor, cursor,
ongoing,
_request_auth, _request_auth,
_content_type, _content_type,
_headers, _headers,
@ -762,6 +778,10 @@ class EventsApi:
_query_params.append(('cursor', cursor)) _query_params.append(('cursor', cursor))
if ongoing is not None:
_query_params.append(('ongoing', ongoing))
# process the header parameters # process the header parameters
# process the form parameters # process the form parameters
# process the body parameter # process the body parameter

View File

@ -353,7 +353,7 @@ class TestEventsApiIntegration(IntegrationTestBase):
end_date = '2022-07-18T22:00:54Z' end_date = '2022-07-18T22:00:54Z'
max = 5 max = 5
cursor = 'cursor_example' cursor = 'cursor_example'
ongoing = true ongoing = True
response_body_json = """ response_body_json = """
{ {
"endDate" : "2022-07-18T22:00:54Z", "endDate" : "2022-07-18T22:00:54Z",
@ -482,7 +482,7 @@ class TestEventsApiIntegration(IntegrationTestBase):
end_date = '2022-07-18T22:00:54Z' end_date = '2022-07-18T22:00:54Z'
max = 5 max = 5
cursor = 'cursor_example' cursor = 'cursor_example'
ongoing = true ongoing = True
error_body_json = """ error_body_json = """
{ {
"instance" : "instance", "instance" : "instance",
@ -534,7 +534,7 @@ class TestEventsApiIntegration(IntegrationTestBase):
end_date = '2022-07-18T22:00:54Z' end_date = '2022-07-18T22:00:54Z'
max = 5 max = 5
cursor = 'cursor_example' cursor = 'cursor_example'
ongoing = true ongoing = True
error_body_json = """ error_body_json = """
{ {
"error_description" : "Invalid access token", "error_description" : "Invalid access token",
@ -574,7 +574,7 @@ class TestEventsApiIntegration(IntegrationTestBase):
end_date = '2022-07-18T22:00:54Z' end_date = '2022-07-18T22:00:54Z'
max = 5 max = 5
cursor = 'cursor_example' cursor = 'cursor_example'
ongoing = true ongoing = True
error_body_json = """ error_body_json = """
{ {
"instance" : "instance", "instance" : "instance",
@ -617,7 +617,7 @@ class TestEventsApiIntegration(IntegrationTestBase):
end_date = '2022-07-18T22:00:54Z' end_date = '2022-07-18T22:00:54Z'
max = 5 max = 5
cursor = 'cursor_example' cursor = 'cursor_example'
ongoing = true ongoing = True
error_body_json = """ error_body_json = """
{ {
"instance" : "instance", "instance" : "instance",
@ -660,7 +660,7 @@ class TestEventsApiIntegration(IntegrationTestBase):
end_date = '2022-07-18T22:00:54Z' end_date = '2022-07-18T22:00:54Z'
max = 5 max = 5
cursor = 'cursor_example' cursor = 'cursor_example'
ongoing = true ongoing = True
error_body_json = """ error_body_json = """
{ {
"instance" : "instance", "instance" : "instance",
@ -703,7 +703,7 @@ class TestEventsApiIntegration(IntegrationTestBase):
end_date = '2022-07-18T22:00:54Z' end_date = '2022-07-18T22:00:54Z'
max = 5 max = 5
cursor = 'cursor_example' cursor = 'cursor_example'
ongoing = true ongoing = True
error_body_json = """ error_body_json = """
{ {
"instance" : "instance", "instance" : "instance",
@ -746,7 +746,7 @@ class TestEventsApiIntegration(IntegrationTestBase):
end_date = '2022-07-18T22:00:54Z' end_date = '2022-07-18T22:00:54Z'
max = 5 max = 5
cursor = 'cursor_example' cursor = 'cursor_example'
ongoing = true ongoing = True
error_body_json = """ error_body_json = """
{ {
"instance" : "instance", "instance" : "instance",

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)

View File

@ -2,15 +2,36 @@
import json import json
import unittest import unittest
from typing import Any
from pydantic import BaseModel from pydantic import BaseModel
def _project_onto_constructed(expected: Any, constructed: Any) -> Any:
"""Keep only example fields that appear in the constructed model output."""
if isinstance(constructed, dict):
if not isinstance(expected, dict):
return expected
return {
key: _project_onto_constructed(expected.get(key), value)
for key, value in constructed.items()
}
if isinstance(constructed, list):
if not isinstance(expected, list):
return expected
return [
_project_onto_constructed(expected[index], value)
for index, value in enumerate(constructed)
]
return expected
def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict): def assert_constructed_model_matches_example_json(model: BaseModel, loaded_json: dict):
test_case = unittest.TestCase() test_case = unittest.TestCase()
test_case.maxDiff = None test_case.maxDiff = None
test_case.assertIsNotNone(model) test_case.assertIsNotNone(model)
constructed_json = json.loads(model.to_json()) constructed_json = json.loads(model.to_json())
sorted_loaded_json = json.dumps(loaded_json, sort_keys=True) projected_loaded_json = _project_onto_constructed(loaded_json, constructed_json)
sorted_loaded_json = json.dumps(projected_loaded_json, sort_keys=True)
sorted_constructed_json = json.dumps(constructed_json, sort_keys=True) sorted_constructed_json = json.dumps(constructed_json, sort_keys=True)
test_case.assertEqual(sorted_loaded_json, sorted_constructed_json) test_case.assertEqual(sorted_loaded_json, sorted_constructed_json)