@@ -63,7 +63,7 @@ def test_build_headers_json_body(self, http_client, patched_version_and_sys):
6363 "X-Nylas-API-Wrapper" : "python" ,
6464 "User-Agent" : "Nylas Python SDK 2.0.0 - 1.2.3" ,
6565 "Authorization" : "Bearer test-key" ,
66- "Content-type" : "application/json" ,
66+ "Content-type" : "application/json; charset=utf-8 " ,
6767 }
6868
6969 def test_build_headers_form_body (self , http_client , patched_version_and_sys ):
@@ -200,7 +200,7 @@ def test_execute_download_request_override_timeout(
200200 "X-Nylas-API-Wrapper" : "python" ,
201201 "User-Agent" : "Nylas Python SDK 2.0.0 - 1.2.3" ,
202202 "Authorization" : "Bearer test-key" ,
203- "Content-type" : "application/json" ,
203+ "Content-type" : "application/json; charset=utf-8 " ,
204204 },
205205 timeout = 60 ,
206206 stream = False ,
@@ -299,12 +299,11 @@ def test_execute(self, http_client, patched_version_and_sys, patched_request):
299299 "X-Nylas-API-Wrapper" : "python" ,
300300 "User-Agent" : "Nylas Python SDK 2.0.0 - 1.2.3" ,
301301 "Authorization" : "Bearer test-key" ,
302- "Content-type" : "application/json" ,
302+ "Content-type" : "application/json; charset=utf-8 " ,
303303 "test" : "header" ,
304304 },
305- json = {"foo" : "bar" },
305+ data = ' {"foo": "bar"}' ,
306306 timeout = 30 ,
307- data = None ,
308307 )
309308
310309 def test_execute_override_timeout (
@@ -334,12 +333,11 @@ def test_execute_override_timeout(
334333 "X-Nylas-API-Wrapper" : "python" ,
335334 "User-Agent" : "Nylas Python SDK 2.0.0 - 1.2.3" ,
336335 "Authorization" : "Bearer test-key" ,
337- "Content-type" : "application/json" ,
336+ "Content-type" : "application/json; charset=utf-8 " ,
338337 "test" : "header" ,
339338 },
340- json = {"foo" : "bar" },
339+ data = ' {"foo": "bar"}' ,
341340 timeout = 60 ,
342- data = None ,
343341 )
344342
345343 def test_execute_timeout (self , http_client , mock_session_timeout ):
@@ -425,10 +423,122 @@ def test_execute_with_headers(self, http_client, patched_version_and_sys, patche
425423 "X-Nylas-API-Wrapper" : "python" ,
426424 "User-Agent" : "Nylas Python SDK 2.0.0 - 1.2.3" ,
427425 "Authorization" : "Bearer test-key" ,
428- "Content-type" : "application/json" ,
426+ "Content-type" : "application/json; charset=utf-8 " ,
429427 "test" : "header" ,
430428 },
431- json = {"foo" : "bar" },
429+ data = ' {"foo": "bar"}' ,
432430 timeout = 30 ,
433- data = None ,
434431 )
432+
433+ def test_execute_with_utf8_characters (self , http_client , patched_version_and_sys , patched_request ):
434+ """Test that UTF-8 characters are preserved in JSON requests (not escaped)."""
435+ mock_response = Mock ()
436+ mock_response .json .return_value = {"success" : True }
437+ mock_response .headers = {"X-Test-Header" : "test" }
438+ mock_response .status_code = 200
439+ patched_request .return_value = mock_response
440+
441+ # Request with special characters
442+ request_body = {
443+ "title" : "Réunion d'équipe" ,
444+ "description" : "De l'idée à la post-prod, sans friction" ,
445+ "location" : "café" ,
446+ }
447+
448+ response_json , response_headers = http_client ._execute (
449+ method = "POST" ,
450+ path = "/events" ,
451+ request_body = request_body ,
452+ )
453+
454+ assert response_json == {"success" : True }
455+ # Verify that the data sent preserves UTF-8 characters (not escaped)
456+ call_kwargs = patched_request .call_args [1 ]
457+ assert "data" in call_kwargs
458+ sent_data = call_kwargs ["data" ]
459+
460+ # The JSON should contain actual UTF-8 characters, not escape sequences
461+ assert "Réunion d'équipe" in sent_data
462+ assert "De l'idée à la post-prod" in sent_data
463+ assert "café" in sent_data
464+ # Should NOT contain unicode escape sequences
465+ assert "\\ u" not in sent_data
466+
467+ def test_execute_with_none_request_body (self , http_client , patched_version_and_sys , patched_request ):
468+ """Test that None request_body is handled correctly."""
469+ mock_response = Mock ()
470+ mock_response .json .return_value = {"success" : True }
471+ mock_response .headers = {"X-Test-Header" : "test" }
472+ mock_response .status_code = 200
473+ patched_request .return_value = mock_response
474+
475+ response_json , response_headers = http_client ._execute (
476+ method = "GET" ,
477+ path = "/events" ,
478+ request_body = None ,
479+ )
480+
481+ assert response_json == {"success" : True }
482+ # Verify that data is None when request_body is None
483+ call_kwargs = patched_request .call_args [1 ]
484+ assert "data" in call_kwargs
485+ assert call_kwargs ["data" ] is None
486+
487+ def test_execute_with_emoji_and_international_characters (self , http_client , patched_version_and_sys , patched_request ):
488+ """Test that emoji and various international characters are preserved."""
489+ mock_response = Mock ()
490+ mock_response .json .return_value = {"success" : True }
491+ mock_response .headers = {"X-Test-Header" : "test" }
492+ mock_response .status_code = 200
493+ patched_request .return_value = mock_response
494+
495+ request_body = {
496+ "emoji" : "🎉 Party time! 🥳" ,
497+ "japanese" : "こんにちは" ,
498+ "chinese" : "你好" ,
499+ "russian" : "Привет" ,
500+ "german" : "Größe" ,
501+ "spanish" : "¿Cómo estás?" ,
502+ }
503+
504+ response_json , response_headers = http_client ._execute (
505+ method = "POST" ,
506+ path = "/messages" ,
507+ request_body = request_body ,
508+ )
509+
510+ assert response_json == {"success" : True }
511+ call_kwargs = patched_request .call_args [1 ]
512+ sent_data = call_kwargs ["data" ]
513+
514+ # All characters should be preserved
515+ assert "🎉 Party time! 🥳" in sent_data
516+ assert "こんにちは" in sent_data
517+ assert "你好" in sent_data
518+ assert "Привет" in sent_data
519+ assert "Größe" in sent_data
520+ assert "¿Cómo estás?" in sent_data
521+
522+ def test_execute_with_multipart_data_not_affected (self , http_client , patched_version_and_sys , patched_request ):
523+ """Test that multipart/form-data is not affected by the change."""
524+ mock_response = Mock ()
525+ mock_response .json .return_value = {"success" : True }
526+ mock_response .headers = {"X-Test-Header" : "test" }
527+ mock_response .status_code = 200
528+ patched_request .return_value = mock_response
529+
530+ # When data is provided (multipart), request_body should be ignored
531+ mock_data = Mock ()
532+ mock_data .content_type = "multipart/form-data"
533+
534+ response_json , response_headers = http_client ._execute (
535+ method = "POST" ,
536+ path = "/messages/send" ,
537+ request_body = {"foo" : "bar" }, # This should be ignored
538+ data = mock_data ,
539+ )
540+
541+ assert response_json == {"success" : True }
542+ call_kwargs = patched_request .call_args [1 ]
543+ # Should use the multipart data, not JSON
544+ assert call_kwargs ["data" ] == mock_data
0 commit comments