Skip to content

Commit

Permalink
tests and a bit of refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
sastels committed Oct 4, 2024
1 parent 7b98b07 commit af22fe3
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 45 deletions.
2 changes: 2 additions & 0 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
from app.notify_client.provider_client import provider_client
from app.notify_client.service_api_client import service_api_client
from app.notify_client.status_api_client import status_api_client
from app.notify_client.support_api_client import support_api_client
from app.notify_client.template_api_prefill_client import template_api_prefill_client
from app.notify_client.template_category_api_client import template_category_api_client
from app.notify_client.template_folder_api_client import template_folder_api_client
Expand Down Expand Up @@ -165,6 +166,7 @@ def get_locale():
provider_client,
service_api_client,
status_api_client,
support_api_client,
template_category_api_client,
template_folder_api_client,
template_statistics_client,
Expand Down
60 changes: 20 additions & 40 deletions app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ class Config(object):
ALLOW_DEBUG_ROUTE = env.bool("ALLOW_DEBUG_ROUTE", False)

# List of allowed service IDs that are allowed to send HTML through their templates.
ALLOW_HTML_SERVICE_IDS: List[str] = [
id.strip() for id in os.getenv("ALLOW_HTML_SERVICE_IDS", "").split(",")]
ALLOW_HTML_SERVICE_IDS: List[str] = [id.strip() for id in os.getenv("ALLOW_HTML_SERVICE_IDS", "").split(",")]
ADMIN_BASE_URL = (
"https://" + os.environ.get("HEROKU_APP_NAME", "") + ".herokuapp.com"
if os.environ.get("HEROKU_APP_NAME", "") != ""
Expand All @@ -48,15 +47,12 @@ class Config(object):
BULK_SEND_AWS_BUCKET = os.getenv("BULK_SEND_AWS_BUCKET")

CHECK_PROXY_HEADER = False
CONTACT_EMAIL = os.environ.get(
"CONTACT_EMAIL", "assistance+notification@cds-snc.ca")
CRM_GITHUB_PERSONAL_ACCESS_TOKEN = os.getenv(
"CRM_GITHUB_PERSONAL_ACCESS_TOKEN")
CONTACT_EMAIL = os.environ.get("CONTACT_EMAIL", "assistance+notification@cds-snc.ca")
CRM_GITHUB_PERSONAL_ACCESS_TOKEN = os.getenv("CRM_GITHUB_PERSONAL_ACCESS_TOKEN")
CRM_ORG_LIST_URL = os.getenv("CRM_ORG_LIST_URL")
CSV_MAX_ROWS = env.int("CSV_MAX_ROWS", 50_000)
CSV_MAX_ROWS_BULK_SEND = env.int("CSV_MAX_ROWS_BULK_SEND", 100_000)
CSV_UPLOAD_BUCKET_NAME = os.getenv(
"CSV_UPLOAD_BUCKET_NAME", "notification-alpha-canada-ca-csv-upload")
CSV_UPLOAD_BUCKET_NAME = os.getenv("CSV_UPLOAD_BUCKET_NAME", "notification-alpha-canada-ca-csv-upload")
DANGEROUS_SALT = os.environ.get("DANGEROUS_SALT")
DEBUG = False
DEBUG_KEY = os.environ.get("DEBUG_KEY", "")
Expand All @@ -71,42 +67,34 @@ class Config(object):
"other": 25_000,
}
DEFAULT_LIVE_SERVICE_LIMIT = env.int("DEFAULT_LIVE_SERVICE_LIMIT", 10_000)
DEFAULT_LIVE_SMS_DAILY_LIMIT = env.int(
"DEFAULT_LIVE_SMS_DAILY_LIMIT", 1000)
DEFAULT_LIVE_SMS_DAILY_LIMIT = env.int("DEFAULT_LIVE_SMS_DAILY_LIMIT", 1000)
DEFAULT_SERVICE_LIMIT = env.int("DEFAULT_SERVICE_LIMIT", 50)
DEFAULT_SMS_DAILY_LIMIT = env.int("DEFAULT_SMS_DAILY_LIMIT", 50)
DOCUMENTATION_DOMAIN = os.getenv(
"DOCUMENTATION_DOMAIN", "documentation.notification.canada.ca")
DOCUMENTATION_DOMAIN = os.getenv("DOCUMENTATION_DOMAIN", "documentation.notification.canada.ca")
EMAIL_2FA_EXPIRY_SECONDS = 1_800 # 30 Minutes
EMAIL_EXPIRY_SECONDS = 3600 # 1 hour

