45154 frontend [ Outputs ] Instead of the performer, a group with the same ID is selected#168
Conversation
backend/src/processes/tests/test_views/test_workflow/test_viewer_access.py
Outdated
Show resolved
Hide resolved
backend/src/processes/tests/test_models/test_template_viewer.py
Outdated
Show resolved
Hide resolved
…agentic QA defined in PR description
4ebcd90 to
307b906
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
|
|
||
| jest.mock('../../../../UI/form/UsersDropdown', () => ({ | ||
| UsersDropdown: jest.fn(() => null), | ||
| EOptionTypes: { User: 'user', Group: 'user-group' }, |
There was a problem hiding this comment.
Test mock uses wrong value for EOptionTypes.Group
Low Severity
The test mock sets EOptionTypes.Group to 'user-group', but the real value is 'group' (from ETaskPerformerType.UserGroup = 'group'). In production, group option values are formatted as "group-5", while the test asserts they are "user-group-5". Because both option generation and value matching in the component use the same mocked EOptionTypes, the test is internally consistent and passes, but it validates against incorrect expected values, weakening its ability to catch regressions.


1. Release notes
Fixed a bug in the user field dropdown on process run steps: when a user and a group had the same numeric ID, the dropdown would display the wrong entity (e.g., showing the group instead of the selected user). The selected value is now correctly preserved and displayed regardless of ID collisions.
2. Description (Problem)
When running a process (Process Run), a step with a «User» type field shows a dropdown to select a user or group. Internally, each dropdown option stored
valueasString(item.id)— just the numeric ID as a string.If a user (
id: 5) and a group (id: 5) both existed, theirvalueentries were identical ("5"), and the.find()method used to locate the selected value would always return the first match — the group (since groups were placed first in the[...groupsDropdownOption, ...usersDropdownOption]array). As a result:Location: Process Run screen → «User» type field (performer selection dropdown).
3. Context
ExtraFieldUser— user/group selection field in kickoff forms and process run steps.WorkflowEditPopup)TaskCard)PublicForm)KickoffEdit)4. Solution
Key idea: replace the numeric
valuewith a composite key in the format"type-id", which uniquely identifies an option even when numeric IDs collide between entities of different types.5. Implementation details
Option
valuegenerationvalue: String(item.id)→ user withid=5and group withid=5both gotvalue: "5".value: "${EOptionTypes.User}-${item.id}"→"user-5"value: "${EOptionTypes.Group}-${item.id}"→"user-group-5"Finding the selected value (
valueprop forUsersDropdown)item.value === String(field.userId) || item.value === String(field.groupId)— both conditions compared against the raw ID; collisions were unresolvable.item.value === "${EOptionTypes.User}-${field.userId}" || item.value === "${EOptionTypes.Group}-${field.groupId}"— comparison uses the composite key, eliminating collisions.Moving
useSelectorout ofrenderSelectableViewuseSelector(getUsers)anduseSelector(state => state.groups.list)were called insiderenderSelectableView()— a nested function (not a React component), violating the Rules of Hooks.useSelectorcalls are at the top level of theExtraFieldUsercomponent. For groups, a typedgetGroupsListselector is used instead of an inlinestate.groups.listaccess.6. What to test
6.1 Preconditions
id=1— the first user and the first group).6.2 Positive scenarios / Testing Report
When running a workflow (Run):
(Desktop Chromium)Screenshot
(Desktop Chromium)(Desktop Chromium)(Desktop Chromium)Screenshot
When executing a task (Task):
(Desktop Chromium)(Desktop Chromium)Screenshot
6.3 Negative scenarios and edge cases
(Desktop Chromium)6.4 Verification points
userId/groupId(one of them beingnull).6.5 What was NOT tested
7. Testing affected shared parts
Moving
useSelectorfrom the nestedrenderSelectableViewfunction to the top level of the component affects all modes ofExtraFieldUser. Previously,useSelector(getUsers)anduseSelector(state => state.groups.list)were only called inProcessRunmode; now they are called in all modes, includingKickoff. Additionally, the inline selectorstate => state.groups.listwas replaced with the typedgetGroupsListselector.Verify:
(Desktop Chromium)(Desktop Chromium)(Desktop Chromium)8. Unit tests
Added tests in
ExtraFieldUser.test.tsx:value: "user-1".value: "user-group-1".value=undefined.editFieldon selection: nullifying the opposite field (userId: nullwhengroupIdis selected and vice versa).10. Commits
146f4817— 45154 Fix performer selection bug, add frontend unit tests, and pass agentic QA defined in PR descriptionNote
Low Risk
Low risk UI logic change that only affects how user/group options are keyed and selected in the
Userextra field dropdown; main risk is unexpected mismatches if any downstream code relied on raw numericvaluestrings.Overview
Fixes a Process Run bug where the
Userextra field dropdown could display the wrong entity when a user and a group shared the same numeric ID.Dropdown option
values are now type-prefixed (e.g.,user-<id>vsuser-group-<id>) and the selected option lookup uses these composite keys, eliminating ID collisions. The component also movesuseSelectorcalls to the component top-level and switches group selection to the sharedgetGroupsListselector.Adds unit tests covering collision-safe selection, empty-state behavior, and ensuring selecting a user clears
groupId(and vice versa). Also updates.gitignoreto ignore Cursor/agent artifacts and treats.antigravityas a directory.Written by Cursor Bugbot for commit 307b906. This will update automatically on new commits. Configure here.
Note
Fix performer vs group misselection in
ExtraFieldUseroutputs dropdown when IDs collideuser-{id}/group-{id}) and the selected value resolution checks the prefix to correctly distinguish between users and groups.userId/groupId, andonChangehandling.Macroscope summarized 307b906.