@@ -71,7 +71,7 @@ def test_rejects_none_configured_secret(self):
7171class TestWebhookEventHandling :
7272 @pytest .mark .asyncio
7373 async def test_client_handle_webhook_rejects_invalid_signature (self , client_for_webhook_tests ):
74- payload = {"type " : "something" }
74+ payload = {"event " : "something" }
7575 mock_req = make_req_for_client_test (payload ) # No signature
7676 with pytest .raises (WasenderAPIError , match = "Invalid webhook signature" ):
7777 await client_for_webhook_tests .handle_webhook_event (
@@ -81,7 +81,7 @@ async def test_client_handle_webhook_rejects_invalid_signature(self, client_for_
8181
8282 @pytest .mark .asyncio
8383 async def test_client_handle_webhook_rejects_incorrect_signature (self , client_for_webhook_tests ):
84- payload = {"type " : "something" }
84+ payload = {"event " : "something" }
8585 mock_req = make_req_for_client_test (payload , "wrongsecret" )
8686 with pytest .raises (WasenderAPIError , match = "Invalid webhook signature" ):
8787 await client_for_webhook_tests .handle_webhook_event (
@@ -96,20 +96,20 @@ async def test_client_handle_webhook_parses_valid_event(self, client_for_webhook
9696 "conversationTimestamp" : 1633456789 , "unreadCount" : 2
9797 }
9898 payload = {
99- "type " : WebhookEventType .CHATS_UPSERT .value ,
99+ "event " : WebhookEventType .CHATS_UPSERT .value ,
100100 "timestamp" : 1633456789 ,
101101 "data" : [chat_entry ],
102102 "sessionId" : "session-id-123"
103103 }
104104 mock_req = make_req_for_client_test (payload , SECRET )
105- evt = await client_for_webhook_tests .handle_webhook_event (
105+ payload = await client_for_webhook_tests .handle_webhook_event (
106106 request_body_bytes = mock_req .body ,
107107 signature_header = mock_req .headers .get (WEBHOOK_SIGNATURE_HEADER )
108108 )
109- assert evt . type == WebhookEventType .CHATS_UPSERT
110- assert evt .data [0 ].id == chat_entry ["id" ]
111- assert evt .timestamp == 1633456789
112- assert evt .session_id == "session-id-123"
109+ assert payload . event == WebhookEventType .CHATS_UPSERT
110+ assert payload .data [0 ].id == chat_entry ["id" ]
111+ assert payload .timestamp == 1633456789
112+ assert payload .session_id == "session-id-123"
113113
114114 # Tests for direct Pydantic model parsing
115115 def test_parses_chats_upsert_event_correctly_model (self ):
@@ -118,44 +118,44 @@ def test_parses_chats_upsert_event_correctly_model(self):
118118 "conversationTimestamp" : 1633456789 , "unreadCount" : 2
119119 }
120120 payload = {
121- "type " : WebhookEventType .CHATS_UPSERT .value ,
121+ "event " : WebhookEventType .CHATS_UPSERT .value ,
122122 "timestamp" : 1633456789 ,
123123 "data" : [chat_entry_data ],
124124 "sessionId" : "session-id-123"
125125 }
126126 adapter = TypeAdapter (WasenderWebhookEvent )
127- evt = adapter .validate_python (payload )
128- assert evt . type == WebhookEventType .CHATS_UPSERT
129- assert isinstance (evt .data , list )
130- assert evt .data [0 ].id == chat_entry_data ["id" ]
131- assert evt .data [0 ].name == chat_entry_data ["name" ]
132- assert evt .timestamp == 1633456789
133- assert evt .session_id == "session-id-123"
127+ payload = adapter .validate_python (payload )
128+ assert payload . event == WebhookEventType .CHATS_UPSERT
129+ assert isinstance (payload .data , list )
130+ assert payload .data [0 ].id == chat_entry_data ["id" ]
131+ assert payload .data [0 ].name == chat_entry_data ["name" ]
132+ assert payload .timestamp == 1633456789
133+ assert payload .session_id == "session-id-123"
134134
135135 def test_parses_chats_update_event_correctly_model (self ):
136136 chat_update_data = {
137137 "id" : "1234567890" , "unreadCount" : 0 , "conversationTimestamp" : 1633456789
138138 }
139139 payload = {
140- "type " : WebhookEventType .CHATS_UPDATE .value ,
140+ "event " : WebhookEventType .CHATS_UPDATE .value ,
141141 "timestamp" : 1633456789 ,
142142 "data" : [chat_update_data ]
143143 }
144144 adapter = TypeAdapter (WasenderWebhookEvent )
145- evt = adapter .validate_python (payload )
146- assert evt . type == WebhookEventType .CHATS_UPDATE
147- assert evt .data [0 ].unread_count == chat_update_data ["unreadCount" ]
145+ payload = adapter .validate_python (payload )
146+ assert payload . event == WebhookEventType .CHATS_UPDATE
147+ assert payload .data [0 ].unread_count == chat_update_data ["unreadCount" ]
148148
149149 def test_parses_chats_delete_event_correctly_model (self ):
150150 payload = {
151- "type " : WebhookEventType .CHATS_DELETE .value ,
151+ "event " : WebhookEventType .CHATS_DELETE .value ,
152152 "timestamp" : 1633456789 ,
153153 "data" : ["1234567890" ]
154154 }
155155 adapter = TypeAdapter (WasenderWebhookEvent )
156- evt = adapter .validate_python (payload )
157- assert evt . type == WebhookEventType .CHATS_DELETE
158- assert evt .data == ["1234567890" ]
156+ payload = adapter .validate_python (payload )
157+ assert payload . event == WebhookEventType .CHATS_DELETE
158+ assert payload .data == ["1234567890" ]
159159
160160 def test_parses_groups_upsert_event_correctly_model (self ):
161161 participant1_data = {
"id" :
"[email protected] " ,
"admin" :
"superadmin" }
@@ -171,17 +171,17 @@ def test_parses_groups_upsert_event_correctly_model(self):
171171 "participants" : [participant1_data , participant2_data , participant3_data ]
172172 }
173173 payload = {
174- "type " : WebhookEventType .GROUPS_UPSERT .value ,
174+ "event " : WebhookEventType .GROUPS_UPSERT .value ,
175175 "timestamp" : 1633456789 ,
176176 "data" : [group_data ]
177177 }
178178 adapter = TypeAdapter (WasenderWebhookEvent )
179- evt = adapter .validate_python (payload )
179+ payload = adapter .validate_python (payload )
180180
181- assert evt . type == WebhookEventType .GROUPS_UPSERT
182- assert isinstance (evt .data , list )
183- assert len (evt .data ) == 1
184- parsed_group_metadata = evt .data [0 ]
181+ assert payload . event == WebhookEventType .GROUPS_UPSERT
182+ assert isinstance (payload .data , list )
183+ assert len (payload .data ) == 1
184+ parsed_group_metadata = payload .data [0 ]
185185 assert isinstance (parsed_group_metadata , WebhookGroupMetadata )
186186 assert parsed_group_metadata .jid == group_data ["jid" ]
187187 assert parsed_group_metadata .subject == group_data ["subject" ]
@@ -201,59 +201,59 @@ def test_parses_groups_update_event_correctly_model(self):
201201 "restrict" : False
202202 }
203203 payload = {
204- "type " : WebhookEventType .GROUPS_UPDATE .value ,
204+ "event " : WebhookEventType .GROUPS_UPDATE .value ,
205205 "timestamp" : 1633456789 ,
206206 "data" : [group_update_data ]
207207 }
208208 adapter = TypeAdapter (WasenderWebhookEvent )
209- evt = adapter .validate_python (payload )
210- assert evt . type == WebhookEventType .GROUPS_UPDATE
211- assert evt .data [0 ].announce == group_update_data ["announce" ]
209+ payload = adapter .validate_python (payload )
210+ assert payload . event == WebhookEventType .GROUPS_UPDATE
211+ assert payload .data [0 ].announce == group_update_data ["announce" ]
212212
213213 def test_parses_group_participants_update_event_correctly_model (self ):
214214 participants_update_data = {
215215 "jid" :
"[email protected] " ,
"participants" : [
"1234567890" ],
"action" :
"add" 216216 }
217217 payload = {
218- "type " : WebhookEventType .GROUP_PARTICIPANTS_UPDATE .value ,
218+ "event " : WebhookEventType .GROUP_PARTICIPANTS_UPDATE .value ,
219219 "timestamp" : 1633456789 ,
220220 "data" : participants_update_data
221221 }
222222 adapter = TypeAdapter (WasenderWebhookEvent )
223- evt = adapter .validate_python (payload )
224- assert evt . type == WebhookEventType .GROUP_PARTICIPANTS_UPDATE
225- assert evt .data .action == participants_update_data ["action" ]
223+ payload = adapter .validate_python (payload )
224+ assert payload . event == WebhookEventType .GROUP_PARTICIPANTS_UPDATE
225+ assert payload .data .action == participants_update_data ["action" ]
226226
227227 def test_parses_contacts_upsert_event_correctly_model (self ):
228228 contact_data = {
229229 "jid" : "1234567890" , "name" : "Contact Name" , "notify" : "Contact Display Name" ,
230230 "verifiedName" : "Verified Business Name" , "status" : "Hey there! I am using WhatsApp."
231231 }
232232 payload = {
233- "type " : WebhookEventType .CONTACTS_UPSERT .value ,
233+ "event " : WebhookEventType .CONTACTS_UPSERT .value ,
234234 "timestamp" : 1633456789 ,
235235 "data" : [contact_data ]
236236 }
237237 adapter = TypeAdapter (WasenderWebhookEvent )
238- evt = adapter .validate_python (payload )
239- assert evt . type == WebhookEventType .CONTACTS_UPSERT
240- assert evt .data [0 ].verified_name == contact_data ["verifiedName" ]
238+ payload = adapter .validate_python (payload )
239+ assert payload . event == WebhookEventType .CONTACTS_UPSERT
240+ assert payload .data [0 ].verified_name == contact_data ["verifiedName" ]
241241
242242 def test_parses_contacts_update_event_correctly_model (self ):
243243 contact_update_data = {
244244 "jid" : "1234567890" ,
245245 "imgUrl" : "https://pps.whatsapp.net/v/t61.24694-24/some.jpg"
246246 }
247247 payload = {
248- "type " : WebhookEventType .CONTACTS_UPDATE .value ,
248+ "event " : WebhookEventType .CONTACTS_UPDATE .value ,
249249 "timestamp" : 1633456789 ,
250250 "data" : [contact_update_data ]
251251 }
252252 adapter = TypeAdapter (WasenderWebhookEvent )
253- evt = adapter .validate_python (payload )
254- assert evt . type == WebhookEventType .CONTACTS_UPDATE
255- assert evt .data [0 ].img_url == contact_update_data ["imgUrl" ]
256- assert evt .data [0 ].jid == contact_update_data ["jid" ]
253+ payload = adapter .validate_python (payload )
254+ assert payload . event == WebhookEventType .CONTACTS_UPDATE
255+ assert payload .data [0 ].img_url == contact_update_data ["imgUrl" ]
256+ assert payload .data [0 ].jid == contact_update_data ["jid" ]
257257
258258 def test_parses_messages_upsert_event_correctly_model (self ):
259259 message_key_data = {
"remoteJid" :
"[email protected] " ,
"id" :
"ABC" ,
"fromMe" :
False }
@@ -263,115 +263,115 @@ def test_parses_messages_upsert_event_correctly_model(self):
263263 "message" : message_content_data , "pushName" : "Sender Name"
264264 }
265265 payload = {
266- "type " : WebhookEventType .MESSAGES_UPSERT .value ,
266+ "event " : WebhookEventType .MESSAGES_UPSERT .value ,
267267 "timestamp" : 1633456789 ,
268268 "data" : messages_upsert_data # Note: Node.js data was List[MessageUpsertData]
269269 # Python model in webhook.py is MessagesUpsertData (singular)
270270 # Test adapted to singular data based on Python model def.
271271 }
272272 adapter = TypeAdapter (WasenderWebhookEvent )
273- evt = adapter .validate_python (payload )
274- assert evt . type == WebhookEventType .MESSAGES_UPSERT
275- assert evt .data .key .id == message_key_data ["id" ]
273+ payload = adapter .validate_python (payload )
274+ assert payload . event == WebhookEventType .MESSAGES_UPSERT
275+ assert payload .data .key .id == message_key_data ["id" ]
276276
277277 def test_parses_messages_update_event_correctly_model (self ):
278278 message_key_data = {
"remoteJid" :
"[email protected] " ,
"id" :
"ABC" ,
"fromMe" :
True }
279279 message_update_data = {"status" : "read" }
280280 messages_update_data_entry = {"key" : message_key_data , "update" : message_update_data }
281281 payload = {
282- "type " : WebhookEventType .MESSAGES_UPDATE .value ,
282+ "event " : WebhookEventType .MESSAGES_UPDATE .value ,
283283 "timestamp" : 1633456789 ,
284284 "data" : [messages_update_data_entry ]
285285 }
286286 adapter = TypeAdapter (WasenderWebhookEvent )
287- evt = adapter .validate_python (payload )
288- assert evt . type == WebhookEventType .MESSAGES_UPDATE
289- assert evt .data [0 ].key .id == message_key_data ["id" ]
290- assert evt .data [0 ].update .status == message_update_data ["status" ]
287+ payload = adapter .validate_python (payload )
288+ assert payload . event == WebhookEventType .MESSAGES_UPDATE
289+ assert payload .data [0 ].key .id == message_key_data ["id" ]
290+ assert payload .data [0 ].update .status == message_update_data ["status" ]
291291
292292 def test_parses_messages_delete_event_correctly_model (self ):
293293 message_key_data = {
"remoteJid" :
"[email protected] " ,
"id" :
"DEF" ,
"fromMe" :
False }
294294 payload = {
295- "type " : WebhookEventType .MESSAGES_DELETE .value ,
295+ "event " : WebhookEventType .MESSAGES_DELETE .value ,
296296 "timestamp" : 1633456789 ,
297297 "data" : {"keys" : [message_key_data ]}
298298 }
299299 adapter = TypeAdapter (WasenderWebhookEvent )
300- evt = adapter .validate_python (payload )
301- assert evt . type == WebhookEventType .MESSAGES_DELETE
302- assert evt .data .keys [0 ].id == message_key_data ["id" ]
300+ payload = adapter .validate_python (payload )
301+ assert payload . event == WebhookEventType .MESSAGES_DELETE
302+ assert payload .data .keys [0 ].id == message_key_data ["id" ]
303303
304304 def test_parses_message_sent_event_correctly_model (self ):
305305 message_sent_data = {
306306 "key" : {
"remoteJid" :
"[email protected] " ,
"id" :
"MSGID" ,
"fromMe" :
True },
# Added key to match model 307307 "status" : "sent" , "timestamp" : 1633456789
308308 }
309309 payload = {
310- "type " : WebhookEventType .MESSAGE_SENT .value ,
310+ "event " : WebhookEventType .MESSAGE_SENT .value ,
311311 "timestamp" : 1633456789 ,
312312 "data" : message_sent_data
313313 }
314314 adapter = TypeAdapter (WasenderWebhookEvent )
315- evt = adapter .validate_python (payload )
316- assert evt . type == WebhookEventType .MESSAGE_SENT
317- assert evt .data .status == message_sent_data ["status" ]
318- assert evt .data .key .id == message_sent_data ["key" ]["id" ]
315+ payload = adapter .validate_python (payload )
316+ assert payload . event == WebhookEventType .MESSAGE_SENT
317+ assert payload .data .status == message_sent_data ["status" ]
318+ assert payload .data .key .id == message_sent_data ["key" ]["id" ]
319319
320320 def test_parses_message_receipt_update_event_correctly_model (self ):
321321 receipt_data = {
"userJid" :
"[email protected] " ,
"status" :
"read" ,
"t" :
1633456800 }
322322 message_key_data = {
"remoteJid" :
"[email protected] " ,
"id" :
"MSGID" ,
"fromMe" :
True }
323323 message_receipt_update_data_entry = {"key" : message_key_data , "receipt" : receipt_data }
324324 payload = {
325- "type " : WebhookEventType .MESSAGE_RECEIPT_UPDATE .value ,
325+ "event " : WebhookEventType .MESSAGE_RECEIPT_UPDATE .value ,
326326 "timestamp" : 1633456789 ,
327327 "data" : [message_receipt_update_data_entry ] # Data is a list
328328 }
329329 adapter = TypeAdapter (WasenderWebhookEvent )
330- evt = adapter .validate_python (payload )
331- assert evt . type == WebhookEventType .MESSAGE_RECEIPT_UPDATE
332- assert evt .data [0 ].key .id == message_key_data ["id" ]
333- assert evt .data [0 ].receipt .status == receipt_data ["status" ]
330+ payload = adapter .validate_python (payload )
331+ assert payload . event == WebhookEventType .MESSAGE_RECEIPT_UPDATE
332+ assert payload .data [0 ].key .id == message_key_data ["id" ]
333+ assert payload .data [0 ].receipt .status == receipt_data ["status" ]
334334
335335 def test_parses_messages_reaction_event_correctly_model (self ):
336336 reaction_key_data = {
"remoteJid" :
"[email protected] " ,
"id" :
"REACTION_ID" ,
"fromMe" :
False }
337337 reaction_data = {"text" : "👍" , "key" : reaction_key_data }
338338 message_key_data = {
"remoteJid" :
"[email protected] " ,
"id" :
"MSG_ID" ,
"fromMe" :
True }
339339 messages_reaction_data_entry = {"key" : message_key_data , "reaction" : reaction_data }
340340 payload = {
341- "type " : WebhookEventType .MESSAGES_REACTION .value ,
341+ "event " : WebhookEventType .MESSAGES_REACTION .value ,
342342 "timestamp" : 1633456789 ,
343343 "data" : [messages_reaction_data_entry ]
344344 }
345345 adapter = TypeAdapter (WasenderWebhookEvent )
346- evt = adapter .validate_python (payload )
347- assert evt . type == WebhookEventType .MESSAGES_REACTION
348- assert evt .data [0 ].key .id == message_key_data ["id" ]
349- assert evt .data [0 ].reaction .text == reaction_data ["text" ]
346+ payload = adapter .validate_python (payload )
347+ assert payload . event == WebhookEventType .MESSAGES_REACTION
348+ assert payload .data [0 ].key .id == message_key_data ["id" ]
349+ assert payload .data [0 ].reaction .text == reaction_data ["text" ]
350350
351351 def test_parses_session_status_event_correctly_model (self ):
352352 session_status_data = {"status" : "CONNECTED" , "reason" : "User initiated connection" }
353353 payload = {
354- "type " : WebhookEventType .SESSION_STATUS .value ,
354+ "event " : WebhookEventType .SESSION_STATUS .value ,
355355 "timestamp" : 1633456789 ,
356356 "data" : session_status_data
357357 }
358358 adapter = TypeAdapter (WasenderWebhookEvent )
359- evt = adapter .validate_python (payload )
360- assert evt . type == WebhookEventType .SESSION_STATUS
361- assert evt .data .status == session_status_data ["status" ]
359+ payload = adapter .validate_python (payload )
360+ assert payload . event == WebhookEventType .SESSION_STATUS
361+ assert payload .data .status == session_status_data ["status" ]
362362
363363 def test_parses_qr_code_updated_event_correctly_model (self ):
364364 qr_code_updated_data = {"qr" : "new_qr_code_string" , "sessionId" : "123-456-789" }
365365 payload = {
366- "type " : WebhookEventType .QRCODE_UPDATED .value ,
366+ "event " : WebhookEventType .QRCODE_UPDATED .value ,
367367 "timestamp" : 1633456789 ,
368368 "data" : qr_code_updated_data
369369 }
370370 adapter = TypeAdapter (WasenderWebhookEvent )
371- evt = adapter .validate_python (payload )
372- assert evt . type == WebhookEventType .QRCODE_UPDATED
373- assert evt .data .qr == qr_code_updated_data ["qr" ]
374- assert evt .data .session_id == qr_code_updated_data ["sessionId" ]
371+ payload = adapter .validate_python (payload )
372+ assert payload . event == WebhookEventType .QRCODE_UPDATED
373+ assert payload .data .qr == qr_code_updated_data ["qr" ]
374+ assert payload .data .session_id == qr_code_updated_data ["sessionId" ]
375375
376376# Client specific fixtures and tests - REMOVED
377377# @pytest.fixture
0 commit comments