Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@AlexKarpov98
Copy link
Contributor

Testing: see ticket.
Go to VM page, go to the Installation Media step and click Upload New Image File

Preview:

Screenshot 2025-11-11 at 11 55 39

Refactored code to avoid code duplications, added more tests for form validator.

Add validation to prevent uploading ISO files to /mnt or pool roots:
- Default path is /mnt which causes '[EINVAL] path must reside within a pool mount point' error
- Add validateNotPoolRoot validator to reject /mnt and pool root paths
- Normalize paths by removing trailing slashes before validation
- Add translated error message to vm-wizard helptext
- Add comprehensive test coverage for path validation scenarios

The Upload button is now disabled when an invalid path is selected,
preventing files from being uploaded to the boot drive's /mnt folder
and the subsequent VM creation error.
Created shared validator to eliminate code duplication:

1. Added validateNotPoolRoot() to app/modules/forms/ix-forms/validators/validators.ts
- Validates that paths are not /mnt or pool roots (/mnt/poolname)
- Accepts optional custom error message
- Properly normalizes paths and handles trailing slashes
- Added comprehensive test suite (12 tests total)

2. Updated upload-iso-dialog.component.ts to use shared validator
- Removed 21 lines of duplicate validation code
- Uses custom error message from helptext

3. Updated export-disk-dialog.component.ts to use shared validator
- Removed 21 lines of duplicate validation code
- Uses custom error message from helptext

4. Fixed tests to use valid dataset paths (/mnt/pool/dataset) instead of pool roots (/mnt/pool)

All 18 component tests and 12 validator tests passing.
1. Enhanced validator documentation
- Added detailed explanation of why pool roots are invalid
- Explained backend requirements and security considerations
- Clarified that operations should target specific datasets

2. Improved test coverage
- Split trailing slash tests into separate test cases
- Added explicit test for multiple trailing slashes (/mnt/tank//////)
- Now 13 validator tests instead of 12

3. Documented empty path default behavior
- Added comment explaining why path starts empty instead of '/mnt'
- Empty path avoids immediate validation error and better UX
- Users navigate to valid dataset using file explorer

Note: mntPath import removal is correct - the constant is still used
elsewhere in the codebase for other file explorer components.

All 31 tests passing.
Changed validateNotPoolRoot to require a translated error message parameter
instead of having an optional parameter with English default fallback.

Why:
- Validators should not contain hardcoded English text for proper i18n
- All callers already pass translated messages via translate.instant()
- Making it required ensures future uses will also provide translations
- Better API design - makes i18n requirement explicit

Changes:
1. validators.ts: Changed errorMessage from optional to required parameter
2. validators.ts: Updated JSDoc to emphasize translation requirement
3. validators.ts: Removed English default fallback message
4. validators.spec.ts: Updated all tests to pass required error message
5. validators.spec.ts: Renamed test from "should use custom error message"
to "should use the provided translated error message"

All 31 tests passing.
@claude
Copy link

claude bot commented Nov 11, 2025

Claude finished @AlexKarpov98's task —— View job


Code Review Complete! ✅

Great work on this PR! The validator refactoring is solid and the test coverage is excellent. Here are my findings:

🎯 What Works Well

The new validateNotPoolRoot validator is well-designed with comprehensive documentation, proper i18n support, and excellent test coverage. The refactoring successfully eliminates code duplication between the upload ISO and export disk dialogs.

Issues to Address

1. UX Issue: Initial Path Behavior 🔴
src/app/pages/vm/vm-wizard/upload-iso-dialog/upload-iso-dialog.component.ts:66

The current implementation starts with an empty path, which immediately shows a validation error when users open the dialog because the path field is required but empty. This creates a confusing UX where users see an error before they've done anything wrong.

Suggestion: Consider one of these approaches:

  • Remove the required validator and let validateNotPoolRoot return null for empty values (it already does this)
  • Start with a sensible default like /mnt/ and guide users to select a dataset
  • Add a placeholder text to the explorer component to guide users

2. Missing LoaderService Methods 🟡
src/app/pages/vm/vm-wizard/upload-iso-dialog/upload-iso-dialog.component.ts:96,144,165,184,211

The code calls loader.removeConfirmationBeforeClose() and loader.setConfirmationBeforeClose(), but these methods aren't mocked in the test file. While tests pass now, this could cause issues if LoaderService behavior changes.

Suggestion: Add these methods to the LoaderService mock:

mockProvider(LoaderService, {
  open: jest.fn(() => of(true)),
  close: jest.fn(),
  setTitle: jest.fn(),
  setConfirmationBeforeClose: jest.fn(),
  removeConfirmationBeforeClose: jest.fn(),
}),

3. Minor: Test Assertion Gap 🟡
src/app/pages/vm/vm-wizard/upload-iso-dialog/upload-iso-dialog.component.spec.ts:107

The test "cancels upload and cleans up when component is destroyed" comments that it verifies the subscription was cancelled, but the assertion doesn't actually verify this - it only checks that the subject itself still emits. Consider verifying that the cancel function was actually called.

📋 Summary

Two minor issues to address: the empty path UX could be improved, and LoaderService mock methods should be added for robustness. Otherwise, the code quality is excellent with great test coverage and clean refactoring! 🚀


@bugclerk bugclerk changed the title NAS-138278: Uploading VM Image File in /mnt NAS-138278 / 26.04 / Uploading VM Image File in /mnt Nov 11, 2025
@bugclerk
Copy link
Contributor

@codecov
Copy link

codecov bot commented Nov 11, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.28%. Comparing base (55e8798) to head (c0d1323).
⚠️ Report is 2 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #12795   +/-   ##
=======================================
  Coverage   86.28%   86.28%           
=======================================
  Files        1825     1825           
  Lines       67908    67917    +9     
  Branches     8219     8222    +3     
=======================================
+ Hits        58593    58604   +11     
+ Misses       9315     9313    -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@AlexKarpov98 AlexKarpov98 marked this pull request as ready for review November 11, 2025 10:27
@AlexKarpov98 AlexKarpov98 requested a review from a team as a code owner November 11, 2025 10:27
@AlexKarpov98 AlexKarpov98 requested review from mattwyatt-ix and removed request for a team November 11, 2025 10:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants