mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-05-27 09:29:22 -04:00
Merge branch 'main' of https://github.com/GSA/notifications-admin into 1674-match-recent-batches-to-wireframe
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
import csv
|
||||
import itertools
|
||||
import json
|
||||
from collections import OrderedDict
|
||||
from datetime import datetime
|
||||
from io import StringIO
|
||||
|
||||
from flask import abort, flash, render_template, request, url_for
|
||||
from flask import Response, abort, flash, render_template, request, url_for
|
||||
from notifications_python_client.errors import HTTPError
|
||||
|
||||
from app import (
|
||||
@@ -70,6 +72,40 @@ def platform_admin():
|
||||
)
|
||||
|
||||
|
||||
@main.route("/platform-admin/download-all-users")
|
||||
@user_is_platform_admin
|
||||
def download_all_users():
|
||||
|
||||
# Create a CSV string from the user data
|
||||
users = user_api_client.get_all_users_detailed()
|
||||
|
||||
if len(users) == 0:
|
||||
return "No data to download."
|
||||
|
||||
output = StringIO()
|
||||
header = ["Name", "Email Address", "Phone Number", "Service"]
|
||||
fieldnames = ["name", "email_address", "mobile_number", "service"]
|
||||
writer = csv.DictWriter(
|
||||
output,
|
||||
fieldnames=fieldnames,
|
||||
delimiter=",",
|
||||
)
|
||||
# Write custom header
|
||||
writer.writerow(dict(zip(fieldnames, header)))
|
||||
for user in users:
|
||||
user_no_commas = {key: value.replace(",", "") for key, value in user.items()}
|
||||
if user_no_commas["name"].startswith("e2e"):
|
||||
continue
|
||||
writer.writerow(user_no_commas)
|
||||
csv_data = output.getvalue()
|
||||
|
||||
# Create a direct download response with the CSV data and appropriate headers
|
||||
response = Response(csv_data, content_type="text/csv; charset=utf-8")
|
||||
response.headers["Content-Disposition"] = "attachment; filename=users.csv"
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def is_over_threshold(number, total, threshold):
|
||||
percentage = number / total * 100 if total else 0
|
||||
return percentage > threshold
|
||||
|
||||
@@ -123,6 +123,7 @@ class HeaderNavigation(Navigation):
|
||||
"get_billing_report",
|
||||
"get_users_report",
|
||||
"get_daily_volumes",
|
||||
"download_all_users",
|
||||
"get_daily_sms_provider_volumes",
|
||||
"get_volumes_by_service",
|
||||
"organizations",
|
||||
|
||||
@@ -157,6 +157,10 @@ class UserApiClient(NotifyAdminAPIClient):
|
||||
endpoint = "/user"
|
||||
return self.get(endpoint)["data"]
|
||||
|
||||
def get_all_users_detailed(self):
|
||||
endpoint = "/user/report-all-users"
|
||||
return self.get(endpoint)["data"]
|
||||
|
||||
@cache.delete("service-{service_id}")
|
||||
@cache.delete("service-{service_id}-template-folders")
|
||||
@cache.delete("user-{user_id}")
|
||||
|
||||
@@ -31,4 +31,8 @@
|
||||
<p>
|
||||
<a class="usa-link" href="{{ url_for('main.get_users_report') }}">Users Report</a>
|
||||
</p>
|
||||
<p>
|
||||
<a class="usa-link" href="{{ url_for('main.download_all_users') }}">Download All Users</a>
|
||||
</p>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -99,10 +99,11 @@ const copyGtmHead = () => {
|
||||
|
||||
// Task to copy images
|
||||
const copyImages = () => {
|
||||
return src(paths.src + 'images/**/*')
|
||||
return src(paths.src + 'images/**/*', { encoding: false })
|
||||
.pipe(dest(paths.dist + 'images/'));
|
||||
};
|
||||
|
||||
|
||||
// Configure USWDS paths
|
||||
uswds.settings.version = 3;
|
||||
uswds.paths.dist.css = paths.dist + 'css';
|
||||
|
||||
@@ -1254,3 +1254,36 @@ def test_get_daily_sms_provider_volumes_report_calls_api_and_download_data(
|
||||
+ "80"
|
||||
+ "\r\n"
|
||||
)
|
||||
|
||||
|
||||
def test_download_all_users(client_request, platform_admin_user, mocker):
|
||||
mocker.patch(
|
||||
"app.main.views.platform_admin.user_api_client.get_all_users_detailed",
|
||||
return_value=[
|
||||
{
|
||||
"name": "Johnny Sokko",
|
||||
"email_address": "j_sokko@unicorn.gov",
|
||||
"mobile_number": "15555555555",
|
||||
"service": "Emperor, Guillotine, Service",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
client_request.login(platform_admin_user)
|
||||
response = client_request.get_response(
|
||||
"main.download_all_users",
|
||||
_data={},
|
||||
_expected_status=200,
|
||||
)
|
||||
|
||||
assert response.content_type == "text/csv; charset=utf-8"
|
||||
assert "attachment" in response.headers["Content-Disposition"]
|
||||
assert "filename" in response.headers["Content-Disposition"]
|
||||
assert "users" in response.headers["Content-Disposition"]
|
||||
|
||||
my_response = response.get_data(as_text=True)
|
||||
|
||||
assert "Johnny Sokko" in my_response
|
||||
assert "Emperor Guillotine Service" in my_response
|
||||
assert "j_sokko@unicorn.gov" in my_response
|
||||
assert "15555555555" in my_response
|
||||
|
||||
@@ -68,6 +68,7 @@ EXCLUDED_ENDPOINTS = tuple(
|
||||
"delivery_status_callback",
|
||||
"design_content",
|
||||
"documentation",
|
||||
"download_all_users",
|
||||
"download_notifications_csv",
|
||||
"download_organization_usage_report",
|
||||
"edit_and_format_messages",
|
||||
|
||||
Reference in New Issue
Block a user