Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions tests/test_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# -*- coding: utf-8 -*-
"""
Tests for xero_python.models.BaseModel.to_dict serialization.

Regression test for #93: BaseModel.to_dict() must return JSON-serializable
primitives. Previously enum-typed (and UUID-typed) attributes were returned
as the raw Enum / UUID object, so json.dumps(model.to_dict()) raised.
"""
import json
from enum import Enum
from uuid import UUID

from xero_python.models import BaseModel


class AccountType(Enum):
BANK = "BANK"
EXPENSE = "EXPENSE"


class Journal(BaseModel):
openapi_types = {"account_type": "AccountType", "journal_id": "UUID", "name": "str"}
attribute_map = {
"account_type": "AccountType",
"journal_id": "JournalID",
"name": "Name",
}

def __init__(self, **kwargs):
# mirror generated models: every declared attribute defaults to None
for name in self.openapi_types:
setattr(self, name, None)
for name, value in kwargs.items():
setattr(self, name, value)


def test_to_dict_serializes_enum_to_its_value():
journal = Journal(account_type=AccountType.BANK)
assert journal.to_dict()["account_type"] == "BANK"


def test_to_dict_serializes_uuid_to_string():
journal = Journal(journal_id=UUID("12345678-1234-5678-1234-567812345678"))
assert journal.to_dict()["journal_id"] == "12345678-1234-5678-1234-567812345678"


def test_to_dict_is_json_serializable():
journal = Journal(
account_type=AccountType.EXPENSE,
journal_id=UUID("12345678-1234-5678-1234-567812345678"),
name="Sales",
)
# should not raise
encoded = json.dumps(journal.to_dict())
assert json.loads(encoded) == {
"account_type": "EXPENSE",
"journal_id": "12345678-1234-5678-1234-567812345678",
"name": "Sales",
}
12 changes: 12 additions & 0 deletions xero_python/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
import pprint
from enum import Enum
from functools import singledispatch
from uuid import UUID


class BaseModel:
Expand Down Expand Up @@ -67,3 +69,13 @@ def serialize_tuple_to_dict(value):
@serialize_to_dict.register(dict)
def serialize_dict_to_dict(value):
return {key: serialize_to_dict(val) for key, val in value.items()}


@serialize_to_dict.register(Enum)
def serialize_enum_to_dict(value):
return value.value


@serialize_to_dict.register(UUID)
def serialize_uuid_to_dict(value):
return str(value)