Bug fixes for uploading the files. I though the changes being made where not supposed to break legacy endpoints. Not sure what happened. Either way things are almost back to normal.

This commit is contained in:
Scott Idem
2026-01-22 16:49:03 -05:00
parent 48d9e38c39
commit 1e6b9d1c18
8 changed files with 521 additions and 17 deletions

View File

@@ -0,0 +1,70 @@
import sys
import os
from unittest.mock import MagicMock
# Add project root to path
sys.path.append(os.getcwd())
# Mock dependencies to allow importing the model without side effects
mock_config = MagicMock()
mock_config.settings = MagicMock()
sys.modules["app.config"] = mock_config
sys.modules["redis"] = MagicMock()
sys.modules["app.log"] = MagicMock()
sys.modules["app.lib_general"] = MagicMock()
# Mock app.db_sql
mock_db_sql = MagicMock()
mock_db_sql.get_id_random.return_value = "random_str_abc"
sys.modules["app.db_sql"] = mock_db_sql
from app.models.hosted_file_models import Hosted_File_Base
def test_hosted_file_model_id_mapping():
print("--- Testing Hosted_File_Base ID Mapping ---")
# 1. Test simulation of database record (integers)
db_record = {
"id": 123,
"id_random": "random_str_abc",
"account_id": 456,
"account_id_random": "acc_rand_xyz",
"filename": "test.txt",
"extension": "txt"
}
model = Hosted_File_Base(**db_record)
result = model.dict(by_alias=True)
print(f"Model Data (by_alias=True): {result}")
# Verify that the frontend sees string IDs
assert result.get("id") == "random_str_abc"
assert result.get("hosted_file_id") == "random_str_abc"
assert result.get("account_id") == "acc_rand_xyz"
# 2. Test simulation of manual creation with mixed IDs
manual_data = {
"account_id": 456, # already resolved integer
"account_id_random": "acc_rand_xyz",
"id_random": "new_file_id"
}
model2 = Hosted_File_Base(**manual_data)
result2 = model2.dict(by_alias=True)
print(f"Model Data 2 (by_alias=True): {result2}")
assert result2.get("account_id") == "acc_rand_xyz"
assert result2.get("id") == "new_file_id"
print("✅ Hosted_File_Base ID mapping verified.")
if __name__ == "__main__":
try:
test_hosted_file_model_id_mapping()
print("\n🎉 MODEL LOGIC TEST PASSED!")
except Exception as e:
print(f"\n❌ TEST FAILED: {e}")
import traceback
traceback.print_exc()
sys.exit(1)

View File

@@ -0,0 +1,71 @@
import sys
import os
from unittest.mock import MagicMock, patch
# Add project root to path
sys.path.append(os.getcwd())
# Mock dependencies
mock_config = MagicMock()
mock_config.settings = MagicMock()
sys.modules["app.config"] = mock_config
sys.modules["redis"] = MagicMock()
sys.modules["app.log"] = MagicMock()
sys.modules["app.lib_general"] = MagicMock()
# Valid random IDs are typically 11 or 22 chars
VALID_RAND_ID = "Q8lR8Ai8hx2FjbQ3C_EH1Q"
from app.lib_redis_helpers import lookup_id_random_pop
def test_hosted_file_resolver_logic():
print("--- Testing ID Resolver logic (lookup_id_random_pop) ---")
# Correctly patch the function where it is DEFINED
with patch('app.lib_redis_helpers.redis_lookup_id_random', side_effect=lambda record_id_random, table_name: 123 if record_id_random == VALID_RAND_ID else 999):
# 1. Test Vision-style payload (account_id is a string)
payload = {
"account_id": VALID_RAND_ID,
"filename": "test.txt"
}
result = lookup_id_random_pop(payload.copy())
print(f"Vision Payload Result: {result}")
# Verify it resolved the string to an integer
assert result.get("account_id") == 123
# 2. Test Legacy-style payload (account_id_random is a string)
payload_legacy = {
"account_id_random": VALID_RAND_ID,
"filename": "test.txt"
}
result_legacy = lookup_id_random_pop(payload_legacy.copy())
print(f"Legacy Payload Result: {result_legacy}")
# Verify it resolved and popped the random key
assert result_legacy.get("account_id") == 123
assert "account_id_random" not in result_legacy
# 3. Test mixed/polymorphic
payload_poly = {
"link_to_type": "archive_content",
"link_to_id": VALID_RAND_ID
}
result_poly = lookup_id_random_pop(payload_poly.copy())
print(f"Polymorphic Payload Result: {result_poly}")
assert result_poly.get("link_to_id") == 123
print("✅ ID Resolver logic verified.")
if __name__ == "__main__":
try:
test_hosted_file_resolver_logic()
print("\n🎉 RESOLVER LOGIC TEST PASSED!")
except Exception as e:
print(f"\n❌ TEST FAILED: {e}")
import traceback
traceback.print_exc()
sys.exit(1)

View File

