Spaces:
Paused
Paused
File size: 15,037 Bytes
8b9e569 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 | import pytest
import sys
from unittest.mock import patch
from classes.session_document_store import SessionDocumentStore
from constants import MAX_FILE_SIZES_PER_SESSION
class TestSessionDocumentStore:
"""Unit tests for SessionDocumentStore class"""
@pytest.fixture
def store(self):
"""Fresh store instance for each test"""
return SessionDocumentStore()
@pytest.fixture
def sample_session_id(self):
return "test-session-123"
@pytest.fixture
def sample_file_text(self):
return "This is sample file content"
@pytest.fixture
def sample_file_name(self):
return "document.txt"
# ==================== create_document Tests ====================
def test_create_document_new_session(
self, store, sample_session_id, sample_file_text, sample_file_name
):
"""Test creating a document in a new session"""
result = store.create_document(
sample_session_id, sample_file_text, sample_file_name
)
assert result is True
assert sample_session_id in store.session_document_map
assert sample_file_name in store.session_document_map[sample_session_id]
stored_text, stored_size = store.session_document_map[sample_session_id][
sample_file_name
]
assert stored_text == sample_file_text
assert stored_size == sys.getsizeof(sample_file_text)
def test_create_document_existing_session(self, store, sample_session_id):
"""Test adding multiple documents to the same session"""
file1_text = "First document"
file2_text = "Second document"
result1 = store.create_document(sample_session_id, file1_text, "file1.txt")
result2 = store.create_document(sample_session_id, file2_text, "file2.txt")
assert result1 is True
assert result2 is True
assert len(store.session_document_map[sample_session_id]) == 2
assert "file1.txt" in store.session_document_map[sample_session_id]
assert "file2.txt" in store.session_document_map[sample_session_id]
def test_create_document_duplicate_filename_overwrites(
self, store, sample_session_id
):
"""Test that creating a document with same filename overwrites the previous one"""
first_text = "Original content"
updated_text = "Updated content"
filename = "document.txt"
store.create_document(sample_session_id, first_text, filename)
store.create_document(sample_session_id, updated_text, filename)
stored_text, _ = store.session_document_map[sample_session_id][filename]
assert stored_text == updated_text
assert len(store.session_document_map[sample_session_id]) == 1
def test_create_document_exceeds_size_limit(self, store, sample_session_id):
"""Test that documents exceeding size limit are rejected"""
# Create a large text that exceeds the limit
large_text = "x" * (MAX_FILE_SIZES_PER_SESSION + 1000)
result = store.create_document(sample_session_id, large_text, "large.txt")
assert result is False
assert sample_session_id not in store.session_document_map
def test_create_document_cumulative_size_limit(self, store, sample_session_id):
"""Test that cumulative size across multiple files is enforced"""
# Calculate size that would fit individually but not together
half_limit_size = MAX_FILE_SIZES_PER_SESSION // 2
# Create text slightly over half the limit
text1 = "a" * (half_limit_size - 100)
text2 = "b" * (half_limit_size - 100)
text3 = "c" * 1000 # This should push over the limit
result1 = store.create_document(sample_session_id, text1, "file1.txt")
result2 = store.create_document(sample_session_id, text2, "file2.txt")
result3 = store.create_document(sample_session_id, text3, "file3.txt")
assert result1 is True
assert result2 is True
assert result3 is False # Should be rejected
assert len(store.session_document_map[sample_session_id]) == 2
def test_create_document_exactly_at_limit(self, store, sample_session_id):
"""Test edge case where document is exactly at the size limit"""
# Mock sys.getsizeof to return exact limit
with patch("sys.getsizeof", return_value=MAX_FILE_SIZES_PER_SESSION):
result = store.create_document(sample_session_id, "text", "file.txt")
assert result is True
def test_create_document_one_byte_over_limit(self, store, sample_session_id):
"""Test edge case where document is one byte over the limit"""
with patch("sys.getsizeof", return_value=MAX_FILE_SIZES_PER_SESSION + 1):
result = store.create_document(sample_session_id, "text", "file.txt")
assert result is False
def test_create_document_empty_text(self, store, sample_session_id):
"""Test creating a document with empty text"""
result = store.create_document(sample_session_id, "", "empty.txt")
assert result is True
assert "" == store.session_document_map[sample_session_id]["empty.txt"][0]
def test_create_document_special_characters_in_filename(
self, store, sample_session_id
):
"""Test filenames with special characters"""
special_filenames = [
"file with spaces.txt",
"file_with_underscores.txt",
"file-with-dashes.txt",
"file.multiple.dots.txt",
]
for filename in special_filenames:
result = store.create_document(sample_session_id, "content", filename)
assert result is True
assert filename in store.session_document_map[sample_session_id]
# ==================== get_document_contents Tests ====================
def test_get_document_contents_single_document(self, store, sample_session_id):
"""Test retrieving content from a session with one document"""
text = "Document content"
store.create_document(sample_session_id, text, "file.txt")
contents = store.get_document_contents(sample_session_id)
assert contents is not None
assert len(contents) == 1
assert contents[0] == text
def test_get_document_contents_multiple_documents(self, store, sample_session_id):
"""Test retrieving content from a session with multiple documents"""
texts = ["First doc", "Second doc", "Third doc"]
filenames = ["file1.txt", "file2.txt", "file3.txt"]
for text, filename in zip(texts, filenames):
store.create_document(sample_session_id, text, filename)
contents = store.get_document_contents(sample_session_id)
assert contents is not None
assert len(contents) == 3
assert set(contents) == set(texts)
def test_get_document_contents_nonexistent_session(self, store):
"""Test retrieving content from a session that doesn't exist"""
contents = store.get_document_contents("nonexistent-session")
assert contents is None
def test_get_document_contents_empty_session(self, store, sample_session_id):
"""Test retrieving content from a session with no documents"""
# Create session but then delete all documents
store.create_document(sample_session_id, "text", "file.txt")
store.delete_document(sample_session_id, "file.txt")
contents = store.get_document_contents(sample_session_id)
assert contents is None
def test_get_document_contents_returns_list(self, store, sample_session_id):
"""Test that get_document_contents returns a list type"""
store.create_document(sample_session_id, "text", "file.txt")
contents = store.get_document_contents(sample_session_id)
assert isinstance(contents, list)
# ==================== delete_document Tests ====================
def test_delete_document_existing_file(self, store, sample_session_id):
"""Test deleting an existing document"""
store.create_document(sample_session_id, "text1", "file1.txt")
store.create_document(sample_session_id, "text2", "file2.txt")
result = store.delete_document(sample_session_id, "file1.txt")
assert result is False # Session still has documents
assert "file1.txt" not in store.session_document_map[sample_session_id]
assert "file2.txt" in store.session_document_map[sample_session_id]
def test_delete_document_last_file_removes_session(self, store, sample_session_id):
"""Test that deleting the last document removes the session"""
store.create_document(sample_session_id, "text", "file.txt")
result = store.delete_document(sample_session_id, "file.txt")
assert result is True # Session was deleted
assert sample_session_id not in store.session_document_map
def test_delete_document_nonexistent_session(self, store):
"""Test deleting a document from a nonexistent session"""
result = store.delete_document("nonexistent-session", "file.txt")
assert result is False
def test_delete_document_nonexistent_file(self, store, sample_session_id):
"""Test deleting a file that doesn't exist in the session"""
store.create_document(sample_session_id, "text", "file1.txt")
result = store.delete_document(sample_session_id, "nonexistent.txt")
assert result is False
assert "file1.txt" in store.session_document_map[sample_session_id]
def test_delete_document_frees_up_space(self, store, sample_session_id):
"""Test that deleting a document frees up space for new uploads"""
# Fill up to near limit
large_text = "x" * (MAX_FILE_SIZES_PER_SESSION - 1000)
store.create_document(sample_session_id, large_text, "large.txt")
# Try to add another file - should fail
result1 = store.create_document(sample_session_id, "y" * 2000, "file2.txt")
assert result1 is False
# Delete the large file
store.delete_document(sample_session_id, "large.txt")
# Now should succeed (assuming session wasn't deleted)
if sample_session_id in store.session_document_map:
result2 = store.create_document(sample_session_id, "y" * 2000, "file2.txt")
assert result2 is True
# ==================== delete_session_documents Tests ====================
def test_delete_session_documents_existing_session(self, store, sample_session_id):
"""Test deleting an entire session"""
store.create_document(sample_session_id, "text1", "file1.txt")
store.create_document(sample_session_id, "text2", "file2.txt")
result = store.delete_session_documents(sample_session_id)
assert result is True
assert sample_session_id not in store.session_document_map
def test_delete_session_documents_nonexistent_session(self, store):
"""Test deleting a session that doesn't exist"""
result = store.delete_session_documents("nonexistent-session")
assert result is False
def test_delete_session_documents_multiple_sessions(self, store):
"""Test that deleting one session doesn't affect others"""
session1 = "session-1"
session2 = "session-2"
store.create_document(session1, "text1", "file1.txt")
store.create_document(session2, "text2", "file2.txt")
store.delete_session_documents(session1)
assert session1 not in store.session_document_map
assert session2 in store.session_document_map
assert "file2.txt" in store.session_document_map[session2]
# ==================== Integration Tests ====================
def test_full_workflow(self, store):
"""Test complete workflow: create, retrieve, delete"""
session_id = "workflow-session"
# Create documents
store.create_document(session_id, "Doc 1", "file1.txt")
store.create_document(session_id, "Doc 2", "file2.txt")
# Retrieve
contents = store.get_document_contents(session_id)
assert len(contents) == 2
# Delete one
store.delete_document(session_id, "file1.txt")
contents = store.get_document_contents(session_id)
assert len(contents) == 1
# Delete last one
store.delete_document(session_id, "file2.txt")
contents = store.get_document_contents(session_id)
assert contents is None
def test_multiple_sessions_isolation(self, store):
"""Test that sessions are isolated from each other"""
session1 = "session-1"
session2 = "session-2"
store.create_document(session1, "Session 1 content", "file.txt")
store.create_document(session2, "Session 2 content", "file.txt")
contents1 = store.get_document_contents(session1)
contents2 = store.get_document_contents(session2)
assert contents1[0] == "Session 1 content"
assert contents2[0] == "Session 2 content"
def test_size_calculation_accuracy(self, store, sample_session_id):
"""Test that size calculations match sys.getsizeof"""
text = "Test content for size validation"
expected_size = sys.getsizeof(text)
store.create_document(sample_session_id, text, "file.txt")
_, actual_size = store.session_document_map[sample_session_id]["file.txt"]
assert actual_size == expected_size
def test_concurrent_operations_same_session(self, store, sample_session_id):
"""Test multiple operations on the same session"""
# Add files
store.create_document(sample_session_id, "text1", "file1.txt")
store.create_document(sample_session_id, "text2", "file2.txt")
# Update one
store.create_document(sample_session_id, "updated text1", "file1.txt")
# Delete one
store.delete_document(sample_session_id, "file2.txt")
# Verify final state
contents = store.get_document_contents(sample_session_id)
assert len(contents) == 1
assert contents[0] == "updated text1"
def test_edge_case_zero_byte_file(self, store, sample_session_id):
"""Test handling of zero-byte files"""
with patch("sys.getsizeof", return_value=0):
result = store.create_document(sample_session_id, "", "empty.txt")
assert result is True
# Should be able to add many zero-byte files
for i in range(100):
result = store.create_document(sample_session_id, "", f"empty{i}.txt")
assert result is True
|