Skip to content

Commit

Permalink
Added clone page
Browse files Browse the repository at this point in the history
  • Loading branch information
srh-sloan committed Jul 19, 2024
1 parent 6c73dd2 commit e36189a
Show file tree
Hide file tree
Showing 3 changed files with 264 additions and 7 deletions.
46 changes: 40 additions & 6 deletions app/db/queries/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,52 @@ def _initiate_cloned_page(to_clone: Page, new_form_id=None):
return clone


def clone_single_page(page_id: str, new_form_id=None) -> Page:
page_to_clone: Page = db.session.query(Page).where(Page.page_id == page_id).one_or_none()
clone = _initiate_cloned_page(page_to_clone, new_form_id)
def _initiate_cloned_form(to_clone: Form, new_section_id: str) -> Form:
clone = Form(**to_clone.as_dict())
clone.form_id = uuid4()
clone.section_id = new_section_id
clone.is_template = False
clone.source_template_id = to_clone.form_id
clone.template_name = None
clone.pages = []
return clone


def clone_single_form(form_id: str, new_section_id=None) -> Form:
form_to_clone: Form = db.session.query(Form).where(Form.form_id == form_id).one_or_none()
clone = _initiate_cloned_form(form_to_clone, new_section_id)

cloned_pages = []
cloned_components = []
for component_to_clone in page_to_clone.components:
for page_to_clone in form_to_clone.pages:

cloned_page = _initiate_cloned_page(page_to_clone, new_form_id=clone.form_id)
cloned_pages.append(cloned_page)
cloned_components.extend(_initiate_cloned_components_for_page(page_to_clone.components, cloned_page.page_id))
db.session.add_all([clone, *cloned_pages, *cloned_components])
db.session.commit()

return clone


def _initiate_cloned_components_for_page(
components_to_clone: list[Component], new_page_id: str = None, new_theme_id: str = None
):
cloned_components = []
for component_to_clone in components_to_clone:

cloned_component = _initiate_cloned_component(
component_to_clone, new_page_id=clone.page_id, new_theme_id=None
component_to_clone, new_page_id=new_page_id, new_theme_id=None
) # TODO how should themes work when cloning?
cloned_components.append(cloned_component)
# clone.components = cloned_components
return cloned_components


def clone_single_page(page_id: str, new_form_id=None) -> Page:
page_to_clone: Page = db.session.query(Page).where(Page.page_id == page_id).one_or_none()
clone = _initiate_cloned_page(page_to_clone, new_form_id)

cloned_components = _initiate_cloned_components_for_page(page_to_clone.components, new_page_id=clone.page_id)
db.session.add_all([clone, *cloned_components])
db.session.commit()

Expand Down
223 changes: 223 additions & 0 deletions tests/test_clone.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
from app.db.models import Component
from app.db.models import ComponentType
from app.db.models import Page
from app.db.models.application_config import Form
from app.db.queries.application import _initiate_cloned_component
from app.db.queries.application import _initiate_cloned_form
from app.db.queries.application import _initiate_cloned_page
from app.db.queries.application import clone_multiple_components
from app.db.queries.application import clone_single_component
from app.db.queries.application import clone_single_form
from app.db.queries.application import clone_single_page


Expand All @@ -24,6 +27,31 @@ def mock_new_uuid(mocker):
# =====================================================================================================================


def test_initiate_cloned_form(mock_new_uuid):
clone: Form = Form(
form_id="old-id",
name_in_apply_json={"en": "test form 1"},
section_id="old-section-id",
is_template=True,
template_name="Template Page",
runner_publish_name="template-form-1",
)
result: Form = _initiate_cloned_form(to_clone=clone, new_section_id="new-section")
assert result
assert result.form_id == mock_new_uuid

# Check other bits are the same
assert result.name_in_apply_json == clone.name_in_apply_json
assert result.runner_publish_name == clone.runner_publish_name

# check template settings
assert result.is_template is False
assert result.source_template_id == "old-id"
assert result.template_name is None

assert result.section_id == "new-section"