@@ -0,0 +1,138 @@
import sys
import os
import asyncio
from unittest.mock import MagicMock, AsyncMock, patch
# Add project root to path
sys.path.append(os.getcwd())
# Mock EVERYTHING before imports
mock_config = MagicMock()
mock_settings = MagicMock()
mock_settings.DB = {'connect_timeout': 10}
mock_config.settings = mock_settings
sys.modules["app.config"] = mock_config
sys.modules["redis"] = MagicMock()
sys.modules["app.log"] = MagicMock()
sys.modules["app.lib_general"] = MagicMock()
sys.modules["app.db_sql"] = MagicMock()
sys.modules["app.db_connection"] = MagicMock()
# Import the target router
import app.routers.hosted_file as router_mod
from app.models.hosted_file_models import Hosted_File_Base
async def test_upload_files_logic_flow():
print("--- Testing upload_files() Logic Flow (Unit) ---")
# Mock parameters
mock_file = MagicMock()
mock_file.filename = "test.txt"
mock_file.content_type = "text/plain"
file_list = [mock_file]
account_id_rand = "Q8lR8Ai8hx2FjbQ3C_EH1Q"
link_to_type = "archive_content"
link_to_id_rand = "bZOa7CtUm0E8hx2FjbQ3C_"
# Mock internal function returns
save_file_ret = {
'saved': True,
'already_exists': False,
'hash_sha256': 'mock_hash',
'extension_allowed': True,
'copy_timer': 0.1,
'filename': 'test.txt',
'extension': 'txt',
'subdirectory_path': 'mo'
}
# Mock load_hosted_file_obj to return a model that prioritizes strings
mock_model = Hosted_File_Base(
id="FILE_RAND_ID",
hosted_file_id="FILE_RAND_ID",
account_id=account_id_rand,
filename="test.txt"
)
with patch('app.routers.hosted_file.redis_lookup_id_random', side_effect=[1, 2]), \
patch('app.routers.hosted_file.save_file', AsyncMock(return_value=save_file_ret)), \
patch('app.routers.hosted_file.create_hosted_file_obj', return_value=123), \
patch('app.routers.hosted_file.load_hosted_file_obj', return_value=mock_model.dict(by_alias=True)), \
patch('app.routers.hosted_file.create_hosted_file_link', return_value=True), \
patch('app.routers.hosted_file.mk_resp', side_effect=lambda data, **kwargs: data):
# Call the router function directly
result = await router_mod.upload_files(
file_list=file_list,
account_id=account_id_rand,
link_to_type=link_to_type,
link_to_id=link_to_id_rand,
x_account_id=account_id_rand,
response=MagicMock()
)
print(f"Result List Count: {len(result)}")
file_resp = result[0]
print(f"File Response Keys: {list(file_resp.keys())}")
print(f"File ID: {file_resp.get('id')}")
assert len(result) == 1
assert file_resp.get('id') == "FILE_RAND_ID"
assert file_resp.get('hosted_file_id') == "FILE_RAND_ID"
print("✅ Single upload flow verified.")
async def test_triple_upload_logic_flow():
print("\n--- Testing Triple upload_files() Logic Flow (Unit) ---")
file_list = [MagicMock(filename=f"f{i}.txt") for i in range(3)]
account_id_rand = "Q8lR8Ai8hx2FjbQ3C_EH1Q"
save_file_side_effect = [
{'saved': True, 'already_exists': False, 'hash_sha256': f'h{i}', 'extension_allowed': True, 'copy_timer': 0.1, 'filename': f'f{i}.txt', 'extension': 'txt'}
for i in range(3)
]
load_hosted_side_effect = [
{'id': f'ID_{i}', 'hosted_file_id': f'ID_{i}', 'filename': f'f{i}.txt'}
for i in range(3)
]
with patch('app.routers.hosted_file.redis_lookup_id_random', return_value=1), \
patch('app.routers.hosted_file.save_file', AsyncMock(side_effect=save_file_side_effect)), \
patch('app.routers.hosted_file.create_hosted_file_obj', return_value=123), \
patch('app.routers.hosted_file.load_hosted_file_obj', side_effect=load_hosted_side_effect), \
patch('app.routers.hosted_file.create_hosted_file_link', return_value=True), \
patch('app.routers.hosted_file.mk_resp', side_effect=lambda data, **kwargs: data):
result = await router_mod.upload_files(
file_list=file_list,
account_id=account_id_rand,
link_to_type="archive_content",
link_to_id="some_id",
x_account_id=account_id_rand,
response=MagicMock()
)
print(f"Result List Count: {len(result)}")
assert len(result) == 3
for i, item in enumerate(result):
print(f" File {i+1} ID: {item.get('id')}")
assert item.get('id') == f'ID_{i}'
print("✅ Triple upload flow verified.")
async def main():
await test_upload_files_logic_flow()
await test_triple_upload_logic_flow()
if __name__ == "__main__":
try:
asyncio.run(main())
print("\n🎉 ALL UPLOAD FLOW TESTS PASSED!")
except Exception as e:
print(f"\n❌ TEST FAILED: {e}")
import traceback
traceback.print_exc()
sys.exit(1)