Skip to content

Commit

Permalink
test_: Code Migration from status-cli-tests added create_private_grou…
Browse files Browse the repository at this point in the history
…ps tests
  • Loading branch information
shashankshampi committed Nov 4, 2024
1 parent 66d612c commit fe0778a
Show file tree
Hide file tree
Showing 5 changed files with 211 additions and 2 deletions.
10 changes: 10 additions & 0 deletions tests-functional/src/node/status_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ def send_contact_request(self, pubkey, message):
params = [{"id": pubkey, "message": message}]
return self.api.send_rpc_request("wakuext_sendContactRequest", params)

def accept_contact_request(self, chatId):
params = [{"id": chatId}]
return self.api.send_rpc_request("wakuext_acceptContactRequest", params)

def send_message(self, pubkey, message):
params = [{"id": pubkey, "message": message}]
return self.api.send_rpc_request("wakuext_sendOneToOneMessage", params)
Expand All @@ -163,3 +167,9 @@ def resume_process(self):
if self.pid:
logger.info(f"Resuming node with pid: {self.pid}")
os.kill(self.pid, signal.SIGCONT)

def create_group_chat_with_members(self, pubkey_list, group_chat_name):
if not isinstance(pubkey_list, list):
raise TypeError("pubkey_list needs to be list")
params = [None, group_chat_name, pubkey_list]
return self.api.send_rpc_request("wakuext_createGroupChatWithMembers", params)
11 changes: 11 additions & 0 deletions tests-functional/src/steps/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,14 @@ def accept_contact_request(self, sending_node=None, receiving_node_pk=None):
if not receiving_node_pk:
receiving_node_pk = self.first_node_pubkey
sending_node.send_contact_request(receiving_node_pk, "hi")

def create_group_chat_with_timestamp(self, sender_node, member_list, private_group_name):
timestamp = datetime.now().strftime("%H:%M:%S")
response = sender_node.create_group_chat_with_members(member_list, private_group_name)
response_messages = response["result"]["messages"]
message_id = None
for m in response_messages:
if private_group_name in m["text"]:
message_id = m["id"]
break
return timestamp, message_id
172 changes: 172 additions & 0 deletions tests-functional/tests/test_create_private_groups.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import pytest
from src.libs.common import delay
from src.libs.custom_logger import get_custom_logger
from src.steps.common import StepsCommon
from constants import *
from validators.contact_request_validator import ContactRequestValidator
from validators.group_chat_validator import GroupChatValidator

logger = get_custom_logger(__name__)


@pytest.mark.usefixtures("start_2_nodes")
class TestCreatePrivateGroups(StepsCommon):
def test_create_group_chat_baseline(self):
num_private_groups = NUM_MESSAGES
private_groups = []
contact_request_sent = False

for i in range(num_private_groups):
if i % 2 == 0:
sender_node = self.first_node
receiver_node = self.second_node
receiver_pubkey = self.second_node_pubkey
else:
sender_node = self.second_node
receiver_node = self.first_node
receiver_pubkey = self.first_node_pubkey

if not contact_request_sent:
display_name = f"{receiver_node.name}_user"
contact_request_message = f"contact_request_{i}"
timestamp, message_id, contact_request_message, response = self.send_and_wait_for_message(
(sender_node, receiver_node), display_name, i
)

if not response:
raise AssertionError(f"Contact request failed between {sender_node.name} and {receiver_node.name}")

chat_id = response["result"]["chats"][0]["lastMessage"]["id"]
accept_response = receiver_node.accept_contact_request(chat_id)

if not accept_response:
raise AssertionError(
f"Failed to accept contact request on {receiver_node.name} for chatId {chat_id}")

contact_request_sent = True
delay(10)

group_name = f"private_group_from_{sender_node.name}_{i}"
try:
timestamp, message_id, response = self.create_and_validate_private_group(
sender_node, [receiver_pubkey], group_name
)

if not response:
raise AssertionError("Failed to create private group. No valid response received.")
else:
print(f"Private group '{group_name}' created successfully with message ID: {message_id}")
private_groups.append((timestamp, group_name, message_id, sender_node.name))

except AssertionError as e:
print(f"Group creation validation failed: {e}")

self.first_node.stop()
self.second_node.stop()

missing_private_groups = [
(ts, name, mid, node) for ts, name, mid, node in private_groups if mid is None
]

