From 455e98481a24d6e81250fb0958ee6662c6e3560b Mon Sep 17 00:00:00 2001 From: Xi Chen Date: Tue, 7 Feb 2023 17:04:58 -0500 Subject: [PATCH] RDISCROWD-5653 Bug With Showing Completed Answers --- pybossa/util.py | 35 ++++++++++++++++++++++++---- test/test_util.py | 58 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 4 deletions(-) diff --git a/pybossa/util.py b/pybossa/util.py index 1871e33c9b..e8ba3cadc1 100644 --- a/pybossa/util.py +++ b/pybossa/util.py @@ -1192,15 +1192,16 @@ def process_annex_load(tp_code, response_value): regex = r"(\w+)\.(loadDocument|loadDocumentLite)\s*\(\s*.*\s*(\))" matches = re.finditer(regex, tp_code) count = 0 - for match in matches: # maching for pure javascript Annex code + for match in matches: # matching docx Annex code annex_tab = match[1] # the first group: (\w+) code_to_append = f".then(() => {annex_tab}.loadAnnotationFromJson('{odfoa}'))" right_parenthesis_end = match.end(3) + len(code_to_append) * count # the 3rd group: (\)) - exclusive tp_code = tp_code[:right_parenthesis_end] + code_to_append + tp_code[right_parenthesis_end:] count += 1 - # Looking for code snippet like shell.setAttribute("hash", "abc"); - regex = r"(\w+)\.setAttribute\(\"hash\",\s*\"\w+\"\);" + # Looking for code snippet like shell = document.getElementById("annex-viewer"); or + # shell = document.getElementById("shell-container"); + regex = r"(\w+)\s*=\s*document\.getElementById\s*\(\s*('|\")?(annex-viewer|shell-container)('|\")?\s*\)\s*;" matches = re.finditer(regex, tp_code) count = 0 for match in matches: @@ -1273,7 +1274,17 @@ def process_table_component(tp_code, user_response, task): break existing_data = request_fields elif initial_data_str.strip().startswith("["): # if it is a list - existing_data = json.loads(initial_data_str) + try: + pattern = r"task\.info(\.\w+)+" + for m in re.finditer(pattern, initial_data_str): + old_str = m.group(0) + new_str = extract_task_info_data(task, old_str) + initial_data_str = initial_data_str.replace(old_str, new_str) + existing_data = json.loads(initial_data_str) + except Exception as e: + current_app.logger.error( + 'parsing initial_data_str: {} error: {}'.format( + initial_data_str, str(e))) # merge existing_data into response_value for i in range(min(len(existing_data), len(response_values))): @@ -1332,3 +1343,19 @@ def remove_element_attributes(page_element, attribute): for attr in attributes: if page_element.has_attr(attr): del page_element[attr] + + +def extract_task_info_data(task, task_info_str): + """ + Extract data from javascript string. + e.g. task.info.a.b -> task.info.get('a').get('b') + + :param task: task object + :param task_info_str: javascript task info string + :return: JSON string + """ + attributes = task_info_str.split(".") + request_fields = task.info + for attribute in attributes[2:]: # skip "task" and "info" + request_fields = request_fields.get(attribute, {}) + return json.dumps(request_fields) diff --git a/test/test_util.py b/test/test_util.py index cc09113bf3..acd67f6235 100644 --- a/test/test_util.py +++ b/test/test_util.py @@ -1155,6 +1155,27 @@ def test_process_table_component_with_initial_data_from_task(self): + + + + 2 @@ -1204,6 +1225,12 @@ def test_process_table_component_with_initial_data_from_task(self): 'hgrt_variable_type': 'MONEY'} ] }, + 'CUSIP': 'Test Cusip', + 'FLT_REFIX_DT': ['test1', 'test2'], + 'c': { + 'd': 'nested d', + "e": 123 + }, 'ruleset_name': 'SR_Q1', 'work_item_completion_date': '3/24/2020'} result = util.process_table_component(tp_code, user_response, task) @@ -1216,6 +1243,10 @@ def test_process_table_component_with_initial_data_from_task(self): assert expected_result in result assert ':initial-value="props.row.QC_Reason"' in result assert ':initial-value="props.row.QC_Notes"' in result + assert '"Test Cusip"' in result, result + assert '["test1", "test2"]' in result, result + assert '"nested d"' in result, result + assert '123' in result, result def test_get_first_existing_data(self): tag = BeautifulSoup('bold', 'html.parser').b @@ -1245,6 +1276,33 @@ def test_remove_element_attributes(self): assert not tag.has_attr(":id") assert not tag.has_attr("id") + @with_request_context + def test_extract_task_info_data(self): + project = ProjectFactory.create(published=True, id=1) + task = TaskFactory.create(id=101, project=project) + + task.info = {'a': {'b': 'answer1'}, + 'c': 'answer2', + 'd': ['hello', 'world'], + 'e': 123 + } + + task_info_str = 'task.info.a.b' + res = util.extract_task_info_data(task, task_info_str) + assert res == '"answer1"', res + + task_info_str = 'task.info.c' + res = util.extract_task_info_data(task, task_info_str) + assert res == '"answer2"', res + + task_info_str = 'task.info.d' + res = util.extract_task_info_data(task, task_info_str) + assert res == '["hello", "world"]', res + + task_info_str = 'task.info.e' + res = util.extract_task_info_data(task, task_info_str) + assert res == '123', res + class TestIsReservedName(object): from test import flask_app as app