diff --git a/SharepointToolbox.Tests/Helpers/ExecuteQueryRetryHelperTests.cs b/SharepointToolbox.Tests/Helpers/ExecuteQueryRetryHelperTests.cs new file mode 100644 index 0000000..e497077 --- /dev/null +++ b/SharepointToolbox.Tests/Helpers/ExecuteQueryRetryHelperTests.cs @@ -0,0 +1,33 @@ +using SharepointToolbox.Core.Helpers; + +namespace SharepointToolbox.Tests.Helpers; + +[Trait("Category", "Unit")] +public class ExecuteQueryRetryHelperTests +{ + [Theory] + [InlineData("The request has been throttled -- 429")] + [InlineData("Service unavailable 503")] + [InlineData("SharePoint has throttled your request")] + public void IsThrottleException_ThrottleMessages_ReturnsTrue(string message) + { + var ex = new Exception(message); + Assert.True(ExecuteQueryRetryHelper.IsThrottleException(ex)); + } + + [Fact] + public void IsThrottleException_NonThrottleMessage_ReturnsFalse() + { + var ex = new Exception("File not found"); + Assert.False(ExecuteQueryRetryHelper.IsThrottleException(ex)); + } + + [Fact] + public void IsThrottleException_NestedThrottleInInnerException_ReturnsFalse() + { + // Documents current behavior: only top-level Message is checked. + // Inner exceptions with "429" are NOT currently detected. + var ex = new Exception("outer", new Exception("429")); + Assert.False(ExecuteQueryRetryHelper.IsThrottleException(ex)); + } +} diff --git a/SharepointToolbox.Tests/Helpers/SharePointPaginationHelperTests.cs b/SharepointToolbox.Tests/Helpers/SharePointPaginationHelperTests.cs new file mode 100644 index 0000000..4a89ca0 --- /dev/null +++ b/SharepointToolbox.Tests/Helpers/SharePointPaginationHelperTests.cs @@ -0,0 +1,49 @@ +using SharepointToolbox.Core.Helpers; + +namespace SharepointToolbox.Tests.Helpers; + +[Trait("Category", "Unit")] +public class SharePointPaginationHelperTests +{ + [Fact] + public void BuildPagedViewXml_NullInput_ReturnsViewWithRowLimit() + { + var result = SharePointPaginationHelper.BuildPagedViewXml(null, 2000); + Assert.Equal("2000", result); + } + + [Fact] + public void BuildPagedViewXml_EmptyString_ReturnsViewWithRowLimit() + { + var result = SharePointPaginationHelper.BuildPagedViewXml("", 2000); + Assert.Equal("2000", result); + } + + [Fact] + public void BuildPagedViewXml_WhitespaceOnly_ReturnsViewWithRowLimit() + { + var result = SharePointPaginationHelper.BuildPagedViewXml(" ", 2000); + Assert.Equal("2000", result); + } + + [Fact] + public void BuildPagedViewXml_ExistingRowLimit_Replaces() + { + var input = "100"; + var result = SharePointPaginationHelper.BuildPagedViewXml(input, 2000); + Assert.Equal("2000", result); + } + + [Fact] + public void BuildPagedViewXml_NoRowLimit_AppendsBeforeClosingView() + { + var input = ""; + var result = SharePointPaginationHelper.BuildPagedViewXml(input, 2000); + Assert.Contains("2000", result); + Assert.EndsWith("", result); + // Ensure RowLimit is inserted before the closing + var rowLimitIndex = result.IndexOf("2000", StringComparison.Ordinal); + var closingViewIndex = result.LastIndexOf("", StringComparison.Ordinal); + Assert.True(rowLimitIndex < closingViewIndex, "RowLimit should appear before "); + } +} diff --git a/SharepointToolbox/Core/Helpers/ExecuteQueryRetryHelper.cs b/SharepointToolbox/Core/Helpers/ExecuteQueryRetryHelper.cs index 7b353e5..76e2c84 100644 --- a/SharepointToolbox/Core/Helpers/ExecuteQueryRetryHelper.cs +++ b/SharepointToolbox/Core/Helpers/ExecuteQueryRetryHelper.cs @@ -36,7 +36,7 @@ public static class ExecuteQueryRetryHelper } } - private static bool IsThrottleException(Exception ex) + internal static bool IsThrottleException(Exception ex) { var msg = ex.Message; return msg.Contains("429") || msg.Contains("503") || diff --git a/SharepointToolbox/Core/Helpers/SharePointPaginationHelper.cs b/SharepointToolbox/Core/Helpers/SharePointPaginationHelper.cs index 151634e..732f213 100644 --- a/SharepointToolbox/Core/Helpers/SharePointPaginationHelper.cs +++ b/SharepointToolbox/Core/Helpers/SharePointPaginationHelper.cs @@ -36,7 +36,7 @@ public static class SharePointPaginationHelper while (query.ListItemCollectionPosition != null); } - private static string BuildPagedViewXml(string? existingXml, int rowLimit) + internal static string BuildPagedViewXml(string? existingXml, int rowLimit) { // Inject or replace RowLimit in existing CAML, or create minimal view if (string.IsNullOrWhiteSpace(existingXml))