139 lines
5.7 KiB
C#
139 lines
5.7 KiB
C#
using SharepointToolbox.Core.Helpers;
|
|
|
|
namespace SharepointToolbox.Tests.Services;
|
|
|
|
/// <summary>
|
|
/// Tests for PERM-03: external user detection, permission-level filtering,
|
|
/// and SharePoint system-group classification (Limited Access / SharingLinks).
|
|
/// Pure static logic — runs immediately without stubs.
|
|
/// </summary>
|
|
public class PermissionEntryClassificationTests
|
|
{
|
|
// ── IsExternalUser ─────────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void IsExternalUser_WithExtHashInLoginName_ReturnsTrue()
|
|
{
|
|
Assert.True(PermissionEntryHelper.IsExternalUser("ext_user_domain.com#EXT#@contoso.onmicrosoft.com"));
|
|
}
|
|
|
|
[Fact]
|
|
public void IsExternalUser_WithNormalLoginName_ReturnsFalse()
|
|
{
|
|
Assert.False(PermissionEntryHelper.IsExternalUser("i:0#.f|membership|alice@contoso.com"));
|
|
}
|
|
|
|
// ── FilterPermissionLevels ─────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void PermissionEntry_FiltersOutLimitedAccess_WhenOnlyPermissionIsLimitedAccess()
|
|
{
|
|
var result = PermissionEntryHelper.FilterPermissionLevels(new[] { "Limited Access" });
|
|
Assert.Empty(result);
|
|
}
|
|
|
|
[Fact]
|
|
public void FilterPermissionLevels_RetainsOtherLevels_WhenMixedWithLimitedAccess()
|
|
{
|
|
var result = PermissionEntryHelper.FilterPermissionLevels(new[] { "Limited Access", "Contribute" });
|
|
Assert.Equal(new[] { "Contribute" }, result);
|
|
}
|
|
|
|
// ── IsBareLimitedAccessSystemGroup ─────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void IsBareLimitedAccessSystemGroup_WithExactMatch_ReturnsTrue()
|
|
{
|
|
Assert.True(PermissionEntryHelper.IsBareLimitedAccessSystemGroup("Limited Access System Group"));
|
|
}
|
|
|
|
[Fact]
|
|
public void IsBareLimitedAccessSystemGroup_WithForWebVariant_ReturnsFalse()
|
|
{
|
|
// The "For Web {guid}" variant is enriched, not filtered.
|
|
Assert.False(PermissionEntryHelper.IsBareLimitedAccessSystemGroup(
|
|
"Limited Access System Group For Web e55a4f7a-b132-4baa-bd96-c63d8dc1fc80"));
|
|
}
|
|
|
|
[Fact]
|
|
public void IsBareLimitedAccessSystemGroup_WithNormalGroup_ReturnsFalse()
|
|
{
|
|
Assert.False(PermissionEntryHelper.IsBareLimitedAccessSystemGroup("Owners"));
|
|
}
|
|
|
|
// ── Classify ───────────────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void Classify_WithNormalGroupTitle_ReturnsNone()
|
|
{
|
|
var c = PermissionEntryHelper.Classify("Site Owners");
|
|
Assert.Equal(SystemGroupKind.None, c.Kind);
|
|
}
|
|
|
|
[Fact]
|
|
public void Classify_WithBareLimitedAccess_ReturnsLimitedAccessBare()
|
|
{
|
|
var c = PermissionEntryHelper.Classify("Limited Access System Group");
|
|
Assert.Equal(SystemGroupKind.LimitedAccessBare, c.Kind);
|
|
}
|
|
|
|
[Fact]
|
|
public void Classify_WithLimitedAccessForWeb_ExtractsWebId()
|
|
{
|
|
var c = PermissionEntryHelper.Classify(
|
|
"Limited Access System Group For Web e55a4f7a-b132-4baa-bd96-c63d8dc1fc80");
|
|
Assert.Equal(SystemGroupKind.LimitedAccessWeb, c.Kind);
|
|
Assert.Equal(Guid.Parse("e55a4f7a-b132-4baa-bd96-c63d8dc1fc80"), c.WebId);
|
|
Assert.Null(c.ListId);
|
|
Assert.Null(c.ItemUniqueId);
|
|
}
|
|
|
|
[Fact]
|
|
public void Classify_WithLimitedAccessForList_ExtractsListId()
|
|
{
|
|
var c = PermissionEntryHelper.Classify(
|
|
"Limited Access System Group For List b20e3b22-2b09-4c99-9ba4-37b42f3a12dc");
|
|
Assert.Equal(SystemGroupKind.LimitedAccessList, c.Kind);
|
|
Assert.Equal(Guid.Parse("b20e3b22-2b09-4c99-9ba4-37b42f3a12dc"), c.ListId);
|
|
Assert.Null(c.WebId);
|
|
Assert.Null(c.ItemUniqueId);
|
|
}
|
|
|
|
[Fact]
|
|
public void Classify_WithSharingLink_ExtractsItemAndShareId()
|
|
{
|
|
var c = PermissionEntryHelper.Classify(
|
|
"SharingLinks.e686221e-d1cb-43c5-8c68-04aa7f90f329.OrganizationEdit.64c27910-66ea-421d-b0f0-8f0f72dcfaf6");
|
|
Assert.Equal(SystemGroupKind.SharingLink, c.Kind);
|
|
Assert.Equal(Guid.Parse("e686221e-d1cb-43c5-8c68-04aa7f90f329"), c.ItemUniqueId);
|
|
Assert.Equal(Guid.Parse("64c27910-66ea-421d-b0f0-8f0f72dcfaf6"), c.ShareId);
|
|
Assert.Equal("OrganizationEdit", c.LinkType);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("SharingLinks.e686221e-d1cb-43c5-8c68-04aa7f90f329.AnonymousView.64c27910-66ea-421d-b0f0-8f0f72dcfaf6", "AnonymousView")]
|
|
[InlineData("SharingLinks.e686221e-d1cb-43c5-8c68-04aa7f90f329.Flexible.64c27910-66ea-421d-b0f0-8f0f72dcfaf6", "Flexible")]
|
|
[InlineData("SharingLinks.e686221e-d1cb-43c5-8c68-04aa7f90f329.OrganizationView.64c27910-66ea-421d-b0f0-8f0f72dcfaf6", "OrganizationView")]
|
|
public void Classify_WithVariousSharingLinkTypes_PreservesLinkType(string title, string expected)
|
|
{
|
|
var c = PermissionEntryHelper.Classify(title);
|
|
Assert.Equal(SystemGroupKind.SharingLink, c.Kind);
|
|
Assert.Equal(expected, c.LinkType);
|
|
}
|
|
|
|
[Fact]
|
|
public void Classify_WithMalformedSharingLink_ReturnsNone()
|
|
{
|
|
// Missing share GUID at the end
|
|
var c = PermissionEntryHelper.Classify("SharingLinks.e686221e-d1cb-43c5-8c68-04aa7f90f329.Edit");
|
|
Assert.Equal(SystemGroupKind.None, c.Kind);
|
|
}
|
|
|
|
[Fact]
|
|
public void Classify_WithEmptyString_ReturnsNone()
|
|
{
|
|
var c = PermissionEntryHelper.Classify("");
|
|
Assert.Equal(SystemGroupKind.None, c.Kind);
|
|
}
|
|
}
|