Skip to content

Commit ea3aaaf

Browse files
author
Abel Milash
committed
Fix 5 broken tests and add docstrings to TestAttributePayloadDtypes
1 parent f36fbd8 commit ea3aaaf

1 file changed

Lines changed: 42 additions & 15 deletions

File tree

tests/unit/data/test_odata_internal.py

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ def test_odata_type_already_present_not_duplicated(self):
647647
[{"@odata.type": "Microsoft.Dynamics.CRM.account", "name": "Test"}],
648648
)
649649
post_calls = [c for c in self.od._request.call_args_list if c.args[0] == "post"]
650-
target = post_calls[0].kwargs["json"]["Targets"][0]
650+
target = json.loads(post_calls[0].kwargs["data"])["Targets"][0]
651651
self.assertEqual(target["@odata.type"], "Microsoft.Dynamics.CRM.account")
652652

653653
def test_body_not_dict_returns_empty_list(self):
@@ -704,6 +704,7 @@ def setUp(self):
704704

705705
def test_cache_miss_resolves_via_entity_set_lookup(self):
706706
"""Cache miss triggers entity set lookup and populates primary ID cache."""
707+
707708
def mock_entity_set(table_schema_name):
708709
cache_key = table_schema_name.lower()
709710
self.od._logical_to_entityset_cache[cache_key] = "accounts"
@@ -716,6 +717,7 @@ def mock_entity_set(table_schema_name):
716717

717718
def test_cache_miss_no_primary_id_raises_runtime_error(self):
718719
"""Cache miss with no PrimaryIdAttribute in metadata raises RuntimeError."""
720+
719721
def mock_entity_set_no_pid(table_schema_name):
720722
cache_key = table_schema_name.lower()
721723
self.od._logical_to_entityset_cache[cache_key] = "accounts"
@@ -820,11 +822,9 @@ def test_empty_list_raises_type_error(self):
820822
def test_odata_type_already_present_not_overridden(self):
821823
"""If all records have @odata.type, it is preserved."""
822824
self.od._request.return_value = _mock_response()
823-
records = [
824-
{"@odata.type": "Microsoft.Dynamics.CRM.CustomType", "accountid": "id-1", "name": "A"}
825-
]
825+
records = [{"@odata.type": "Microsoft.Dynamics.CRM.CustomType", "accountid": "id-1", "name": "A"}]
826826
self.od._update_multiple("accounts", "account", records)
827-
payload = self.od._request.call_args.kwargs["json"]
827+
payload = json.loads(self.od._request.call_args.kwargs["data"])
828828
self.assertEqual(payload["Targets"][0]["@odata.type"], "Microsoft.Dynamics.CRM.CustomType")
829829

830830
def test_posts_to_update_multiple_endpoint(self):
@@ -839,7 +839,7 @@ def test_payload_contains_targets_array(self):
839839
"""_update_multiple sends {"Targets": [...]} with @odata.type injected per record."""
840840
self.od._request.return_value = _mock_response()
841841
self.od._update_multiple("accounts", "account", [{"accountid": "id-1", "name": "X"}])
842-
payload = self.od._request.call_args.kwargs["json"]
842+
payload = json.loads(self.od._request.call_args.kwargs["data"])
843843
self.assertIn("Targets", payload)
844844
self.assertEqual(len(payload["Targets"]), 1)
845845
self.assertIn("@odata.type", payload["Targets"][0])
@@ -866,15 +866,13 @@ def test_filters_out_falsy_ids(self):
866866

867867
def test_posts_bulk_delete_payload(self):
868868
"""_delete_multiple issues POST to BulkDelete with correct payload."""
869-
self.od._request.return_value = _mock_response(
870-
json_data={"JobId": "job-001"}, text='{"JobId": "job-001"}'
871-
)
869+
self.od._request.return_value = _mock_response(json_data={"JobId": "job-001"}, text='{"JobId": "job-001"}')
872870
result = self.od._delete_multiple("account", ["id-1", "id-2"])
873871
self.assertEqual(result, "job-001")
874872
call_args = self.od._request.call_args
875873
self.assertEqual(call_args.args[0], "post")
876874
self.assertIn("BulkDelete", call_args.args[1])
877-
payload = call_args.kwargs["json"]
875+
payload = json.loads(call_args.kwargs["data"])
878876
self.assertIn("QuerySet", payload)
879877
self.assertIn("JobName", payload)
880878
query = payload["QuerySet"][0]
@@ -1149,6 +1147,7 @@ def setUp(self):
11491147