# for waffles: pull out the routes into a flat list of the form ['/home', '/accueil', '/why-gc-notify', ...]
EXTRA_ROUTES = [item for sublist in map(
lambda x: x.values(), GC_ARTICLES_ROUTES.values()) for item in sublist]
EXTRA_ROUTES = [item for sublist in map(lambda x: x.values(), GC_ARTICLES_ROUTES.values()) for item in sublist]

# FEATURE FLAGS
FF_SALESFORCE_CONTACT = env.bool("FF_SALESFORCE_CONTACT", True)

FREE_YEARLY_EMAIL_LIMIT = env.int("FREE_YEARLY_EMAIL_LIMIT", 10_000_000)
FREE_YEARLY_SMS_LIMIT = env.int("FREE_YEARLY_SMS_LIMIT", 25_000)
GC_ARTICLES_API = os.environ.get(
"GC_ARTICLES_API", "articles.alpha.canada.ca/notification-gc-notify")
GC_ARTICLES_API_AUTH_PASSWORD = os.environ.get(
"GC_ARTICLES_API_AUTH_PASSWORD")
GC_ARTICLES_API_AUTH_USERNAME = os.environ.get(
"GC_ARTICLES_API_AUTH_USERNAME")
GC_ARTICLES_API = os.environ.get("GC_ARTICLES_API", "articles.alpha.canada.ca/notification-gc-notify")
GC_ARTICLES_API_AUTH_PASSWORD = os.environ.get("GC_ARTICLES_API_AUTH_PASSWORD")
GC_ARTICLES_API_AUTH_USERNAME = os.environ.get("GC_ARTICLES_API_AUTH_USERNAME")
GOOGLE_ANALYTICS_ID = os.getenv("GOOGLE_ANALYTICS_ID", "UA-102484926-14")
GOOGLE_TAG_MANAGER_ID = os.getenv("GOOGLE_TAG_MANAGER_ID", "GTM-KRKRZQV")
HC_EN_SERVICE_ID = os.getenv("HC_EN_SERVICE_ID")
HC_FR_SERVICE_ID = os.getenv("HC_FR_SERVICE_ID")
HIPB_ENABLED = True
HTTP_PROTOCOL = "http"
INVITATION_EXPIRY_SECONDS = 3_600 * 24 * 2 # 2 days - also set on api
IP_GEOLOCATE_SERVICE = os.environ.get(
"IP_GEOLOCATE_SERVICE", "").rstrip("/")
IP_GEOLOCATE_SERVICE = os.environ.get("IP_GEOLOCATE_SERVICE", "").rstrip("/")
LANGUAGES = ["en", "fr"]
LOGO_UPLOAD_BUCKET_NAME = os.getenv(
"ASSET_UPLOAD_BUCKET_NAME", "notification-alpha-canada-ca-asset-upload")
LOGO_UPLOAD_BUCKET_NAME = os.getenv("ASSET_UPLOAD_BUCKET_NAME", "notification-alpha-canada-ca-asset-upload")
MAX_FAILED_LOGIN_COUNT = 10
MOU_BUCKET_NAME = os.getenv("MOU_BUCKET_NAME", "")

Expand All @@ -129,10 +117,8 @@ class Config(object):
SCANFILES_URL = os.environ.get("SCANFILES_URL", "")

SECRET_KEY = env.list("SECRET_KEY", [])
SECURITY_EMAIL = os.environ.get(
"SECURITY_EMAIL", "security+securite@cds-snc.ca")
SENDING_DOMAIN = os.environ.get(
"SENDING_DOMAIN", "notification.alpha.canada.ca")
SECURITY_EMAIL = os.environ.get("SECURITY_EMAIL", "security+securite@cds-snc.ca")
SENDING_DOMAIN = os.environ.get("SENDING_DOMAIN", "notification.alpha.canada.ca")
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_NAME = "notify_admin_session"
SESSION_COOKIE_SAMESITE = "Lax"
Expand All @@ -146,10 +132,8 @@ class Config(object):
STATSD_PORT = 8_125
STATSD_PREFIX = os.getenv("STATSD_PREFIX")

TEMPLATE_PREVIEW_API_HOST = os.environ.get(
"TEMPLATE_PREVIEW_API_HOST", "http://localhost:6013")
TEMPLATE_PREVIEW_API_KEY = os.environ.get(
"TEMPLATE_PREVIEW_API_KEY", "my-secret-key")
TEMPLATE_PREVIEW_API_HOST = os.environ.get("TEMPLATE_PREVIEW_API_HOST", "http://localhost:6013")
TEMPLATE_PREVIEW_API_KEY = os.environ.get("TEMPLATE_PREVIEW_API_KEY", "my-secret-key")
WAF_SECRET = os.environ.get("WAF_SECRET", "waf-secret")
WTF_CSRF_ENABLED = True
WTF_CSRF_TIME_LIMIT = None
Expand All @@ -160,8 +144,7 @@ class Config(object):

