You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

108 lines
4.2 KiB

from decimal import Decimal
from django.test import TestCase
from django.contrib.auth import get_user_model
from rest_framework.test import APIClient
from rest_framework import status
from apps.profiles.models import Institution
from apps.projects.models import Project
from apps.lms.models import Course, CourseCategory, CourseLevel, CourseLanguage
from apps.tickets.models import Ticket, TicketCategory, TicketPriority, TicketStatus
from apps.donations.models import DonationCampaign, CampaignCategory, CampaignPriority
from apps.diplomacy.models import RepresentativeReport, ReportStatus
User = get_user_model()
class Phase9AnalyticsAPITests(TestCase):
"""
Automated test suite for Phase 9: Executive Analytics Dashboard
- Multi-Module Real-Time Aggregated Metrics
- Breakdown by Institution Type, Project Status, LMS Stats, Ticketing & Donations
"""
def setUp(self):
self.client = APIClient()
self.user = User.objects.create_user(
email="[email protected]",
password="Password123!",
fullname="Executive Observer",
)
# Seed data
self.inst = Institution.objects.create(
name="Mashhad Razavi Center",
country="Iran",
city="Mashhad",
type=Institution.InstitutionType.CULTURAL_CENTER,
verification_status=Institution.VerificationStatus.APPROVED,
)
self.proj = Project.objects.create(
title="Global Interfaith Forum",
owner_institution=self.inst,
status=Project.Status.ACTIVE,
)
self.course = Course.objects.create(
title="Diplomacy 101",
category=CourseCategory.CULTURAL_DIPLOMACY,
language=CourseLanguage.EN,
level=CourseLevel.INTRODUCTORY,
instructor_name="Prof. Seyed",
description="Introduction to diplomacy.",
is_published=True,
)
self.ticket = Ticket.objects.create(
user=self.user,
subject="Assistance with registration",
category=TicketCategory.GENERAL,
status=TicketStatus.CLOSED,
satisfaction_rating=5,
)
self.campaign = DonationCampaign.objects.create(
title="Winter Relief",
description="Relief campaign",
target_amount=Decimal('10000.00'),
raised_amount=Decimal('4500.00'),
category=CampaignCategory.HUMANITARIAN_RELIEF,
priority=CampaignPriority.HIGH,
is_active=True,
)
self.report = RepresentativeReport.objects.create(
representative=self.user,
title="Monthly Report",
region_hub="Europe",
period="Feb 2026",
activities_summary="Activities summary",
centers_visited_count=6,
status=ReportStatus.APPROVED,
)
def test_executive_dashboard_kpis(self):
response = self.client.get("/api/v1/analytics/dashboard/")
self.assertEqual(response.status_code, status.HTTP_200_OK)
# 1. Institutions
self.assertEqual(response.data["institutions"]["total_institutions"], 1)
self.assertEqual(response.data["institutions"]["verified_institutions"], 1)
self.assertEqual(response.data["institutions"]["countries_count"], 1)
# 2. Projects
self.assertEqual(response.data["projects"]["total_projects"], 1)
self.assertEqual(response.data["projects"]["active_projects"], 1)
# 3. LMS
self.assertEqual(response.data["lms"]["total_courses"], 1)
# 4. Ticketing
self.assertEqual(response.data["ticketing"]["total_tickets"], 1)
self.assertEqual(response.data["ticketing"]["average_satisfaction_rating"], 5.0)
# 5. Donations
self.assertEqual(response.data["donations"]["active_campaigns_count"], 1)
self.assertEqual(response.data["donations"]["total_funds_raised_usd"], 4500.0)
# 6. Diplomacy
self.assertEqual(response.data["diplomacy"]["total_reports_submitted"], 1)
self.assertEqual(response.data["diplomacy"]["approved_reports_count"], 1)
self.assertEqual(response.data["diplomacy"]["total_centers_visited"], 6)