Files
DashBoard/tests/test_template_integration.py
2026-02-08 08:30:48 +08:00

250 lines
8.8 KiB
Python

# -*- coding: utf-8 -*-
"""Unit tests for template integration with _base.html.
Verifies that all templates properly extend _base.html and include
required core JavaScript resources.
"""
import unittest
from unittest.mock import patch
from mes_dashboard.app import create_app
import mes_dashboard.core.database as db
def _login_as_admin(client):
with client.session_transaction() as sess:
sess['admin'] = {'displayName': 'Test Admin', 'employeeNo': 'A001'}
class TestTemplateIntegration(unittest.TestCase):
"""Test that all templates properly extend _base.html."""
def setUp(self):
db._ENGINE = None
self.app = create_app('testing')
self.app.config['TESTING'] = True
self.client = self.app.test_client()
_login_as_admin(self.client)
def test_portal_includes_base_scripts(self):
response = self.client.get('/')
self.assertEqual(response.status_code, 200)
html = response.data.decode('utf-8')
self.assertIn('toast.js', html)
self.assertIn('mes-api.js', html)
self.assertIn('mes-toast-container', html)
def test_wip_overview_includes_base_scripts(self):
response = self.client.get('/wip-overview')
self.assertEqual(response.status_code, 200)
html = response.data.decode('utf-8')
self.assertIn('toast.js', html)
self.assertIn('mes-api.js', html)
self.assertIn('mes-toast-container', html)
def test_wip_detail_includes_base_scripts(self):
response = self.client.get('/wip-detail')
self.assertEqual(response.status_code, 200)
html = response.data.decode('utf-8')
self.assertIn('toast.js', html)
self.assertIn('mes-api.js', html)
self.assertIn('mes-toast-container', html)
def test_tables_page_includes_base_scripts(self):
response = self.client.get('/tables')
self.assertEqual(response.status_code, 200)
html = response.data.decode('utf-8')
self.assertIn('toast.js', html)
self.assertIn('mes-api.js', html)
self.assertIn('mes-toast-container', html)
def test_resource_page_includes_base_scripts(self):
response = self.client.get('/resource')
self.assertEqual(response.status_code, 200)
html = response.data.decode('utf-8')
self.assertIn('toast.js', html)
self.assertIn('mes-api.js', html)
self.assertIn('mes-toast-container', html)
def test_excel_query_page_includes_base_scripts(self):
response = self.client.get('/excel-query')
self.assertEqual(response.status_code, 200)
html = response.data.decode('utf-8')
self.assertIn('toast.js', html)
self.assertIn('mes-api.js', html)
self.assertIn('mes-toast-container', html)
class TestToastCSSIntegration(unittest.TestCase):
"""Test that Toast CSS styles are included in pages."""
def setUp(self):
db._ENGINE = None
self.app = create_app('testing')
self.app.config['TESTING'] = True
self.client = self.app.test_client()
_login_as_admin(self.client)
def test_portal_includes_toast_css(self):
response = self.client.get('/')
html = response.data.decode('utf-8')
self.assertIn('.mes-toast-container', html)
self.assertIn('.mes-toast', html)
def test_wip_overview_includes_toast_css(self):
response = self.client.get('/wip-overview')
html = response.data.decode('utf-8')
self.assertIn('.mes-toast-container', html)
self.assertIn('.mes-toast', html)
def test_wip_detail_includes_toast_css(self):
response = self.client.get('/wip-detail')
html = response.data.decode('utf-8')
self.assertIn('.mes-toast-container', html)
self.assertIn('.mes-toast', html)
class TestMesApiUsageInTemplates(unittest.TestCase):
"""Test that templates either inline MesApi usage or load Vite modules."""
def setUp(self):
db._ENGINE = None
self.app = create_app('testing')
self.app.config['TESTING'] = True
self.client = self.app.test_client()
_login_as_admin(self.client)
def test_wip_overview_uses_mesapi(self):
response = self.client.get('/wip-overview')
html = response.data.decode('utf-8')
self.assertTrue('MesApi.get' in html or '/static/dist/wip-overview.js' in html)
self.assertNotIn('fetchWithTimeout', html)
def test_wip_detail_uses_mesapi(self):
response = self.client.get('/wip-detail')
html = response.data.decode('utf-8')
self.assertTrue('MesApi.get' in html or '/static/dist/wip-detail.js' in html)
self.assertNotIn('fetchWithTimeout', html)
def test_tables_page_uses_mesapi_or_vite_module(self):
response = self.client.get('/tables')
html = response.data.decode('utf-8')
self.assertTrue('MesApi.post' in html or '/static/dist/tables.js' in html)
def test_resource_page_uses_mesapi_or_vite_module(self):
response = self.client.get('/resource')
html = response.data.decode('utf-8')
self.assertTrue('MesApi.post' in html or '/static/dist/resource-status.js' in html)
class TestViteModuleFallbackIntegration(unittest.TestCase):
"""Ensure page templates support Vite module assets with inline fallback."""
def setUp(self):
db._ENGINE = None
self.app = create_app('testing')
self.app.config['TESTING'] = True
self.client = self.app.test_client()
_login_as_admin(self.client)
def test_pages_render_inline_fallback_when_asset_missing(self):
endpoints_and_markers = [
('/wip-overview', 'function applyFilters'),
('/wip-detail', 'function init'),
('/hold-detail?reason=test-reason', 'function loadAllData'),
('/tables', 'function loadTableData'),
('/resource', 'function loadData'),
('/resource-history', 'function executeQuery'),
('/job-query', 'function queryJobs'),
('/excel-query', 'function uploadExcel'),
]
for endpoint, marker in endpoints_and_markers:
with patch('mes_dashboard.app.os.path.exists', return_value=False):
response = self.client.get(endpoint)
self.assertEqual(response.status_code, 200)
html = response.data.decode('utf-8')
self.assertIn(marker, html)
def test_pages_render_vite_module_when_asset_exists(self):
endpoints_and_assets = [
('/wip-overview', 'wip-overview.js'),
('/wip-detail', 'wip-detail.js'),
('/hold-detail?reason=test-reason', 'hold-detail.js'),
('/tables', 'tables.js'),
('/resource', 'resource-status.js'),
('/resource-history', 'resource-history.js'),
('/job-query', 'job-query.js'),
('/excel-query', 'excel-query.js'),
]
for endpoint, asset in endpoints_and_assets:
with patch('mes_dashboard.app.os.path.exists', return_value=True):
response = self.client.get(endpoint)
self.assertEqual(response.status_code, 200)
html = response.data.decode('utf-8')
self.assertIn(f'/static/dist/{asset}', html)
self.assertIn('type="module"', html)
class TestStaticFilesServing(unittest.TestCase):
"""Test that static JavaScript files are served correctly."""
def setUp(self):
db._ENGINE = None
self.app = create_app('testing')
self.app.config['TESTING'] = True
self.client = self.app.test_client()
_login_as_admin(self.client)
def test_toast_js_is_served(self):
response = self.client.get('/static/js/toast.js')
self.assertEqual(response.status_code, 200)
content = response.data.decode('utf-8')
self.assertIn('Toast', content)
self.assertIn('info', content)
self.assertIn('success', content)
self.assertIn('error', content)
self.assertIn('loading', content)
def test_mes_api_js_is_served(self):
response = self.client.get('/static/js/mes-api.js')
self.assertEqual(response.status_code, 200)
content = response.data.decode('utf-8')
self.assertIn('MesApi', content)
self.assertIn('get', content)
self.assertIn('post', content)
self.assertIn('AbortController', content)
def test_toast_js_contains_retry_button(self):
response = self.client.get('/static/js/toast.js')
content = response.data.decode('utf-8')
self.assertIn('retry', content)
self.assertIn('mes-toast-retry', content)
def test_mes_api_js_has_exponential_backoff(self):
response = self.client.get('/static/js/mes-api.js')
content = response.data.decode('utf-8')
self.assertIn('1000', content)
self.assertIn('retry', content.lower())
if __name__ == "__main__":
unittest.main()