@@ -45,7 +45,7 @@ async def test_create_or_update_creates_when_no_match(configured_client: None) -
4545 result = await client .create_or_update (
4646 typename = "customer" ,
4747 match = {"external_id" : "abc" },
48- data = {"name" : "John" },
48+ create_data = {"name" : "John" },
4949 on_multiple = OnMultiple .ERROR ,
5050 )
5151
@@ -55,6 +55,86 @@ async def test_create_or_update_creates_when_no_match(configured_client: None) -
5555 assert create_route .call_count == 1
5656
5757
58+ @respx .mock
59+ async def test_create_or_update_with_both_create_and_update_data_creates (configured_client : None ) -> None :
60+ """Test that create_data is used when creating, not update_data."""
61+ import json
62+
63+ respx .get ("https://test.example.com/customer" ).mock (
64+ return_value = httpx .Response (200 , json = {"response" : {"results" : [], "count" : 0 , "remaining" : 0 }})
65+ )
66+ create_route = respx .post ("https://test.example.com/customer" ).mock (
67+ return_value = httpx .Response (200 , json = {"status" : "success" , "id" : "new123" })
68+ )
69+
70+ async with RawClient () as client :
71+ result = await client .create_or_update (
72+ typename = "customer" ,
73+ match = {"external_id" : "abc" },
74+ create_data = {"status" : "new" , "created_by" : "system" },
75+ update_data = {"status" : "active" , "last_seen" : "2024-01-01" },
76+ on_multiple = OnMultiple .ERROR ,
77+ )
78+
79+ assert result ["created" ] is True
80+ assert result ["uids" ] == ["new123" ]
81+ # verify create was called with match + create_data (not update_data)
82+ request_body = json .loads (create_route .calls [0 ].request .content )
83+ assert request_body == {"external_id" : "abc" , "status" : "new" , "created_by" : "system" }
84+
85+
86+ @respx .mock
87+ async def test_create_or_update_with_both_create_and_update_data_updates (configured_client : None ) -> None :
88+ """Test that update_data is used when updating, not create_data."""
89+ import json
90+
91+ respx .get ("https://test.example.com/customer" ).mock (
92+ return_value = httpx .Response (
93+ 200 , json = {"response" : {"results" : [{"_id" : "existing123" }], "count" : 1 , "remaining" : 0 }}
94+ )
95+ )
96+ update_route = respx .patch ("https://test.example.com/customer/existing123" ).mock (return_value = httpx .Response (204 ))
97+
98+ async with RawClient () as client :
99+ result = await client .create_or_update (
100+ typename = "customer" ,
101+ match = {"external_id" : "abc" },
102+ create_data = {"status" : "new" , "created_by" : "system" },
103+ update_data = {"status" : "active" , "last_seen" : "2024-01-01" },
104+ on_multiple = OnMultiple .ERROR ,
105+ )
106+
107+ assert result ["created" ] is False
108+ assert result ["uids" ] == ["existing123" ]
109+ # verify update was called with update_data (not create_data)
110+ request_body = json .loads (update_route .calls [0 ].request .content )
111+ assert request_body == {"status" : "active" , "last_seen" : "2024-01-01" }
112+
113+
114+ @respx .mock
115+ async def test_create_or_update_with_only_create_data_skips_update (configured_client : None ) -> None :
116+ """Test that when only create_data is provided, updates are skipped."""
117+ find_route = respx .get ("https://test.example.com/customer" ).mock (
118+ return_value = httpx .Response (
119+ 200 , json = {"response" : {"results" : [{"_id" : "existing123" }], "count" : 1 , "remaining" : 0 }}
120+ )
121+ )
122+ # no update route - should not be called
123+
124+ async with RawClient () as client :
125+ result = await client .create_or_update (
126+ typename = "customer" ,
127+ match = {"external_id" : "abc" },
128+ create_data = {"status" : "new" },
129+ on_multiple = OnMultiple .ERROR ,
130+ )
131+
132+ assert result ["created" ] is False
133+ assert result ["uids" ] == ["existing123" ]
134+ assert find_route .call_count == 1
135+ # no PATCH call should have been made
136+
137+
58138@respx .mock
59139async def test_create_or_update_updates_when_single_match (configured_client : None ) -> None :
60140 """Test that create_or_update updates when exactly one match is found."""
@@ -71,7 +151,7 @@ async def test_create_or_update_updates_when_single_match(configured_client: Non
71151 result = await client .create_or_update (
72152 typename = "customer" ,
73153 match = {"external_id" : "abc" },
74- data = {"name" : "John" },
154+ update_data = {"name" : "John" },
75155 on_multiple = OnMultiple .ERROR ,
76156 )
77157
@@ -103,7 +183,7 @@ async def test_create_or_update_error_on_multiple_matches(configured_client: Non
103183 await client .create_or_update (
104184 typename = "customer" ,
105185 match = {"external_id" : "abc" },
106- data = {"name" : "John" },
186+ update_data = {"name" : "John" },
107187 on_multiple = OnMultiple .ERROR ,
108188 )
109189
@@ -132,7 +212,7 @@ async def test_create_or_update_update_first(configured_client: None) -> None:
132212 result = await client .create_or_update (
133213 typename = "customer" ,
134214 match = {"external_id" : "abc" },
135- data = {"name" : "John" },
215+ update_data = {"name" : "John" },
136216 on_multiple = OnMultiple .UPDATE_FIRST ,
137217 )
138218
@@ -164,7 +244,7 @@ async def test_create_or_update_update_all(configured_client: None) -> None:
164244 result = await client .create_or_update (
165245 typename = "customer" ,
166246 match = {"external_id" : "abc" },
167- data = {"name" : "John" },
247+ update_data = {"name" : "John" },
168248 on_multiple = OnMultiple .UPDATE_ALL ,
169249 )
170250
@@ -199,7 +279,7 @@ async def test_create_or_update_dedupe_oldest_created(configured_client: None) -
199279 result = await client .create_or_update (
200280 typename = "customer" ,
201281 match = {"external_id" : "abc" },
202- data = {"name" : "John" },
282+ update_data = {"name" : "John" },
203283 on_multiple = OnMultiple .DEDUPE_OLDEST_CREATED ,
204284 )
205285
@@ -234,7 +314,7 @@ async def test_create_or_update_dedupe_newest_created(configured_client: None) -
234314 result = await client .create_or_update (
235315 typename = "customer" ,
236316 match = {"external_id" : "abc" },
237- data = {"name" : "John" },
317+ update_data = {"name" : "John" },
238318 on_multiple = OnMultiple .DEDUPE_NEWEST_CREATED ,
239319 )
240320
@@ -269,7 +349,7 @@ async def test_create_or_update_dedupe_oldest_modified(configured_client: None)
269349 result = await client .create_or_update (
270350 typename = "customer" ,
271351 match = {"external_id" : "abc" },
272- data = {"name" : "John" },
352+ update_data = {"name" : "John" },
273353 on_multiple = OnMultiple .DEDUPE_OLDEST_MODIFIED ,
274354 )
275355
@@ -304,7 +384,7 @@ async def test_create_or_update_dedupe_newest_modified(configured_client: None)
304384 result = await client .create_or_update (
305385 typename = "customer" ,
306386 match = {"external_id" : "abc" },
307- data = {"name" : "John" },
387+ update_data = {"name" : "John" },
308388 on_multiple = OnMultiple .DEDUPE_NEWEST_MODIFIED ,
309389 )
310390
@@ -322,7 +402,7 @@ async def test_create_or_update_invalid_on_multiple(configured_client: None) ->
322402 await client .create_or_update (
323403 typename = "customer" ,
324404 match = {"external_id" : "abc" },
325- data = {"name" : "John" },
405+ update_data = {"name" : "John" },
326406 on_multiple = "invalid" , # type: ignore[arg-type]
327407 )
328408
@@ -334,19 +414,18 @@ async def test_create_or_update_empty_match_raises(configured_client: None) -> N
334414 await client .create_or_update (
335415 typename = "customer" ,
336416 match = {},
337- data = {"name" : "John" },
417+ update_data = {"name" : "John" },
338418 on_multiple = OnMultiple .ERROR ,
339419 )
340420
341421
342- async def test_create_or_update_empty_data_raises (configured_client : None ) -> None :
343- """Test that empty data dict raises ValueError."""
422+ async def test_create_or_update_no_data_raises (configured_client : None ) -> None :
423+ """Test that no data provided raises ValueError."""
344424 async with RawClient () as client :
345- with pytest .raises (ValueError , match = "data cannot be empty " ):
425+ with pytest .raises (ValueError , match = "at least one of create_data or update_data must be provided " ):
346426 await client .create_or_update (
347427 typename = "customer" ,
348428 match = {"external_id" : "abc" },
349- data = {},
350429 on_multiple = OnMultiple .ERROR ,
351430 )
352431
@@ -378,7 +457,7 @@ async def test_create_or_update_update_all_partial_failure(configured_client: No
378457 await client .create_or_update (
379458 typename = "customer" ,
380459 match = {"external_id" : "abc" },
381- data = {"name" : "John" },
460+ update_data = {"name" : "John" },
382461 on_multiple = OnMultiple .UPDATE_ALL ,
383462 )
384463
@@ -417,7 +496,7 @@ async def test_create_or_update_dedupe_partial_delete_failure(configured_client:
417496 await client .create_or_update (
418497 typename = "customer" ,
419498 match = {"external_id" : "abc" },
420- data = {"name" : "John" },
499+ update_data = {"name" : "John" },
421500 on_multiple = OnMultiple .DEDUPE_OLDEST_CREATED ,
422501 )
423502
0 commit comments