Skip to content

Commit 54e9044

Browse files
committed
fix session types
1 parent 8657363 commit 54e9044

File tree

9 files changed

+68
-42
lines changed

9 files changed

+68
-42
lines changed

.coverage

0 Bytes
Binary file not shown.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/dist
-26.6 KB
Binary file not shown.

dist/wasenderapi-0.2.2.tar.gz

-72.3 KB
Binary file not shown.
858 Bytes
Binary file not shown.

tests/test_sessions.py

Lines changed: 52 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ async def json_func():
6060
@pytest.fixture
6161
def mock_session_status_response_data():
6262
return {
63-
"status": "CONNECTED"
63+
"status": "connected"
6464
}
6565

6666
@pytest.fixture
@@ -75,7 +75,7 @@ def mock_whatsapp_session_data():
7575
"id": 1,
7676
"name": "Business WhatsApp",
7777
"phoneNumber": "+1234567890",
78-
"status": "CONNECTED",
78+
"status": "connected",
7979
"accountProtection": True,
8080
"logMessages": True,
8181
"webhookUrl": "https://example.com/webhook",
@@ -96,17 +96,27 @@ def mock_rate_limit_info_dict():
9696
@pytest.fixture
9797
def mock_whatsapp_session_api_data():
9898
return {
99-
"id": 1,
100-
"name": "Business WhatsApp API",
101-
"phoneNumber": "+1234567890",
102-
"status": "CONNECTED",
103-
"accountProtection": True,
104-
"logMessages": True,
105-
"webhookUrl": "https://example.com/webhook_api",
106-
"webhookEnabled": True,
107-
"webhookEvents": ["message", "group_update"],
108-
"createdAt": "2025-04-01T12:00:00Z",
109-
"updatedAt": "2025-05-08T15:30:00Z"
99+
"id": 123,
100+
"userId": 456,
101+
"name": "Test Session",
102+
"phoneNumber": "+1234567890",
103+
"status": "connected",
104+
"apiKey": "test_api_key_123",
105+
"sessionData": {
106+
"status_updated_at": "2025-01-01T12:00:00+00:00",
107+
"status_info": {
108+
"status": "connected"
109+
}
110+
},
111+
"lastActiveAt": "2025-01-01T12:00:00Z",
112+
"createdAt": "2025-01-01T12:00:00Z",
113+
"updatedAt": "2025-01-01T12:00:00Z",
114+
"accountProtection": 1,
115+
"logMessages": 1,
116+
"webhookUrl": None,
117+
"webhookEvents": [],
118+
"webhookEnabled": False,
119+
"webhookSecret": "test_webhook_secret_123"
110120
}
111121

112122
@pytest.fixture
@@ -124,7 +134,7 @@ class TestSessionsClientMethods:
124134
async def test_get_session_status(self, async_client_sessions_mocked_internals, mock_rate_limit_info_dict):
125135
client = async_client_sessions_mocked_internals
126136
session_id_str = "session_123"
127-
mock_api_response_data = {"status": "CONNECTED"}
137+
mock_api_response_data = {"status": "connected"}
128138

