From 818437cbaa8c86a7b3e668231e8e53bbb93b1b6c Mon Sep 17 00:00:00 2001 From: RamuniN Date: Mon, 13 Nov 2023 16:52:31 +0000 Subject: [PATCH 1/4] added edit comment feature --- app/blueprints/assessments/routes.py | 18 +++++++++ .../templates/macros/comments.html | 36 +++++++++++++++++- .../templates/macros/comments_box.html | 6 ++- .../templates/macros/comments_edit_box.html | 30 +++++++++++++++ .../assessments/templates/sub_criteria.html | 6 ++- app/blueprints/services/data_services.py | 37 +++++++++++++------ app/blueprints/services/models/comment.py | 18 ++++++++- 7 files changed, 133 insertions(+), 18 deletions(-) create mode 100644 app/blueprints/assessments/templates/macros/comments_edit_box.html diff --git a/app/blueprints/assessments/routes.py b/app/blueprints/assessments/routes.py index e43ffe38..83161851 100644 --- a/app/blueprints/assessments/routes.py +++ b/app/blueprints/assessments/routes.py @@ -397,6 +397,22 @@ def display_sub_criteria( ) ) + edit_comment_argument = request.args.get("edit_comment") + comment_id = request.args.get("comment_id") + if edit_comment_argument and comment_form.validate_on_submit(): + comment = comment_form.comment.data + submit_comment(comment=comment, comment_id=comment_id) + + return redirect( + url_for( + "assessment_bp.display_sub_criteria", + application_id=application_id, + sub_criteria_id=sub_criteria_id, + theme_id=theme_id, + _anchor="comments", + ) + ) + state = get_state_for_tasklist_banner(application_id) flags_list = get_flags(application_id) @@ -426,6 +442,8 @@ def display_sub_criteria( "comments": theme_matched_comments, "is_flaggable": False, # Flag button is disabled in sub-criteria page, "display_comment_box": add_comment_argument, + "display_comment_edit_box": edit_comment_argument, + "comment_id": comment_id, "comment_form": comment_form, "current_theme": current_theme, "flag_status": flag_status, diff --git a/app/blueprints/assessments/templates/macros/comments.html b/app/blueprints/assessments/templates/macros/comments.html index 98468406..5ff89cab 100644 --- a/app/blueprints/assessments/templates/macros/comments.html +++ b/app/blueprints/assessments/templates/macros/comments.html @@ -3,7 +3,6 @@

Comments

Summarise any thoughts you have on the information provided.

-

You cannot edit or delete your comment once you have saved it.

{% if comments == None %}
@@ -18,13 +17,46 @@

Comments

{% else %}
-

{{ comment.comment }}

+

{{ comment.updates[-1]['comment'] }}

{{ comment.full_name }} ({{ comment.highest_role|all_caps_to_human }}) {{ comment.email_address }}

{{ comment.date_created|utc_to_bst }}

+ {% if g.account_id == comment.user_id %} +
+ Edit comment + {% if comment.updates|length > 1 %} + See history + {% endif %} +
+ {% endif %}
{% endif %} {% endfor %} {% endfor %} {% endif %} +{#
+
+
+ +
+

This is a comment that has been left by you and has the ability to be edited as well as see previous edits for this comment.

+

Your name (Assessor) yourname@assessment.org.uk

+

19/05/2022 at 14:58

+
+ + +
+
+
#} {% endmacro %} diff --git a/app/blueprints/assessments/templates/macros/comments_box.html b/app/blueprints/assessments/templates/macros/comments_box.html index ca9f4f7e..b1b2317d 100644 --- a/app/blueprints/assessments/templates/macros/comments_box.html +++ b/app/blueprints/assessments/templates/macros/comments_box.html @@ -1,7 +1,7 @@ {%- from 'govuk_frontend_jinja/components/textarea/macro.html' import govukTextarea -%} {%- from "govuk_frontend_jinja/components/button/macro.html" import govukButton -%} -{% macro comment_box(comment_form) %} +{% macro comment_box(comment_form, html_text, placeholder) %}
@@ -12,10 +12,12 @@ "id": comment_form.comment.id, "rows": 8, "label": { - "text": "Add a comment", + "text": "" if html_text else "Add a comment", + "html": html_text if html_text else "", "classes": "govuk-label--m", isPageHeading: true }, + "value": placeholder if placeholder else "", "errorMessage": { "text": comment_form.comment.errors.0 } if comment_form.comment.errors diff --git a/app/blueprints/assessments/templates/macros/comments_edit_box.html b/app/blueprints/assessments/templates/macros/comments_edit_box.html new file mode 100644 index 00000000..265353dc --- /dev/null +++ b/app/blueprints/assessments/templates/macros/comments_edit_box.html @@ -0,0 +1,30 @@ +{% from "macros/comments_box.html" import comment_box %} + +{% macro edit_comment_box(comments, comment_id, comment_form) %} + + {# Using namespace objects to access variables set outside of for loop #} + {% set comment_text = namespace(str = "") %} + {% set comment_author = namespace(str = "") %} + {% set comment_date = namespace(str = "") %} + + {% for comment_list in comments.values() %} + {% for comment in comment_list %} + {% if comment.id == comment_id %} + {% set comment_text.str = comment.updates[-1]['comment'] %} + {% set comment_author.str = comment.full_name + " (" + comment.highest_role|all_caps_to_human + ") "+ comment.email_address %} + {% set comment_date.str = comment.date_created|utc_to_bst %} + {% endif %} + {% endfor %} + {% endfor %} + + {% set HtmlData %} +

Edit comment

+
+

{{ comment_text.str }}

+

{{ comment_author.str }}

+

{{ comment_date.str }}

+
+ {% endset %} + + {{ comment_box(comment_form, HtmlData, comment_text.str) }} +{% endmacro %} diff --git a/app/blueprints/assessments/templates/sub_criteria.html b/app/blueprints/assessments/templates/sub_criteria.html index 5f01b78c..36b62caa 100644 --- a/app/blueprints/assessments/templates/sub_criteria.html +++ b/app/blueprints/assessments/templates/sub_criteria.html @@ -4,6 +4,7 @@ {% from "macros/banner_summary.html" import banner_summary %} {% from "macros/flag_application_button.html" import flag_application_button %} {% from "macros/comments.html" import comment %} +{% from "macros/comments_edit_box.html" import edit_comment_box %} {% from "macros/comments_box.html" import comment_box %} {% set pageHeading -%} @@ -55,7 +56,7 @@

{{ sub_criteria.name }}

{{ theme(answers_meta)}} {{ comment(comments)}} - {% if display_comment_box != True %} + {% if display_comment_box != True and not display_comment_edit_box %} {{ sub_criteria.name }} {% if display_comment_box == True %} {{ comment_box(comment_form) }} {% endif %} + {% if display_comment_edit_box %} + {{ edit_comment_box(comments, comment_id, comment_form)}} + {% endif %}
{% endblock content %} diff --git a/app/blueprints/services/data_services.py b/app/blueprints/services/data_services.py index b3fc0c9a..49a91d39 100644 --- a/app/blueprints/services/data_services.py +++ b/app/blueprints/services/data_services.py @@ -729,22 +729,35 @@ def match_comment_to_theme(comment_response, themes, fund_short_name): def submit_comment( - comment, application_id, sub_criteria_id, user_id, theme_id + comment, + application_id=None, + sub_criteria_id=None, + user_id=None, + theme_id=None, + comment_id=None, ): - data_dict = { - "comment": comment, - "user_id": user_id, - "application_id": application_id, - "sub_criteria_id": sub_criteria_id, - "comment_type": "COMMENT", - "theme_id": theme_id, - } - url = Config.ASSESSMENT_COMMENT_ENDPOINT - response = requests.post(url, json=data_dict) + if not comment_id: + data_dict = { + "comment": comment, + "user_id": user_id, + "application_id": application_id, + "sub_criteria_id": sub_criteria_id, + "comment_type": "COMMENT", + "theme_id": theme_id, + } + url = Config.ASSESSMENT_COMMENT_ENDPOINT + response = requests.post(url, json=data_dict) + else: + data_dict = { + "comment": comment, + "comment_id": comment_id, + } + url = Config.ASSESSMENT_COMMENT_ENDPOINT + response = requests.put(url, json=data_dict) + current_app.logger.info( f"Response from Assessment Store: '{response.json()}'." ) - return response.ok diff --git a/app/blueprints/services/models/comment.py b/app/blueprints/services/models/comment.py index b8a5b2e7..16e98787 100644 --- a/app/blueprints/services/models/comment.py +++ b/app/blueprints/services/models/comment.py @@ -1,10 +1,11 @@ import inspect from dataclasses import dataclass +from datetime import datetime @dataclass class Comment: - comment: str + id: str user_id: str date_created: str email_address: str @@ -12,6 +13,21 @@ class Comment: highest_role: str theme_id: str fund_short_name: str + updates: list + application_id: str + sub_criteria_id: str + + def __post_init__(self): + for item in self.updates: + item["date_created"] = datetime.fromisoformat( + item["date_created"] + ).strftime("%Y-%m-%d %X") + + # sort the updates in the order they are created + if self.updates: + self.updates = sorted( + self.updates, key=lambda x: x["date_created"] + ) @classmethod def from_dict(cls, d: dict): From 1a43b483096fd6bd737126f3742fbd85b2c640c1 Mon Sep 17 00:00:00 2001 From: RamuniN Date: Mon, 13 Nov 2023 17:40:29 +0000 Subject: [PATCH 2/4] updated unit tests --- .../templates/macros/comments.html | 4 +- .../templates/macros/comments_summary.html | 2 +- tests/api_data/test_data.py | 55 +++++++++++++++++-- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/app/blueprints/assessments/templates/macros/comments.html b/app/blueprints/assessments/templates/macros/comments.html index 5ff89cab..f8cf3dd0 100644 --- a/app/blueprints/assessments/templates/macros/comments.html +++ b/app/blueprints/assessments/templates/macros/comments.html @@ -29,9 +29,9 @@

Comments

edit_comment="1", comment_id=comment.id ) }}" >Edit comment
- {% if comment.updates|length > 1 %} + {# {% if comment.updates|length > 1 %} See history - {% endif %} + {% endif %} #} {% endif %} diff --git a/app/blueprints/scoring/templates/macros/comments_summary.html b/app/blueprints/scoring/templates/macros/comments_summary.html index f728200a..8e3e7198 100644 --- a/app/blueprints/scoring/templates/macros/comments_summary.html +++ b/app/blueprints/scoring/templates/macros/comments_summary.html @@ -16,7 +16,7 @@

{{ theme.name }}

{% else %}
-

{{ comment.comment }}

+

{{ comment.updates[-1].comment }}

{{ comment.full_name }} ({{ comment.highest_role|all_caps_to_human }}) {{ comment.email_address }}

{{ comment.date_created|utc_to_bst }}

diff --git a/tests/api_data/test_data.py b/tests/api_data/test_data.py index 3eeaba3b..3cb829e0 100644 --- a/tests/api_data/test_data.py +++ b/tests/api_data/test_data.py @@ -583,34 +583,79 @@ ], "assessment_store/comment?": [ { - "comment": "This is a comment", + "id": "test_id_1", "user_id": test_user_id_lead_assessor, "date_created": "2022-12-08T08:00:01.748170", "theme_id": resolved_app["theme_id"], + "sub_criteria_id": "test_sub_criteria_id", + "application_id": resolved_app["id"], + "updates": [ + { + "comment": "This is a comment", + "comment_id": "test_id_1", + "date_created": "2022-12-08T08:00:01.748170", + } + ], }, { - "comment": "You're missing some details", + "id": "test_id_2", "user_id": test_user_id_lead_assessor, "date_created": "2022-10-27T08:00:02.748170", "theme_id": resolved_app["theme_id"], + "sub_criteria_id": "test_sub_criteria_id", + "application_id": resolved_app["id"], + "updates": [ + { + "comment": "You're missing some details", + "comment_id": "test_id_2", + "date_created": "2022-10-27T08:00:02.748170", + } + ], }, { - "comment": "Im a lead assessor", + "id": "test_id_3", "user_id": test_user_id_lead_assessor, "date_created": "2022-10-27T08:00:03.748170", "theme_id": resolved_app["theme_id"], + "sub_criteria_id": "test_sub_criteria_id", + "application_id": resolved_app["id"], + "updates": [ + { + "comment": "You're missing some details", + "comment_id": "test_id_3", + "date_created": "2022-10-27T08:00:03.748170", + } + ], }, { - "comment": "Im an assessor", + "id": "test_id_4", "user_id": test_user_id_assessor, "date_created": "2022-10-27T08:00:04.748170", "theme_id": resolved_app["theme_id"], + "sub_criteria_id": "test_sub_criteria_id", + "application_id": resolved_app["id"], + "updates": [ + { + "comment": "Im an assessor", + "comment_id": "test_id_4", + "date_created": "2022-10-27T08:00:04.748170", + } + ], }, { - "comment": "Im a commenter", + "id": "test_id_5", "user_id": test_user_id_commenter, "date_created": "2022-10-27T08:00:05.748170", "theme_id": resolved_app["theme_id"], + "sub_criteria_id": "test_sub_criteria_id", + "application_id": resolved_app["id"], + "updates": [ + { + "comment": "Im a commenter", + "comment_id": "test_id_5", + "date_created": "2022-10-27T08:00:05.748170", + } + ], }, ], "assessment_store/score?": [ From a2862713de8fa45f0018bfc1147a0aba41729110 Mon Sep 17 00:00:00 2001 From: RamuniN Date: Mon, 13 Nov 2023 18:20:12 +0000 Subject: [PATCH 3/4] update tests for edit comments scenario --- tests/api_data/test_data.py | 6 +++--- tests/test_authorisation.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/tests/api_data/test_data.py b/tests/api_data/test_data.py index 3cb829e0..8849e0b0 100644 --- a/tests/api_data/test_data.py +++ b/tests/api_data/test_data.py @@ -5,9 +5,9 @@ test_fund_id = "test-fund" test_round_id = "test-round" -test_user_id_lead_assessor = "test_user_lead_assessor" -test_user_id_assessor = "test_user_assessor" -test_user_id_commenter = "test_user_commenter" +test_user_id_lead_assessor = "lead" +test_user_id_assessor = "assessor" +test_user_id_commenter = "commenter" test_funding_requested = 5000.0 # application specific config diff --git a/tests/test_authorisation.py b/tests/test_authorisation.py index a35f1fa4..77b7b31a 100644 --- a/tests/test_authorisation.py +++ b/tests/test_authorisation.py @@ -298,6 +298,20 @@ def test_different_user_levels_see_correct_comments_on_sub_criteria_view( ) assert g.user.roles is not None + soup = BeautifulSoup(response.data, "html.parser") + all_comments = soup.find_all("div", class_="comment-group") + + if claim["accountId"] == "commenter": + assert "Permission required to see comment." in str(all_comments) + + for comment in all_comments: + comment_str = str(comment) + # "Edit comment" is available only for comment owner + if claim["email"] in comment_str: + assert "Edit comment" in comment_str + else: + assert "Edit comment" not in comment_str + if expect_all_comments_available: assert is_lead_assessor_comment_visible assert is_assessor_comment_visible From 74236a48253293442909ac58977aaa444e89139d Mon Sep 17 00:00:00 2001 From: RamuniN Date: Tue, 14 Nov 2023 09:50:06 +0000 Subject: [PATCH 4/4] updated code comments --- .../templates/macros/comments.html | 19 ------------------- tests/test_authorisation.py | 2 +- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/app/blueprints/assessments/templates/macros/comments.html b/app/blueprints/assessments/templates/macros/comments.html index f8cf3dd0..1d25ce9f 100644 --- a/app/blueprints/assessments/templates/macros/comments.html +++ b/app/blueprints/assessments/templates/macros/comments.html @@ -40,23 +40,4 @@

Comments

{% endfor %} {% endif %}
-{# -
-
- -
-

This is a comment that has been left by you and has the ability to be edited as well as see previous edits for this comment.

-

Your name (Assessor) yourname@assessment.org.uk

-

19/05/2022 at 14:58

-
- - -
-
-
#} {% endmacro %} diff --git a/tests/test_authorisation.py b/tests/test_authorisation.py index 77b7b31a..dbf019cd 100644 --- a/tests/test_authorisation.py +++ b/tests/test_authorisation.py @@ -306,7 +306,7 @@ def test_different_user_levels_see_correct_comments_on_sub_criteria_view( for comment in all_comments: comment_str = str(comment) - # "Edit comment" is available only for comment owner + # "Edit comment" button is available only for the comment owner if claim["email"] in comment_str: assert "Edit comment" in comment_str else: