feat(18-01): models, SettingsService, OwnershipElevationService + tests
- AppSettings.AutoTakeOwnership bool property defaulting to false - PermissionEntry.WasAutoElevated optional param (default false, last position) - SettingsService.SetAutoTakeOwnershipAsync persists toggle - IOwnershipElevationService interface + OwnershipElevationService wrapping Tenant.SetSiteAdmin - SettingsViewModel.AutoTakeOwnership property loads and persists via SetAutoTakeOwnershipAsync - DI registration in App.xaml.cs (Phase 18 section) - 8 new tests: models, persistence, service, viewmodel
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
using SharepointToolbox.Services;
|
||||
|
||||
namespace SharepointToolbox.Tests.Services;
|
||||
|
||||
[Trait("Category", "Unit")]
|
||||
public class OwnershipElevationServiceTests
|
||||
{
|
||||
[Fact]
|
||||
public void OwnershipElevationService_ImplementsIOwnershipElevationService()
|
||||
{
|
||||
var service = new OwnershipElevationService();
|
||||
Assert.IsAssignableFrom<IOwnershipElevationService>(service);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppSettings_AutoTakeOwnership_DefaultsFalse()
|
||||
{
|
||||
var settings = new SharepointToolbox.Core.Models.AppSettings();
|
||||
Assert.False(settings.AutoTakeOwnership);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AppSettings_AutoTakeOwnership_RoundTripsThroughJson()
|
||||
{
|
||||
var json = System.Text.Json.JsonSerializer.Serialize(
|
||||
new SharepointToolbox.Core.Models.AppSettings { AutoTakeOwnership = true },
|
||||
new System.Text.Json.JsonSerializerOptions { PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase });
|
||||
|
||||
var loaded = System.Text.Json.JsonSerializer.Deserialize<SharepointToolbox.Core.Models.AppSettings>(json,
|
||||
new System.Text.Json.JsonSerializerOptions { PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase });
|
||||
|
||||
Assert.NotNull(loaded);
|
||||
Assert.True(loaded!.AutoTakeOwnership);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PermissionEntry_WasAutoElevated_DefaultsFalse()
|
||||
{
|
||||
var entry = new SharepointToolbox.Core.Models.PermissionEntry(
|
||||
"Site", "Title", "https://example.com", false,
|
||||
"User", "user@example.com", "Read", "Direct Permissions", "User");
|
||||
|
||||
Assert.False(entry.WasAutoElevated);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PermissionEntry_WasAutoElevated_TrueWhenSet()
|
||||
{
|
||||
var entry = new SharepointToolbox.Core.Models.PermissionEntry(
|
||||
"Site", "Title", "https://example.com", false,
|
||||
"User", "user@example.com", "Read", "Direct Permissions", "User",
|
||||
WasAutoElevated: true);
|
||||
|
||||
Assert.True(entry.WasAutoElevated);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PermissionEntry_WithExpression_CopiesWasAutoElevated()
|
||||
{
|
||||
var original = new SharepointToolbox.Core.Models.PermissionEntry(
|
||||
"Site", "Title", "https://example.com", false,
|
||||
"User", "user@example.com", "Read", "Direct Permissions", "User");
|
||||
|
||||
var elevated = original with { WasAutoElevated = true };
|
||||
|
||||
Assert.False(original.WasAutoElevated);
|
||||
Assert.True(elevated.WasAutoElevated);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
using SharepointToolbox.Infrastructure.Persistence;
|
||||
using SharepointToolbox.Services;
|
||||
using SharepointToolbox.ViewModels;
|
||||
using SharepointToolbox.ViewModels.Tabs;
|
||||
|
||||
namespace SharepointToolbox.Tests.ViewModels;
|
||||
|
||||
[Trait("Category", "Unit")]
|
||||
public class SettingsViewModelOwnershipTests : IDisposable
|
||||
{
|
||||
private readonly string _tempFile;
|
||||
|
||||
public SettingsViewModelOwnershipTests()
|
||||
{
|
||||
_tempFile = Path.GetTempFileName();
|
||||
File.Delete(_tempFile);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (File.Exists(_tempFile)) File.Delete(_tempFile);
|
||||
if (File.Exists(_tempFile + ".tmp")) File.Delete(_tempFile + ".tmp");
|
||||
}
|
||||
|
||||
private SettingsViewModel CreateViewModel()
|
||||
{
|
||||
var settingsService = new SettingsService(new SettingsRepository(_tempFile));
|
||||
var mockBranding = new Mock<IBrandingService>().Object;
|
||||
var logger = NullLogger<FeatureViewModelBase>.Instance;
|
||||
return new SettingsViewModel(settingsService, mockBranding, logger);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task LoadAsync_AutoTakeOwnership_LoadsFalseByDefault()
|
||||
{
|
||||
var vm = CreateViewModel();
|
||||
|
||||
await vm.LoadAsync();
|
||||
|
||||
Assert.False(vm.AutoTakeOwnership);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SetAutoTakeOwnership_True_CallsSetAutoTakeOwnershipAsync()
|
||||
{
|
||||
// Use a real SettingsService backed by temp file to verify persistence
|
||||
var settingsService = new SettingsService(new SettingsRepository(_tempFile));
|
||||
var mockBranding = new Mock<IBrandingService>().Object;
|
||||
var logger = NullLogger<FeatureViewModelBase>.Instance;
|
||||
var vm = new SettingsViewModel(settingsService, mockBranding, logger);
|
||||
|
||||
await vm.LoadAsync();
|
||||
vm.AutoTakeOwnership = true;
|
||||
|
||||
// Small delay to let the fire-and-forget persist
|
||||
await Task.Delay(100);
|
||||
|
||||
var persisted = await settingsService.GetSettingsAsync();
|
||||
Assert.True(persisted.AutoTakeOwnership);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user