11501148
def _setup_entity_creation(self, get_response=None):
11511149
"""Mock _request: POST returns 201, GET returns entity definition."""
1150+
11521151
def side_effect(method, url, **kwargs):
11531152
if method == "post":
11541153
return _mock_response(status_code=201)
@@ -1324,6 +1323,7 @@ def setUp(self):
13241323

13251324
def test_empty_enum_raises_value_error(self):
13261325
"""_enum_optionset_payload raises ValueError for enum with no members."""
1326+
13271327
class EmptyEnum(Enum):
13281328
pass
13291329

@@ -1333,6 +1333,7 @@ class EmptyEnum(Enum):
13331333

13341334
def test_int_key_in_labels_resolved_to_member_name(self):
13351335
"""__labels__ with int keys (matching enum values) are resolved to member names."""
1336+
13361337
class Status(Enum):
13371338
Active = 1
13381339
Inactive = 2
@@ -1343,6 +1344,7 @@ class Status(Enum):
13431344

13441345
def test_enum_member_object_as_labels_key(self):
13451346
"""__labels__ with enum member objects as keys resolves member name."""
1347+
13461348
class Status(Enum):
13471349
Active = 1
13481350
Inactive = 2
@@ -1359,6 +1361,7 @@ class Status(Enum):
13591361

13601362
def test_int_key_not_matching_any_member_raises_value_error(self):
13611363
"""__labels__ with int key not matching any member raises ValueError."""
1364+
13621365
class Status(Enum):
13631366
Active = 1
13641367

@@ -1369,6 +1372,7 @@ class Status(Enum):
13691372

13701373
def test_duplicate_enum_values_raises_value_error(self):
13711374
"""_enum_optionset_payload raises ValueError when two members share the same int value."""
1375+
13721376
# Python treats second definition as an alias; __members__ exposes both names
13731377
class Status(Enum):
13741378
Active = 1
@@ -1380,6 +1384,7 @@ class Status(Enum):
13801384

13811385
def test_non_int_enum_value_raises_value_error(self):
13821386
"""_enum_optionset_payload raises ValueError for enum member with a non-int value."""
1387+
13831388
class Status(Enum):
13841389
Active = "active"
13851390