NOTIFY_USER_ID = "6af522d0-2915-4e52-83a3-3690455a5fe6"
NOTIFY_SERVICE_ID = "d6aa2c68-a2d9-4437-ab19-3ae8eb202553"
NO_BRANDING_ID = os.environ.get(
"NO_BRANDING_ID", "0af93cf1-2c49-485f-878f-f3e662e651ef")
NO_BRANDING_ID = os.environ.get("NO_BRANDING_ID", "0af93cf1-2c49-485f-878f-f3e662e651ef")

@classmethod
def get_sensitive_config(cls) -> list[str]:
Expand Down Expand Up @@ -189,8 +172,7 @@ def get_safe_config(cls) -> dict[str, Any]:


class Development(Config):
ADMIN_CLIENT_SECRET = os.environ.get(
"ADMIN_CLIENT_SECRET", "dev-notify-secret-key")
ADMIN_CLIENT_SECRET = os.environ.get("ADMIN_CLIENT_SECRET", "dev-notify-secret-key")
ANTIVIRUS_API_HOST = "http://localhost:6016"
ANTIVIRUS_API_KEY = "test-key"
API_HOST_NAME = os.environ.get("API_HOST_NAME", "http://localhost:6011")
Expand All @@ -207,8 +189,7 @@ class Development(Config):


class Test(Development):
ADMIN_CLIENT_SECRET = os.environ.get(
"ADMIN_CLIENT_SECRET", "dev-notify-secret-key")
ADMIN_CLIENT_SECRET = os.environ.get("ADMIN_CLIENT_SECRET", "dev-notify-secret-key")
ANTIVIRUS_API_HOST = "https://test-antivirus"
ANTIVIRUS_API_KEY = "test-antivirus-secret"
API_HOST_NAME = os.environ.get("API_HOST_NAME", "http://localhost:6011")
Expand Down Expand Up @@ -239,8 +220,7 @@ class Test(Development):


class ProductionFF(Config):
ADMIN_CLIENT_SECRET = os.environ.get(
"ADMIN_CLIENT_SECRET", "dev-notify-secret-key")
ADMIN_CLIENT_SECRET = os.environ.get("ADMIN_CLIENT_SECRET", "dev-notify-secret-key")
ANTIVIRUS_API_HOST = "https://test-antivirus"
ANTIVIRUS_API_KEY = "test-antivirus-secret"
API_HOST_NAME = os.environ.get("API_HOST_NAME", "http://localhost:6011")
Expand Down
1 change: 1 addition & 0 deletions app/main/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -1328,6 +1328,7 @@ class SearchUsersByEmailForm(StripWhitespaceForm):
validators=[DataRequired(_l("You need to enter full or partial email address to search by."))],
)


