Files
SaaS-PDF/backend/tests/test_download.py
Your Name 314f847ece fix: Add scrollable container to ToolSelectorModal for small screens
- Add max-h-[90vh] and flex-col to modal content container
- Wrap tools grid in max-h-[50vh] overflow-y-auto container
- Add overscroll-contain for smooth scroll behavior on mobile
- Fixes issue where 21 PDF tools overflow viewport on small screens
2026-04-01 22:22:48 +02:00

97 lines
4.1 KiB
Python

"""Tests for file download route."""
import os
from app.services.account_service import create_user
from app.utils.auth import TASK_ACCESS_SESSION_KEY
class TestDownload:
def test_download_anonymous_returns_401(self, client):
"""Anonymous users should be blocked by the download gate."""
response = client.get('/api/download/some-task-id/output.pdf')
assert response.status_code == 401
assert response.get_json()['error'] == 'signup_required'
def test_download_nonexistent_file(self, client, app):
"""Should return 404 for missing file when authenticated."""
with app.app_context():
user = create_user('download-test@example.com', 'pass12345')
with client.session_transaction() as session:
session['user_id'] = user['id']
session[TASK_ACCESS_SESSION_KEY] = ['some-task-id']
response = client.get('/api/download/some-task-id/output.pdf')
assert response.status_code == 404
def test_download_path_traversal_task_id(self, client):
"""Should reject task_id with path traversal characters."""
response = client.get('/api/download/../etc/output.pdf')
# Flask will handle this — either 400 or 404
assert response.status_code in (400, 404)
def test_download_path_traversal_filename(self, client):
"""Should reject filename with path traversal characters."""
response = client.get('/api/download/valid-id/../../etc/passwd')
assert response.status_code in (400, 404)
def test_download_valid_file(self, client, app):
"""Should serve file if it exists and user is authenticated."""
task_id = 'test-download-id'
filename = 'output.pdf'
with app.app_context():
user = create_user('download-valid@example.com', 'pass12345')
# Create the file in the output directory
output_dir = os.path.join(app.config['OUTPUT_FOLDER'], task_id)
os.makedirs(output_dir, exist_ok=True)
file_path = os.path.join(output_dir, filename)
with open(file_path, 'wb') as f:
f.write(b'%PDF-1.4 test content')
with client.session_transaction() as session:
session['user_id'] = user['id']
session[TASK_ACCESS_SESSION_KEY] = [task_id]
response = client.get(f'/api/download/{task_id}/{filename}')
assert response.status_code == 200
assert response.data == b'%PDF-1.4 test content'
def test_download_with_custom_name(self, client, app):
"""Should use the ?name= parameter as download filename."""
task_id = 'test-name-id'
filename = 'output.pdf'
with app.app_context():
user = create_user('download-name@example.com', 'pass12345')
output_dir = os.path.join(app.config['OUTPUT_FOLDER'], task_id)
os.makedirs(output_dir, exist_ok=True)
with open(os.path.join(output_dir, filename), 'wb') as f:
f.write(b'%PDF-1.4')
with client.session_transaction() as session:
session['user_id'] = user['id']
session[TASK_ACCESS_SESSION_KEY] = [task_id]
response = client.get(f'/api/download/{task_id}/{filename}?name=my-document.pdf')
assert response.status_code == 200
def test_download_requires_task_access(self, client, app):
"""Should not serve an existing file without task access, even if authenticated."""
task_id = 'protected-download-id'
filename = 'output.pdf'
with app.app_context():
user = create_user('download-noaccess@example.com', 'pass12345')
output_dir = os.path.join(app.config['OUTPUT_FOLDER'], task_id)
os.makedirs(output_dir, exist_ok=True)
with open(os.path.join(output_dir, filename), 'wb') as f:
f.write(b'%PDF-1.4 protected')
with client.session_transaction() as session:
session['user_id'] = user['id']
# No TASK_ACCESS_SESSION_KEY set — user can't access this task
response = client.get(f'/api/download/{task_id}/{filename}')
assert response.status_code == 404