Skip to content

Commit 97b300d

Browse files
committed
fix for session types
1 parent 4a283dd commit 97b300d

File tree

6 files changed

+84
-83
lines changed

6 files changed

+84
-83
lines changed

.coverage

0 Bytes
Binary file not shown.
-75 Bytes
Binary file not shown.

tests/test_sessions.py

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,15 @@ def mock_whatsapp_session_data():
7474
return {
7575
"id": 1,
7676
"name": "Business WhatsApp",
77-
"phoneNumber": "+1234567890",
77+
"phone_number": "+1234567890",
7878
"status": "connected",
79-
"accountProtection": True,
80-
"logMessages": True,
81-
"webhookUrl": "https://example.com/webhook",
82-
"webhookEnabled": True,
83-
"webhookEvents": ["message", "group_update"],
84-
"createdAt": "2025-04-01T12:00:00Z",
85-
"updatedAt": "2025-05-08T15:30:00Z"
79+
"account_protection": True,
80+
"log_messages": True,
81+
"webhook_url": "https://example.com/webhook",
82+
"webhook_enabled": True,
83+
"webhook_events": ["messages.upsert", "status.update"],
84+
"created_at": "2025-04-01T12:00:00Z",
85+
"updated_at": "2025-05-08T15:30:00Z"
8686
}
8787

