151 lines
5 KiB
Python
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,
|
|
)
|