Spaces:
Sleeping
Sleeping
""" | |
اختبارات تكامل للوحة المعلومات | |
""" | |
import unittest | |
import pandas as pd | |
import numpy as np | |
import os | |
import sys | |
import json | |
from datetime import datetime, timedelta | |
# إضافة المسار الرئيسي للمشروع لاستيراد الوحدات | |
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..'))) | |
from modules.reports.reports_app import ReportsApp | |
import streamlit as st | |
class TestDashboard(unittest.TestCase): | |
"""اختبارات تكامل للوحة المعلومات""" | |
def setUp(self): | |
"""إعداد بيئة الاختبار""" | |
self.reports_app = ReportsApp() | |
# إنشاء بيانات محاكاة للمشاريع | |
self.mock_projects = [ | |
{ | |
'id': 1, | |
'name': 'مشروع 1', | |
'number': 'T-2024001', | |
'client': 'وزارة الصحة', | |
'location': 'الرياض', | |
'status': 'جديد', | |
'submission_date': '2024-01-15', | |
'tender_type': 'عامة', | |
'created_at': '2024-01-10', | |
'value': 1500000, | |
'local_content': 75 | |
}, | |
{ | |
'id': 2, | |
'name': 'مشروع 2', | |
'number': 'T-2024002', | |
'client': 'وزارة التعليم', | |
'location': 'جدة', | |
'status': 'قيد التسعير', | |
'submission_date': '2024-01-28', | |
'tender_type': 'خاصة', | |
'created_at': '2024-01-20', | |
'value': 4500000, | |
'local_content': 80 | |
}, | |
{ | |
'id': 3, | |
'name': 'مشروع 3', | |
'number': 'T-2024003', | |
'client': 'وزارة الصحة', | |
'location': 'الدمام', | |
'status': 'تم التقديم', | |
'submission_date': '2024-02-10', | |
'tender_type': 'عامة', | |
'created_at': '2024-02-01', | |
'value': 8000000, | |
'local_content': 70 | |
}, | |
{ | |
'id': 4, | |
'name': 'مشروع 4', | |
'number': 'T-2024004', | |
'client': 'شركة أرامكو', | |
'location': 'الظهران', | |
'status': 'تمت الترسية', | |
'submission_date': '2024-02-15', | |
'tender_type': 'عامة', | |
'created_at': '2024-02-05', | |
'value': 15000000, | |
'local_content': 85 | |
}, | |
{ | |
'id': 5, | |
'name': 'مشروع 5', | |
'number': 'T-2024005', | |
'client': 'شركة سابك', | |
'location': 'الجبيل', | |
'status': 'قيد التنفيذ', | |
'submission_date': '2024-02-20', | |
'tender_type': 'خاصة', | |
'created_at': '2024-02-10', | |
'value': 25000000, | |
'local_content': 75 | |
}, | |
{ | |
'id': 6, | |
'name': 'مشروع 6', | |
'number': 'T-2024006', | |
'client': 'وزارة النقل', | |
'location': 'الرياض', | |
'status': 'منتهي', | |
'submission_date': '2024-01-05', | |
'tender_type': 'عامة', | |
'created_at': '2023-12-20', | |
'value': 5000000, | |
'local_content': 72 | |
}, | |
{ | |
'id': 7, | |
'name': 'مشروع 7', | |
'number': 'T-2024007', | |
'client': 'وزارة الإسكان', | |
'location': 'مكة', | |
'status': 'ملغي', | |
'submission_date': '2024-01-10', | |
'tender_type': 'خاصة', | |
'created_at': '2023-12-25', | |
'value': 12000000, | |
'local_content': 65 | |
} | |
] | |
# تعيين المشاريع في حالة الجلسة | |
st.session_state.projects = self.mock_projects | |
def test_dashboard_metrics(self): | |
"""اختبار مؤشرات لوحة المعلومات الرئيسية""" | |
# الحصول على المؤشرات | |
total_projects = self.reports_app._get_total_projects() | |
active_projects = self.reports_app._get_active_projects() | |
won_projects = self.reports_app._get_won_projects() | |
avg_local_content = self.reports_app._get_avg_local_content() | |
# التحقق من المؤشرات | |
self.assertEqual(total_projects, 7) | |
self.assertEqual(active_projects, 4) # قيد التسعير، تم التقديم، تمت الترسية، قيد التنفيذ | |
self.assertEqual(won_projects, 3) # تمت الترسية، قيد التنفيذ، منتهي | |
# التحقق من أن متوسط المحتوى المحلي قريب من القيمة المتوقعة | |
expected_avg_local_content = sum(p['local_content'] for p in self.mock_projects) / len(self.mock_projects) | |
self.assertAlmostEqual(avg_local_content, expected_avg_local_content, delta=1.0) | |
def test_project_status_distribution(self): | |
"""اختبار توزيع المشاريع حسب الحالة""" | |
# الحصول على بيانات التوزيع | |
status_data = self.reports_app._get_project_status_data() | |
# التحقق من أن البيانات إطار بيانات | |
self.assertIsInstance(status_data, pd.DataFrame) | |
# التحقق من الأعمدة | |
self.assertIn('status', status_data.columns) | |
self.assertIn('count', status_data.columns) | |
# التحقق من أن عدد الحالات الفريدة يساوي 7 | |
self.assertEqual(len(status_data), 7) | |
# التحقق من أن مجموع المشاريع صحيح | |
self.assertEqual(status_data['count'].sum(), 7) | |
# التحقق من عدد المشاريع في كل حالة | |
status_counts = status_data.set_index('status')['count'].to_dict() | |
self.assertEqual(status_counts['جديد'], 1) | |
self.assertEqual(status_counts['قيد التسعير'], 1) | |
self.assertEqual(status_counts['تم التقديم'], 1) | |
self.assertEqual(status_counts['تمت الترسية'], 1) | |
self.assertEqual(status_counts['قيد التنفيذ'], 1) | |
self.assertEqual(status_counts['منتهي'], 1) | |
self.assertEqual(status_counts['ملغي'], 1) | |
def test_monthly_trend_data(self): | |
"""اختبار بيانات الاتجاه الشهري""" | |
# الحصول على بيانات الاتجاه | |
monthly_data = self.reports_app._get_monthly_project_data() | |
# التحقق من أن البيانات إطار بيانات | |
self.assertIsInstance(monthly_data, pd.DataFrame) | |
# التحقق من الأعمدة | |
self.assertIn('month', monthly_data.columns) | |
self.assertIn('new', monthly_data.columns) | |
self.assertIn('submitted', monthly_data.columns) | |
self.assertIn('won', monthly_data.columns) | |
# التحقق من أن عدد الأشهر يساوي 6 | |
self.assertEqual(len(monthly_data), 6) | |
def test_project_value_distribution(self): | |
"""اختبار توزيع المشاريع حسب القيمة""" | |
# الحصول على بيانات التوزيع | |
value_data = self.reports_app._get_project_value_data() | |
# التحقق من أن البيانات إطار بيانات | |
self.assertIsInstance(value_data, pd.DataFrame) | |
# التحقق من الأعمدة | |
self.assertIn('range', value_data.columns) | |
self.assertIn('count', value_data.columns) | |
# التحقق من أن عدد النطاقات يساوي 7 | |
self.assertEqual(len(value_data), 7) | |
# التحقق من أن عدد المشاريع صحيح | |
self.assertEqual(value_data['count'].sum(), 7) | |
# التحقق من نطاقات القيمة | |
value_ranges = value_data['range'].tolist() | |
self.assertIn('أقل من 1 مليون', value_ranges) | |
self.assertIn('1-5 مليون', value_ranges) | |
self.assertIn('5-10 مليون', value_ranges) | |
self.assertIn('10-20 مليون', value_ranges) | |
self.assertIn('20-50 مليون', value_ranges) | |
def test_custom_report_generation(self): | |
"""اختبار إنشاء التقارير المخصصة""" | |
# اختبار إنشاء تقرير جدول | |
table_data = self.reports_app._generate_sample_data( | |
data_source="المشاريع", | |
fields=["اسم المشروع", "العميل", "الحالة", "تاريخ التقديم"], | |
rows=10 | |
) | |
# التحقق من النتائج | |
self.assertIsInstance(table_data, pd.DataFrame) | |
self.assertEqual(len(table_data), 10) | |
self.assertEqual(len(table_data.columns), 4) | |
# اختبار فلترة البيانات | |
filters = [ | |
{ | |
'field': 'العميل', | |
'operator': 'يساوي', | |
'value': 'وزارة الصحة' | |
} | |
] | |
filtered_data = table_data.copy() | |
for filter_info in filters: | |
field = filter_info['field'] | |
operator = filter_info['operator'] | |
value = filter_info['value'] | |
if field in filtered_data.columns: | |
if operator == "يساوي": | |
filtered_data = filtered_data[filtered_data[field] == value] | |
# التحقق من أن الفلترة تعمل بشكل صحيح | |
if not filtered_data.empty: | |
self.assertTrue(all(client == 'وزارة الصحة' for client in filtered_data['العميل'])) | |
def test_report_export_functionality(self): | |
"""اختبار وظيفة تصدير التقارير""" | |
# في هذا الاختبار نفترض وجود وظيفة تصدير تعمل بشكل صحيح | |
# ونتحقق فقط من أن البيانات جاهزة للتصدير | |
# الحصول على بيانات المشاريع | |
project_data = pd.DataFrame(self.mock_projects) | |
# التحقق من أن البيانات جاهزة للتصدير | |
self.assertTrue(len(project_data) > 0) | |
self.assertIn('name', project_data.columns) | |
self.assertIn('client', project_data.columns) | |
self.assertIn('status', project_data.columns) | |
if __name__ == '__main__': | |
unittest.main() |