admin-panel-backend/apps/reports/tests.py
Ali Asadi 1376ead48a Revert reports app to standalone single-report generation
Restore the original report_type-driven endpoint (users/tickets picked
individually via serializer + orchestrator) that was replaced by the
bundled zip export in b293509, on top of current master.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-19 17:13:53 +03:30

151 lines
5 KiB
Python

from io import BytesIO
from unittest.mock import patch
from django.test import override_settings
from openpyxl import load_workbook
from rest_framework import status
from rest_framework.test import APITestCase
from apps.reports.services.oauth import OAuth2ClientCredentials
class GenerateReportTests(APITestCase):
@patch("apps.reports.services.data_sources.ReportDataSources.fetch_user_metrics")
@patch("apps.reports.services.data_sources.ReportDataSources.fetch_users")
def test_generate_user_report_is_public_and_returns_excel(
self,
mock_fetch_users,
mock_fetch_user_metrics,
):
mock_fetch_users.return_value = [
{
"id": 1,
"full_name": "Alice Doe",
"email": "alice@example.com",
"status": "active",
}
]
mock_fetch_user_metrics.return_value = {
1: {"ticket_count": 3},
}
response = self.client.post(
"/api/reports/generate/",
{
"report_type": "user",
"filters": {"status": "active"},
},
format="json",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(
response["Content-Type"],
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
)
self.assertEqual(
response["Content-Disposition"],
'attachment; filename="user-report.xlsx"',
)
workbook = load_workbook(BytesIO(response.content))
worksheet = workbook.active
self.assertEqual(worksheet["A1"].value, "User Report")
self.assertEqual(
[cell.value for cell in worksheet[2]],
["User ID", "Full Name", "Email", "Status", "Ticket Count"],
)
self.assertEqual(
[cell.value for cell in worksheet[3]],
[1, "Alice Doe", "alice@example.com", "active", 3],
)
mock_fetch_users.assert_called_once_with({"status": "active"})
@patch("apps.reports.services.data_sources.ReportDataSources.fetch_ticket_metrics")
@patch("apps.reports.services.data_sources.ReportDataSources.fetch_tickets")
def test_generate_tickets_report_uses_static_columns(
self,
mock_fetch_tickets,
mock_fetch_ticket_metrics,
):
mock_fetch_tickets.return_value = [
{
"id": 11,
"title": "Login issue",
"status": "open",
"priority": "high",
"assignee": {"name": "Support Agent"},
"created_at": "2026-05-20T10:00:00Z",
}
]
mock_fetch_ticket_metrics.return_value = {}
response = self.client.post(
"/api/reports/generate/",
{"report_type": "tickets"},
format="json",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(
response["Content-Disposition"],
'attachment; filename="tickets-report.xlsx"',
)
workbook = load_workbook(BytesIO(response.content))
worksheet = workbook.active
self.assertEqual(worksheet["A1"].value, "Tickets Report")
self.assertEqual(
[cell.value for cell in worksheet[2]],
["Ticket ID", "Title", "Status", "Priority", "Assignee", "Created At"],
)
self.assertEqual(
[cell.value for cell in worksheet[3]],
[
11,
"Login issue",
"open",
"high",
"Support Agent",
"2026-05-20T10:00:00Z",
],
)
def test_unknown_report_type_returns_validation_error(self):
response = self.client.post(
"/api/reports/generate/",
{"report_type": "unknown"},
format="json",
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
class OAuth2ClientCredentialsTests(APITestCase):
@override_settings(
OAUTH2_PROVIDER_PRIVATE_URL="https://auth.internal",
OAUTH2_CLIENT_ID="client-id",
OAUTH2_CLIENT_SECRET="client-secret",
OAUTH2_SCOPES="reports:read customers:read",
SERVICE_REQUEST_TIMEOUT=10,
)
@patch("apps.reports.services.oauth.requests.post")
def test_get_access_token_uses_client_credentials(self, mock_post):
mock_post.return_value.json.return_value = {
"access_token": "token-value",
"expires_in": 3600,
}
mock_post.return_value.raise_for_status.return_value = None
token = OAuth2ClientCredentials().get_access_token()
self.assertEqual(token, "token-value")
mock_post.assert_called_once_with(
"https://auth.internal/oauth2/token",
data={
"grant_type": "client_credentials",
"scope": "reports:read customers:read",
},
auth=("client-id", "client-secret"),
timeout=10,
)