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:
Dev
2026-04-07 10:41:39 +02:00
parent 52670bd262
commit 5666565ac1
3 changed files with 133 additions and 2 deletions

View 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

View File

@@ -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 =>
{

View File

@@ -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;