test(06): complete UAT - 0 passed, 3 issues, 7 skipped
Fix two pre-existing blockers found during UAT: - ProfileManagementViewModel: add NotifyCanExecuteChanged on property changes - SessionManager: open browser in openBrowserCallback (was no-op) Remaining blocker: SitePickerDialog parsing error from PnP Framework. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
118
.planning/phases/06-global-site-selection/06-UAT.md
Normal file
118
.planning/phases/06-global-site-selection/06-UAT.md
Normal file
@@ -0,0 +1,118 @@
|
||||
---
|
||||
status: complete
|
||||
phase: 06-global-site-selection
|
||||
source: [06-01-SUMMARY.md, 06-02-SUMMARY.md, 06-03-SUMMARY.md, 06-04-SUMMARY.md, 06-05-SUMMARY.md]
|
||||
started: 2026-04-07T11:00:00Z
|
||||
updated: 2026-04-07T11:30:00Z
|
||||
---
|
||||
|
||||
## Current Test
|
||||
|
||||
[testing complete]
|
||||
|
||||
## Tests
|
||||
|
||||
### 1. Select Sites Button in Toolbar
|
||||
expected: After connecting to a tenant, the toolbar shows a "Select Sites" button (localized). Clicking it opens the SitePickerDialog. The button is disabled when no profile is connected.
|
||||
result: issue
|
||||
reported: "Cant add a profile to connect to a tenant, the add button stays greyed out. After fix applied, Connect button didn't open browser. After second fix, SitePickerDialog shows parsing error: Must specify valid information for parsing in the string"
|
||||
severity: blocker
|
||||
|
||||
### 2. Global Sites Count Label
|
||||
expected: After selecting sites via the global picker, a label next to the button shows the count of selected sites (e.g., "3 sites selected"). When no sites are selected, the label shows the empty state. Label is localized (EN/FR).
|
||||
result: skipped
|
||||
reason: Blocked by Test 1 — cannot select sites without working SitePickerDialog
|
||||
|
||||
### 3. Single-Site Tab Pre-Fill (Storage, Search, Duplicates, FolderStructure)
|
||||
expected: Select one site globally. Switch to Storage/Search/Duplicates/FolderStructure tab — the SiteUrl field is automatically pre-filled with the globally selected site URL.
|
||||
result: skipped
|
||||
reason: Blocked by Test 1 — cannot select sites
|
||||
|
||||
### 4. Permissions Tab Multi-Site Pre-Fill
|
||||
expected: Select multiple sites globally. Switch to the Permissions tab — SelectedSites is pre-populated with all globally selected sites.
|
||||
result: skipped
|
||||
reason: Blocked by Test 1 — cannot select sites
|
||||
|
||||
### 5. Transfer Tab Pre-Fill
|
||||
expected: Select a site globally. Switch to Transfer tab — the SourceSiteUrl field is pre-filled with the globally selected site URL.
|
||||
result: skipped
|
||||
reason: Blocked by Test 1 — cannot select sites
|
||||
|
||||
### 6. Local Override Protection
|
||||
expected: On a single-site tab, manually type a different site URL. Then change the global site selection. The manually-entered URL is NOT overwritten — local input takes priority.
|
||||
result: skipped
|
||||
reason: Blocked by Test 1 — cannot select sites
|
||||
|
||||
### 7. Clear Field Reverts to Global
|
||||
expected: On a single-site tab with a local override active, clear the SiteUrl field (make it empty). The field immediately re-fills with the current global site URL — clearing means "go back to global."
|
||||
result: skipped
|
||||
reason: Blocked by Test 1 — cannot select sites
|
||||
|
||||
### 8. Tenant Switch Clears Global Sites
|
||||
expected: Select sites globally, then switch to a different tenant. The global site selection is cleared (no sites selected). The toolbar label returns to the empty state. Tab SiteUrl fields are cleared.
|
||||
result: skipped
|
||||
reason: Blocked by Test 1 — cannot select sites
|
||||
|
||||
## Summary
|
||||
|
||||
total: 8
|
||||
passed: 0
|
||||
issues: 3
|
||||
pending: 0
|
||||
skipped: 7
|
||||
|
||||
## Gaps
|
||||
|
||||
- truth: "Add profile button enables as user fills fields"
|
||||
status: failed
|
||||
reason: "User reported: add button stays greyed out — ProfileManagementViewModel missing NotifyCanExecuteChanged on property changes"
|
||||
severity: blocker
|
||||
test: 1
|
||||
root_cause: "ProfileManagementViewModel.CanAdd() never re-evaluated because ObservableProperty changes for NewName, NewTenantUrl, NewClientId did not call AddCommand.NotifyCanExecuteChanged()"
|
||||
artifacts:
|
||||
- path: "SharepointToolbox/ViewModels/ProfileManagementViewModel.cs"
|
||||
issue: "Missing partial void OnNewNameChanged/OnNewTenantUrlChanged/OnNewClientIdChanged hooks to notify commands"
|
||||
missing:
|
||||
- "partial void OnXxxChanged methods that call NotifyCanExecuteChanged on AddCommand and RenameCommand"
|
||||
fix_applied: true
|
||||
fix_commit: pending
|
||||
|
||||
- truth: "Clicking Connect opens browser for interactive Microsoft login"
|
||||
status: failed
|
||||
reason: "User reported: clicking Connect does nothing, no browser opens, no log output — openBrowserCallback in SessionManager was a no-op"
|
||||
severity: blocker
|
||||
test: 1
|
||||
root_cause: "SessionManager.GetOrCreateContextAsync openBrowserCallback was empty (comment said MSAL handles it, but PnP CreateWithInteractiveLogin requires the callback to open the browser)"
|
||||
artifacts:
|
||||
- path: "SharepointToolbox/Services/SessionManager.cs"
|
||||
issue: "openBrowserCallback was no-op — needed Process.Start with UseShellExecute"
|
||||
missing:
|
||||
- "Process.Start(new ProcessStartInfo { FileName = url, UseShellExecute = true }) in openBrowserCallback"
|
||||
fix_applied: true
|
||||
fix_commit: pending
|
||||
|
||||
- truth: "SitePickerDialog loads tenant sites after successful connection"
|
||||
status: failed
|
||||
reason: "User reported: error 'Must specify valid information for parsing in the string' in site selector after connecting"
|
||||
severity: blocker
|
||||
test: 1
|
||||
root_cause: "Likely UriFormatException from PnP Framework internal URL parsing when SiteListService.GetSitesAsync calls GetOrCreateContextAsync with the admin URL, or during Tenant.GetSitePropertiesFromSharePoint"
|
||||
artifacts:
|
||||
- path: "SharepointToolbox/Services/SiteListService.cs"
|
||||
issue: "DeriveAdminUrl or downstream PnP call produces UriFormatException"
|
||||
missing:
|
||||
- "Debug with actual tenant URL to identify exact parsing failure point"
|
||||
fix_applied: false
|
||||
|
||||
- truth: "Connect button disables or changes state after successful connection"
|
||||
status: failed
|
||||
reason: "User reported: Connect button stays active after successful connection"
|
||||
severity: minor
|
||||
test: 1
|
||||
root_cause: "ConnectCommand CanExecute is () => SelectedProfile != null — does not check IsAuthenticated state"
|
||||
artifacts:
|
||||
- path: "SharepointToolbox/ViewModels/MainWindowViewModel.cs"
|
||||
issue: "ConnectCommand CanExecute does not account for connection state"
|
||||
missing:
|
||||
- "Add _sessionManager.IsAuthenticated(SelectedProfile.TenantUrl) check to ConnectCommand CanExecute, or change button text to 'Reconnect' after connection"
|
||||
fix_applied: false
|
||||
@@ -60,8 +60,11 @@ public class SessionManager : ISessionManager
|
||||
clientId: profile.ClientId,
|
||||
openBrowserCallback: (url, port) =>
|
||||
{
|
||||
// The browser/WAM flow is handled by MSAL; this callback receives the
|
||||
// local redirect URL and port. No action needed here — MSAL opens the browser.
|
||||
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
|
||||
{
|
||||
FileName = url,
|
||||
UseShellExecute = true
|
||||
});
|
||||
},
|
||||
tokenCacheCallback: tokenCache =>
|
||||
{
|
||||
|
||||
@@ -58,6 +58,16 @@ public partial class ProfileManagementViewModel : ObservableObject
|
||||
}
|
||||
}
|
||||
|
||||
partial void OnNewNameChanged(string value) => NotifyCommandsCanExecuteChanged();
|
||||
partial void OnNewTenantUrlChanged(string value) => NotifyCommandsCanExecuteChanged();
|
||||
partial void OnNewClientIdChanged(string value) => NotifyCommandsCanExecuteChanged();
|
||||
|
||||
private void NotifyCommandsCanExecuteChanged()
|
||||
{
|
||||
AddCommand.NotifyCanExecuteChanged();
|
||||
RenameCommand.NotifyCanExecuteChanged();
|
||||
}
|
||||
|
||||
private bool CanAdd()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(NewName)) return false;
|
||||
|
||||
Reference in New Issue
Block a user