forked from p15670423/monkey
Island: Fix representations.py to encode lists and objects
Previously lists and objects didn't get encoded. This forced explicit encoding on the endpoints, which is not necessary
This commit is contained in:
parent
cd839884eb
commit
da9f3c97ed
|
@ -6,35 +6,39 @@ from bson.json_util import dumps
|
|||
from flask import make_response
|
||||
|
||||
|
||||
def normalize_obj(obj):
|
||||
def _normalize_obj(obj):
|
||||
if ("_id" in obj) and ("id" not in obj):
|
||||
obj["id"] = obj["_id"]
|
||||
del obj["_id"]
|
||||
|
||||
for key, value in list(obj.items()):
|
||||
if isinstance(value, list):
|
||||
for i in range(0, len(value)):
|
||||
obj[key][i] = _normalize_value(value[i])
|
||||
else:
|
||||
obj[key] = _normalize_value(value)
|
||||
obj[key] = _normalize_value(value)
|
||||
return obj
|
||||
|
||||
|
||||
def _normalize_value(value):
|
||||
if isinstance(value, list):
|
||||
for i in range(0, len(value)):
|
||||
value[i] = _normalize_value(value[i])
|
||||
if type(value) == dict:
|
||||
return normalize_obj(value)
|
||||
return _normalize_obj(value)
|
||||
if isinstance(value, bson.objectid.ObjectId):
|
||||
return str(value)
|
||||
if isinstance(value, datetime):
|
||||
return str(value)
|
||||
if issubclass(type(value), Enum):
|
||||
return value.name
|
||||
else:
|
||||
return value
|
||||
|
||||
try:
|
||||
return value.__dict__
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def output_json(obj, code, headers=None):
|
||||
obj = normalize_obj(obj)
|
||||
resp = make_response(dumps(obj), code)
|
||||
def output_json(value, code, headers=None):
|
||||
value = _normalize_value(value)
|
||||
resp = make_response(dumps(value), code)
|
||||
resp.headers.extend(headers or {})
|
||||
return resp
|
||||
|
|
|
@ -1,55 +1,62 @@
|
|||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from unittest import TestCase
|
||||
|
||||
import bson
|
||||
|
||||
from monkey_island.cc.services.representations import normalize_obj
|
||||
from monkey_island.cc.services.representations import _normalize_value
|
||||
|
||||
|
||||
class TestRepresentations(TestCase):
|
||||
def test_normalize_obj(self):
|
||||
# empty
|
||||
self.assertEqual({}, normalize_obj({}))
|
||||
@dataclass
|
||||
class MockClass:
|
||||
a: int
|
||||
|
||||
# no special content
|
||||
self.assertEqual({"a": "a"}, normalize_obj({"a": "a"}))
|
||||
|
||||
# _id field -> id field
|
||||
self.assertEqual({"id": 12345}, normalize_obj({"_id": 12345}))
|
||||
obj_id_str = "123456789012345678901234"
|
||||
mock_object = MockClass(1)
|
||||
|
||||
# obj id field -> str
|
||||
obj_id_str = "123456789012345678901234"
|
||||
self.assertEqual(
|
||||
{"id": obj_id_str}, normalize_obj({"_id": bson.objectid.ObjectId(obj_id_str)})
|
||||
)
|
||||
|
||||
# datetime -> str
|
||||
dt = datetime.now()
|
||||
expected = {"a": str(dt)}
|
||||
result = normalize_obj({"a": dt})
|
||||
self.assertEqual(expected, result)
|
||||
def test_normalize_dicts():
|
||||
assert {} == _normalize_value({})
|
||||
|
||||
# dicts and lists
|
||||
self.assertEqual(
|
||||
{"a": [{"ba": obj_id_str, "bb": obj_id_str}], "b": {"id": obj_id_str}},
|
||||
normalize_obj(
|
||||
{
|
||||
"a": [
|
||||
{
|
||||
"ba": bson.objectid.ObjectId(obj_id_str),
|
||||
"bb": bson.objectid.ObjectId(obj_id_str),
|
||||
}
|
||||
],
|
||||
"b": {"_id": bson.objectid.ObjectId(obj_id_str)},
|
||||
}
|
||||
),
|
||||
)
|
||||
assert {"a": "a"} == _normalize_value({"a": "a"})
|
||||
|
||||
def test_normalize__enum(self):
|
||||
class BogusEnum(Enum):
|
||||
bogus_val = "Bogus"
|
||||
assert {"id": 12345} == _normalize_value({"_id": 12345})
|
||||
|
||||
my_obj = {"something": "something", "my_enum": BogusEnum.bogus_val}
|
||||
assert {"id": obj_id_str} == _normalize_value({"_id": bson.objectid.ObjectId(obj_id_str)})
|
||||
|
||||
assert {"something": "something", "my_enum": "bogus_val"} == normalize_obj(my_obj)
|
||||
dt = datetime.now()
|
||||
expected = {"a": str(dt)}
|
||||
result = _normalize_value({"a": dt})
|
||||
assert expected == result
|
||||
|
||||
|
||||
def test_normalize_complex():
|
||||
mock_dict = {
|
||||
"a": [
|
||||
{
|
||||
"ba": bson.objectid.ObjectId(obj_id_str),
|
||||
"bb": bson.objectid.ObjectId(obj_id_str),
|
||||
}
|
||||
],
|
||||
"b": {"_id": bson.objectid.ObjectId(obj_id_str)},
|
||||
}
|
||||
|
||||
expected_dict = {"a": [{"ba": obj_id_str, "bb": obj_id_str}], "b": {"id": obj_id_str}}
|
||||
assert expected_dict == _normalize_value(mock_dict)
|
||||
|
||||
|
||||
def test_normalize_list():
|
||||
mock_list = [bson.objectid.ObjectId(obj_id_str), {"a": "b"}, {"object": [mock_object]}]
|
||||
|
||||
expected_list = [obj_id_str, {"a": "b"}, {"object": [{"a": 1}]}]
|
||||
assert expected_list == _normalize_value(mock_list)
|
||||
|
||||
|
||||
def test_normalize__enum():
|
||||
class BogusEnum(Enum):
|
||||
bogus_val = "Bogus"
|
||||
|
||||
my_obj = {"something": "something", "my_enum": BogusEnum.bogus_val}
|
||||
|
||||
assert {"something": "something", "my_enum": "bogus_val"} == _normalize_value(my_obj)
|
||||
|
|
Loading…
Reference in New Issue