Skip to content

Commit

Permalink
Merge pull request #53 from Police-Data-Accessibility-Project/mc_form…
Browse files Browse the repository at this point in the history
…atting_and_test_fixes

Mc formatting and test fixes
  • Loading branch information
maxachis authored Jul 11, 2024
2 parents 146ccc7 + 23dcf45 commit c40ff7e
Show file tree
Hide file tree
Showing 24 changed files with 71 additions and 51 deletions.
5 changes: 0 additions & 5 deletions .github/workflows/pull.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,6 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Test with pytest
run: |
pip install pytest pytest-cov
pytest tests/resources/app_test.py --doctest-modules --junitxml=junit/test-results.xml --cov=com --cov-report=xml --cov-report=html
setup_client:
defaults:
Expand Down
2 changes: 1 addition & 1 deletion app.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@ def create_app() -> Flask:

if __name__ == "__main__":
app = create_app()
app.run(host=os.getenv('FLASK_RUN_HOST', '127.0.0.1'))
app.run(host=os.getenv("FLASK_RUN_HOST", "127.0.0.1"))
2 changes: 1 addition & 1 deletion database_client/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,4 @@
"approval_status",
"airtable_uid",
"airtable_source_last_modified",
]
]
1 change: 0 additions & 1 deletion database_client/database_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,6 @@ def get_needs_identification_data_sources(self) -> list[tuple[Any, ...]]:
self.cursor.execute(sql_query)
return self.cursor.fetchall()


def add_new_data_source(self, data: dict) -> None:
"""
Processes a request to add a new data source.
Expand Down
4 changes: 3 additions & 1 deletion database_client/result_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ def zip_get_data_source_by_id_results(results: tuple[Any, ...]) -> dict[str, Any
data_source_and_agency_columns = (
DATA_SOURCES_APPROVED_COLUMNS + AGENCY_APPROVED_COLUMNS
)
data_source_and_agency_columns.extend(['data_source_id', 'agency_id', 'agency_name'])
data_source_and_agency_columns.extend(
["data_source_id", "agency_id", "agency_name"]
)
# Convert to a list and only return the first (and only)
return ResultFormatter.convert_data_source_matches(
data_source_and_agency_columns, [results]
Expand Down
2 changes: 1 addition & 1 deletion middleware/access_token_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

from database_client.database_client import DatabaseClient


def insert_access_token(db_client: DatabaseClient):
token = uuid.uuid4().hex
expiration = datetime.datetime.now() + datetime.timedelta(minutes=5)
db_client.add_new_access_token(token, expiration)

3 changes: 1 addition & 2 deletions middleware/agencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from database_client.database_client import DatabaseClient
from utilities.common import convert_dates_to_strings


def get_agencies(db_client: DatabaseClient, page: int) -> Response:
"""
Retrieves a paginated list of approved agencies from the database.
Expand Down Expand Up @@ -40,5 +41,3 @@ def process_results(results: list[dict]) -> list[dict]:
list[dict]: The processed list of dictionaries with converted dates.
"""
return [convert_dates_to_strings(dict(result)) for result in results]


1 change: 1 addition & 0 deletions middleware/archives_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def archives_get_query(

return archives_combined_results_clean


def update_archives_data(
db_client: DatabaseClient,
data_id: str,
Expand Down
3 changes: 3 additions & 0 deletions middleware/data_source_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
class DataSourceNotFoundError(Exception):
pass


def get_approved_data_sources_wrapper(db_client: DatabaseClient) -> Response:
raw_results = db_client.get_approved_data_sources()
zipped_results = ResultFormatter.zip_get_approved_data_sources_results(raw_results)
Expand All @@ -23,6 +24,7 @@ def get_approved_data_sources_wrapper(db_client: DatabaseClient) -> Response:
HTTPStatus.OK.value,
)


def data_source_by_id_wrapper(arg, db_client: DatabaseClient) -> Response:
try:
data_source_details = data_source_by_id_query(
Expand Down Expand Up @@ -73,6 +75,7 @@ def get_restricted_columns():
]
return restricted_columns


def update_data_source_wrapper(
db_client: DatabaseClient, data: dict, data_source_id: str
) -> Response:
Expand Down
12 changes: 6 additions & 6 deletions middleware/login_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
from middleware.util import get_env_variable




def try_logging_in(db_client: DatabaseClient, email: str, password: str) -> Response:
"""
Tries to log in a user.
Expand Down Expand Up @@ -50,6 +48,7 @@ def is_admin(db_client: DatabaseClient, email: str) -> bool:
role_info = db_client.get_role_by_email(email)
return role_info.role == "admin"


