Skip to content

Commit

Permalink
Merge pull request strictdoc-project#1451 from strictdoc-project/mett…
Browse files Browse the repository at this point in the history
…ta/_#1271_UID_autogeneration

export/html: 'UID reset button' on the requirement form
  • Loading branch information
mettta authored Nov 14, 2023
2 parents 9895eee + aa60c90 commit b13a3cb
Show file tree
Hide file tree
Showing 18 changed files with 303 additions and 7 deletions.
6 changes: 6 additions & 0 deletions strictdoc/export/html/templates/_res/svg_ico16_reset.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<svg class="svg_icon" width="16px" height="16px" viewBox="0 0 16 16">
<path d="M11,12 C7.5,14.5 3,12 3,7"/>
<path d="M5,4 C8.5,1.5 13,4 13,9"/>
<polyline points="5 8 3 6 1 8" />
<polyline points="11 8 13 10 15 8" />
</svg>
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
mid = custom_field_row_context.field.field_mid,
testid_postfix = "custom-field"
%}
{%- include "components/form/new_field/index.jinja" %}
{%- include "components/form/field/contenteditable/index.jinja" %}
{%- endwith -%}

{% endblock row_content %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
mid = relation_row_context.relation.relation_mid,
testid_postfix = "relation-role"
%}
{%- include "components/form/new_field/index.jinja" %}
{%- include "components/form/field/contenteditable/index.jinja" %}
{%- endwith -%}

{% endif %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
mid = reserved_field_row_context.field.field_mid,
testid_postfix = "reserved_field"
%}
{%- include "components/form/new_field/index.jinja" %}
{%- include "components/form/field/contenteditable/index.jinja" %}
{%- endwith -%}

{% endblock row_content %}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{%- extends "components/form/row.jinja" %}

{% assert text_field_row_context is defined, "row_with_text: row_context must be defined." %}

{% assert text_field_row_context.errors is defined, "row_with_text: errors must be defined." %}
{% assert text_field_row_context.field is defined, "row_with_text: field must be defined." %}
{% assert text_field_row_context.field_type is defined, "row_with_text: field_type must be defined." %}
{% assert text_field_row_context.field_type in ("singleline", "multiline"), "row_with_text: field_type must be singleline or multiline." %}
{% assert text_field_row_context.reference_mid is defined, "row_with_text: reference_mid must be defined." %}

{%- set row_context = text_field_row_context -%}

{% block row_form_attributes %}
{# Explicitly no attributes. #}
{% endblock row_form_attributes %}

{% block row_left %}
{# Explicitly nothing. #}
{% endblock row_left %}

{% block row_content scoped %}
{%- set placeholder_name = text_field_row_context.field.field_name %}

{%- with
mid = text_field_row_context.field.field_mid,
field_class_name = none,
field_input_name = text_field_row_context.field.get_input_field_name(),
field_label = text_field_row_context.field.field_name,
field_placeholder = "Enter "~placeholder_name~" here...",
field_type = text_field_row_context.field_type,
field_value = text_field_row_context.field.field_escaped_value,
testid_postfix = "requirement-field-"~text_field_row_context.field.field_name
%}
{%- include "components/form/field/contenteditable/index.jinja" %}
{%- endwith -%}

<input
type="hidden"
name="{{ text_field_row_context.field.get_input_field_type_name() }}"
value="{{ text_field_row_context.field.field_name }}"
/>
{% endblock row_content %}

{% block row_right scoped %}
<a
class="field_action"
href="/reset_uid?reference_mid={{ text_field_row_context.reference_mid }}"
mid="{{ text_field_row_context.field.field_mid }}"
title="Reset UID to default"
data-action-type="reset"
data-turbo-action="replace"
data-turbo="true"
data-testid="reset-uid-field-action"
>{% include "_res/svg_ico16_reset.jinja" %}</a>
{% endblock row_right %}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,15 @@
{% set text_field_row_context.errors=form_object.get_errors(field_.field_name) %}
{% set text_field_row_context.field = field_ %}
{% set text_field_row_context.field_type = "singleline" %}
{% include "components/requirement_form/row_with_text_field.jinja" %}
{% set text_field_row_context.reference_mid = form_object.requirement_mid %}
{%- if field_.field_name == "UID" and field_.field_escaped_value == "" -%}
<turbo-frame id="uid_with_reset-{{ text_field_row_context.reference_mid }}">
{# this template is turbo-frame and has a button to reset to the default value: #}
{% include "components/requirement_form/frame_row_with_uid_with_reset_field.jinja" %}
</turbo-frame>
{%- else -%}
{% include "components/requirement_form/row_with_text_field.jinja" %}
{%- endif -%}
{%- endfor -%}
{%- endfor -%}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
mid = comment_field_row_context.field.field_mid,
testid_postfix = "requirement-field-COMMENT"
%}
{%- include "components/form/new_field/index.jinja" %}
{%- include "components/form/field/contenteditable/index.jinja" %}
{%- endwith -%}

<input
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
mid = relation_row_context.field.field_mid,
testid_postfix = "requirement-relation-uid"
%}
{%- include "components/form/new_field/index.jinja" %}
{%- include "components/form/field/contenteditable/index.jinja" %}
{%- endwith -%}

<sdoc-form-field field-type="select">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
field_value = text_field_row_context.field.field_escaped_value,
testid_postfix = "requirement-field-"~text_field_row_context.field.field_name
%}
{%- include "components/form/new_field/index.jinja" %}
{%- include "components/form/field/contenteditable/index.jinja" %}
{%- endwith -%}

