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
This commit is contained in:
Your Name
2026-04-01 22:22:48 +02:00
parent 3e1c0e5f99
commit 314f847ece
49 changed files with 2142 additions and 361 deletions

View File

@@ -46,7 +46,8 @@ class TestConfigEndpoint:
usage = data["usage"]
assert usage["plan"] == "free"
assert "web_quota" in usage
assert "api_quota" in usage
assert "credits" in usage
assert usage["credits"]["credits_allocated"] == 50
def test_max_upload_mb_is_correct(self, client):
"""max_upload_mb should equal the largest single-type limit."""

View File

@@ -1,12 +1,24 @@
"""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_nonexistent_file(self, client):
"""Should return 404 for missing file."""
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
@@ -22,10 +34,13 @@ class TestDownload:
assert response.status_code in (400, 404)
def test_download_valid_file(self, client, app):
"""Should serve file if it exists."""
"""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)
@@ -34,6 +49,7 @@ class TestDownload:
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}')
@@ -45,26 +61,37 @@ class TestDownload:
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 session or API ownership."""
"""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