def test_initiate_cloned_page(mock_new_uuid):
clone: Page = Page(
page_id="old-id",
Expand Down Expand Up @@ -324,3 +352,198 @@ def test_clone_page_with_components(seed_dynamic_data, _db):
assert len(old_page_from_db.components) == 3
for component in old_page_from_db.components:
assert str(component.component_id) in old_component_ids


@pytest.mark.seed_config(
{
"forms": [
Form(
form_id=uuid4(),
section_id=None,
name_in_apply_json={"en": "UT Form 1"},
section_index=2,
runner_publish_name="ut-form-1",
)
]
}
)
def test_clone_form_no_pages(seed_dynamic_data, _db):
old_form = _db.session.get(Form, seed_dynamic_data["forms"][0].form_id)
assert old_form

result = clone_single_form(form_id=old_form.form_id, new_section_id=None)
assert result
assert result.form_id != old_form.form_id

cloned_form = _db.session.get(Form, result.form_id)
assert cloned_form
assert len(cloned_form.pages) == 0

old_form_from_db = _db.session.get(Form, old_form.form_id)
assert old_form_from_db


form_id_2 = uuid4()


@pytest.mark.seed_config(
{
"forms": [
Form(
form_id=form_id_2,
section_id=None,
name_in_apply_json={"en": "UT Form 2"},
section_index=2,
runner_publish_name="ut-form-2",
)
],
"pages": [
Page(
page_id=uuid4(),
form_id=form_id_2,
display_path="testing-clone-from-form",
is_template=True,
name_in_apply_json={"en": "Clone testing"},
form_index=0,
)
],
}
)
def test_clone_form_with_page(seed_dynamic_data, _db):
old_form = _db.session.get(Form, seed_dynamic_data["forms"][0].form_id)
assert old_form

result = clone_single_form(form_id=old_form.form_id, new_section_id=None)
assert result
assert result.form_id != old_form.form_id

cloned_form = _db.session.get(Form, result.form_id)
assert cloned_form
assert len(cloned_form.pages) == 1
new_page_id = cloned_form.pages[0].page_id

old_form_from_db = _db.session.get(Form, old_form.form_id)
assert old_form_from_db
assert len(old_form_from_db.pages) == 1
old_page_id = old_form_from_db.pages[0].page_id

assert old_page_id != new_page_id


form_id_3 = uuid4()
page_id_2 = uuid4()
page_id_3 = uuid4()


@pytest.mark.seed_config(
{
"forms": [
Form(
form_id=form_id_3,
section_id=None,
name_in_apply_json={"en": "UT Form 2"},
section_index=2,
runner_publish_name="ut-form-2",
)
],
"pages": [
Page(
page_id=page_id_2,
form_id=form_id_3,
display_path="testing-clone-from-form-2",
is_template=True,
name_in_apply_json={"en": "Clone testing"},
form_index=0,
),
Page(
page_id=page_id_3,
form_id=form_id_3,
display_path="testing-clone-from-form-3",
is_template=True,
name_in_apply_json={"en": "Clone testing"},
form_index=0,
),
],
"components": [
Component(
component_id=uuid4(),
page_id=page_id_2,
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_2,
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_3,
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_form_with_pages_and_components(seed_dynamic_data, _db):
old_form = _db.session.get(Form, seed_dynamic_data["forms"][0].form_id)
assert old_form

result = clone_single_form(form_id=old_form.form_id, new_section_id=None)
assert result
assert result.form_id != old_form.form_id

cloned_form = _db.session.get(Form, result.form_id)
assert cloned_form
assert len(cloned_form.pages) == 2
new_page_id_1 = next(p.page_id for p in cloned_form.pages if p.display_path == "testing-clone-from-form-2")
new_page_id_2 = next(p.page_id for p in cloned_form.pages if p.display_path == "testing-clone-from-form-3")
new_page_1: Page = _db.session.get(Page, new_page_id_1)
new_page_2: Page = _db.session.get(Page, new_page_id_2)

old_form_from_db = _db.session.get(Form, old_form.form_id)
assert old_form_from_db
assert len(old_form_from_db.pages) == 2

# Set old page id 1 and 2 to be the ids of the old pages that correspond to the new
# pages 1 and 2 by matching display path
old_page_id_1 = next(p.page_id for p in old_form_from_db.pages if p.display_path == new_page_1.display_path)
old_page_id_2 = next(p.page_id for p in old_form_from_db.pages if p.display_path == new_page_2.display_path)

assert new_page_id_1 not in [old_page_id_1, old_page_id_2]
assert new_page_id_2 not in [old_page_id_1, old_page_id_2]

# Check pages and components

assert len(new_page_1.components) == 2
assert len(new_page_2.components) == 1

old_page_1 = _db.session.get(Page, old_page_id_1)
old_page_2 = _db.session.get(Page, old_page_id_2)

old_component_ids_1 = [c.component_id for c in old_page_1.components]
old_component_ids_2 = [c.component_id for c in old_page_2.components]

# check the new components are different than the old ones
assert new_page_1.components[0].component_id not in old_component_ids_1
assert new_page_1.components[1].component_id not in old_component_ids_1
assert new_page_2.components[0].component_id not in old_component_ids_2
2 changes: 1 addition & 1 deletion tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def test_build_form_json_with_conditions(seed_dynamic_data):


# TODO this fails with components from a template (branching logic)
def test_build_assessment_config(seed_dynamic_data):
def test_build_assessment_config_no_branching(seed_dynamic_data):

f: Fund = get_fund_by_id(seed_dynamic_data["funds"][0].fund_id)
criteria = f.rounds[0].criteria[0]
Expand Down

0 comments on commit e36189a

Please sign in to comment.