Skip to content

Commit cfe1a46

Browse files
committed
[tests] adding more tests for updates
1 parent d919c89 commit cfe1a46

File tree

2 files changed

+119
-46
lines changed

2 files changed

+119
-46
lines changed

tests/data/18.0/message.json

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,46 @@
381381
}
382382
]
383383
},
384+
"unreaction": {
385+
"object": "whatsapp_business_account",
386+
"entry": [
387+
{
388+
"id": "1234567890987654321",
389+
"changes": [
390+
{
391+
"value": {
392+
"messaging_product": "whatsapp",
393+
"metadata": {
394+
"display_phone_number": "972123456789",
395+
"phone_number_id": "1122334455667"
396+
},
397+
"contacts": [
398+
{
399+
"profile": {
400+
"name": "Test Name"
401+
},
402+
"wa_id": "972987654321"
403+
}
404+
],
405+
"messages": [
406+
{
407+
"from": "972987654321",
408+
"id": "wamid.xyzxyz",
409+
"timestamp": "1697044456",
410+
"type": "reaction",
411+
"reaction": {
412+
"message_id": "wamid.yzxyzx=",
413+
"emoji": ""
414+
}
415+
}
416+
]
417+
},
418+
"field": "messages"
419+
}
420+
]
421+
}
422+
]
423+
},
384424
"location": {
385425
"object": "whatsapp_business_account",
386426
"entry": [
@@ -632,6 +672,10 @@
632672
],
633673
"messages": [
634674
{
675+
"context": {
676+
"from": "972123456789",
677+
"id": "wamid.xyzxyz=="
678+
},
635679
"from": "972987654321",
636680
"id": "wamid.xyzxyz",
637681
"timestamp": "1697044746",

tests/test_updates.py

Lines changed: 75 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import json
2-
from typing import Any
2+
from typing import Any, TypeVar, Callable
33

44
from pywa import WhatsApp
55
from pywa.types import (
@@ -8,59 +8,88 @@
88
CallbackSelection,
99
MessageStatus,
1010
TemplateStatus,
11+
MessageType,
12+
MessageStatusType,
1113
)
1214
from pywa.types.base_update import BaseUpdate
15+
from pywa.types.media import Image, Video, Document, Audio
1316

1417
API_VERSIONS: list[float] = [18.0]
18+
T = TypeVar("T", bound=BaseUpdate)
1519

16-
UPDATES: dict[tuple[str, type[BaseUpdate]], list[str]] = {
17-
("message", Message): [
18-
"text",
19-
"image",
20-
"video",
21-
"document",
22-
"audio",
23-
"voice",
24-
"static_sticker",
25-
"animated_sticker",
26-
"location",
27-
"contacts",
28-
"order",
29-
"unsupported",
30-
"reply",
31-
"forwarded",
32-
"forwarded_many_times",
33-
],
34-
("callback_button", CallbackButton): [
35-
"button",
36-
"quick_reply",
37-
],
38-
("callback_selection", CallbackSelection): [
39-
"callback",
40-
"description",
41-
],
42-
("message_status", MessageStatus): [
43-
"sent",
44-
"failed",
45-
],
46-
("template_status", TemplateStatus): [
47-
"approved",
48-
],
20+
UPDATES: dict[tuple[str, type[T]], dict[str, list[Callable[[T], bool]]]] = {
21+
("message", Message): {
22+
"text": [lambda m: m.text is not None],
23+
"image": [
24+
lambda m: m.image is not None,
25+
lambda m: m.has_media,
26+
lambda m: isinstance(m.media, Image),
27+
],
28+
"video": [
29+
lambda m: m.video is not None,
30+
lambda m: m.has_media,
31+
lambda m: isinstance(m.media, Video),
32+
],
33+
"document": [
34+
lambda m: m.document is not None,
35+
lambda m: m.has_media,
36+
lambda m: isinstance(m.media, Document),
37+
],
38+
"audio": [
39+
lambda m: not m.audio.voice,
40+
lambda m: m.has_media,
41+
lambda m: isinstance(m.media, Audio),
42+
],
43+
"voice": [lambda m: m.audio.voice],
44+
"static_sticker": [lambda m: not m.sticker.animated],
45+
"animated_sticker": [lambda m: m.sticker.animated],
46+
"reaction": [
47+
lambda m: m.reaction.emoji is not None,
48+
lambda m: m.id != m.message_id_to_reply,
49+
],
50+
"unreaction": [lambda m: m.reaction.emoji is None],
51+
"location": [lambda m: m.location is not None],
52+
"contacts": [lambda m: m.contacts is not None],
53+
"order": [lambda m: m.order is not None],
54+
"unsupported": [lambda m: m.error is not None],
55+
"reply": [lambda m: m.is_reply],
56+
"forwarded": [lambda m: m.forwarded],
57+
"forwarded_many_times": [lambda m: m.forwarded_many_times],
58+
},
59+
("callback_button", CallbackButton): {
60+
"button": [lambda b: b.type == MessageType.INTERACTIVE],
61+
"quick_reply": [lambda b: b.type == MessageType.BUTTON],
62+
},
63+
("callback_selection", CallbackSelection): {
64+
"callback": [lambda s: s.data is not None],
65+
"description": [lambda s: s.description is not None],
66+
},
67+
("message_status", MessageStatus): {
68+
"sent": [lambda s: s.status == MessageStatusType.SENT],
69+
"failed": [lambda s: s.error is not None],
70+
},
71+
("template_status", TemplateStatus): {
72+
"approved": [lambda s: s.event == TemplateStatus.TemplateEvent.APPROVED],
73+
},
4974
}
5075

5176

5277
def test_types():
5378
client = WhatsApp(phone_id="1234567890", token="xyzxyzxyz")
5479
for version in API_VERSIONS:
55-
for (update_id, update_type), updates in UPDATES.items():
56-
with open(f"tests/data/{version}/{update_id}.json", "r") as update_file:
57-
update_data: dict[str, Any] = json.load(update_file)
58-
for update in updates:
59-
try:
60-
update = update_type.from_update(
61-
client=client, update=update_data[update]
62-
) # noqa
63-
except Exception as e:
64-
raise AssertionError(
65-
f"Failed to parse update '{update_id}': test='{update}', v={version}, error={e}"
66-
)
80+
for (update_filename, update_class), examples in UPDATES.items():
81+
with open(
82+
f"tests/data/{version}/{update_filename}.json", "r"
83+
) as update_file:
84+
examples_data: dict[str, Any] = json.load(update_file)
85+
for test_name, test_funcs in examples.items():
86+
try:
87+
update_obj = update_class.from_update(
88+
client=client, update=examples_data[test_name]
89+
) # noqa
90+
for test_func in test_funcs:
91+
assert test_func(update_obj)
92+
except Exception as e:
93+
raise AssertionError(
94+
f"Failed to parse update='{update_filename}', test='{test_name}', v={version}, error={e}"
95+
)

0 commit comments

Comments
 (0)