<input
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{% assert uid_form_field is defined %}

{% set text_field_row_context = namespace() %}
{% set row_context = text_field_row_context %}

{#
When called in the template:
"strictdoc/export/html/templates/components/requirement_form/index.jinja",
the following parameters are passed:
{% set text_field_row_context.errors=form_object.get_errors(field_.field_name) %}
{% set text_field_row_context.field = field_ %}
{% set text_field_row_context.field_type = "singleline" %}
{% set text_field_row_context.reference_mid = form_object.requirement_mid %}
There's no form_object here in Stream.
And we also create a field in the router "/reset_uid",
which we will pass here (instead of the field from the form_object, as in a normal form).
#}
{# So we redefine the parameters like this: #}
{% set text_field_row_context.errors=[] %}
{% set text_field_row_context.field = uid_form_field %}
{% set text_field_row_context.field_type = "singleline" %}
{% set text_field_row_context.reference_mid = uid_form_field.field_mid %}

<turbo-stream action="replace" target="uid_with_reset-{{ reference_mid }}">
{# this template is turbo-frame and has a button to reset to the default value: #}
<template>
{%- include "components/requirement_form/frame_row_with_uid_with_reset_field.jinja" %}
</template>
</turbo-stream>
46 changes: 46 additions & 0 deletions strictdoc/server/routers/main_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,52 @@ def get_edit_requirement(requirement_id: str):
},
)

@router.get(
"/reset_uid",
response_class=Response,
)
def reset_uid(reference_mid: str):
reference_node = export_action.traceability_index.get_node_by_mid(
MID(reference_mid)
)

assert isinstance(reference_node, Requirement)
# FIXME: it might as well be a section?

document_tree_stats: DocumentTreeStats = (
DocumentUIDAnalyzer.analyze_document_tree(
export_action.traceability_index
)
)
next_uid: str = document_tree_stats.get_next_requirement_uid(
reference_node.get_requirement_prefix()
)

uid_form_field: RequirementFormField = RequirementFormField(
field_mid=MID.create().get_string_value(),
field_name="UID",
field_type=RequirementFormFieldType.SINGLELINE,
field_unescaped_value=next_uid,
field_escaped_value=next_uid,
)
template = env().get_template(
"components/"
"requirement_form/"
"stream_row_with_uid_with_reset_field.jinja"
)
output = template.render(
next_uid=next_uid,
reference_mid=reference_mid,
uid_form_field=uid_form_field,
)
return HTMLResponse(
content=output,
status_code=200,
headers={
"Content-Type": "text/vnd.turbo-stream.html",
},
)

@router.post("/actions/document/update_requirement")
async def document__update_requirement(request: Request):
request_form_data: FormData = await request.form()
Expand Down
8 changes: 8 additions & 0 deletions tests/end2end/helpers/components/node/requirement.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ def assert_requirement_title(
by=By.XPATH,
)

def assert_requirement_has_no_uid(self) -> None:
"""Use it with full requirement. <sdoc-requirement-field ...>"""
self.test_case.assert_element_not_present(
f"{self.node_xpath}"
"//sdoc-requirement-field[@data-field-label='UID']",
by=By.XPATH,
)

def assert_requirement_uid_contains(
self,
uid: str,
Expand Down
32 changes: 32 additions & 0 deletions tests/end2end/helpers/screens/document/form_edit_requirement.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,35 @@ def do_fill_in_field_statement(self, field_value: str) -> None:
def do_fill_in_field_rationale(self, field_value: str) -> None:
assert isinstance(field_value, str)
super().do_fill_in("requirement-field-RATIONALE", field_value)

# Reset UID button

def assert_uid_field_contains(self, string: str) -> None:
self.test_case.assert_element_present(
"//*[@data-testid='form-field-requirement-field-UID']"
f"[contains(., '{string}')]",
by=By.XPATH,
)

def assert_uid_field_does_not_contain(self, string: str) -> None:
self.test_case.assert_element_not_present(
"//*[@data-testid='form-field-requirement-field-UID']"
f"[contains(., '{string}')]",
by=By.XPATH,
)

def assert_uid_field_has_reset_button(self) -> None:
self.test_case.assert_element_present(
"//*[@data-testid='reset-uid-field-action']",
by=By.XPATH,
)

def assert_uid_field_has_not_reset_button(self) -> None:
self.test_case.assert_element_not_present(
"//*[@data-testid='reset-uid-field-action']",
by=By.XPATH,
)

def do_reset_uid_field(self, field_name: str = "") -> None:
assert isinstance(field_name, str)
self.test_case.click_xpath("//*[@data-testid='reset-uid-field-action']")
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[DOCUMENT]
TITLE: Document 1

[FREETEXT]
Hello world!
[/FREETEXT]

[REQUIREMENT]
UID: REQ-1
STATEMENT: >>>
Requirement statement.
<<<

[REQUIREMENT]
UID: REQ-2
STATEMENT: >>>
Requirement statement.
<<<
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[DOCUMENT]
TITLE: Document 1

[FREETEXT]
Hello world!
[/FREETEXT]

[REQUIREMENT]
UID: REQ-1
STATEMENT: >>>
Requirement statement.
<<<

[REQUIREMENT]
STATEMENT: >>>
Requirement statement.
<<<
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from tests.end2end.e2e_case import E2ECase
from tests.end2end.end2end_test_setup import End2EndTestSetup
from tests.end2end.helpers.screens.document.form_edit_requirement import (
Form_EditRequirement,
)
from tests.end2end.helpers.screens.project_index.screen_project_index import (
Screen_ProjectIndex,
)
from tests.end2end.server import SDocTestServer


class Test(E2ECase):
def test(self):
test_setup = End2EndTestSetup(path_to_test_file=__file__)

with SDocTestServer(
input_path=test_setup.path_to_sandbox
) as test_server:
self.open(test_server.get_host_and_port())

screen_project_index = Screen_ProjectIndex(self)

screen_project_index.assert_on_screen()
screen_project_index.assert_contains_document("Document 1")

screen_document = screen_project_index.do_click_on_first_document()

screen_document.assert_on_screen_document()
screen_document.assert_header_document_title("Document 1")
screen_document.assert_text("Hello world!")

# Requirement 1 has UID.
# It shouldn't have a reset button.
requirement1 = screen_document.get_requirement(1)
requirement1.assert_requirement_uid_contains("REQ-1")
form_edit_requirement1: Form_EditRequirement = (
requirement1.do_open_form_edit_requirement()
)
form_edit_requirement1.assert_on_form()
form_edit_requirement1.assert_uid_field_contains("REQ-1")
form_edit_requirement1.assert_uid_field_has_not_reset_button()
form_edit_requirement1.do_form_cancel()

# New requirement form shouldn't have a reset button,
# but must have the correct UID entered in the field.
node_menu = requirement1.do_open_node_menu()
form_add_requirement: Form_EditRequirement = (
node_menu.do_node_add_requirement_above()
)
form_add_requirement.assert_on_form()
form_add_requirement.assert_uid_field_has_not_reset_button()
form_add_requirement.assert_uid_field_contains("REQ-2")
form_add_requirement.do_form_cancel()

# Requirement 2 has UID.
# It shouldn't have a reset button.
requirement2 = screen_document.get_requirement(2)
requirement2.assert_requirement_has_no_uid()
form_edit_requirement2: Form_EditRequirement = (
requirement2.do_open_form_edit_requirement()
)
form_edit_requirement2.assert_on_form()
form_edit_requirement2.assert_uid_field_has_reset_button()
form_edit_requirement2.assert_uid_field_does_not_contain("REQ-2")
# Use the reset button.
form_edit_requirement2.do_reset_uid_field()
form_edit_requirement2.assert_uid_field_contains("REQ-2")
form_edit_requirement2.do_form_submit()

# Checking the success of the button.
requirement2.assert_requirement_uid_contains("REQ-2")

assert test_setup.compare_sandbox_and_expected_output()

0 comments on commit b13a3cb

Please sign in to comment.