def create_session_token(db_client: DatabaseClient, user_id: int, email: str) -> str:
"""
Generates a session token for a user and inserts it into the session_tokens table.
Expand Down Expand Up @@ -77,11 +76,14 @@ def create_session_token(db_client: DatabaseClient, user_id: int, email: str) ->

SessionTokenUserData = namedtuple("SessionTokenUserData", ["id", "email"])


def generate_api_key() -> str:
return uuid.uuid4().hex


def get_api_key_for_user(db_client: DatabaseClient, email: str, password: str) -> Response:
def get_api_key_for_user(
db_client: DatabaseClient, email: str, password: str
) -> Response:
"""
Tries to log in a user. If successful, generates API key
Expand All @@ -94,9 +96,7 @@ def get_api_key_for_user(db_client: DatabaseClient, email: str, password: str) -

if check_password_hash(user_data.password_digest, password):
api_key = generate_api_key()
db_client.update_user_api_key(
user_id=user_data.id, api_key=api_key
)
db_client.update_user_api_key(user_id=user_data.id, api_key=api_key)
payload = {"api_key": api_key}
return make_response(payload, HTTPStatus.OK)

Expand Down
11 changes: 6 additions & 5 deletions middleware/quick_search_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ def quick_search_query(

processed_search_parameters = process_search_parameters(search_parameters)

data_source_matches = get_data_source_matches(db_client, processed_search_parameters)
data_source_matches = get_data_source_matches(
db_client, processed_search_parameters
)
processed_data_source_matches = process_data_source_matches(data_source_matches)

data_sources = {
Expand Down Expand Up @@ -102,7 +104,8 @@ def get_data_source_matches(
unaltered_results = db_client.get_quick_search_results(sp.search, sp.location)

spacy_results = db_client.get_quick_search_results(
search=depluralize(sp.search), location=sp.location.strip())
search=depluralize(sp.search), location=sp.location.strip()
)

# Compare altered search term results with unaltered search term results, return the longer list
results = (
Expand All @@ -116,9 +119,7 @@ def get_data_source_matches(
return data_source_matches


def quick_search_query_wrapper(
arg1, arg2, db_client: DatabaseClient
) -> Response:
def quick_search_query_wrapper(arg1, arg2, db_client: DatabaseClient) -> Response:
try:
data_sources = quick_search_query(
SearchParameters(search=arg1, location=arg2), db_client=db_client
Expand Down
3 changes: 2 additions & 1 deletion tests/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,12 @@ def client_with_db(dev_db_connection: psycopg2.extensions.connection, monkeypatc
def bypass_api_required(monkeypatch):
monkeypatch.setattr("middleware.security.validate_token", lambda: None)


@pytest.fixture
def live_database_client(db_cursor) -> DatabaseClient:
"""
Returns a database client with a live connection to the database
:param db_cursor:
:return:
"""
return DatabaseClient(db_cursor)
return DatabaseClient(db_cursor)
1 change: 1 addition & 0 deletions tests/helper_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def insert_test_agencies_and_sources(cursor: psycopg2.extensions.cursor) -> None
"""
)


def insert_test_agencies_and_sources_if_not_exist(cursor: psycopg2.extensions.cursor):
try:
cursor.execute("SAVEPOINT my_savepoint")
Expand Down
15 changes: 11 additions & 4 deletions tests/helper_scripts/test_data_generator.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import psycopg2
from psycopg2 import sql


class TestDataGenerator:
"""
A class for generating test data.
Expand All @@ -13,13 +14,17 @@ def __init__(self, cursor: psycopg2.extensions.cursor):
def build_savepoint(self, savepoint_name: str = "test_savepoint"):
# Build savepoint using SQL composed
raw_query = f"SAVEPOINT {savepoint_name}"
sql_query = sql.SQL(raw_query).format(savepoint_name=sql.Identifier(savepoint_name))
sql_query = sql.SQL(raw_query).format(
savepoint_name=sql.Identifier(savepoint_name)
)
self.cursor.execute(sql_query)
self.savepoint = savepoint_name

def rollback_savepoint(self):
raw_query = f"ROLLBACK TO SAVEPOINT {self.savepoint}"
sql_query = sql.SQL(raw_query).format(savepoint_name=sql.Identifier(self.savepoint))
sql_query = sql.SQL(raw_query).format(
savepoint_name=sql.Identifier(self.savepoint)
)
self.cursor.execute(sql_query)

def build_xylonslvania(self):
Expand All @@ -31,7 +36,8 @@ def build_xylonslvania(self):
and test data sources
:return:
"""
self.cursor.execute("""
self.cursor.execute(
"""
INSERT INTO state_names (state_iso, state_name)
VALUES ('XY', 'Xylonsylvania');
Expand Down Expand Up @@ -75,4 +81,5 @@ def build_xylonslvania(self):
WHERE ds.record_type = rt.name;
""")
"""
)
3 changes: 2 additions & 1 deletion tests/integration/test_data_sources_by_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
from tests.helper_functions import (
create_test_user_api,
create_api_key,
give_user_admin_role, check_response_status,
give_user_admin_role,
check_response_status,
)


Expand Down
6 changes: 5 additions & 1 deletion tests/middleware/test_agencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
)
from tests.helper_functions import DynamicMagicMock


class AgenciesMocks(DynamicMagicMock):
db_client: MagicMock
page: MagicMock
results: MagicMock


def test_get_agencies_matches(monkeypatch):
mock = AgenciesMocks()
mock.db_client.get_agencies_from_page = MagicMock(return_value=mock.results)
Expand All @@ -37,7 +39,9 @@ def test_get_agencies(monkeypatch):
mock_get_agencies_matches = MagicMock(return_value=mock_agencies_matches)
mock_make_response = MagicMock(return_value=mock.response)

monkeypatch.setattr("middleware.agencies.get_agencies_matches", mock_get_agencies_matches)
monkeypatch.setattr(
"middleware.agencies.get_agencies_matches", mock_get_agencies_matches
)
monkeypatch.setattr("middleware.agencies.make_response", mock_make_response)

# Call function
Expand Down
6 changes: 3 additions & 3 deletions tests/middleware/test_archives_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
)




class UpdateArchivesDataMocks(DynamicMagicMock):
db_client: MagicMock
data_id: MagicMock
Expand All @@ -35,7 +33,9 @@ def test_update_archives_data_broken_as_of(setup_update_archives_data_mocks):
mock = setup_update_archives_data_mocks

# Call function
update_archives_data(mock.db_client, mock.data_id, mock.last_cached, mock.broken_as_of)
update_archives_data(
mock.db_client, mock.data_id, mock.last_cached, mock.broken_as_of
)

mock.db_client.update_url_status_to_broken.assert_called_with(
mock.data_id, mock.broken_as_of, mock.last_cached
Expand Down
8 changes: 4 additions & 4 deletions tests/middleware/test_data_source_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ def setup_try_logging_in_mocks(monkeypatch, check_password_hash_return_value):
mock_user_id = MagicMock()
mock_session_token = MagicMock()
mock_user_info = DatabaseClient.UserInfo(
password_digest=mock_password_digest,
id=mock_user_id,
api_key=None
password_digest=mock_password_digest, id=mock_user_id, api_key=None
)
mock_db_client.get_user_info = MagicMock(return_value=mock_user_info)
mock_make_response = MagicMock()
Expand Down Expand Up @@ -85,7 +83,9 @@ def test_try_logging_in_successful(monkeypatch):

# Assert
mock_db_client.get_user_info.assert_called_with(mock_email)
mock_create_session_token.assert_called_with(mock_db_client, mock_user_id, mock_email)
mock_create_session_token.assert_called_with(
mock_db_client, mock_user_id, mock_email
)
mock_make_response.assert_called_with(
{"message": "Successfully logged in", "data": mock_session_token}, HTTPStatus.OK
)
Expand Down
4 changes: 2 additions & 2 deletions tests/middleware/test_quick_search_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
from tests.fixtures import connection_with_test_data, dev_db_connection



def test_quick_search_query_logging(
connection_with_test_data: psycopg2.extensions.connection,
) -> None:
Expand All @@ -40,7 +39,8 @@ def test_quick_search_query_logging(
test_datetime = result[0]

quick_search_query(
SearchParameters(search="Source 1", location="City A"), db_client=DatabaseClient(cursor)
SearchParameters(search="Source 1", location="City A"),
db_client=DatabaseClient(cursor),
)
# Test that query inserted into log
result = get_most_recent_quick_search_query_log(cursor, "Source 1", "City A")
Expand Down
1 change: 0 additions & 1 deletion tests/middleware/test_reset_token_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ def test_validate_token_token_is_expired(monkeypatch, setup_validate_token_mocks
mock.db_client.delete_reset_token.assert_called_once_with(mock.email, mock.token)



def test_set_new_user_password_happy_path(monkeypatch):
mock_db_client = MagicMock()
mock_email = MagicMock()
Expand Down
5 changes: 2 additions & 3 deletions tests/middleware/test_user_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class TestUserMagicMock(DynamicMagicMock):
user_id: MagicMock
email: MagicMock


def test_user_check_email(monkeypatch) -> None:
"""
Verify the functionality of the `user_check_email` method.
Expand All @@ -45,9 +46,7 @@ def test_user_check_email(monkeypatch) -> None:
mock.db_client.get_user_id.assert_called_once_with(mock.email)


def test_user_check_email_raises_user_not_found_error(
monkeypatch
) -> None:
def test_user_check_email_raises_user_not_found_error(monkeypatch) -> None:
mock = TestUserMagicMock()
mock.db_client.get_user_id.return_value = None

Expand Down
5 changes: 4 additions & 1 deletion tests/middleware/test_webhook_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ def mock_requests_post():


def test_post_to_webhook(mock_env_variable, mock_requests_post):
mock_env_variable.side_effect = ["https://base_app.com","https://example.com/webhook"]
mock_env_variable.side_effect = [
"https://base_app.com",
"https://example.com/webhook",
]
data = '{"key": "value"}'
post_to_webhook(data)

Expand Down
Loading

0 comments on commit c40ff7e

Please sign in to comment.