Negative and edge cases for/store/v3/messages with query param hashes (#74)
* added test with hashes edge and boundry cases * added 2 test with incorrect query param in cursor and hashes * fixed linters error and handeliong for None error
This commit is contained in:
parent
4c706c34bb
commit
b0dc5206c9
|
@ -195,3 +195,57 @@ class TestCursor(StepsStore):
|
||||||
|
|
||||||
# Validate that paginationCursor is **not** present when we reach the boundary (end of pagination)
|
# Validate that paginationCursor is **not** present when we reach the boundary (end of pagination)
|
||||||
assert store_response.pagination_cursor is None, "paginationCursor should be absent when at the boundary"
|
assert store_response.pagination_cursor is None, "paginationCursor should be absent when at the boundary"
|
||||||
|
|
||||||
|
# This test publishes 5 messages and retrieves them using the store API with a page size of 3.
|
||||||
|
# It attempts to use an invalid 'paginationCursor' query parameter instead of the correct 'cursor'.
|
||||||
|
# The test then validates that the incorrect parameter doesn't affect pagination and that the correct
|
||||||
|
# 'cursor' parameter successfully retrieves the remaining messages.
|
||||||
|
def test_invalid_pagination_cursor_param(self):
|
||||||
|
# Store the timestamps used when creating messages
|
||||||
|
timestamps = []
|
||||||
|
|
||||||
|
# Publish 5 messages
|
||||||
|
for i in range(5):
|
||||||
|
message = self.create_message(payload=to_base64(f"Message_{i}"))
|
||||||
|
timestamps.append(message["timestamp"]) # Save the timestamp
|
||||||
|
self.publish_message(message=message)
|
||||||
|
|
||||||
|
for node in self.store_nodes:
|
||||||
|
# Step 1: Request first page with pageSize = 3
|
||||||
|
store_response = self.get_messages_from_store(node, page_size=3)
|
||||||
|
assert len(store_response.messages) == 3, "Message count mismatch on first page"
|
||||||
|
pagination_cursor = store_response.pagination_cursor
|
||||||
|
|
||||||
|
# Step 2: Attempt to use invalid paginationCursor param (expect 200 but no page change)
|
||||||
|
invalid_cursor = pagination_cursor
|
||||||
|
store_response_invalid = self.get_messages_from_store(node, page_size=3, paginationCursor=invalid_cursor)
|
||||||
|
assert store_response_invalid.status_code == 200, "Expected 200 response with invalid paginationCursor param"
|
||||||
|
assert len(store_response_invalid.messages) == 3, "Expected the same page content since paginationCursor is ignored"
|
||||||
|
assert store_response_invalid.messages == store_response.messages, "Messages should be the same as the first page"
|
||||||
|
|
||||||
|
# Step 3: Use correct cursor to get the remaining messages
|
||||||
|
store_response_valid = self.get_messages_from_store(node, page_size=3, cursor=pagination_cursor)
|
||||||
|
assert len(store_response_valid.messages) == 2, "Message count mismatch on second page"
|
||||||
|
assert store_response_valid.pagination_cursor is None, "There should be no pagination cursor for the last page"
|
||||||
|
|
||||||
|
# Validate the message content using the correct timestamp
|
||||||
|
expected_message_hashes = [
|
||||||
|
self.compute_message_hash(
|
||||||
|
self.test_pubsub_topic,
|
||||||
|
{
|
||||||
|
"payload": to_base64(f"Message_3"),
|
||||||
|
"contentTopic": "/myapp/1/latest/proto",
|
||||||
|
"timestamp": timestamps[3], # Use the stored timestamp for Message_3
|
||||||
|
},
|
||||||
|
),
|
||||||
|
self.compute_message_hash(
|
||||||
|
self.test_pubsub_topic,
|
||||||
|
{
|
||||||
|
"payload": to_base64(f"Message_4"),
|
||||||
|
"contentTopic": "/myapp/1/latest/proto",
|
||||||
|
"timestamp": timestamps[4], # Use the stored timestamp for Message_4
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
for i, message in enumerate(store_response_valid.messages):
|
||||||
|
assert message["messageHash"] == expected_message_hashes[i], f"Message hash mismatch for message {i}"
|
||||||
|
|
|
@ -64,3 +64,109 @@ class TestHashes(StepsStore):
|
||||||
assert not store_response.messages
|
assert not store_response.messages
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
assert "waku message hash parsing error: invalid hash length" in str(ex)
|
assert "waku message hash parsing error: invalid hash length" in str(ex)
|
||||||
|
|
||||||
|
# Addon on Test
|
||||||
|
|
||||||
|
# Test when the hashes parameter is an empty string.
|
||||||
|
def test_store_with_empty_hashes(self):
|
||||||
|
for i in range(4):
|
||||||
|
self.publish_message(message=self.create_message(payload=to_base64(f"Message_{i}")))
|
||||||
|
|
||||||
|
# Test with an empty string for the hashes parameter
|
||||||
|
for node in self.store_nodes:
|
||||||
|
store_response = self.get_messages_from_store(node, hashes="", page_size=50)
|
||||||
|
assert len(store_response.messages) == 4, "Messages found"
|
||||||
|
|
||||||
|
# Test when the hash is longer than the valid length (e.g., 45 characters or more).
|
||||||
|
def test_store_with_excessive_length_hash(self):
|
||||||
|
excessive_length_hash = "A" * 50 # Exceeds valid length of 44 characters for a Base64-encoded hash
|
||||||
|
for i in range(4):
|
||||||
|
self.publish_message(message=self.create_message(payload=to_base64(f"Message_{i}")))
|
||||||
|
|
||||||
|
for node in self.store_nodes:
|
||||||
|
store_response = self.get_store_messages_with_errors(node, hashes=excessive_length_hash, page_size=50)
|
||||||
|
|
||||||
|
# Check if the response has a "messages" key and if it's empty
|
||||||
|
assert "messages" not in store_response, "Messages found for an excessive length hash"
|
||||||
|
|
||||||
|
# Test the behavior when you supply an empty hash alongside valid hashes.
|
||||||
|
def test_store_with_empty_and_valid_hash(self):
|
||||||
|
message_hash_list = []
|
||||||
|
for i in range(4):
|
||||||
|
message = self.create_message(payload=to_base64(f"Message_{i}"))
|
||||||
|
self.publish_message(message=message)
|
||||||
|
message_hash_list.append(self.compute_message_hash(self.test_pubsub_topic, message))
|
||||||
|
|
||||||
|
empty_hash = ""
|
||||||
|
for node in self.store_nodes:
|
||||||
|
try:
|
||||||
|
# Combining valid hash with an empty hash
|
||||||
|
store_response = self.get_messages_from_store(node, hashes=f"{message_hash_list[0]},{empty_hash}", page_size=50)
|
||||||
|
assert len(store_response.messages) == 1, "Message count mismatch with empty and valid hashes"
|
||||||
|
except Exception as ex:
|
||||||
|
assert "waku message hash parsing error" in str(ex), "Unexpected error for combined empty and valid hash"
|
||||||
|
|
||||||
|
# Test for hashes that include non-Base64 characters.
|
||||||
|
def test_store_with_non_base64_characters_in_hash(self):
|
||||||
|
non_base64_hash = "###INVALID###" # Invalid hash with non-Base64 characters
|
||||||
|
for i in range(4):
|
||||||
|
self.publish_message(message=self.create_message(payload=to_base64(f"Message_{i}")))
|
||||||
|
|
||||||
|
for node in self.store_nodes:
|
||||||
|
store_response = self.get_store_messages_with_errors(node, hashes=non_base64_hash, page_size=50)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
"waku message hash parsing error: Incorrect base64 string" in store_response["error_message"]
|
||||||
|
), f"Expected 'Incorrect base64 string' error, got {store_response['error_message']}"
|
||||||
|
|
||||||
|
# Test when duplicate valid hashes are provided.
|
||||||
|
def test_store_with_duplicate_hashes(self):
|
||||||
|
message_hash_list = []
|
||||||
|
for i in range(4):
|
||||||
|
message = self.create_message(payload=to_base64(f"Message_{i}"))
|
||||||
|
self.publish_message(message=message)
|
||||||
|
message_hash_list.append(self.compute_message_hash(self.test_pubsub_topic, message))
|
||||||
|
|
||||||
|
# Use the same hash twice
|
||||||
|
duplicate_hash = f"{message_hash_list[0]},{message_hash_list[0]}"
|
||||||
|
for node in self.store_nodes:
|
||||||
|
store_response = self.get_messages_from_store(node, hashes=duplicate_hash, page_size=50)
|
||||||
|
assert len(store_response.messages) == 1, "Expected only one message for duplicate hashes"
|
||||||
|
assert store_response.message_hash(0) == message_hash_list[0], "Incorrect message returned for duplicate hashes"
|
||||||
|
|
||||||
|
# Invalid Query Parameter (hash) for Hashes
|
||||||
|
def test_invalid_hash_param(self):
|
||||||
|
# Publish 4 messages
|
||||||
|
published_messages = []
|
||||||
|
for i in range(4):
|
||||||
|
message = self.create_message(payload=to_base64(f"Message_{i}"))
|
||||||
|
self.publish_message(message=message)
|
||||||
|
published_messages.append(message)
|
||||||
|
|
||||||
|
for node in self.store_nodes:
|
||||||
|
# Step 1: Request messages with the correct 'hashes' parameter
|
||||||
|
correct_hash = self.compute_message_hash(self.test_pubsub_topic, published_messages[2])
|
||||||
|
store_response_valid = self.get_messages_from_store(node, hashes=correct_hash)
|
||||||
|
|
||||||
|
assert store_response_valid.status_code == 200, "Expected 200 response with correct 'hashes' parameter"
|
||||||
|
assert len(store_response_valid.messages) == 1, "Expected exactly one message in the response"
|
||||||
|
assert store_response_valid is not None and store_response_valid.messages, "Store response is None or has no messages"
|
||||||
|
assert store_response_valid.messages[0]["messageHash"] == correct_hash, "Returned message hash does not match the expected hash"
|
||||||
|
|
||||||
|
# Step 2: Attempt to use the invalid 'hash' parameter (expect all messages to be returned)
|
||||||
|
store_response_invalid = self.get_messages_from_store(node, hash=correct_hash)
|
||||||
|
|
||||||
|
assert store_response_invalid.status_code == 200, "Expected 200 response with invalid 'hash' parameter"
|
||||||
|
assert len(store_response_invalid.messages) == 4, "Expected all messages to be returned since 'hash' filter is ignored"
|
||||||
|
|
||||||
|
# Collect the hashes of all published messages
|
||||||
|
if store_response_invalid is not None and store_response_invalid.messages:
|
||||||
|
expected_hashes = [msg["messageHash"] for msg in store_response_invalid.messages]
|
||||||
|
returned_hashes = [msg["messageHash"] for msg in store_response_invalid.messages]
|
||||||
|
else:
|
||||||
|
expected_hashes = []
|
||||||
|
returned_hashes = []
|
||||||
|
|
||||||
|
print("expected_hashes: ", expected_hashes)
|
||||||
|
print("returned_hashes: ", returned_hashes)
|
||||||
|
assert set(returned_hashes) == set(expected_hashes), "Returned message hashes do not match the expected hashes"
|
||||||
|
|
Loading…
Reference in New Issue