@@ -1552,7 +1557,10 @@ def test_step2_option_with_non_int_value_skipped(self):
15521557
json_data={
15531558
"OptionSet": {
15541559
"Options": [
1555-
{"Value": "not-an-int", "Label": {"LocalizedLabels": [{"Label": "Active", "LanguageCode": 1033}]}},
1560+
{
1561+
"Value": "not-an-int",
1562+
"Label": {"LocalizedLabels": [{"Label": "Active", "LanguageCode": 1033}]},
1563+
},
15561564
{"Value": 2, "Label": {"LocalizedLabels": [{"Label": "Inactive", "LanguageCode": 1033}]}},
15571565
]
15581566
}
@@ -1623,53 +1631,66 @@ def setUp(self):
16231631
self.od = _make_odata_client()
16241632

16251633
def test_int_dtype(self):
1634+
"""'int' produces IntegerAttributeMetadata."""
16261635
result = self.od._attribute_payload("new_Count", "int")
16271636
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.IntegerAttributeMetadata")
16281637

16291638
def test_integer_dtype_alias(self):
1639+
"""'integer' is an alias for 'int'."""
16301640
result = self.od._attribute_payload("new_Count", "integer")
16311641
self.assertIn("Integer", result["@odata.type"])
16321642

16331643
def test_decimal_dtype(self):
1644+
"""'decimal' produces DecimalAttributeMetadata."""
16341645
result = self.od._attribute_payload("new_Price", "decimal")
16351646
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.DecimalAttributeMetadata")
16361647

16371648
def test_money_dtype_alias(self):
1649+
"""'money' is an alias for 'decimal'."""
16381650
result = self.od._attribute_payload("new_Revenue", "money")
16391651
self.assertIn("Decimal", result["@odata.type"])
16401652

16411653
def test_float_dtype(self):
1654+
"""'float' produces DoubleAttributeMetadata."""
16421655
result = self.od._attribute_payload("new_Score", "float")
16431656
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.DoubleAttributeMetadata")
16441657

16451658
def test_double_dtype_alias(self):
1659+
"""'double' is an alias for 'float'."""
16461660
result = self.od._attribute_payload("new_Score", "double")
16471661
self.assertIn("Double", result["@odata.type"])
16481662

16491663
def test_datetime_dtype(self):
1664+
"""'datetime' produces DateTimeAttributeMetadata."""
16501665
result = self.od._attribute_payload("new_CreatedDate", "datetime")
16511666
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.DateTimeAttributeMetadata")
16521667

16531668
def test_date_dtype_alias(self):
1669+
"""'date' is an alias for 'datetime'."""
16541670
result = self.od._attribute_payload("new_BirthDate", "date")
16551671
self.assertIn("DateTime", result["@odata.type"])
16561672

16571673
def test_bool_dtype(self):
1674+
"""'bool' produces BooleanAttributeMetadata."""
16581675
result = self.od._attribute_payload("new_IsActive", "bool")
16591676
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.BooleanAttributeMetadata")
16601677

16611678
def test_boolean_dtype_alias(self):
1679+
"""'boolean' is an alias for 'bool'."""
16621680
result = self.od._attribute_payload("new_IsActive", "boolean")
16631681
self.assertIn("Boolean", result["@odata.type"])
16641682

16651683
def test_file_dtype(self):
1684+
"""'file' produces FileAttributeMetadata."""
16661685
result = self.od._attribute_payload("new_Attachment", "file")
16671686
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.FileAttributeMetadata")
16681687

16691688
def test_unsupported_dtype_returns_none(self):
1689+
"""Unrecognized dtype string returns None."""
16701690
self.assertIsNone(self.od._attribute_payload("new_Unknown", "unsupported_type"))
16711691

16721692
def test_non_string_dtype_raises_value_error(self):
1693+
"""Non-string dtype raises ValueError."""
16731694
with self.assertRaises(ValueError):
16741695
self.od._attribute_payload("new_Field", 42) # type: ignore[arg-type]
16751696

@@ -1916,9 +1937,11 @@ def test_table_not_found_raises_metadata_error(self):
19161937
with self.assertRaises(MetadataError):
19171938
self.od._create_columns("new_NonExistent", {"new_Col": "string"})
19181939

1919-
def test_unsupported_column_type_raises_value_error(self):
1920-
"""_create_columns raises ValueError for unsupported column type."""
1921-
with self.assertRaises(ValueError):
1940+
def test_unsupported_column_type_raises_validation_error(self):
1941+
"""Raises ValidationError for unsupported column type."""
1942+
from PowerPlatform.Dataverse.core.errors import ValidationError
1943+
1944+
with self.assertRaises(ValidationError):
19221945
self.od._create_columns("new_Test", {"new_Col": "unsupported"})
19231946

19241947
def test_picklist_column_flushes_cache(self):
@@ -1995,7 +2018,11 @@ def test_missing_metadata_id_raises_runtime_error(self):
19952018
def test_picklist_column_deletion_flushes_cache(self):
19962019
"""_delete_columns flushes picklist cache when a picklist column is deleted."""
19972020
self.od._get_attribute_metadata = MagicMock(
1998-
return_value={"MetadataId": "attr-001", "LogicalName": "new_status", "@odata.type": "PicklistAttributeMetadata"}
2021+
return_value={
2022+
"MetadataId": "attr-001",
2023+
"LogicalName": "new_status",
2024+
"@odata.type": "PicklistAttributeMetadata",
2025+
}
19992026
)
20002027
self.od._flush_cache = MagicMock(return_value=0)
20012028
self.od._delete_columns("new_Test", "new_Status")

0 commit comments

Comments
 (0)