Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions modules/weko-items-ui/weko_items_ui/static/js/weko_items_ui/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2176,14 +2176,22 @@ function validateThumbnails(rootScope, scope, itemSizeCheckFlg, files) {
};

$scope.isExistingTitle = function () {
// The subitem key used for an item type's title varies by item

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Pr title lacks prefix 📘 Rule violation ⚙ Maintainability

The PR title weko#62759 Fix title auto-fill leaving the title blank for non-standard item types
does not begin with a lowercase prefix followed by : . It therefore fails the required `^[a-z]+:
\S.*$` format.

// type (e.g. `subitem_item_title` vs.
// `subitem_restricted_access_item_title`). It is resolved
// server-side (weko_workflow.views.get_title_subitem_keys) and
// passed down via these hidden inputs, falling back to the
// standard JPCOAR name if unresolved.
let titleSubKey = $("#title_subitem_key").val() || "subitem_item_title";
let titleLanguageKey = $("#title_language_subitem_key").val() || "subitem_item_title_language";
let model = $rootScope.recordsVM.invenioRecordsModel;
if (Object.keys(model).length === 0 && model.constructor === Object) {
return false;
} else {
let isExisted = false;
for (let key in model) {
if (model.hasOwnProperty(key) && model[key].length > 0) {
let title = model[key][0]['subitem_item_title'];
let title = model[key][0][titleSubKey];
if (title){
$scope.item_tile_key = key
let activity_id= title.match(/A-[0-9]{8}-[0-9]{5}/g);
Expand All @@ -2194,7 +2202,7 @@ function validateThumbnails(rootScope, scope, itemSizeCheckFlg, files) {
if (title && $("#auto_fill_title").val() !== '""') {
$scope.setFormReadOnly(key);
setTimeout(function () {
$("input[name='subitem_item_title'], select[name='subitem_item_title_language']").attr("disabled", "disabled");
$("input[name='" + titleSubKey + "'], select[name='" + titleLanguageKey + "']").attr("disabled", "disabled");
}, 3000);
isExisted = true;
break;
Expand Down Expand Up @@ -2226,21 +2234,28 @@ function validateThumbnails(rootScope, scope, itemSizeCheckFlg, files) {
userName = JSON.parse(userInfoData).results["subitem_displayname"];
}
}
let titleSubKey = "subitem_item_title";
let titleLanguageKey = "subitem_item_title_language";
let titleSubKey = $("#title_subitem_key").val() || "subitem_item_title";
let titleLanguageKey = $("#title_language_subitem_key").val() || "subitem_item_title_language";
let recordsVM = $rootScope["recordsVM"];
Object.entries(recordsVM["invenioRecordsSchema"].properties).forEach(
function ([key, value]) {
if (value && value.type === "array" && value.items) {
if (value.items.properties && value.items.properties.hasOwnProperty(titleSubKey)) {
// Not every title property declares a language sub-key
// (e.g. item_1578299480500 on item type 3007/3008) --
// assigning an undeclared property breaks the whole
// array item and the record fails to save with a title.
let hasLanguageKey = value.items.properties.hasOwnProperty(titleLanguageKey);
$scope.item_tile_key = key;
let enTitle = {};
let jaTitle = {};
// TitleData and Username are mandatory, dataType either way
enTitle[titleSubKey] = dataType ? [dataType, titleData['en'], userName].join(" - ") : [titleData['en'], userName].join(" - ");
enTitle[titleLanguageKey] = "en";
jaTitle[titleSubKey] = dataType ? [dataType, titleData['ja'], userName].join(" - ") : [titleData['ja'], userName].join(" - ");
jaTitle[titleLanguageKey] = "ja";
if (hasLanguageKey) {
enTitle[titleLanguageKey] = "en";
jaTitle[titleLanguageKey] = "ja";
}
Comment on lines +2255 to +2258

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. app.js behavior lacks tests 📘 Rule violation ▣ Testability

The PR changes title lookup and introduces the hasLanguageKey branch in app.js, but the added
tests only exercise the Python key resolver. The client-side behavior for non-standard keys and
schemas without language fields therefore lacks regression coverage.
Agent Prompt
## Issue description
The modified automatic-title behavior in `app.js` is not covered by tests.

## Issue Context
Add regression cases for non-standard title subitem keys, existing-title detection, and title schemas that omit the language subitem key.

## Fix Focus Areas
- modules/weko-items-ui/weko_items_ui/static/js/weko_items_ui/app.js[2178-2259]
- modules/weko-items-ui/weko_items_ui/static/js/weko_items_ui/app.js[5284-5285]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

recordsVM["invenioRecordsModel"][key] = [jaTitle, enTitle];
}
}
Expand Down Expand Up @@ -5266,8 +5281,8 @@ function validateThumbnails(rootScope, scope, itemSizeCheckFlg, files) {
let defaultTitleEn = titleData['en'] + userName;
let defaultTitleJa = titleData['ja'] + userName;

let titleSubKey = "subitem_item_title";
let titleLanguageKey = "subitem_item_title_language";
let titleSubKey = $("#title_subitem_key").val() || "subitem_item_title";
let titleLanguageKey = $("#title_language_subitem_key").val() || "subitem_item_title_language";
let selectedUsageApplicationIDs = []

let model = $rootScope["recordsVM"].invenioRecordsModel;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,8 @@ <h3 class="panel-title">Contributor</h3>
<input type="hidden" id="item_save_uri" name="item_save_uri" value='{{item_save_uri}}'>
<input type="hidden" id="item_save_frequency" name="item_save_frequency" value='{{config.WEKO_ITEMS_UI_SAVE_FREQUENCY}}'>
<input type="hidden" id="auto_fill_title" name="auto_fill_title" value='{{title}}'>
<input type="hidden" id="title_subitem_key" name="title_subitem_key" value="{{title_subitem_key}}">
<input type="hidden" id="title_language_subitem_key" name="title_language_subitem_key" value="{{title_language_subitem_key}}">
<input type="hidden" id="data_type_title" name="data_type_title" value='{{data_type}}'>
<input type="hidden" id="out_put_report_title" name="out_put_report_title" value='{{out_put_report}}'>
<input type="hidden" id="is_hidden_pubdate" name="is_hidden_pubdate" value='{{is_hidden_pubdate}}'>
Expand Down
25 changes: 24 additions & 1 deletion modules/weko-workflow/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
check_authority,
display_guest_activity,
display_guest_activity_item_application,
render_guest_workflow)
render_guest_workflow,
get_title_subitem_keys)
from marshmallow.exceptions import ValidationError
from weko_records_ui.models import FileOnetimeDownload, FilePermission
from weko_records.models import ItemMetadata, ItemReference
Expand Down Expand Up @@ -4627,6 +4628,28 @@ def prepare_activity(act_id, recid, with_item=False, is_deleted=False):
assert res.status_code == 200
assert json.loads(res.data) == {"code": 200, 'for_delete': False, "is_deleted": True}

# .tox/c1/bin/pytest --cov=weko_workflow tests/test_views.py::test_get_title_subitem_keys -vv -s --cov-branch --cov-report=term --basetemp=/code/modules/weko_workflow/.tox/c1/tmp
def test_get_title_subitem_keys(app, item_type):
"""get_title_subitem_keys() should resolve the title subitem key names
from the item type's own jpcoar_mapping, not a hardcoded name -- the
title subitem key varies by item type (e.g. subitem_item_title vs.
subitem_restricted_access_item_title)."""
item_type_id = item_type[0]["id"]
# tests/data/item_type/item_type_mapping.json maps
# item_1617186331708.jpcoar_mapping.title to these subitem keys.
title_subitem_key, title_language_subitem_key = \
get_title_subitem_keys(item_type_id)
assert title_subitem_key == "subitem_1551255647225"
assert title_language_subitem_key == "subitem_1551255648112"


def test_get_title_subitem_keys_no_mapping(app, db):
"""Falls back to empty strings (never raises) when there is no
item_type_mapping for the given id, or no id at all."""
assert get_title_subitem_keys(None) == ("", "")
assert get_title_subitem_keys(999999) == ("", "")


# .tox/c1/bin/pytest --cov=weko_workflow tests/test_views.py::test_display_activity_nologin -vv -s --cov-branch --cov-report=term --basetemp=/code/modules/weko_workflow/.tox/c1/tmp
def test_display_activity_nologin(client,db_register2,mocker):
"""Test of display activity."""
Expand Down
39 changes: 38 additions & 1 deletion modules/weko-workflow/weko_workflow/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
from weko_items_ui.utils import check_item_is_being_edit, get_workflow_by_item_type_id, \
get_current_user
from weko_logging.activity_logger import UserActivityLogger
from weko_records.api import FeedbackMailList, RequestMailList, ItemLink, ItemTypes, ItemApplication
from weko_records.api import FeedbackMailList, RequestMailList, ItemLink, ItemTypes, ItemApplication, Mapping

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

3. mapping import is unsorted 📘 Rule violation ⚙ Maintainability

The newly added Mapping member is placed after ItemApplication rather than in alphabetic order.
This violates the configured isort sorting requirement for from-import members.
Agent Prompt
## Issue description
The modified `weko_records.api` import does not alphabetize its imported members.

## Issue Context
The module's tox configuration uses isort with the Black profile. Run isort or manually place `Mapping` in the resulting alphabetical order.

## Fix Focus Areas
- modules/weko-workflow/weko_workflow/views.py[61-61]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

from weko_records.models import ItemMetadata
from weko_records.serializers.utils import get_item_type_name
from weko_records_ui.models import FilePermission
Expand Down Expand Up @@ -797,6 +797,37 @@ def verify_deletion(activity_id="0"):

return jsonify(res), 200

def get_title_subitem_keys(item_type_id):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

5. Missing function separation 📘 Rule violation ✧ Quality

The new top-level get_title_subitem_keys() definition has only one blank line after the preceding
function. Flake8 reports this as E305, so the touched Python file does not pass static analysis.
Agent Prompt
## Issue description
The new top-level helper is not separated from the preceding function by two blank lines.

## Issue Context
Flake8 requires two blank lines before a top-level function definition and reports the current layout as `E305`.

## Fix Focus Areas
- modules/weko-workflow/weko_workflow/views.py[798-800]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

"""Resolve the subitem key names used for an item type's title.

Different item types name their "title" subitem differently
(e.g. ``subitem_item_title`` for the standard JPCOAR title
property, ``subitem_restricted_access_item_title`` for the
restricted-access reference item type). Rather than hardcoding
one name, resolve it the same way
:meth:`weko_deposit.api.WekoDeposit.get_titles` does: via the
item type's ``jpcoar_mapping.title`` mapping entry.

:param item_type_id: ID of the item type.
:returns: (title_subitem_key, title_language_subitem_key), each
an empty string if it could not be resolved.
"""
title_subitem_key = ""
title_language_subitem_key = ""
item_type_mapping = Mapping.get_record(item_type_id) if item_type_id else None
if item_type_mapping:
for mapping_value in item_type_mapping.values():
if not isinstance(mapping_value, dict):
continue
jpcoar_title = (mapping_value.get('jpcoar_mapping') or {}).get('title')
if isinstance(jpcoar_title, dict) and jpcoar_title.get('@value'):
title_subitem_key = jpcoar_title.get('@value')
title_language_subitem_key = jpcoar_title.get(
'@attributes', {}).get('xml:lang') or ""
Comment on lines +822 to +826

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): A truthy non-dict jpcoar_mapping value causes (mapping_value.get('jpcoar_mapping') or {}).get('title') to raise AttributeError, and a non-dict @attributes value causes the subsequent .get('@attributes', {}).get(...) chain to raise as well. The helper is documented and tested as a safe fallback, but malformed mapping data makes the item-edit page fail instead of returning empty keys.

Triggers: When an item type mapping contains a non-empty malformed jpcoar_mapping or @attributes value.

Suggested fix: Check that jpcoar_mapping and @attributes are dictionaries before calling .get(), or catch malformed mapping data and retain the empty-key fallback.

Suggested change
jpcoar_title = (mapping_value.get('jpcoar_mapping') or {}).get('title')
if isinstance(jpcoar_title, dict) and jpcoar_title.get('@value'):
title_subitem_key = jpcoar_title.get('@value')
title_language_subitem_key = jpcoar_title.get(
'@attributes', {}).get('xml:lang') or ""
jpcoar_mapping = mapping_value.get('jpcoar_mapping')
if not isinstance(jpcoar_mapping, dict):
continue
jpcoar_title = jpcoar_mapping.get('title')
if isinstance(jpcoar_title, dict) and jpcoar_title.get('@value'):
title_subitem_key = jpcoar_title.get('@value')
jpcoar_attributes = jpcoar_title.get('@attributes')
if isinstance(jpcoar_attributes, dict):
title_language_subitem_key = jpcoar_attributes.get(
'xml:lang') or ""

Comment on lines +822 to +826

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

4. Helper fails black formatting 📘 Rule violation ⚙ Maintainability

The newly added helper uses formatting that Black would rewrite, including single-quoted string
literals. Consequently, black --check would not accept the modified Python code unchanged.
Agent Prompt
## Issue description
The added `get_title_subitem_keys()` implementation is not in Black-normalized form.

## Issue Context
The repository lint environment invokes `black .`; run the configured formatter and commit its changes to the modified Python files.

## Fix Focus Areas
- modules/weko-workflow/weko_work_workflow/views.py[800-828]
- modules/weko-workflow/tests/test_views.py[4631-4650]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

break
return title_subitem_key, title_language_subitem_key


@workflow_blueprint.route('/activity/detail/<string:activity_id>',
methods=['GET', 'POST'])
@login_required_customize
Expand Down Expand Up @@ -955,6 +986,8 @@ def display_activity(activity_id="0", community_id=None):
step_item_login_url = None
term_and_condition_content = ''
title = ""
title_subitem_key = ""
title_language_subitem_key = ""
user_lock_key = "workflow_userlock_activity_{}".format(str(current_user.get_id()))
if action_endpoint in ['item_login',
'item_login_application',
Expand Down Expand Up @@ -1007,6 +1040,8 @@ def display_activity(activity_id="0", community_id=None):


title = auto_fill_title(item_type_name)
title_subitem_key, title_language_subitem_key = \
get_title_subitem_keys(workflow_detail.itemtype_id)
show_autofill_metadata = is_show_autofill_metadata(item_type_name)
is_hidden_pubdate_value = is_hidden_pubdate(item_type_name)

Expand Down Expand Up @@ -1209,6 +1244,8 @@ def display_activity(activity_id="0", community_id=None):
approval_preview=approval_preview,
auto_fill_data_type=data_type,
auto_fill_title=title,
title_subitem_key=title_subitem_key,
title_language_subitem_key=title_language_subitem_key,
community_id=community_id,
cur_step=cur_step,
contributors=contributors,
Expand Down
Loading