From 57fe6379e9c782252b746d0d3aa4cabf57df29fc Mon Sep 17 00:00:00 2001 From: Sarah Sloan Date: Thu, 18 Jul 2024 11:49:25 +0000 Subject: [PATCH] updating tests to use utils fixtures --- config/envs/unit_test.py | 3 +- docker-compose.yml | 1 + tasks/test_data.py | 124 +++++++++++----------- tests/test_clone.py | 214 +++++++++++++++++++++++--------------- tests/test_db.py | 156 ++++++++++++++++++--------- tests/test_integration.py | 12 +-- 6 files changed, 309 insertions(+), 201 deletions(-) diff --git a/config/envs/unit_test.py b/config/envs/unit_test.py index 526846e..d8ed1fb 100644 --- a/config/envs/unit_test.py +++ b/config/envs/unit_test.py @@ -13,5 +13,6 @@ class UnitTestConfig(Config): FSD_LOG_LEVEL = logging.DEBUG SQLALCHEMY_DATABASE_URI = getenv( - "DATABASE_URL", "postgresql://postgres:postgres@127.0.0.1:5432/fab_unit_test" # pragma: allowlist secret + "DATABASE_URL_UNIT_TEST", + "postgresql://postgres:postgres@127.0.0.1:5432/fab_unit_test", # pragma: allowlist secret ) diff --git a/docker-compose.yml b/docker-compose.yml index 8b0a44f..e4c5051 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,6 +8,7 @@ services: command: sleep infinity environment: - DATABASE_URL=postgresql://postgres:password@fab-db:5432/fab + - DATABASE_URL_UNIT_TEST=postgresql://postgres:password@fab-db:5432/fab_unit_test fab-db: diff --git a/tasks/test_data.py b/tasks/test_data.py index f6efc5a..ffe7fc2 100644 --- a/tasks/test_data.py +++ b/tasks/test_data.py @@ -101,30 +101,30 @@ def init_data() -> dict: name_in_apply_json={"en": "Organisation Classification"}, form_index=4, ) - p4: Page = Page( - page_id=uuid4(), - form_id=None, - display_path="organisation-alternative-names", - name_in_apply_json={"en": "Alternative names of your organisation"}, - form_index=2, - is_template=True, - ) - template_page: Page = Page( - page_id=uuid4(), - form_id=None, - display_path="testing_templates_path", - is_template=True, - name_in_apply_json={"en": "Template Path"}, - form_index=0, - ) - non_template_page: Page = Page( - page_id=uuid4(), - form_id=None, - display_path="testing_templates_path", - is_template=False, - name_in_apply_json={"en": "Not Template Path"}, - form_index=0, - ) + # p_org_alt_names: Page = Page( + # page_id=uuid4(), + # form_id=None, + # display_path="organisation-alternative-names", + # name_in_apply_json={"en": "Alternative names of your organisation"}, + # form_index=2, + # is_template=True, + # ) + # template_page: Page = Page( + # page_id=uuid4(), + # form_id=None, + # display_path="testing_templates_path", + # is_template=True, + # name_in_apply_json={"en": "Template Path"}, + # form_index=0, + # ) + # non_template_page: Page = Page( + # page_id=uuid4(), + # form_id=None, + # display_path="testing_templates_path", + # is_template=False, + # name_in_apply_json={"en": "Not Template Path"}, + # form_index=0, + # ) cri1: Criteria = Criteria(criteria_id=uuid4(), index=1, round_id=r.round_id, name="Unscored", weighting=0.0) sc1: Subcriteria = Subcriteria( subcriteria_id=uuid4(), criteria_index=1, criteria_id=cri1.criteria_id, name="Organisation Information" @@ -178,31 +178,31 @@ def init_data() -> dict: options={"hideTitle": False, "classes": ""}, runner_component_name="organisation_name", ) - c3: Component = Component( - component_id=uuid4(), - page_id=p1.page_id, - title="Does your organisation use any other names?", - type=ComponentType.YES_NO_FIELD, - page_index=2, - theme_id=t1.theme_id, - theme_index=2, - options={"hideTitle": False, "classes": ""}, - runner_component_name="does_your_organisation_use_other_names", - conditions=[ - { - "name": "organisation_other_names_no", - "value": "false", # this must be lowercaes or the navigation doesn't work - "operator": "is", - "destination_page_path": "CONTINUE", - }, - { - "name": "organisation_other_names_yes", - "value": "true", # this must be lowercaes or the navigation doesn't work - "operator": "is", - "destination_page_path": "organisation-alternative-names", - }, - ], - ) + # c3: Component = Component( + # component_id=uuid4(), + # page_id=p1.page_id, + # title="Does your organisation use any other names?", + # type=ComponentType.YES_NO_FIELD, + # page_index=2, + # theme_id=t1.theme_id, + # theme_index=2, + # options={"hideTitle": False, "classes": ""}, + # runner_component_name="does_your_organisation_use_other_names", + # conditions=[ + # { + # "name": "organisation_other_names_no", + # "value": "false", # this must be lowercaes or the navigation doesn't work + # "operator": "is", + # "destination_page_path": "CONTINUE", + # }, + # { + # "name": "organisation_other_names_yes", + # "value": "true", # this must be lowercaes or the navigation doesn't work + # "operator": "is", + # "destination_page_path": "organisation-alternative-names", + # }, + # ], + # ) c2: Component = Component( component_id=uuid4(), page_id=p2.page_id, @@ -215,17 +215,17 @@ def init_data() -> dict: options={"hideTitle": False, "classes": ""}, runner_component_name="organisation_address", ) - c7: Component = Component( - component_id=uuid4(), - page_id=p4.page_id, - title="Alternative Name 1", - type=ComponentType.TEXT_FIELD, - page_index=1, - theme_id=None, - theme_index=None, - options={"hideTitle": False, "classes": ""}, - runner_component_name="alt_name_1", - ) + # c7: Component = Component( + # component_id=uuid4(), + # page_id=p_org_alt_names.page_id, + # title="Alternative Name 1", + # type=ComponentType.TEXT_FIELD, + # page_index=1, + # theme_id=None, + # theme_index=None, + # options={"hideTitle": False, "classes": ""}, + # runner_component_name="alt_name_1", + # ) l1: Lizt = Lizt( list_id=uuid4(), name="classifications_list", @@ -251,8 +251,8 @@ def init_data() -> dict: "rounds": [r, r2], "sections": [s1], "forms": [f1, f2], - "pages": [p1, p2, p3, template_page, non_template_page, p4, p5], - "components": [c1, c2, c3, c4, c5, c6, c7, c8], + "pages": [p1, p2, p3, p5], # template_page, non_template_page, p_org_alt_names + "components": [c1, c2, c4, c5, c6, c8], # c3,c7 "criteria": [cri1], "subcriteria": [sc1], "themes": [t1, t2], diff --git a/tests/test_clone.py b/tests/test_clone.py index 156a007..1719243 100644 --- a/tests/test_clone.py +++ b/tests/test_clone.py @@ -19,62 +19,6 @@ def mock_new_uuid(mocker): yield new_id -@pytest.fixture -def page_with_components(flask_test_client, _db): - - page: Page = Page( - page_id=uuid4(), - form_id=None, - display_path="testing-clones-1", - is_template=True, - name_in_apply_json={"en": "Clone testing"}, - form_index=0, - ) - - template_component_1: Component = Component( - component_id=uuid4(), - page_id=page.page_id, - title="Template qustion 1?", - type=ComponentType.YES_NO_FIELD, - page_index=1, - theme_id=None, - theme_index=2, - options={"hideTitle": False, "classes": "test-class"}, - runner_component_name="template_question_name_1", - is_template=True, - ) - - template_component_2: Component = Component( - component_id=uuid4(), - page_id=page.page_id, - title="Template qustion 2?", - type=ComponentType.YES_NO_FIELD, - page_index=1, - theme_id=None, - theme_index=2, - options={"hideTitle": False, "classes": "test-class"}, - runner_component_name="template_question_name_2", - is_template=True, - ) - - template_component_3: Component = Component( - component_id=uuid4(), - page_id=page.page_id, - title="Template qustion 3?", - type=ComponentType.YES_NO_FIELD, - page_index=1, - theme_id=None, - theme_index=2, - options={"hideTitle": False, "classes": "test-class"}, - runner_component_name="template_question_name_3", - is_template=True, - ) - - _db.session.bulk_save_objects([page, template_component_1, template_component_2, template_component_3]) - _db.session.commit() - yield page - - # ===================================================================================================================== # These functions mock the _initiate_cloned_XXX functions and don't use the db # ===================================================================================================================== @@ -191,12 +135,56 @@ def test_clone_single_component(flask_test_client, _db): assert _db.session.get(Component, old_id) -def test_clone_multiple_components(flask_test_client, _db, page_with_components): - existing_page = _db.session.get(Page, page_with_components.page_id) - assert existing_page +page_id = uuid4() + + +@pytest.mark.seed_config( + { + "components": [ + Component( + component_id=uuid4(), + page_id=None, + title="Template qustion 1?", + type=ComponentType.YES_NO_FIELD, + page_index=1, + theme_id=None, + theme_index=2, + options={"hideTitle": False, "classes": "test-class"}, + runner_component_name="template_question_name_1", + is_template=True, + ), + Component( + component_id=uuid4(), + page_id=None, + title="Template qustion 2?", + type=ComponentType.YES_NO_FIELD, + page_index=1, + theme_id=None, + theme_index=2, + options={"hideTitle": False, "classes": "test-class"}, + runner_component_name="template_question_name_2", + is_template=True, + ), + Component( + component_id=uuid4(), + page_id=None, + title="Template qustion 3?", + type=ComponentType.YES_NO_FIELD, + page_index=1, + theme_id=None, + theme_index=2, + options={"hideTitle": False, "classes": "test-class"}, + runner_component_name="template_question_name_3", + is_template=True, + ), + ], + } +) +def test_clone_multiple_components(seed_dynamic_data, _db): + existing_components = seed_dynamic_data["components"] results = clone_multiple_components( - component_ids=[c.component_id for c in existing_page.components], + component_ids=[c.component_id for c in existing_components], new_page_id=None, new_theme_id=None, ) @@ -211,34 +199,36 @@ def test_clone_multiple_components(flask_test_client, _db, page_with_components) # Check the old ones exist from_db = ( _db.session.query(Component) - .filter(Component.component_id.in_([c.component_id for c in existing_page.components])) + .filter(Component.component_id.in_([c.component_id for c in existing_components])) .all() ) assert from_db assert len(from_db) == 3 -def test_clone_page_no_components(flask_test_client, _db, mocker): - - page: Page = Page( - page_id=uuid4(), - form_id=None, - display_path="testing-clones-1", - is_template=True, - name_in_apply_json={"en": "Clone testing"}, - form_index=0, - ) - - old_id = page.page_id - - _db.session.bulk_save_objects([page]) - _db.session.commit() +@pytest.mark.seed_config( + { + "pages": [ + Page( + page_id=uuid4(), + form_id=None, + display_path="testing-clones-no-components", + is_template=True, + name_in_apply_json={"en": "Clone testing"}, + form_index=0, + ) + ] + } +) +def test_clone_page_no_components(seed_dynamic_data, _db): + + old_id = seed_dynamic_data["pages"][0].page_id # check initial page exists initial_page_from_db = _db.session.query(Page).where(Page.page_id == old_id).one_or_none() assert initial_page_from_db - result = clone_single_page(page_id=page.page_id, new_form_id=None) + result = clone_single_page(page_id=old_id, new_form_id=None) assert result new_id = result.page_id @@ -251,17 +241,71 @@ def test_clone_page_no_components(flask_test_client, _db, mocker): assert old_page_from_db -def test_clone_page_with_components(flask_test_client, _db, mocker, page_with_components): - - old_id = page_with_components.page_id - existing_page = _db.session.get(Page, old_id) - old_component_ids = [str(c.component_id) for c in existing_page.components] +page_id = uuid4() + + +@pytest.mark.seed_config( + { + "pages": [ + Page( + page_id=page_id, + form_id=None, + display_path="testing-clones-with-components", + is_template=True, + name_in_apply_json={"en": "Clone testing"}, + form_index=0, + ) + ], + "components": [ + Component( + component_id=uuid4(), + page_id=page_id, + title="Template qustion 1?", + type=ComponentType.YES_NO_FIELD, + page_index=1, + theme_id=None, + theme_index=2, + options={"hideTitle": False, "classes": "test-class"}, + runner_component_name="template_question_name_1", + is_template=True, + ), + Component( + component_id=uuid4(), + page_id=page_id, + title="Template qustion 2?", + type=ComponentType.YES_NO_FIELD, + page_index=1, + theme_id=None, + theme_index=2, + options={"hideTitle": False, "classes": "test-class"}, + runner_component_name="template_question_name_2", + is_template=True, + ), + Component( + component_id=uuid4(), + page_id=page_id, + title="Template qustion 3?", + type=ComponentType.YES_NO_FIELD, + page_index=1, + theme_id=None, + theme_index=2, + options={"hideTitle": False, "classes": "test-class"}, + runner_component_name="template_question_name_3", + is_template=True, + ), + ], + } +) +def test_clone_page_with_components(seed_dynamic_data, _db): + + old_page_id = seed_dynamic_data["pages"][0].page_id + old_component_ids = [str(c.component_id) for c in seed_dynamic_data["components"]] # check initial page exists - initial_page_from_db = _db.session.query(Page).where(Page.page_id == old_id).one_or_none() + initial_page_from_db = _db.session.query(Page).where(Page.page_id == old_page_id).one_or_none() assert initial_page_from_db - result = clone_single_page(page_id=old_id, new_form_id=None) + result = clone_single_page(page_id=old_page_id, new_form_id=None) assert result new_id = result.page_id @@ -274,7 +318,7 @@ def test_clone_page_with_components(flask_test_client, _db, mocker, page_with_co assert str(component.component_id) not in old_component_ids # check old page still exists - old_page_from_db = _db.session.query(Page).where(Page.page_id == old_id).one_or_none() + old_page_from_db = _db.session.query(Page).where(Page.page_id == old_page_id).one_or_none() assert old_page_from_db # check old page still has references to original components assert len(old_page_from_db.components) == 3 diff --git a/tests/test_db.py b/tests/test_db.py index f408a43..d8a60e3 100644 --- a/tests/test_db.py +++ b/tests/test_db.py @@ -2,7 +2,7 @@ from random import randint from uuid import uuid4 -from sqlalchemy import text +import pytest from app.db.models import Form from app.db.models import Fund @@ -30,11 +30,24 @@ def test_add_fund(flask_test_client, _db): assert result.fund_id -def test_add_round(flask_test_client, _db): - fund = _db.session.execute(text("select * from fund limit 1;")).one() +@pytest.mark.seed_config( + { + "funds": [ + Fund( + fund_id=uuid4(), + name_json={"en": "Test Fund To Create Rounds"}, + title_json={"en": "funding to improve stuff"}, + description_json={"en": "A £10m fund to improve stuff across the devolved nations."}, + welsh_available=False, + short_name="TFCR1", + ) + ] + } +) +def test_add_round(seed_dynamic_data): result = add_round( Round( - fund_id=fund.fund_id, + fund_id=seed_dynamic_data["funds"][0].fund_id, audit_info={"user": "dummy_user", "timestamp": datetime.now().isoformat(), "action": "create"}, title_json={"en": "test title"}, short_name=f"Z{randint(0,99999)}", @@ -57,11 +70,24 @@ def test_get_all_funds(flask_test_client, _db): assert results[0].fund_id -def test_get_fund_by_id(flask_test_client, _db): - any_fund = _db.session.execute(text("select * from fund limit 1;")).one() - result: Fund = get_fund_by_id(any_fund.fund_id) +@pytest.mark.seed_config( + { + "funds": [ + Fund( + fund_id=uuid4(), + name_json={"en": "Test Fund 1"}, + title_json={"en": "funding to improve stuff"}, + description_json={"en": "A £10m fund to improve stuff across the devolved nations."}, + welsh_available=False, + short_name="TF1", + ) + ] + } +) +def test_get_fund_by_id(seed_dynamic_data): + result: Fund = get_fund_by_id(seed_dynamic_data["funds"][0].fund_id) assert result - assert result.name_json == any_fund.name_json + assert result.name_json["en"] == "Test Fund 1" def test_get_fund_by_id_none(flask_test_client, _db): @@ -74,51 +100,87 @@ def test_get_round_by_id_none(flask_test_client, _db): assert result is None -def test_get_round_by_id(flask_test_client, _db): - any_round = _db.session.execute(text("select * from round limit 1;")).one() - result: Round = get_round_by_id(any_round.round_id) - assert result.title_json == any_round.title_json +fund_id = uuid4() + + +@pytest.mark.seed_config( + { + "funds": [ + Fund( + fund_id=fund_id, + name_json={"en": "Test Fund 1"}, + title_json={"en": "funding to improve stuff"}, + description_json={"en": "A £10m fund to improve stuff across the devolved nations."}, + welsh_available=False, + short_name="TFR1", + ) + ], + "rounds": [ + Round( + round_id=uuid4(), + fund_id=fund_id, + audit_info={"user": "dummy_user", "timestamp": datetime.now().isoformat(), "action": "create"}, + title_json={"en": "round the first"}, + short_name="R1", + opens=datetime.now(), + deadline=datetime.now(), + assessment_start=datetime.now(), + reminder_date=datetime.now(), + assessment_deadline=datetime.now(), + prospectus_link="http://www.google.com", + privacy_notice_link="http://www.google.com", + ) + ], + } +) +def test_get_round_by_id(seed_dynamic_data): + + result: Round = get_round_by_id(seed_dynamic_data["rounds"][0].round_id) + assert result.title_json["en"] == "round the first" + + +@pytest.mark.seed_config( + { + "pages": [ + Page( + page_id=uuid4(), + form_id=None, + display_path="testing_templates_path", + is_template=True, + name_in_apply_json={"en": "Template Path"}, + form_index=0, + ), + Page( + page_id=uuid4(), + form_id=None, + display_path="testing_templates_path", + is_template=False, + name_in_apply_json={"en": "Not Template Path"}, + form_index=0, + ), + ] + } +) +def test_get_template_page_by_display_path(seed_dynamic_data): - -def test_get_template_page_by_display_path(flask_test_client, _db): - _db.session.execute( - text("TRUNCATE TABLE fund, round, section,form, page, component, theme, subcriteria, criteria CASCADE;") - ) - _db.session.commit() - - template_page: Page = Page( - page_id=uuid4(), - form_id=None, - display_path="testing_templates_path", - is_template=True, - name_in_apply_json={"en": "Template Path"}, - form_index=0, - ) - non_template_page: Page = Page( - page_id=uuid4(), - form_id=None, - display_path="testing_templates_path", - is_template=False, - name_in_apply_json={"en": "Not Template Path"}, - form_index=0, - ) - - _db.session.bulk_save_objects([template_page, non_template_page]) - _db.session.commit() result = get_template_page_by_display_path("testing_templates_path") assert result - assert result.page_id == template_page.page_id + assert result.page_id == seed_dynamic_data["pages"][0].page_id -def test_form_sorting(flask_test_client, _db): - # Create a section with one form, at index 1 - section: Section = Section(section_id=uuid4(), name_in_apply_json={"en": "hello section"}) - form1: Form = Form( - form_id=uuid4(), section_id=section.section_id, section_index=1, name_in_apply_json={"en": "Form 1"} - ) - _db.session.bulk_save_objects([section, form1]) - _db.session.commit() +section_id = uuid4() + +# Create a section with one form, at index 1 +@pytest.mark.seed_config( + { + "sections": [Section(section_id=section_id, name_in_apply_json={"en": "hello section"})], + "forms": [Form(form_id=uuid4(), section_id=section_id, section_index=1, name_in_apply_json={"en": "Form 1"})], + } +) +def test_form_sorting(seed_dynamic_data, _db): + section = seed_dynamic_data["sections"][0] + form1 = seed_dynamic_data["forms"][0] result_section = _db.session.query(Section).where(Section.section_id == section.section_id).one_or_none() assert len(result_section.forms) == 1 diff --git a/tests/test_integration.py b/tests/test_integration.py index 1b7460d..9c36780 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -20,7 +20,7 @@ def test_build_form_json(seed_dynamic_data): result = build_form_json(form=form) assert result - assert len(result["pages"]) == 6 + assert len(result["pages"]) == 5 exp_start_path = "/intro-about-your-organisation" exp_second_path = "/organisation-name" assert result["startPage"] == exp_start_path @@ -30,11 +30,11 @@ def test_build_form_json(seed_dynamic_data): org_name_page = next((p for p in result["pages"] if p["path"] == exp_second_path), None) assert org_name_page - assert len(org_name_page["next"]) == 2 + assert len(org_name_page["next"]) == 1 - alt_names_page = next((p for p in result["pages"] if p["path"] == "/organisation-alternative-names"), None) - assert alt_names_page - assert alt_names_page["next"][0]["path"] == "/organisation-address" + # alt_names_page = next((p for p in result["pages"] if p["path"] == "/organisation-alternative-names"), None) + # assert alt_names_page + # assert alt_names_page["next"][0]["path"] == "/organisation-address" address_page = next((p for p in result["pages"] if p["path"] == "/organisation-address"), None) assert address_page @@ -60,7 +60,7 @@ def test_build_assessment_config(seed_dynamic_data): assert first_unscored["name"] == "Unscored" assert len(first_unscored["subcriteria"]) == 1 assert len(first_unscored["subcriteria"][0]["themes"]) == 2 - assert len(first_unscored["subcriteria"][0]["themes"][0]["answers"]) == 4 + assert len(first_unscored["subcriteria"][0]["themes"][0]["answers"]) == 3 assert len(first_unscored["subcriteria"][0]["themes"][1]["answers"]) == 3