129139
client._get_internal.return_value = {
130140
"response": mock_api_response_data,
@@ -156,7 +166,7 @@ async def test_get_qr_code(self, async_client_sessions_mocked_internals, mock_ra
156166
async def test_disconnect_whatsapp_session(self, async_client_sessions_mocked_internals, mock_rate_limit_info_dict):
157167
client = async_client_sessions_mocked_internals
158168
session_id_int = 123
159-
disconnect_data = {"status": "DISCONNECTED", "message": "Session logged out"}
169+
disconnect_data = {"status": "disconnected", "message": "Session logged out"}
160170
mock_api_response_data = {"success": True, "message": "Logged out op", "data": disconnect_data}
161171
client._post_internal.return_value = {"response": mock_api_response_data, "rate_limit": mock_rate_limit_info_dict}
162172

@@ -175,7 +185,7 @@ async def test_disconnect_whatsapp_session(self, async_client_sessions_mocked_in
175185
async def test_connect_whatsapp_session(self, async_client_sessions_mocked_internals, mock_rate_limit_info_dict, qr_as_image_param, path_has_query_param):
176186
client = async_client_sessions_mocked_internals
177187
session_id_int = 123
178-
connect_response_data = {"status": "CONNECTED", "message": "Session connected"}
188+
connect_response_data = {"status": "connected", "message": "Session connected"}
179189
mock_api_response_data = {"success": True, "message": "Connection status", "data": connect_response_data}
180190
client._post_internal.return_value = {"response": mock_api_response_data, "rate_limit": mock_rate_limit_info_dict}
181191

@@ -284,8 +294,8 @@ def test_whatsapp_session_model(self, mock_whatsapp_session_api_data):
284294
assert model.name == mock_whatsapp_session_api_data["name"]
285295
assert model.phone_number == mock_whatsapp_session_api_data["phoneNumber"]
286296
assert model.status == WhatsAppSessionStatus.CONNECTED
287-
assert model.account_protection == mock_whatsapp_session_api_data["accountProtection"]
288-
assert model.log_messages == mock_whatsapp_session_api_data["logMessages"]
297+
assert model.account_protection is True
298+
assert model.log_messages is True
289299
assert model.webhook_url == mock_whatsapp_session_api_data["webhookUrl"]
290300
assert model.webhook_enabled == mock_whatsapp_session_api_data["webhookEnabled"]
291301
assert model.webhook_events == mock_whatsapp_session_api_data["webhookEvents"]
@@ -298,26 +308,33 @@ def test_whatsapp_session_model(self, mock_whatsapp_session_api_data):
298308
dumped_model = model.model_dump(by_alias=True, mode='json')
299309
assert dumped_model["phoneNumber"] == mock_whatsapp_session_api_data["phoneNumber"]
300310

301-
# model_dump(mode='json') should serialize datetime to ISO string (typically with Z or offset)
302-
# The input mock_whatsapp_session_api_data["createdAt"] is '2025-04-01T12:00:00Z'
303-
# We need to ensure Pydantic's output matches this specific Z format or compare parsed datetimes.
304-
# Forcing our model's datetime to the 'Z' format for comparison is safest if Pydantic's default differs.
305-
306-
# Re-parse the dumped string and compare with the model's datetime attribute if exact string match is tricky.
307-
# Or, compare against the original input string if Pydantic serializes to the same format.
308311
assert dumped_model["createdAt"] == mock_whatsapp_session_api_data["createdAt"]
309312
assert dumped_model["updatedAt"] == mock_whatsapp_session_api_data["updatedAt"]
310313

311-
required_fields = ["id", "name", "phoneNumber", "status", "accountProtection", "logMessages", "webhookEnabled", "createdAt", "updatedAt"]
312-
for field_to_omit in required_fields:
314+
model_fields = WhatsAppSession.model_fields.keys()
315+
316+
required_model_fields_for_validation_test = [
317+
"id", "user_id", "name", "phone_number", "status", "api_key", "session_data",
318+
"last_active_at", "account_protection", "log_messages",
319+
"webhook_enabled", "webhook_secret", "created_at", "updated_at"
320+
]
321+
322+
for field_name_snake_case in required_model_fields_for_validation_test:
323+
field_info = WhatsAppSession.model_fields[field_name_snake_case]
324+
api_key_to_omit = field_info.alias or field_name_snake_case
325+
313326
bad_data = mock_whatsapp_session_api_data.copy()
314-
del bad_data[field_to_omit]
315-
with pytest.raises(ValidationError, match=field_to_omit):
327+
if api_key_to_omit in bad_data:
328+
del bad_data[api_key_to_omit]
329+
else:
330+
pass
331+
332+
with pytest.raises(ValidationError, match=rf"(^|\W){field_name_snake_case}(\W|$)|(^|\W){api_key_to_omit}(\W|$)"):
316333
WhatsAppSession(**bad_data)
317334

318335
def test_whatsapp_session_status_enum(self):
319-
assert WhatsAppSessionStatus.CONNECTED.value == "CONNECTED"
320-
assert WhatsAppSessionStatus.NEED_SCAN.value == "NEED_SCAN"
336+
assert WhatsAppSessionStatus.CONNECTED.value == "connected"
337+
assert WhatsAppSessionStatus.NEED_SCAN.value == "need_scan"
321338
with pytest.raises(ValueError):
322339
WhatsAppSessionStatus("INVALID_STATUS")
323340

@@ -389,7 +406,7 @@ def test_connect_session_payload(self):
389406
class TestSessionResultModels:
390407
def test_connect_session_result_model(self, mock_rate_limit_info_dict):
391408
# Case: Need Scan
392-
need_scan_data = {"status": "NEED_SCAN", "qrCode": "base64string", "message": "Scan QR"}
409+
need_scan_data = {"status": "need_scan", "qrCode": "base64string", "message": "Scan QR"}
393410
response_need_scan = {"success": True, "message": "Connect attempt", "data": need_scan_data}
394411
result_data_need_scan = {"response": response_need_scan, "rate_limit": mock_rate_limit_info_dict}
395412
model_need_scan = ConnectSessionResult(**result_data_need_scan)
@@ -398,7 +415,7 @@ def test_connect_session_result_model(self, mock_rate_limit_info_dict):
398415
assert model_need_scan.rate_limit is not None
399416

400417
# Case: Already Connected
401-
connected_data = {"status": "CONNECTED", "message": "Already connected"}
418+
connected_data = {"status": "connected", "message": "Already connected"}
402419
response_connected = {"success": True, "message": "Connect attempt", "data": connected_data}
403420
result_data_connected = {"response": response_connected}
404421
model_connected = ConnectSessionResult(**result_data_connected)
@@ -414,7 +431,7 @@ def test_qr_code_result_model(self, mock_rate_limit_info_dict):
414431
assert model.response.data.qr_code == "base64qr"
415432

416433
def test_disconnect_session_result_model(self, mock_rate_limit_info_dict):
417-
disconnect_data = {"status": "DISCONNECTED", "message": "Logged out"}
434+
disconnect_data = {"status": "disconnected", "message": "Logged out"}
418435
response = {"success": True, "message": "Disconnect op", "data": disconnect_data}
419436
result_data = {"response": response, "rate_limit": mock_rate_limit_info_dict}
420437
model = DisconnectSessionResult(**result_data)
@@ -431,7 +448,7 @@ def test_regenerate_api_key_result_model(self, mock_rate_limit_info_dict):
431448
assert model.response.api_key == "newkey123"
432449

433450
def test_get_session_status_result_model(self, mock_rate_limit_info_dict):
434-
status_data = {"status": "CONNECTED"} # This is GetSessionStatusResponse structure
451+
status_data = {"status": "connected"} # This is GetSessionStatusResponse structure
435452
# GetSessionStatusResult directly wraps GetSessionStatusResponse
436453
result_data = {"response": status_data, "rate_limit": mock_rate_limit_info_dict}
437454
model = GetSessionStatusResult(**result_data)
390 Bytes
Binary file not shown.

wasenderapi/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.2.2"
1+
__version__ = "0.2.3"

wasenderapi/sessions.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,34 @@
55
from .models import RateLimitInfo
66

77
class WhatsAppSessionStatus(str, Enum):
8-
CONNECTED = "CONNECTED"
9-
DISCONNECTED = "DISCONNECTED"
10-
NEED_SCAN = "NEED_SCAN"
11-
CONNECTING = "CONNECTING"
12-
LOGGED_OUT = "LOGGED_OUT"
13-
EXPIRED = "EXPIRED"
8+
CONNECTED = "connected"
9+
DISCONNECTED = "disconnected"
10+
NEED_SCAN = "need_scan"
11+
CONNECTING = "connecting"
12+
LOGGED_OUT = "logged_out"
13+
EXPIRED = "expired"
1414

1515
class WhatsAppSession(BaseModel):
1616
id: int
17+
user_id: int = Field(..., alias="userId")
1718
name: str
1819
phone_number: str = Field(..., alias="phoneNumber")
1920
status: WhatsAppSessionStatus
21+
api_key: str = Field(..., alias="apiKey")
22+
session_data: dict = Field(..., alias="sessionData")
23+
last_active_at: datetime = Field(..., alias="lastActiveAt")
2024
account_protection: bool = Field(..., alias="accountProtection")
2125
log_messages: bool = Field(..., alias="logMessages")
2226
webhook_url: Optional[str] = Field(None, alias="webhookUrl")
2327
webhook_enabled: bool = Field(..., alias="webhookEnabled")
2428
webhook_events: Optional[List[str]] = Field(None, alias="webhookEvents")
29+
webhook_secret: str = Field(..., alias="webhookSecret")
2530
created_at: datetime = Field(..., alias="createdAt")
2631
updated_at: datetime = Field(..., alias="updatedAt")
2732

33+
34+
35+
2836
class CreateWhatsAppSessionPayload(BaseModel):
2937
name: str
3038
phone_number: str = Field(..., alias="phoneNumber")

0 commit comments

Comments
 (0)