mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-04-28 08:21:13 -05:00
347 lines
12 KiB
Python
347 lines
12 KiB
Python
"""Tests for internationalization (i18n) functionality"""
|
|
|
|
import pytest
|
|
from flask import session
|
|
from app import create_app, db
|
|
from app.models import User
|
|
from flask_babel import get_locale
|
|
|
|
|
|
class TestI18nConfiguration:
|
|
"""Test internationalization configuration"""
|
|
|
|
def test_supported_languages_configured(self, client):
|
|
"""Test that all supported languages are configured"""
|
|
with client.application.app_context():
|
|
languages = client.application.config.get('LANGUAGES', {})
|
|
|
|
# Check that all required languages are present
|
|
assert 'en' in languages
|
|
assert 'de' in languages
|
|
assert 'fr' in languages
|
|
assert 'es' in languages
|
|
assert 'ar' in languages
|
|
assert 'he' in languages
|
|
assert 'nl' in languages
|
|
assert 'it' in languages
|
|
assert 'fi' in languages
|
|
|
|
# Check that language labels are set
|
|
assert languages['en'] == 'English'
|
|
assert languages['es'] == 'Español'
|
|
assert languages['ar'] == 'العربية'
|
|
assert languages['he'] == 'עברית'
|
|
|
|
def test_rtl_languages_configured(self, client):
|
|
"""Test that RTL languages are configured"""
|
|
with client.application.app_context():
|
|
rtl_languages = client.application.config.get('RTL_LANGUAGES', set())
|
|
|
|
# Check that RTL languages are present
|
|
assert 'ar' in rtl_languages
|
|
assert 'he' in rtl_languages
|
|
|
|
# Check that LTR languages are not in RTL set
|
|
assert 'en' not in rtl_languages
|
|
assert 'de' not in rtl_languages
|
|
assert 'es' not in rtl_languages
|
|
|
|
def test_default_locale_is_english(self, client):
|
|
"""Test that default locale is English"""
|
|
with client.application.app_context():
|
|
default_locale = client.application.config.get('BABEL_DEFAULT_LOCALE')
|
|
assert default_locale == 'en'
|
|
|
|
|
|
class TestLocaleSelection:
|
|
"""Test locale selection logic"""
|
|
|
|
def test_locale_from_user_preference(self, client, test_user):
|
|
"""Test that locale is selected from user's preference"""
|
|
# Set user's preferred language
|
|
test_user.preferred_language = 'de'
|
|
db.session.commit()
|
|
|
|
# Login as user
|
|
with client.session_transaction() as sess:
|
|
sess['_user_id'] = str(test_user.id)
|
|
|
|
# Check that locale is set to user's preference
|
|
with client.application.test_request_context():
|
|
with client.session_transaction() as sess:
|
|
# Simulate request context
|
|
from flask import g
|
|
from app import babel
|
|
|
|
# The locale selector should return user's preference
|
|
assert test_user.preferred_language == 'de'
|
|
|
|
def test_locale_from_session(self, client):
|
|
"""Test that locale is selected from session when not logged in"""
|
|
with client:
|
|
# Set language in session
|
|
with client.session_transaction() as sess:
|
|
sess['preferred_language'] = 'fr'
|
|
|
|
# Make a request
|
|
response = client.get('/')
|
|
|
|
# Check that session language is used
|
|
with client.session_transaction() as sess:
|
|
assert sess.get('preferred_language') == 'fr'
|
|
|
|
def test_locale_fallback_to_default(self, client):
|
|
"""Test that locale falls back to default when not set"""
|
|
with client:
|
|
# Don't set any language preference
|
|
response = client.get('/')
|
|
|
|
# Should use default locale (English)
|
|
assert response.status_code in [200, 302] # May redirect to login
|
|
|
|
|
|
class TestLanguageSwitching:
|
|
"""Test language switching functionality"""
|
|
|
|
def test_set_language_direct_route(self, client, test_user):
|
|
"""Test direct language switching route"""
|
|
# Login first
|
|
with client.session_transaction() as sess:
|
|
sess['_user_id'] = str(test_user.id)
|
|
|
|
# Switch to Spanish
|
|
response = client.get('/set-language/es', follow_redirects=False)
|
|
|
|
# Should redirect
|
|
assert response.status_code == 302
|
|
|
|
# Check that user's preference is updated
|
|
db.session.refresh(test_user)
|
|
assert test_user.preferred_language == 'es'
|
|
|
|
# Check that session is updated
|
|
with client.session_transaction() as sess:
|
|
assert sess.get('preferred_language') == 'es'
|
|
|
|
def test_set_language_api_endpoint(self, client, test_user):
|
|
"""Test API endpoint for language switching"""
|
|
# Login first
|
|
with client.session_transaction() as sess:
|
|
sess['_user_id'] = str(test_user.id)
|
|
|
|
# Switch to Arabic via API
|
|
response = client.post(
|
|
'/api/language',
|
|
json={'language': 'ar'},
|
|
content_type='application/json'
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
data = response.get_json()
|
|
assert data['success'] is True
|
|
assert data['language'] == 'ar'
|
|
|
|
# Check that user's preference is updated
|
|
db.session.refresh(test_user)
|
|
assert test_user.preferred_language == 'ar'
|
|
|
|
def test_set_invalid_language(self, client, test_user):
|
|
"""Test that invalid languages are rejected"""
|
|
# Login first
|
|
with client.session_transaction() as sess:
|
|
sess['_user_id'] = str(test_user.id)
|
|
|
|
# Try to set invalid language
|
|
response = client.post(
|
|
'/api/language',
|
|
json={'language': 'invalid'},
|
|
content_type='application/json'
|
|
)
|
|
|
|
assert response.status_code == 400
|
|
data = response.get_json()
|
|
assert 'error' in data
|
|
|
|
def test_language_persists_across_sessions(self, client, test_user):
|
|
"""Test that language preference persists across sessions"""
|
|
# Login and set language
|
|
with client.session_transaction() as sess:
|
|
sess['_user_id'] = str(test_user.id)
|
|
client.get('/set-language/de', follow_redirects=True)
|
|
|
|
# Logout
|
|
client.get('/auth/logout', follow_redirects=True)
|
|
|
|
# Login again
|
|
with client.session_transaction() as sess:
|
|
sess['_user_id'] = str(test_user.id)
|
|
|
|
# Check that language preference is still set
|
|
db.session.refresh(test_user)
|
|
assert test_user.preferred_language == 'de'
|
|
|
|
|
|
class TestRTLSupport:
|
|
"""Test Right-to-Left language support"""
|
|
|
|
def test_rtl_detection_for_arabic(self, client, test_user):
|
|
"""Test that Arabic is detected as RTL"""
|
|
# Set language to Arabic
|
|
test_user.preferred_language = 'ar'
|
|
db.session.commit()
|
|
|
|
# Login
|
|
with client.session_transaction() as sess:
|
|
sess['_user_id'] = str(test_user.id)
|
|
|
|
# Get dashboard
|
|
response = client.get('/dashboard')
|
|
|
|
# Check that page includes RTL directive
|
|
assert response.status_code == 200
|
|
assert b'dir="rtl"' in response.data or b"dir='rtl'" in response.data
|
|
|
|
def test_rtl_detection_for_hebrew(self, client, test_user):
|
|
"""Test that Hebrew is detected as RTL"""
|
|
# Set language to Hebrew
|
|
test_user.preferred_language = 'he'
|
|
db.session.commit()
|
|
|
|
# Login
|
|
with client.session_transaction() as sess:
|
|
sess['_user_id'] = str(test_user.id)
|
|
|
|
# Get dashboard
|
|
response = client.get('/dashboard')
|
|
|
|
# Check that page includes RTL directive
|
|
assert response.status_code == 200
|
|
assert b'dir="rtl"' in response.data or b"dir='rtl'" in response.data
|
|
|
|
def test_ltr_for_english(self, client, test_user):
|
|
"""Test that English is LTR"""
|
|
# Set language to English
|
|
test_user.preferred_language = 'en'
|
|
db.session.commit()
|
|
|
|
# Login
|
|
with client.session_transaction() as sess:
|
|
sess['_user_id'] = str(test_user.id)
|
|
|
|
# Get dashboard
|
|
response = client.get('/dashboard')
|
|
|
|
# Check that page includes LTR directive
|
|
assert response.status_code == 200
|
|
assert b'dir="ltr"' in response.data or b"dir='ltr'" in response.data
|
|
|
|
|
|
class TestTranslations:
|
|
"""Test that translations are working"""
|
|
|
|
def test_english_translations(self, client):
|
|
"""Test English translations"""
|
|
with client.application.test_request_context():
|
|
from flask_babel import _
|
|
|
|
# Test common translations
|
|
assert _('Dashboard') == 'Dashboard'
|
|
assert _('Projects') == 'Projects'
|
|
assert _('Login') == 'Login'
|
|
|
|
def test_translation_files_exist(self, client):
|
|
"""Test that translation files exist for all languages"""
|
|
import os
|
|
|
|
languages = ['en', 'de', 'fr', 'es', 'ar', 'he', 'nl', 'it', 'fi']
|
|
|
|
for lang in languages:
|
|
po_file = os.path.join('translations', lang, 'LC_MESSAGES', 'messages.po')
|
|
assert os.path.exists(po_file), f"Translation file missing for {lang}"
|
|
|
|
|
|
class TestLanguageSelectorUI:
|
|
"""Test language selector UI"""
|
|
|
|
def test_language_selector_in_header(self, client, test_user):
|
|
"""Test that language selector appears in header"""
|
|
# Login
|
|
with client.session_transaction() as sess:
|
|
sess['_user_id'] = str(test_user.id)
|
|
|
|
# Get dashboard
|
|
response = client.get('/dashboard')
|
|
|
|
# Check that language selector is present
|
|
assert response.status_code == 200
|
|
assert b'langDropdown' in response.data or b'lang-dropdown' in response.data.lower()
|
|
assert b'fa-globe' in response.data or b'globe' in response.data.lower()
|
|
|
|
def test_language_list_contains_all_languages(self, client, test_user):
|
|
"""Test that language selector contains all available languages"""
|
|
# Login
|
|
with client.session_transaction() as sess:
|
|
sess['_user_id'] = str(test_user.id)
|
|
|
|
# Get dashboard
|
|
response = client.get('/dashboard')
|
|
assert response.status_code == 200
|
|
response_text = response.data.decode('utf-8')
|
|
|
|
# Check for language names in the page
|
|
languages_to_check = ['English', 'Español', 'Français', 'Deutsch']
|
|
for lang in languages_to_check:
|
|
assert lang in response_text, f"Language '{lang}' not found in language selector"
|
|
|
|
|
|
class TestUserSettingsLanguage:
|
|
"""Test language settings in user settings page"""
|
|
|
|
def test_language_setting_in_user_settings(self, client, test_user):
|
|
"""Test that language setting is available in user settings"""
|
|
# Login
|
|
with client.session_transaction() as sess:
|
|
sess['_user_id'] = str(test_user.id)
|
|
|
|
# Get settings page
|
|
response = client.get('/settings')
|
|
|
|
# Check that language setting is present
|
|
assert response.status_code == 200
|
|
assert b'preferred_language' in response.data or b'language' in response.data.lower()
|
|
|
|
def test_save_language_in_user_settings(self, client, test_user):
|
|
"""Test saving language preference in user settings"""
|
|
# Login
|
|
with client.session_transaction() as sess:
|
|
sess['_user_id'] = str(test_user.id)
|
|
|
|
# Update settings with language
|
|
response = client.post('/settings', data={
|
|
'preferred_language': 'fr',
|
|
'full_name': test_user.full_name or 'Test User',
|
|
'email': test_user.email or 'test@example.com'
|
|
}, follow_redirects=True)
|
|
|
|
# Check that setting was saved
|
|
assert response.status_code == 200
|
|
db.session.refresh(test_user)
|
|
assert test_user.preferred_language == 'fr'
|
|
|
|
|
|
@pytest.fixture
|
|
def test_user(client):
|
|
"""Create a test user"""
|
|
with client.application.app_context():
|
|
user = User(username='testuser', role='user')
|
|
user.is_active = True
|
|
db.session.add(user)
|
|
db.session.commit()
|
|
yield user
|
|
# Cleanup - delete related activities first to avoid constraint violations
|
|
from app.models import Activity
|
|
Activity.query.filter_by(user_id=user.id).delete()
|
|
db.session.delete(user)
|
|
db.session.commit()
|
|
|