class SearchIds(StripWhitespaceForm):
search = SearchField(
_l("List of IDs"),
Expand Down
5 changes: 2 additions & 3 deletions app/main/views/find_ids.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from flask import render_template

from app import user_api_client
from app import support_api_client
from app.main import main
from app.main.forms import SearchIds
from app.utils import user_is_platform_admin
Expand All @@ -12,6 +12,5 @@ def find_ids():
form = SearchIds()
records = None
if form.validate_on_submit():
records = user_api_client.find_ids(form.search.data)
records = support_api_client.find_ids(form.search.data)
return render_template("views/find-ids/find-ids.html", form=form, records=records)

20 changes: 20 additions & 0 deletions app/notify_client/support_api_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from flask import current_app

from app.notify_client import NotifyAdminAPIClient


class SupportApiClient(NotifyAdminAPIClient):
def init_app(self, app):
super().init_app(app)
self.admin_url = app.config["ADMIN_BASE_URL"]
self.contact_email = app.config["CONTACT_EMAIL"]
self.notify_user_id = app.config["NOTIFY_USER_ID"]
self.notify_service_id = app.config["NOTIFY_SERVICE_ID"]

def find_ids(self, ids):
data = self.get("/support/find-ids", params={"ids": ids})
current_app.logger.info(f"-----------\n {data}")
return data


support_api_client = SupportApiClient()
2 changes: 1 addition & 1 deletion app/templates/views/find-ids/find-ids.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{% from "components/textbox.html" import textbox_search %}

{% block per_page_title %}
{{ _('Search for uuids') }}
{{ _('Search for ids') }}
{% endblock %}

{% block platform_admin_content %}
Expand Down
2 changes: 1 addition & 1 deletion app/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def from_lambda_api(line):
return isinstance(line, dict)


@cache.memoize(timeout=12*60*60)
@cache.memoize(timeout=12 * 60 * 60)
def get_latest_stats(lang, filter_heartbeats=None):
results = service_api_client.get_stats_by_month(filter_heartbeats=filter_heartbeats)["data"]

Expand Down
115 changes: 115 additions & 0 deletions tests/app/main/views/test_find_ids.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
def test_find_ids_page_loads_correctly(client_request, platform_admin_user):
client_request.login(platform_admin_user)
document = client_request.get("main.find_ids")

assert document.h1.text.strip() == "Search for ids"
assert len(document.find_all("input", {"type": "search"})) > 0


def test_find_ids_displays_services_found(client_request, platform_admin_user, mocker):
client_request.login(platform_admin_user)
get_records = mocker.patch(
"app.support_api_client.find_ids",
return_value=[{"id": "1234", "type": "service", "service_name": "Test Service"}],
)
document = client_request.post(
"main.find_ids",
_data={"search": "1234"},
_expected_status=200,
)
get_records.assert_called_once_with("1234")
result = document.find("a", {"class": "browse-list-link"})
assert result.text.strip() == "Test Service"
assert result.attrs["href"] == "/services/1234"


def test_find_ids_displays_notifications_found(client_request, platform_admin_user, mocker):
client_request.login(platform_admin_user)
get_records = mocker.patch(
"app.support_api_client.find_ids",
return_value=[{"id": "1234", "type": "notification", "service_id": "service_1234"}],
)
document = client_request.post(
"main.find_ids",
_data={"search": "1234"},
_expected_status=200,
)
get_records.assert_called_once_with("1234")
result = document.find("a", {"class": "browse-list-link"})
assert result.text.strip() == "notification"
assert result.attrs["href"] == "/services/service_1234/notification/1234"


def test_find_ids_displays_templates_found(client_request, platform_admin_user, mocker):
client_request.login(platform_admin_user)
get_records = mocker.patch(
"app.support_api_client.find_ids",
return_value=[{"id": "1234", "type": "template", "template_name": "Test Template", "service_id": "service_1234"}],
)
document = client_request.post(
"main.find_ids",
_data={"search": "1234"},
_expected_status=200,
)
get_records.assert_called_once_with("1234")
result = document.find("a", {"class": "browse-list-link"})
assert result.text.strip() == "Test Template"
assert result.attrs["href"] == "/services/service_1234/templates/1234"


def test_find_ids_displays_users_found(client_request, platform_admin_user, mocker):
client_request.login(platform_admin_user)
get_records = mocker.patch(
"app.support_api_client.find_ids",
return_value=[{"id": "1234", "type": "user", "user_name": "Test User"}],
)
document = client_request.post(
"main.find_ids",
_data={"search": "1234"},
_expected_status=200,
)
get_records.assert_called_once_with("1234")
result = document.find("a", {"class": "browse-list-link"})

assert result.text.strip() == "Test User"
assert result.attrs["href"] == "/users/1234"


def test_find_ids_displays_jobs_found(client_request, platform_admin_user, mocker):
client_request.login(platform_admin_user)
get_records = mocker.patch(
"app.support_api_client.find_ids",
return_value=[{"id": "1234", "type": "job", "service_id": "service_1234"}],
)
document = client_request.post(
"main.find_ids",
_data={"search": "1234"},
_expected_status=200,
)
get_records.assert_called_once_with("1234")
result = document.find("a", {"class": "browse-list-link"})
assert result.text.strip() == "job"
assert result.attrs["href"] == "/services/service_1234/jobs/1234"


def test_find_ids_display_two_records(client_request, platform_admin_user, mocker):
client_request.login(platform_admin_user)
get_records = mocker.patch(
"app.support_api_client.find_ids",
return_value=[
{"id": "1234", "type": "service", "service_name": "Test Service"},
{"id": "5678", "type": "user", "user_name": "Test User"},
],
)
document = client_request.post("main.find_ids", _data={"search": "1234,5678"}, _expected_status=200)
get_records.assert_called_once_with("1234,5678")
results = document.findAll("a", {"class": "browse-list-link"})
assert len(results) == 2
assert [result.text.strip() for result in results] == [
"Test Service",
"Test User",
]
assert [result.attrs["href"] for result in results] == [
"/services/1234",
"/users/5678",
]

0 comments on commit af22fe3

Please sign in to comment.