mirror of
https://github.com/GSA/notifications-api.git
synced 2025-12-12 00:02:36 -05:00
252 lines
7.4 KiB
Python
252 lines
7.4 KiB
Python
import datetime
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
from marshmallow import ValidationError
|
|
from sqlalchemy import desc, select
|
|
|
|
from app import db
|
|
from app.dao.provider_details_dao import (
|
|
dao_update_provider_details,
|
|
get_provider_details_by_identifier,
|
|
)
|
|
from app.models import ProviderDetailsHistory, ServicePermission
|
|
from app.schema_validation import validate_schema_date_with_hour
|
|
from app.schemas import ServiceSchema, UserSchema
|
|
from tests.app.db import create_api_key
|
|
|
|
|
|
def test_job_schema_doesnt_return_notifications(sample_notification_with_job):
|
|
from app.schemas import job_schema
|
|
|
|
job = sample_notification_with_job.job
|
|
assert job.notifications.count() == 1
|
|
|
|
data = job_schema.dump(job)
|
|
|
|
assert "notifications" not in data
|
|
|
|
|
|
def test_notification_schema_ignores_absent_api_key(sample_notification_with_job):
|
|
from app.schemas import notification_with_template_schema
|
|
|
|
data = notification_with_template_schema.dump(sample_notification_with_job)
|
|
assert data["key_name"] is None
|
|
|
|
|
|
def test_notification_schema_adds_api_key_name(sample_notification):
|
|
from app.schemas import notification_with_template_schema
|
|
|
|
api_key = create_api_key(sample_notification.service, key_name="Test key")
|
|
sample_notification.api_key = api_key
|
|
|
|
data = notification_with_template_schema.dump(sample_notification)
|
|
assert data["key_name"] == "Test key"
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"schema_name",
|
|
[
|
|
"notification_with_template_schema",
|
|
"notification_schema",
|
|
"notification_with_template_schema",
|
|
"public_notification_response_schema",
|
|
],
|
|
)
|
|
def test_notification_schema_has_correct_status(sample_notification, schema_name):
|
|
from app import schemas
|
|
|
|
data = getattr(schemas, schema_name).dump(sample_notification)
|
|
|
|
assert data["status"] == sample_notification.status
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"user_attribute, user_value",
|
|
[
|
|
("name", "New User"),
|
|
("email_address", "newuser@mail.com"),
|
|
("mobile_number", "+14254147755"),
|
|
],
|
|
)
|
|
def test_user_update_schema_accepts_valid_attribute_pairs(
|
|
notify_api, user_attribute, user_value
|
|
):
|
|
update_dict = {user_attribute: user_value}
|
|
from app.schemas import user_update_schema_load_json
|
|
|
|
errors = user_update_schema_load_json.validate(update_dict)
|
|
assert not errors
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"user_attribute, user_value",
|
|
[
|
|
("name", None),
|
|
("name", ""),
|
|
("email_address", "bademail@...com"),
|
|
("mobile_number", "+44077009"),
|
|
],
|
|
)
|
|
def test_user_update_schema_rejects_invalid_attribute_pairs(
|
|
notify_api, user_attribute, user_value
|
|
):
|
|
from app.schemas import user_update_schema_load_json
|
|
|
|
update_dict = {user_attribute: user_value}
|
|
|
|
with pytest.raises(ValidationError):
|
|
user_update_schema_load_json.load(update_dict)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"user_attribute",
|
|
[
|
|
"id",
|
|
"updated_at",
|
|
"created_at",
|
|
"user_to_service",
|
|
"_password",
|
|
"verify_codes",
|
|
"logged_in_at",
|
|
"password_changed_at",
|
|
"failed_login_count",
|
|
"state",
|
|
"platform_admin",
|
|
],
|
|
)
|
|
def test_user_update_schema_rejects_disallowed_attribute_keys(
|
|
notify_api, user_attribute
|
|
):
|
|
update_dict = {user_attribute: "not important"}
|
|
from app.schemas import user_update_schema_load_json
|
|
|
|
with pytest.raises(ValidationError) as excinfo:
|
|
user_update_schema_load_json.load(update_dict)
|
|
|
|
assert excinfo.value.messages["_schema"][0] == "Unknown field name {}".format(
|
|
user_attribute
|
|
)
|
|
|
|
|
|
def test_provider_details_schema_returns_user_details(
|
|
mocker, sample_user, restore_provider_details
|
|
):
|
|
from app.schemas import provider_details_schema
|
|
|
|
current_sms_provider = get_provider_details_by_identifier("sns")
|
|
current_sms_provider.created_by = sample_user
|
|
data = provider_details_schema.dump(current_sms_provider)
|
|
|
|
assert sorted(data["created_by"].keys()) == sorted(["id", "email_address", "name"])
|
|
|
|
|
|
def test_provider_details_history_schema_returns_user_details(
|
|
mocker,
|
|
sample_user,
|
|
restore_provider_details,
|
|
):
|
|
from app.schemas import provider_details_schema
|
|
|
|
current_sms_provider = get_provider_details_by_identifier("sns")
|
|
current_sms_provider.created_by_id = sample_user.id
|
|
data = provider_details_schema.dump(current_sms_provider)
|
|
|
|
dao_update_provider_details(current_sms_provider)
|
|
|
|
stmt = (
|
|
select(ProviderDetailsHistory)
|
|
.where(ProviderDetailsHistory.id == current_sms_provider.id)
|
|
.order_by(desc(ProviderDetailsHistory.version))
|
|
)
|
|
current_sms_provider_in_history = db.session.execute(stmt).scalars().first()
|
|
|
|
data = provider_details_schema.dump(current_sms_provider_in_history)
|
|
|
|
assert sorted(data["created_by"].keys()) == sorted(["id", "email_address", "name"])
|
|
|
|
|
|
def test_valid_date_within_24_hours(mocker):
|
|
mocker.patch(
|
|
"app.schema_validation.utc_now",
|
|
return_value=datetime.datetime(2024, 10, 27, 15, 0, 0),
|
|
)
|
|
valid_datetime = "2024-10-28T14:00:00Z"
|
|
assert validate_schema_date_with_hour(valid_datetime)
|
|
|
|
|
|
def test_date_in_past(mocker):
|
|
mocker.patch(
|
|
"app.schema_validation.utc_now",
|
|
return_value=datetime.datetime(2024, 10, 27, 15, 0, 0),
|
|
)
|
|
past_datetime = "2024-10-26T14:00:00Z"
|
|
try:
|
|
validate_schema_date_with_hour(past_datetime)
|
|
assert 1 == 0
|
|
except Exception as e:
|
|
assert "datetime can not be in the past" in str(e)
|
|
|
|
|
|
def test_date_more_than_24_hours_in_future(mocker):
|
|
mocker.patch(
|
|
"app.schema_validation.utc_now",
|
|
return_value=datetime.datetime(2024, 10, 27, 15, 0, 0),
|
|
)
|
|
past_datetime = "2024-10-31T14:00:00Z"
|
|
try:
|
|
validate_schema_date_with_hour(past_datetime)
|
|
assert 1 == 0
|
|
except Exception as e:
|
|
assert "datetime can only be 24 hours in the future" in str(e)
|
|
|
|
|
|
def test_user_permissions_returns_correct_dict(sample_user):
|
|
sample_user.id = 1
|
|
mock_permissions = [
|
|
MagicMock(service_id=111, permission="read"),
|
|
MagicMock(service_id=111, permission="write"),
|
|
MagicMock(service_id=222, permission="admin"),
|
|
]
|
|
with patch(
|
|
"app.schemas.permission_dao.get_permissions_by_user_id",
|
|
return_value=mock_permissions,
|
|
):
|
|
schema = UserSchema()
|
|
|
|
result = schema.user_permissions(sample_user)
|
|
|
|
expected = {
|
|
"111": ["read", "write"],
|
|
"222": ["admin"],
|
|
}
|
|
|
|
assert result == expected
|
|
|
|
|
|
def test_deserialize_with_permissions():
|
|
input_data = {"id": "service-123", "permissions": ["read", "write"]}
|
|
|
|
schema = ServiceSchema()
|
|
result = schema.deserialize_service_permissions(input_data)
|
|
|
|
assert isinstance(result["permissions"], list)
|
|
assert all(isinstance(p, ServicePermission) for p in result["permissions"])
|
|
assert result["permissions"][0].service_id == "service-123"
|
|
assert result["permissions"][0].permission == "read"
|
|
assert result["permissions"][1].permission == "write"
|
|
|
|
|
|
def test_deserialize_with_no_permissions_key():
|
|
input_data = {"id": "service-123", "other_data": "value"}
|
|
schema = ServiceSchema()
|
|
result = schema.deserialize_service_permissions(input_data.copy())
|
|
assert result == input_data
|
|
|
|
|
|
def test_deserialize_with_non_dict_input():
|
|
input_data = ["not", "a", "dict"]
|
|
schema = ServiceSchema()
|
|
result = schema.deserialize_service_permissions(input_data)
|
|
assert result == input_data
|