2023-08-11 15:02:34 -07:00
|
|
|
|
import datetime
|
2023-08-14 07:21:18 -07:00
|
|
|
|
import os
|
2023-08-11 15:02:34 -07:00
|
|
|
|
|
2022-03-22 09:46:26 +00:00
|
|
|
|
import pytest
|
|
|
|
|
|
|
2022-02-28 18:18:02 +00:00
|
|
|
|
from app.commands import (
|
2023-02-03 10:11:21 -05:00
|
|
|
|
_update_template,
|
2022-10-28 14:07:43 -04:00
|
|
|
|
create_test_user,
|
2023-08-11 11:47:57 -07:00
|
|
|
|
fix_billable_units,
|
2022-02-28 18:18:02 +00:00
|
|
|
|
insert_inbound_numbers_from_file,
|
2022-03-22 09:46:26 +00:00
|
|
|
|
populate_annual_billing_with_defaults,
|
2023-08-10 12:58:52 -07:00
|
|
|
|
populate_annual_billing_with_the_previous_years_allowance,
|
2023-08-14 07:41:17 -07:00
|
|
|
|
populate_organization_agreement_details_from_file,
|
2023-08-14 07:21:18 -07:00
|
|
|
|
populate_organizations_from_file,
|
2023-08-11 13:48:45 -07:00
|
|
|
|
purge_functional_test_data,
|
2023-08-11 15:02:34 -07:00
|
|
|
|
update_jobs_archived_flag,
|
2022-02-28 18:18:02 +00:00
|
|
|
|
)
|
|
|
|
|
|
from app.dao.inbound_numbers_dao import dao_get_available_inbound_numbers
|
2023-08-14 07:21:18 -07:00
|
|
|
|
from app.models import (
|
2023-08-14 09:04:06 -07:00
|
|
|
|
KEY_TYPE_NORMAL,
|
|
|
|
|
|
NOTIFICATION_DELIVERED,
|
|
|
|
|
|
SMS_TYPE,
|
2023-08-14 07:21:18 -07:00
|
|
|
|
AnnualBilling,
|
|
|
|
|
|
Job,
|
|
|
|
|
|
Notification,
|
|
|
|
|
|
Organization,
|
|
|
|
|
|
Template,
|
|
|
|
|
|
User,
|
|
|
|
|
|
)
|
2023-08-10 12:58:52 -07:00
|
|
|
|
from tests.app.db import (
|
|
|
|
|
|
create_annual_billing,
|
2023-08-11 15:02:34 -07:00
|
|
|
|
create_job,
|
2023-08-11 11:47:57 -07:00
|
|
|
|
create_notification,
|
2023-08-14 07:41:17 -07:00
|
|
|
|
create_organization,
|
2023-08-10 12:58:52 -07:00
|
|
|
|
create_service,
|
2023-08-11 15:02:34 -07:00
|
|
|
|
create_template,
|
2023-08-10 12:58:52 -07:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-11 13:48:45 -07:00
|
|
|
|
|
2023-08-11 14:42:21 -07:00
|
|
|
|
def test_purge_functional_test_data(notify_db_session, notify_api):
|
|
|
|
|
|
orig_user_count = User.query.count()
|
2023-08-11 13:48:45 -07:00
|
|
|
|
|
|
|
|
|
|
notify_api.test_cli_runner().invoke(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
create_test_user,
|
|
|
|
|
|
[
|
|
|
|
|
|
"--email",
|
|
|
|
|
|
"somebody+7af2cdb0-7cbc-44dc-a5d0-f817fc6ee94e@fake.gov",
|
|
|
|
|
|
"--mobile_number",
|
|
|
|
|
|
"202-555-5555",
|
|
|
|
|
|
"--password",
|
|
|
|
|
|
"correct horse battery staple",
|
|
|
|
|
|
"--name",
|
|
|
|
|
|
"Fake Humanson",
|
|
|
|
|
|
],
|
2023-08-11 13:48:45 -07:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
user_count = User.query.count()
|
2023-08-11 14:42:21 -07:00
|
|
|
|
assert user_count == orig_user_count + 1
|
2023-08-29 14:54:30 -07:00
|
|
|
|
notify_api.test_cli_runner().invoke(purge_functional_test_data, ["-u", "somebody"])
|
2023-08-11 13:48:45 -07:00
|
|
|
|
# if the email address has a uuid, it is test data so it should be purged and there should be
|
|
|
|
|
|
# zero users. Otherwise, it is real data so there should be one user.
|
2023-08-11 14:42:21 -07:00
|
|
|
|
assert User.query.count() == orig_user_count
|
2023-08-10 12:58:52 -07:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-14 07:21:18 -07:00
|
|
|
|
def test_purge_functional_test_data_bad_mobile(notify_db_session, notify_api):
|
|
|
|
|
|
user_count = User.query.count()
|
|
|
|
|
|
assert user_count == 0
|
|
|
|
|
|
# run the command
|
2023-08-15 11:44:47 -07:00
|
|
|
|
command_response = notify_api.test_cli_runner().invoke(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
create_test_user,
|
|
|
|
|
|
[
|
|
|
|
|
|
"--email",
|
|
|
|
|
|
"somebody+7af2cdb0-7cbc-44dc-a5d0-f817fc6ee94e@fake.gov",
|
|
|
|
|
|
"--mobile_number",
|
|
|
|
|
|
"555-555-55554444",
|
|
|
|
|
|
"--password",
|
|
|
|
|
|
"correct horse battery staple",
|
|
|
|
|
|
"--name",
|
|
|
|
|
|
"Fake Personson",
|
|
|
|
|
|
],
|
2023-08-14 07:21:18 -07:00
|
|
|
|
)
|
|
|
|
|
|
# The bad mobile phone number results in a bad parameter error, leading to a system exit 2 and no entry made in db
|
2023-08-15 11:44:47 -07:00
|
|
|
|
assert "SystemExit(2)" in str(command_response)
|
2023-08-14 07:21:18 -07:00
|
|
|
|
user_count = User.query.count()
|
|
|
|
|
|
assert user_count == 0
|
2023-08-10 12:58:52 -07:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-11 15:02:34 -07:00
|
|
|
|
def test_update_jobs_archived_flag(notify_db_session, notify_api):
|
|
|
|
|
|
service = create_service()
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
sms_template = create_template(service=service, template_type="sms")
|
2023-08-11 15:02:34 -07:00
|
|
|
|
create_job(sms_template)
|
|
|
|
|
|
|
|
|
|
|
|
right_now = datetime.datetime.utcnow()
|
|
|
|
|
|
tomorrow = right_now + datetime.timedelta(days=1)
|
|
|
|
|
|
|
|
|
|
|
|
right_now = right_now.strftime("%Y-%m-%d")
|
|
|
|
|
|
tomorrow = tomorrow.strftime("%Y-%m-%d")
|
|
|
|
|
|
|
|
|
|
|
|
archived_jobs = Job.query.filter(Job.archived is True).count()
|
|
|
|
|
|
assert archived_jobs == 0
|
|
|
|
|
|
|
|
|
|
|
|
notify_api.test_cli_runner().invoke(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
update_jobs_archived_flag,
|
|
|
|
|
|
[
|
|
|
|
|
|
"-e",
|
|
|
|
|
|
tomorrow,
|
|
|
|
|
|
"-s",
|
|
|
|
|
|
right_now,
|
|
|
|
|
|
],
|
2023-08-11 15:02:34 -07:00
|
|
|
|
)
|
|
|
|
|
|
jobs = Job.query.all()
|
|
|
|
|
|
assert len(jobs) == 1
|
|
|
|
|
|
for job in jobs:
|
|
|
|
|
|
assert job.archived is True
|
2023-08-10 12:58:52 -07:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-14 07:21:18 -07:00
|
|
|
|
def test_populate_organizations_from_file(notify_db_session, notify_api):
|
|
|
|
|
|
org_count = Organization.query.count()
|
|
|
|
|
|
assert org_count == 0
|
|
|
|
|
|
|
|
|
|
|
|
file_name = "./tests/app/orgs1.csv"
|
2023-08-29 14:54:30 -07:00
|
|
|
|
text = "name|blah|blah|blah|||\n" "foo|Federal|True|'foo.gov'|'foo.gov'||\n"
|
2023-08-14 07:21:18 -07:00
|
|
|
|
f = open(file_name, "a")
|
|
|
|
|
|
f.write(text)
|
|
|
|
|
|
f.close()
|
2023-08-15 11:44:47 -07:00
|
|
|
|
command_response = notify_api.test_cli_runner().invoke(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
populate_organizations_from_file, ["-f", file_name]
|
2023-08-14 07:21:18 -07:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
os.remove(file_name)
|
2023-08-15 11:44:47 -07:00
|
|
|
|
print(f"command_response = {command_response}")
|
2023-08-14 07:21:18 -07:00
|
|
|
|
|
|
|
|
|
|
org_count = Organization.query.count()
|
|
|
|
|
|
assert org_count == 1
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_populate_organization_agreement_details_from_file(
|
|
|
|
|
|
notify_db_session, notify_api
|
|
|
|
|
|
):
|
2023-08-14 07:41:17 -07:00
|
|
|
|
file_name = "./tests/app/orgs.csv"
|
|
|
|
|
|
|
|
|
|
|
|
org_count = Organization.query.count()
|
|
|
|
|
|
assert org_count == 0
|
|
|
|
|
|
create_organization()
|
|
|
|
|
|
org_count = Organization.query.count()
|
|
|
|
|
|
assert org_count == 1
|
|
|
|
|
|
|
|
|
|
|
|
org = Organization.query.one()
|
|
|
|
|
|
org.agreement_signed = True
|
|
|
|
|
|
notify_db_session.commit()
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
text = (
|
|
|
|
|
|
"id,agreement_signed_version,agreement_signed_on_behalf_of_name,agreement_signed_at\n"
|
|
|
|
|
|
f"{org.id},1,bob,'2023-01-01 00:00:00'\n"
|
|
|
|
|
|
)
|
2023-08-14 07:41:17 -07:00
|
|
|
|
f = open(file_name, "a")
|
|
|
|
|
|
f.write(text)
|
|
|
|
|
|
f.close()
|
2023-08-15 11:44:47 -07:00
|
|
|
|
command_response = notify_api.test_cli_runner().invoke(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
populate_organization_agreement_details_from_file, ["-f", file_name]
|
2023-08-14 07:41:17 -07:00
|
|
|
|
)
|
2023-08-15 11:44:47 -07:00
|
|
|
|
print(f"command_response = {command_response}")
|
2023-08-14 07:41:17 -07:00
|
|
|
|
|
|
|
|
|
|
org_count = Organization.query.count()
|
|
|
|
|
|
assert org_count == 1
|
|
|
|
|
|
org = Organization.query.one()
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert org.agreement_signed_on_behalf_of_name == "bob"
|
2023-08-14 07:41:17 -07:00
|
|
|
|
os.remove(file_name)
|
2021-09-08 09:45:32 +01:00
|
|
|
|
|
|
|
|
|
|
|
2022-10-28 14:07:43 -04:00
|
|
|
|
def test_create_test_user_command(notify_db_session, notify_api):
|
|
|
|
|
|
# number of users before adding ours
|
2023-08-14 07:41:17 -07:00
|
|
|
|
user_count = User.query.count()
|
2022-10-28 14:42:25 -04:00
|
|
|
|
|
2022-10-28 14:07:43 -04:00
|
|
|
|
# run the command
|
|
|
|
|
|
notify_api.test_cli_runner().invoke(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
create_test_user,
|
|
|
|
|
|
[
|
|
|
|
|
|
"--email",
|
|
|
|
|
|
"somebody@fake.gov",
|
|
|
|
|
|
"--mobile_number",
|
|
|
|
|
|
"202-555-5555",
|
|
|
|
|
|
"--password",
|
|
|
|
|
|
"correct horse battery staple",
|
|
|
|
|
|
"--name",
|
|
|
|
|
|
"Fake Personson",
|
|
|
|
|
|
],
|
2022-10-28 14:07:43 -04:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# there should be one more user
|
2023-08-14 07:41:17 -07:00
|
|
|
|
assert User.query.count() == user_count + 1
|
2022-10-28 14:07:43 -04:00
|
|
|
|
|
|
|
|
|
|
# that user should be the one we added
|
2023-08-29 14:54:30 -07:00
|
|
|
|
user = User.query.filter_by(name="Fake Personson").first()
|
|
|
|
|
|
assert user.email_address == "somebody@fake.gov"
|
|
|
|
|
|
assert user.auth_type == "sms_auth"
|
|
|
|
|
|
assert user.state == "active"
|
2022-10-28 14:07:43 -04:00
|
|
|
|
|
|
|
|
|
|
|
2022-02-28 18:18:02 +00:00
|
|
|
|
def test_insert_inbound_numbers_from_file(notify_db_session, notify_api, tmpdir):
|
|
|
|
|
|
numbers_file = tmpdir.join("numbers.txt")
|
|
|
|
|
|
numbers_file.write("07700900373\n07700900473\n07700900375\n\n\n\n")
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
notify_api.test_cli_runner().invoke(
|
|
|
|
|
|
insert_inbound_numbers_from_file, ["-f", numbers_file]
|
|
|
|
|
|
)
|
2022-02-28 18:18:02 +00:00
|
|
|
|
|
|
|
|
|
|
inbound_numbers = dao_get_available_inbound_numbers()
|
|
|
|
|
|
assert len(inbound_numbers) == 3
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert set(x.number for x in inbound_numbers) == {
|
|
|
|
|
|
"07700900373",
|
|
|
|
|
|
"07700900473",
|
|
|
|
|
|
"07700900375",
|
|
|
|
|
|
}
|
2022-02-28 18:18:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"organization_type, expected_allowance", [("federal", 40000), ("state", 40000)]
|
|
|
|
|
|
)
|
2022-03-22 09:46:26 +00:00
|
|
|
|
def test_populate_annual_billing_with_defaults(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
notify_db_session, notify_api, organization_type, expected_allowance
|
2022-03-22 09:46:26 +00:00
|
|
|
|
):
|
2023-08-29 14:54:30 -07:00
|
|
|
|
service = create_service(
|
|
|
|
|
|
service_name=organization_type, organization_type=organization_type
|
|
|
|
|
|
)
|
2022-03-22 09:46:26 +00:00
|
|
|
|
|
|
|
|
|
|
notify_api.test_cli_runner().invoke(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
populate_annual_billing_with_defaults, ["-y", 2022]
|
2022-03-22 09:46:26 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
results = AnnualBilling.query.filter(
|
|
|
|
|
|
AnnualBilling.financial_year_start == 2022,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
AnnualBilling.service_id == service.id,
|
2022-03-22 09:46:26 +00:00
|
|
|
|
).all()
|
|
|
|
|
|
|
|
|
|
|
|
assert len(results) == 1
|
|
|
|
|
|
assert results[0].free_sms_fragment_limit == expected_allowance
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"organization_type, expected_allowance", [("federal", 40000), ("state", 40000)]
|
|
|
|
|
|
)
|
2023-08-10 12:58:52 -07:00
|
|
|
|
def test_populate_annual_billing_with_the_previous_years_allowance(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
notify_db_session, notify_api, organization_type, expected_allowance
|
2023-08-10 12:58:52 -07:00
|
|
|
|
):
|
2023-08-29 14:54:30 -07:00
|
|
|
|
service = create_service(
|
|
|
|
|
|
service_name=organization_type, organization_type=organization_type
|
|
|
|
|
|
)
|
2023-08-10 12:58:52 -07:00
|
|
|
|
|
|
|
|
|
|
notify_api.test_cli_runner().invoke(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
populate_annual_billing_with_defaults, ["-y", 2022]
|
2023-08-10 12:58:52 -07:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
results = AnnualBilling.query.filter(
|
|
|
|
|
|
AnnualBilling.financial_year_start == 2022,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
AnnualBilling.service_id == service.id,
|
2023-08-10 12:58:52 -07:00
|
|
|
|
).all()
|
|
|
|
|
|
|
|
|
|
|
|
assert len(results) == 1
|
|
|
|
|
|
assert results[0].free_sms_fragment_limit == expected_allowance
|
|
|
|
|
|
|
|
|
|
|
|
notify_api.test_cli_runner().invoke(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
populate_annual_billing_with_the_previous_years_allowance, ["-y", 2023]
|
2023-08-10 12:58:52 -07:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
results = AnnualBilling.query.filter(
|
|
|
|
|
|
AnnualBilling.financial_year_start == 2023,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
AnnualBilling.service_id == service.id,
|
2023-08-10 12:58:52 -07:00
|
|
|
|
).all()
|
|
|
|
|
|
|
|
|
|
|
|
assert len(results) == 1
|
|
|
|
|
|
assert results[0].free_sms_fragment_limit == expected_allowance
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-11 11:47:57 -07:00
|
|
|
|
def test_fix_billable_units(notify_db_session, notify_api, sample_template):
|
|
|
|
|
|
create_notification(template=sample_template)
|
|
|
|
|
|
notification = Notification.query.one()
|
2023-08-14 09:04:06 -07:00
|
|
|
|
notification.billable_units = 0
|
|
|
|
|
|
notification.notification_type = SMS_TYPE
|
|
|
|
|
|
notification.status = NOTIFICATION_DELIVERED
|
|
|
|
|
|
notification.sent_at = None
|
|
|
|
|
|
notification.key_type = KEY_TYPE_NORMAL
|
|
|
|
|
|
|
|
|
|
|
|
notify_db_session.commit()
|
2023-08-11 11:47:57 -07:00
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
notify_api.test_cli_runner().invoke(fix_billable_units, [])
|
2023-08-11 11:47:57 -07:00
|
|
|
|
|
|
|
|
|
|
notification = Notification.query.one()
|
|
|
|
|
|
assert notification.billable_units == 1
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-03-22 09:46:26 +00:00
|
|
|
|
def test_populate_annual_billing_with_defaults_sets_free_allowance_to_zero_if_previous_year_is_zero(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
notify_db_session, notify_api
|
2022-03-22 09:46:26 +00:00
|
|
|
|
):
|
2023-08-29 14:54:30 -07:00
|
|
|
|
service = create_service(organization_type="federal")
|
|
|
|
|
|
create_annual_billing(
|
|
|
|
|
|
service_id=service.id, free_sms_fragment_limit=0, financial_year_start=2021
|
|
|
|
|
|
)
|
2022-03-22 09:46:26 +00:00
|
|
|
|
notify_api.test_cli_runner().invoke(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
populate_annual_billing_with_defaults, ["-y", 2022]
|
2022-03-22 09:46:26 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
results = AnnualBilling.query.filter(
|
|
|
|
|
|
AnnualBilling.financial_year_start == 2022,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
AnnualBilling.service_id == service.id,
|
2022-03-22 09:46:26 +00:00
|
|
|
|
).all()
|
|
|
|
|
|
|
|
|
|
|
|
assert len(results) == 1
|
|
|
|
|
|
assert results[0].free_sms_fragment_limit == 0
|
2023-02-03 10:11:21 -05:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_update_template(notify_db_session, email_2fa_code_template):
|
2023-02-03 10:11:21 -05:00
|
|
|
|
_update_template(
|
|
|
|
|
|
"299726d2-dba6-42b8-8209-30e1d66ea164",
|
|
|
|
|
|
"Example text message template!",
|
|
|
|
|
|
"sms",
|
2023-08-29 14:54:30 -07:00
|
|
|
|
[
|
|
|
|
|
|
"Hi, I’m trying out U.S. Notify! Today is ((day of week)) and my favorite color is ((color))."
|
|
|
|
|
|
],
|
|
|
|
|
|
"",
|
2023-02-03 10:11:21 -05:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
t = Template.query.all()
|
|
|
|
|
|
|
|
|
|
|
|
assert t[0].name == "Example text message template!"
|