mirror of
https://github.com/thousandeyes/thousandeyes-sdk-python.git
synced 2026-08-04 00:46:52 +00:00
Normalize ISO8601 datetimes in mock server request body matching.
Treat Z and +00:00 as equivalent when comparing serialized SDK request bodies to OAS examples, fixing alert suppression window integration tests. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
b1faff026e
commit
f1f280d48c
@ -19,6 +19,7 @@ from __future__ import annotations
|
|||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
import threading
|
import threading
|
||||||
|
from datetime import datetime
|
||||||
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||||
from typing import Any, Dict, Mapping, Optional
|
from typing import Any, Dict, Mapping, Optional
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
@ -30,12 +31,21 @@ ERROR_STATUS_HEADER = "X-TE-Error-Status"
|
|||||||
AUTHORIZATION_HEADER = "Authorization"
|
AUTHORIZATION_HEADER = "Authorization"
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_scalar(value: Any) -> Any:
|
||||||
|
if isinstance(value, str) and "T" in value:
|
||||||
|
try:
|
||||||
|
return datetime.fromisoformat(value.replace("Z", "+00:00")).isoformat().replace("+00:00", "Z")
|
||||||
|
except ValueError:
|
||||||
|
return value
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
def _normalize_json(value: Any) -> Any:
|
def _normalize_json(value: Any) -> Any:
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
return {key: _normalize_json(value[key]) for key in sorted(value.keys())}
|
return {key: _normalize_json(value[key]) for key in sorted(value.keys())}
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
return [_normalize_json(item) for item in value]
|
return [_normalize_json(item) for item in value]
|
||||||
return value
|
return _normalize_scalar(value)
|
||||||
|
|
||||||
|
|
||||||
def _json_body_matches(expected: Any, actual: Any) -> bool:
|
def _json_body_matches(expected: Any, actual: Any) -> bool:
|
||||||
|
|||||||
@ -185,3 +185,32 @@ def test_mock_server_rejects_path_missing_path_variable(manifest):
|
|||||||
)
|
)
|
||||||
assert status == 400
|
assert status == 400
|
||||||
assert json.loads(body.decode("utf-8"))["detail"] == "Path does not match operation expectation"
|
assert json.loads(body.decode("utf-8"))["detail"] == "Path does not match operation expectation"
|
||||||
|
|
||||||
|
|
||||||
|
def test_mock_server_accepts_equivalent_iso8601_datetime_formats(manifest):
|
||||||
|
datetime_manifest = {
|
||||||
|
**manifest,
|
||||||
|
"createAlertRule": OperationExpectation(
|
||||||
|
operation_id="createAlertRule",
|
||||||
|
method="POST",
|
||||||
|
path="/alerts/rules",
|
||||||
|
request_body_example={
|
||||||
|
"ruleName": "Example",
|
||||||
|
"startDate": "2017-07-01T05:00:00Z",
|
||||||
|
},
|
||||||
|
success_status=201,
|
||||||
|
success_body={"ruleId": "1"},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
with MockApiServer(datetime_manifest) as server:
|
||||||
|
status, body = _request(
|
||||||
|
server,
|
||||||
|
method="POST",
|
||||||
|
path="/alerts/rules",
|
||||||
|
body={
|
||||||
|
"ruleName": "Example",
|
||||||
|
"startDate": "2017-07-01T05:00:00+00:00",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert status == 201
|
||||||
|
assert json.loads(body.decode("utf-8")) == {"ruleId": "1"}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user