Fix: Multi-Selection Batch Operations with Unit Test Compatibility#312
Open
Szy-Cathay wants to merge 1 commit intodonkeyProgramming:masterfrom
Open
Fix: Multi-Selection Batch Operations with Unit Test Compatibility#312Szy-Cathay wants to merge 1 commit intodonkeyProgramming:masterfrom
Szy-Cathay wants to merge 1 commit intodonkeyProgramming:masterfrom
Conversation
# Fix: Multi-Selection Batch Operations with Unit Test Compatibility ## Description This PR reintroduces batch delete and move operations for multi-selected tags in the Metadata Editor, with critical fixes to ensure full unit test compatibility and defensive programming practices. **Key Features:** - ✅ Multi-selection support via `IsSelected` property - ✅ Backward compatibility with single-selection via `SelectedTag` - ✅ Comprehensive unit tests covering all scenarios - ✅ Defensive null/boundary checks for headless environments ## Technical Rationale (Why This Approach?) ### Problem Diagnosis The previous implementation failed unit tests due to **tight coupling between UI state and data operations**: 1. **Selection State Mismatch**: Tests set `SelectedTag` property, but commands only checked `IsSelected` flags 2. **No Fallback Mechanism**: When `IsSelected` was empty, commands returned early instead of checking `SelectedTag` 3. **Insufficient Defensive Programming**: Lacked null checks for headless test environments ### Solution Architecture **Adapter Pattern for Selection Modes:** ┌─────────────────────────────────────────┐ │ Input: IsSelected (multi) OR SelectedTag │ └──────────────┬──────────────────────────┘ │ Priority: IsSelected > SelectedTag ▼ ┌─────────────────────────────────────────┐ │ Unified: List │ └──────────────┬──────────────────────────┘ │ Pure data operations ▼ ┌─────────────────────────────────────────┐ │ Output: Batch delete/move operations │ └─────────────────────────────────────────┘ **Key Design Decisions:** 1. **Dual-Mode Selection Handler** (`GetSelectedItems` method): - First checks `IsSelected` for multi-selection scenarios - Falls back to `SelectedTag` for single-selection backward compatibility - Returns empty list if neither is set (safe no-op) 2. **Defensive Programming Practices**: - Null checks on `controller` and `ParsedFile` before any operation - Boundary validation (e.g., can't move top item up, bottom item down) - Safe collection modification using `ToList()` snapshot pattern 3. **Group Movement Logic**: - Selected items move as a cohesive block - Sorted traversal order prevents items from "jumping over" each other - Selection state automatically restored after move operations ### Test Rationale **Test Coverage Strategy:** | Test Scenario | Purpose | |---------------|---------| | `DeleteAction_MultiSelectedTags` | Verify batch deletion via `IsSelected` | | `DeleteAction_SelectedTagOnly` | Verify backward compatibility with `SelectedTag` | | `DeleteAction_NoSelection` | Verify safe no-op behavior | | `MoveUpAction_MultiSelectedTags` | Verify group movement maintains order | | `MoveUpAction_SelectedTagOnly` | Verify single-item move backward compatibility | | `MoveUpAction_TopTag` | Verify boundary condition handling | | `DeleteAndMoveOperations_WithNullParsedFile` | Verify crash-resistance in headless mode | **Why These Tests Matter:** - **Regression Prevention**: Existing tests (`MetaDataEditor_DeleteAndSave`, `MetaDataEditor_MoveUpAndSave`) continue to pass - **New Feature Validation**: Multi-selection scenarios are fully covered - **Edge Case Handling**: Null states, boundaries, and empty selections are tested - **Integration Verification**: Save/reload cycle confirms data persistence ### Changes Summary **Modified Files:** - `DeleteEntryCommand.cs`: Added dual-mode selection, null safety, improved documentation - `MoveEntryCommand.cs`: Added dual-mode selection, boundary checks, selection restoration **New Test File:** - `MetaDataEditorMultiSelectTests.cs`: 11 comprehensive test cases ### Verification Steps 1. Run existing tests: `dotnet test --filter "FullyQualifiedName~MetaDataEditorViewModelTests"` 2. Run new tests: `dotnet test --filter "FullyQualifiedName~MetaDataEditorMultiSelectTests"` 3. All 17 tests (6 existing + 11 new) should pass ✅ --- **Technical Rationale Summary:** This approach prioritizes **test compatibility**, **backward compatibility**, and **defensive programming**. The dual-mode selection handler ensures that both existing test patterns (`SelectedTag`) and new multi-selection features (`IsSelected`) work seamlessly, while comprehensive null/boundary checks prevent crashes in headless environments. The additional unit tests provide confidence that the implementation is robust and maintainable.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix: Multi-Selection Batch Operations with Unit Test Compatibility
Description
This PR reintroduces batch delete and move operations for multi-selected tags in the Metadata Editor, with critical fixes to ensure full unit test compatibility and defensive programming practices.
Key Features:
IsSelectedpropertySelectedTagTechnical Rationale (Why This Approach?)
Problem Diagnosis
The previous implementation failed unit tests due to tight coupling between UI state and data operations:
SelectedTagproperty, but commands only checkedIsSelectedflagsIsSelectedwas empty, commands returned early instead of checkingSelectedTagSolution Architecture
Adapter Pattern for Selection Modes:
┌─────────────────────────────────────────┐
│ Input: IsSelected (multi) OR SelectedTag │
└──────────────┬──────────────────────────┘
│ Priority: IsSelected > SelectedTag
▼
┌─────────────────────────────────────────┐
│ Unified: List │
└──────────────┬──────────────────────────┘
│ Pure data operations
▼
┌─────────────────────────────────────────┐
│ Output: Batch delete/move operations │
└─────────────────────────────────────────┘
Key Design Decisions:
Dual-Mode Selection Handler (
GetSelectedItemsmethod):IsSelectedfor multi-selection scenariosSelectedTagfor single-selection backward compatibilityDefensive Programming Practices:
controllerandParsedFilebefore any operationToList()snapshot patternGroup Movement Logic:
Test Rationale
Test Coverage Strategy:
DeleteAction_MultiSelectedTagsIsSelectedWhy These Tests Matter:
MetaDataEditor_DeleteAndSave,MetaDataEditor_MoveUpAndSave) continue to passChanges Summary
Modified Files:
DeleteEntryCommand.cs: Added dual-mode selection, null safety, improved documentationMoveEntryCommand.cs: Added dual-mode selection, boundary checks, selection restorationNew Test File:
MetaDataEditorMultiSelectTests.cs: 11 comprehensive test casesVerification Steps
dotnet test --filter "FullyQualifiedName~MetaDataEditorViewModelTests"dotnet test --filter "FullyQualifiedName~MetaDataEditorMultiSelectTests"Technical Rationale Summary: This approach prioritizes test compatibility, backward compatibility, and defensive programming. The dual-mode selection handler ensures that both existing test patterns (
SelectedTag) and new multi-selection features (IsSelected) work seamlessly, while comprehensive null/boundary checks prevent crashes in headless environments. The additional unit tests provide confidence that the implementation is robust and maintainable.