8888
@pytest.fixture
@@ -97,26 +97,26 @@ def mock_rate_limit_info_dict():
9797
def mock_whatsapp_session_api_data():
9898
return {
9999
"id": 123,
100-
"userId": 456,
100+
"user_id": 456,
101101
"name": "Test Session",
102-
"phoneNumber": "+1234567890",
102+
"phone_number": "+1234567890",
103103
"status": "connected",
104-
"apiKey": "test_api_key_123",
105-
"sessionData": {
104+
"api_key": "test_api_key_123",
105+
"session_data": {
106106
"status_updated_at": "2025-01-01T12:00:00+00:00",
107107
"status_info": {
108108
"status": "connected"
109109
}
110110
},
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"
111+
"last_active_at": "2025-01-01T12:00:00Z",
112+
"created_at": "2025-01-01T12:00:00Z",
113+
"updated_at": "2025-01-01T12:00:00Z",
114+
"account_protection": True,
115+
"log_messages": True,
116+
"webhook_url": None,
117+
"webhook_events": [],
118+
"webhook_enabled": False,
119+
"webhook_secret": "test_webhook_secret_123"
120120
}
121121

122122
@pytest.fixture
@@ -152,7 +152,7 @@ async def test_get_session_status(self, async_client_sessions_mocked_internals,
152152
async def test_get_qr_code(self, async_client_sessions_mocked_internals, mock_rate_limit_info_dict):
153153
client = async_client_sessions_mocked_internals
154154
session_id_int = 123
155-
qr_data = {"qrCode": "base64qrdata"}
155+
qr_data = {"qr_code": "base64qrdata"}
156156
mock_api_response_data = {"success": True, "message": "QR Code", "data": qr_data}
157157
client._get_internal.return_value = {"response": mock_api_response_data, "rate_limit": mock_rate_limit_info_dict}
158158

@@ -217,7 +217,7 @@ async def test_get_all_whatsapp_sessions(self, async_client_sessions_mocked_inte
217217
@pytest.mark.asyncio
218218
async def test_create_whatsapp_session(self, async_client_sessions_mocked_internals, mock_whatsapp_session_api_data, mock_rate_limit_info_dict):
219219
client = async_client_sessions_mocked_internals
220-
payload_data = {"name": "New Session", "phoneNumber": "+123", "accountProtection": True, "logMessages": True}
220+
payload_data = {"name": "New Session", "phone_number": "+123", "account_protection": True, "log_messages": True}
221221
payload_model = CreateWhatsAppSessionPayload(**payload_data)
222222
mock_api_response_data = {"success": True, "message": "Session created", "data": mock_whatsapp_session_api_data}
223223
client._post_internal.return_value = {"response": mock_api_response_data, "rate_limit": mock_rate_limit_info_dict}
@@ -239,7 +239,7 @@ async def test_get_whatsapp_session_details(self, async_client_sessions_mocked_i
239239

240240
client._get_internal.assert_called_once_with(f"/whatsapp-sessions/{session_id_int}", use_personal_token=True)
241241
assert isinstance(result, GetWhatsAppSessionDetailsResult)
242-
assert result.response.data.phone_number == mock_whatsapp_session_api_data["phoneNumber"]
242+
assert result.response.data.phone_number == mock_whatsapp_session_api_data["phone_number"]
243243

244244
@pytest.mark.asyncio
245245
async def test_update_whatsapp_session(self, async_client_sessions_mocked_internals, mock_whatsapp_session_api_data, mock_rate_limit_info_dict):
@@ -278,7 +278,7 @@ async def test_delete_whatsapp_session(self, async_client_sessions_mocked_intern
278278
async def test_regenerate_api_key(self, async_client_sessions_mocked_internals, mock_rate_limit_info_dict):
279279
client = async_client_sessions_mocked_internals
280280
session_id_int = 123
281-
api_key_data = {"apiKey": "new_key_value"}
281+
api_key_data = {"api_key": "new_key_value"}
282282
client._post_internal.return_value = {"response": api_key_data, "rate_limit": mock_rate_limit_info_dict}
283283

284284
result: RegenerateApiKeyResult = await client.regenerate_api_key(session_id=session_id_int)
@@ -292,24 +292,24 @@ def test_whatsapp_session_model(self, mock_whatsapp_session_api_data):
292292
model = WhatsAppSession(**mock_whatsapp_session_api_data)
293293
assert model.id == mock_whatsapp_session_api_data["id"]
294294
assert model.name == mock_whatsapp_session_api_data["name"]
295-
assert model.phone_number == mock_whatsapp_session_api_data["phoneNumber"]
295+
assert model.phone_number == mock_whatsapp_session_api_data["phone_number"]
296296
assert model.status == WhatsAppSessionStatus.CONNECTED
297297
assert model.account_protection is True
298298
assert model.log_messages is True
299-
assert model.webhook_url == mock_whatsapp_session_api_data["webhookUrl"]
300-
assert model.webhook_enabled == mock_whatsapp_session_api_data["webhookEnabled"]
301-
assert model.webhook_events == mock_whatsapp_session_api_data["webhookEvents"]
299+
assert model.webhook_url == mock_whatsapp_session_api_data["webhook_url"]
300+
assert model.webhook_enabled == mock_whatsapp_session_api_data["webhook_enabled"]
301+
assert model.webhook_events == mock_whatsapp_session_api_data["webhook_events"]
302302

303-
expected_created_at_dt = datetime.fromisoformat(mock_whatsapp_session_api_data["createdAt"].replace("Z", "+00:00"))
304-
expected_updated_at_dt = datetime.fromisoformat(mock_whatsapp_session_api_data["updatedAt"].replace("Z", "+00:00"))
303+
expected_created_at_dt = datetime.fromisoformat(mock_whatsapp_session_api_data["created_at"].replace("Z", "+00:00"))
304+
expected_updated_at_dt = datetime.fromisoformat(mock_whatsapp_session_api_data["updated_at"].replace("Z", "+00:00"))
305305
assert model.created_at == expected_created_at_dt
306306
assert model.updated_at == expected_updated_at_dt
307307

308308
dumped_model = model.model_dump(by_alias=True, mode='json')
309-
assert dumped_model["phoneNumber"] == mock_whatsapp_session_api_data["phoneNumber"]
309+
assert dumped_model["phone_number"] == mock_whatsapp_session_api_data["phone_number"]
310310

311-
assert dumped_model["createdAt"] == mock_whatsapp_session_api_data["createdAt"]
312-
assert dumped_model["updatedAt"] == mock_whatsapp_session_api_data["updatedAt"]
311+
assert dumped_model["created_at"] == mock_whatsapp_session_api_data["created_at"]
312+
assert dumped_model["updated_at"] == mock_whatsapp_session_api_data["updated_at"]
313313

314314
model_fields = WhatsAppSession.model_fields.keys()
315315

@@ -341,45 +341,45 @@ def test_whatsapp_session_status_enum(self):
341341
class TestSessionRequestPayloadModels:
342342
def test_create_whatsapp_session_payload(self):
343343
valid_data_all_fields = {
344-
"name": "Test Session", "phoneNumber": "+19998887777",
345-
"accountProtection": False, "logMessages": False,
346-
"webhookUrl": "https://test.com/hook", "webhookEnabled": True,
347-
"webhookEvents": ["message", "status"]
344+
"name": "Test Session", "phone_number": "+19998887777",
345+
"account_protection": False, "log_messages": False,
346+
"webhook_url": "https://test.com/hook", "webhook_enabled": True,
347+
"webhook_events": ["messages.upsert", "session.status"]
348348
}
349349
model = CreateWhatsAppSessionPayload(**valid_data_all_fields)
350350
assert model.name == valid_data_all_fields["name"]
351-
assert model.phone_number == valid_data_all_fields["phoneNumber"]
352-
assert model.webhook_events == valid_data_all_fields["webhookEvents"]
351+
assert model.phone_number == valid_data_all_fields["phone_number"]
352+
assert model.webhook_events == valid_data_all_fields["webhook_events"]
353353
dumped = model.model_dump(by_alias=True, exclude_none=True)
354-
assert dumped["phoneNumber"] == valid_data_all_fields["phoneNumber"]
355-
assert dumped["webhookUrl"] == valid_data_all_fields["webhookUrl"]
354+
assert dumped["phone_number"] == valid_data_all_fields["phone_number"]
355+
assert dumped["webhook_url"] == valid_data_all_fields["webhook_url"]
356356

357357
valid_data_required_only = {
358-
"name": "Minimal Session", "phoneNumber": "+12223334444",
359-
"accountProtection": True, "logMessages": True
358+
"name": "Minimal Session", "phone_number": "+12223334444",
359+
"account_protection": True, "log_messages": True
360360
}
361361
model_req = CreateWhatsAppSessionPayload(**valid_data_required_only)
362362
assert model_req.name == valid_data_required_only["name"]
363363
assert model_req.webhook_url is None
364364
dumped_req = model_req.model_dump(by_alias=True, exclude_none=True)
365-
assert "webhookUrl" not in dumped_req
366-
assert "webhookEvents" not in dumped_req
365+
assert "webhook_url" not in dumped_req
366+
assert "webhook_events" not in dumped_req
367367

368368
with pytest.raises(ValidationError):
369-
CreateWhatsAppSessionPayload(phoneNumber="+1", accountProtection=True, logMessages=True)
369+
CreateWhatsAppSessionPayload(phone_number="+1", account_protection=True, log_messages=True)
370370

371371
def test_update_whatsapp_session_payload(self):
372372
payload_all = {
373-
"name": "Updated Name", "phoneNumber": "+1newphone",
374-
"accountProtection": True, "logMessages": False,
375-
"webhookUrl": "https://new.hook", "webhookEnabled": False,
376-
"webhookEvents": ["message"]
373+
"name": "Updated Name", "phone_number": "+1newphone",
374+
"account_protection": True, "log_messages": False,
375+
"webhook_url": "https://new.hook", "webhook_enabled": False,
376+
"webhook_events": ["messages.upsert"]
377377
}
378378
model_all = UpdateWhatsAppSessionPayload(**payload_all)
379379
assert model_all.name == payload_all["name"]
380380
dumped_all = model_all.model_dump(by_alias=True, exclude_none=True)
381-
assert dumped_all["phoneNumber"] == payload_all["phoneNumber"]
382-
assert dumped_all["webhookEvents"] == payload_all["webhookEvents"]
381+
assert dumped_all["phone_number"] == payload_all["phone_number"]
382+
assert dumped_all["webhook_events"] == payload_all["webhook_events"]
383383

384384
payload_partial = {"name": "Partial Update"}
385385
model_partial = UpdateWhatsAppSessionPayload(**payload_partial)
@@ -424,7 +424,7 @@ def test_connect_session_result_model(self, mock_rate_limit_info_dict):
424424
assert model_connected.rate_limit is None
425425

426426
def test_qr_code_result_model(self, mock_rate_limit_info_dict):
427-
qr_data = {"qrCode": "base64qr"}
427+
qr_data = {"qr_code": "base64qr"}
428428
response = {"success": True, "message": "QR data", "data": qr_data}
429429
result_data = {"response": response, "rate_limit": mock_rate_limit_info_dict}
430430
model = GetQRCodeResult(**result_data)
@@ -439,8 +439,8 @@ def test_disconnect_session_result_model(self, mock_rate_limit_info_dict):
439439
assert model.response.data.message == "Logged out"
440440

441441
def test_regenerate_api_key_result_model(self, mock_rate_limit_info_dict):
442-
api_key_data = {"apiKey": "newkey123"} # This is the structure of RegenerateApiKeyResponse
443-
# Note: RegenerateApiKeyResponse itself has success=True and apiKey fields.
442+
api_key_data = {"api_key": "newkey123"} # This is the structure of RegenerateApiKeyResponse
443+
# Note: RegenerateApiKeyResponse itself has success=True and api_key fields.
444444
# It is not nested under a generic success/message/data structure like others.
445445
result_data = {"response": api_key_data, "rate_limit": mock_rate_limit_info_dict}
446446
model = RegenerateApiKeyResult(**result_data)
0 Bytes
Binary file not shown.
-893 Bytes
Binary file not shown.

wasenderapi/sessions.py

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from datetime import datetime
44
from pydantic import BaseModel, Field
55
from .models import RateLimitInfo
6+
from .webhook import WasenderWebhookEventType
67

78
class WhatsAppSessionStatus(str, Enum):
89
CONNECTED = "connected"
@@ -14,42 +15,42 @@ class WhatsAppSessionStatus(str, Enum):
1415

1516
class WhatsAppSession(BaseModel):
1617
id: int
17-
user_id: int = Field(..., alias="userId")
18+
user_id: int
1819
name: str
19-
phone_number: str = Field(..., alias="phoneNumber")
20+
phone_number: str
2021
status: WhatsAppSessionStatus
21-
api_key: str = Field(..., alias="apiKey")
22-
session_data: dict = Field(..., alias="sessionData")
23-
last_active_at: datetime = Field(..., alias="lastActiveAt")
24-
account_protection: bool = Field(..., alias="accountProtection")
25-
log_messages: bool = Field(..., alias="logMessages")
26-
webhook_url: Optional[str] = Field(None, alias="webhookUrl")
27-
webhook_enabled: bool = Field(..., alias="webhookEnabled")
28-
webhook_events: Optional[List[str]] = Field(None, alias="webhookEvents")
29-
webhook_secret: str = Field(..., alias="webhookSecret")
30-
created_at: datetime = Field(..., alias="createdAt")
31-
updated_at: datetime = Field(..., alias="updatedAt")
22+
api_key: str
23+
session_data: dict
24+
last_active_at: datetime
25+
account_protection: bool
26+
log_messages: bool
27+
webhook_url: Optional[str] = None
28+
webhook_enabled: bool
29+
webhook_events: Optional[List[WasenderWebhookEventType]] = None
30+
webhook_secret: str
31+
created_at: datetime
32+
updated_at: datetime
3233

3334

3435

3536

3637
class CreateWhatsAppSessionPayload(BaseModel):
3738
name: str
38-
phone_number: str = Field(..., alias="phoneNumber")
39-
account_protection: bool = Field(..., alias="accountProtection")
40-
log_messages: bool = Field(..., alias="logMessages")
41-
webhook_url: Optional[str] = Field(None, alias="webhookUrl")
42-
webhook_enabled: Optional[bool] = Field(None, alias="webhookEnabled")
43-
webhook_events: Optional[List[str]] = Field(None, alias="webhookEvents")
39+
phone_number: str
40+
account_protection: bool
41+
log_messages: bool
42+
webhook_url: Optional[str] = None
43+
webhook_enabled: Optional[bool] = None
44+
webhook_events: Optional[List[WasenderWebhookEventType]] = None
4445

4546
class UpdateWhatsAppSessionPayload(BaseModel):
4647
name: Optional[str] = None
47-
phone_number: Optional[str] = Field(None, alias="phoneNumber")
48-
account_protection: Optional[bool] = Field(None, alias="accountProtection")
49-
log_messages: Optional[bool] = Field(None, alias="logMessages")
50-
webhook_url: Optional[str] = Field(None, alias="webhookUrl")
51-
webhook_enabled: Optional[bool] = Field(None, alias="webhookEnabled")
52-
webhook_events: Optional[List[str]] = Field(None, alias="webhookEvents")
48+
phone_number: Optional[str] = None
49+
account_protection: Optional[bool] = None
50+
log_messages: Optional[bool] = None
51+
webhook_url: Optional[str] = None
52+
webhook_enabled: Optional[bool] = None
53+
webhook_events: Optional[List[WasenderWebhookEventType]] = None
5354

5455
class ConnectSessionPayload(BaseModel):
5556
qr_as_image: Optional[bool] = Field(None, alias="qrAsImage")
@@ -60,15 +61,15 @@ class ConnectSessionResponseData(BaseModel):
6061
message: Optional[str] = None
6162

6263
class QRCodeResponseData(BaseModel):
63-
qr_code: str = Field(..., alias="qrCode")
64+
qr_code: str
6465

6566
class DisconnectSessionResponseData(BaseModel):
6667
status: WhatsAppSessionStatus
6768
message: Optional[str] = None
6869

6970
class RegenerateApiKeyResponse(BaseModel):
7071
success: bool = True
71-
api_key: str = Field(..., alias="apiKey")
72+
api_key: str
7273

7374
class SessionStatusData(BaseModel):
7475
status: WhatsAppSessionStatus

0 commit comments

Comments
 (0)