if missing_private_groups:
formatted_missing_groups = [
f"Timestamp: {ts}, GroupName: {msg}, ID: {mid}, Node: {node}" for ts, msg, mid, node in
missing_private_groups
]
raise AssertionError(
f"{len(missing_private_groups)} private groups out of {num_private_groups} were not created: " +
"\n".join(formatted_missing_groups)
)

def send_and_wait_for_message(self, nodes, display_name, index, timeout=10):
sender_node, receiver_node = nodes

receiver_pubkey = receiver_node.get_pubkey(display_name)
contact_request_message = f"contact_request_{index}"

timestamp, message_id, response = self.send_with_timestamp(
sender_node.send_contact_request, receiver_pubkey, contact_request_message
)

validator = ContactRequestValidator(response)
validator.run_all_validations(receiver_pubkey, display_name, contact_request_message)

try:
receiver_node.wait_for_signal("history.request.started", timeout)

messages_new_events = receiver_node.wait_for_complete_signal("messages.new", timeout)
messages_new_event = None

for event in messages_new_events:
if "chats" in event.get("event", {}):
messages_new_event = event
try:
validator.validate_event_against_response(
messages_new_event,
fields_to_validate={
"text": "text",
"displayName": "displayName",
"id": "id"
}
)
break
except AssertionError as validation_error:
logger.error(f"Validation failed for event: {messages_new_event}, Error: {validation_error}")
continue

if messages_new_event is None:
raise ValueError("No 'messages.new' event with 'chats' data found within the timeout period.")

receiver_node.wait_for_signal("history.request.completed", timeout)

except (TimeoutError, ValueError) as e:
logger.error(f"Signal validation failed: {str(e)}")
return timestamp, message_id, contact_request_message, None

return timestamp, message_id, contact_request_message, response

def create_and_validate_private_group(self, node, members_pubkeys, group_name, timeout=10):
timestamp, message_id, response = self.send_with_timestamp(
node.create_group_chat_with_members, members_pubkeys, group_name
)

if not response or "result" not in response or "chats" not in response["result"]:
raise AssertionError("Invalid response structure. Expected 'result' with 'chats' list.")

chat_data = response["result"]["chats"][0]
validator = GroupChatValidator(chat_data)

try:
validator.validate_fields(
{
"id": "id",
"name": group_name,
"active": True,
"chatType": 3,
"members": [
{"id": pubkey} for pubkey in members_pubkeys
]
}
)
except AssertionError as validation_error:
raise AssertionError(f"Validation failed for group chat creation: {validation_error}")

try:
node.wait_for_signal("history.request.completed", timeout)
except TimeoutError:
logger.error("Timeout waiting for group chat creation events.")
return timestamp, message_id, None

return timestamp, message_id, response

def test_create_group_chat_with_latency(self):
with self.add_latency():
self.test_create_group_chat_baseline()

def test_create_group_chat_with_packet_loss(self):
with self.add_packet_loss():
self.test_create_group_chat_baseline()

def test_create_group_chat_with_low_bandwith(self):
with self.add_low_bandwidth():
self.test_create_group_chat_baseline()
4 changes: 2 additions & 2 deletions tests-functional/validators/contact_request_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ def validate_chat_data(self, expected_chat_id, expected_display_name, expected_t
)

actual_contact_request_state = last_message.get("contactRequestState")
assert actual_contact_request_state == 1, (
f"Unexpected contact request state: Expected '1', found '{actual_contact_request_state}'"
assert actual_contact_request_state >= 1, (
f"Unexpected contact request state: Expected '1' or higher, found '{actual_contact_request_state}'"
)

assert "compressedKey" in last_message, "Missing 'compressedKey' in last message"
Expand Down
16 changes: 16 additions & 0 deletions tests-functional/validators/group_chat_validator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class GroupChatValidator:
def __init__(self, response_data):
self.response_data = response_data

def validate_fields(self, expected_fields):
for field, expected_value in expected_fields.items():
actual_value = self.response_data.get(field)
if isinstance(expected_value, list):
if not all(
any(member.get("id") == ev["id"] for member in actual_value)
for ev in expected_value
):
raise AssertionError(f"Validation failed: Mismatched members for field '{field}'")
elif actual_value != expected_value:
raise AssertionError(
f"Validation failed for field '{field}': expected '{expected_value}', got '{actual_value}'")

0 comments on commit fe0778a

Please sign in to comment.