11from datetime import datetime , timezone
22import json
3+ from typing import Any
34
45from nonebot .adapters .discord .api import (
56 ActionRow ,
1617)
1718from nonebot .adapters .discord .api .types import UNSET
1819from nonebot .adapters .discord .api .utils import parse_data , parse_forum_thread_message
19- from nonebot .adapters .discord .serialization import encode_prepared_request
20+ from nonebot .adapters .discord .serialization import (
21+ PreparedRequest ,
22+ encode_prepared_request ,
23+ )
2024from nonebot .adapters .discord .utils import omit_unset
2125
2226
27+ def _json_payload (prepared : PreparedRequest ) -> dict [str , Any ]:
28+ encoded = encode_prepared_request (prepared )
29+ assert "json" in encoded
30+ return encoded ["json" ]
31+
32+
33+ def _payload_json_text (prepared : PreparedRequest ) -> str :
34+ encoded = encode_prepared_request (prepared )
35+ assert "files" in encoded
36+ payload_json = encoded ["files" ]["payload_json" ]
37+ assert isinstance (payload_json , tuple )
38+ assert len (payload_json ) >= 2
39+ payload_body = payload_json [1 ]
40+ assert isinstance (payload_body , (bytes , str ))
41+ return payload_body .decode () if isinstance (payload_body , bytes ) else payload_body
42+
43+
2344def _assert_transport_datetime (actual : str , expected : datetime ) -> None :
2445 assert datetime .fromisoformat (actual .replace ("Z" , "+00:00" )) == expected
2546
2647
2748def test_parse_data_keeps_explicit_null () -> None :
28- payload = encode_prepared_request (parse_data ({"content" : None }, MessageEditParams ))[
29- "json"
30- ]
49+ payload = _json_payload (parse_data ({"content" : None }, MessageEditParams ))
3150 assert payload == {"content" : None }
3251
3352
3453def test_parse_data_omits_unset () -> None :
35- payload = encode_prepared_request (
36- parse_data ({"content" : UNSET }, MessageEditParams )
37- )["json" ]
54+ payload = _json_payload (parse_data ({"content" : UNSET }, MessageEditParams ))
3855 assert payload == {}
3956
4057
@@ -44,61 +61,59 @@ def test_omit_unset_filters_unset_in_list() -> None:
4461
4562
4663def test_parse_data_message_send_omits_unset_fields () -> None :
47- payload = encode_prepared_request (parse_data ({}, MessageSend ))[ "json" ]
64+ payload = _json_payload (parse_data ({}, MessageSend ))
4865 assert payload == {}
4966
5067
5168def test_parse_data_execute_webhook_omits_unset_fields () -> None :
52- payload = encode_prepared_request (parse_data ({}, ExecuteWebhookParams ))[ "json" ]
69+ payload = _json_payload (parse_data ({}, ExecuteWebhookParams ))
5370 assert payload == {}
5471
5572
5673def test_parse_data_serializes_embed_timestamp () -> None :
5774 timestamp = datetime (2026 , 3 , 14 , 12 , 0 , tzinfo = timezone .utc )
58- payload = encode_prepared_request (
75+ payload = _json_payload (
5976 parse_data (
6077 {"embeds" : [Embed (timestamp = timestamp )]},
6178 MessageSend ,
6279 )
63- )[ "json" ]
80+ )
6481
6582 _assert_transport_datetime (payload ["embeds" ][0 ]["timestamp" ], timestamp )
6683
6784
6885def test_parse_data_multipart_keeps_null_attachments () -> None :
69- res = encode_prepared_request (
70- parse_data (
71- {
72- "files" : [File (content = b"1" , filename = "a.txt" )],
73- "attachments" : None ,
74- },
75- MessageEditParams ,
86+ payload = json .loads (
87+ _payload_json_text (
88+ parse_data (
89+ {
90+ "files" : [File (content = b"1" , filename = "a.txt" )],
91+ "attachments" : None ,
92+ },
93+ MessageEditParams ,
94+ )
7695 )
7796 )
78- multipart = res ["files" ]
79- _ , payload_json , _ = multipart ["payload_json" ]
80- payload = json .loads (payload_json )
8197 assert payload ["attachments" ] is None
8298
8399
84100def test_parse_data_multipart_maps_attachment_id () -> None :
85- res = encode_prepared_request (
86- parse_data (
87- {
88- "files" : [File (content = b"1" , filename = "a.txt" )],
89- "attachments" : [{"filename" : "a.txt" }],
90- },
91- MessageEditParams ,
101+ payload = json .loads (
102+ _payload_json_text (
103+ parse_data (
104+ {
105+ "files" : [File (content = b"1" , filename = "a.txt" )],
106+ "attachments" : [{"filename" : "a.txt" }],
107+ },
108+ MessageEditParams ,
109+ )
92110 )
93111 )
94- multipart = res ["files" ]
95- _ , payload_json , _ = multipart ["payload_json" ]
96- payload = json .loads (payload_json )
97112 assert payload ["attachments" ][0 ]["id" ] == 0
98113
99114
100115def test_parse_data_keeps_action_row_type_for_components () -> None :
101- payload = encode_prepared_request (
116+ payload = _json_payload (
102117 parse_data (
103118 {
104119 "components" : [
@@ -115,54 +130,50 @@ def test_parse_data_keeps_action_row_type_for_components() -> None:
115130 },
116131 MessageSend ,
117132 )
118- )[ "json" ]
133+ )
119134 assert "content" not in payload
120135 assert int (payload ["components" ][0 ]["type" ]) == int (ComponentType .ActionRow )
121136
122137
123138def test_parse_forum_thread_message_keeps_name () -> None :
124- payload = encode_prepared_request (
139+ payload = _json_payload (
125140 parse_forum_thread_message ({"name" : "thread-name" , "content" : "hello" })
126- )[ "json" ]
141+ )
127142 assert payload ["name" ] == "thread-name"
128143
129144
130145def test_parse_forum_thread_message_without_content () -> None :
131- payload = encode_prepared_request (
132- parse_forum_thread_message ({"name" : "thread-name" })
133- )["json" ]
146+ payload = _json_payload (parse_forum_thread_message ({"name" : "thread-name" }))
134147 assert payload ["message" ] == {}
135148
136149
137150def test_parse_forum_thread_message_serializes_embed_timestamp_in_multipart () -> None :
138151 timestamp = datetime (2026 , 3 , 14 , 12 , 0 , tzinfo = timezone .utc )
139- res = encode_prepared_request (
140- parse_forum_thread_message (
141- {
142- "name" : "thread-name" ,
143- "files" : [File (content = b"1" , filename = "a.txt" )],
144- "embeds" : [Embed (timestamp = timestamp )],
145- }
152+ payload = json .loads (
153+ _payload_json_text (
154+ parse_forum_thread_message (
155+ {
156+ "name" : "thread-name" ,
157+ "files" : [File (content = b"1" , filename = "a.txt" )],
158+ "embeds" : [Embed (timestamp = timestamp )],
159+ }
160+ )
146161 )
147162 )
148- multipart = res ["files" ]
149- _ , payload_json , _ = multipart ["payload_json" ]
150- payload = json .loads (payload_json )
151163
152164 _assert_transport_datetime (payload ["message" ]["embeds" ][0 ]["timestamp" ], timestamp )
153165
154166
155167def test_parse_forum_thread_message_maps_message_attachment_id () -> None :
156- res = encode_prepared_request (
157- parse_forum_thread_message (
158- {
159- "name" : "thread-name" ,
160- "files" : [File (content = b"1" , filename = "a.txt" )],
161- "attachments" : [{"filename" : "a.txt" }],
162- }
168+ payload = json .loads (
169+ _payload_json_text (
170+ parse_forum_thread_message (
171+ {
172+ "name" : "thread-name" ,
173+ "files" : [File (content = b"1" , filename = "a.txt" )],
174+ "attachments" : [{"filename" : "a.txt" }],
175+ }
176+ )
163177 )
164178 )
165- multipart = res ["files" ]
166- _ , payload_json , _ = multipart ["payload_json" ]
167- payload = json .loads (payload_json )
168179 assert payload ["message" ]["attachments" ][0 ]["id" ] == 0
0 commit comments