Retrieves item counts before and after the target for sibling endpoints and returns in API response (#19844)

* Added user start node restrictions to sibling endpoints.

* Further integration tests.

* Tidy up.

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Revert previous update.

* Retrieves item counts before and after the target for sibling endpoints and returns in API response.

* Applied previous update correctly.

* Removed blank line.

* Fix build and test asserts following merge.

* Update OpenApi.json.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: mole <nikolajlauridsen@protonmail.ch>
This commit is contained in:
Andy Butland
2025-08-05 11:14:59 +02:00
committed by GitHub
parent 20254f0bbc
commit fcba10aecf
21 changed files with 526 additions and 115 deletions

View File

@@ -17,9 +17,13 @@ public partial class UserStartNodeEntitiesServiceMediaTests
_mediaByName["1-5"].Key,
2,
2,
BySortOrder)
BySortOrder,
out long totalBefore,
out long totalAfter)
.ToArray();
Assert.AreEqual(2, totalBefore);
Assert.AreEqual(3, totalAfter);
Assert.AreEqual(5, siblings.Length);
Assert.Multiple(() =>
{
@@ -45,9 +49,13 @@ public partial class UserStartNodeEntitiesServiceMediaTests
_mediaByName["1-5"].Key,
2,
2,
BySortOrder)
BySortOrder,
out long totalBefore,
out long totalAfter)
.ToArray();
Assert.AreEqual(0, totalBefore);
Assert.AreEqual(0, totalAfter);
Assert.AreEqual(1, siblings.Length);
Assert.Multiple(() =>
{
@@ -68,9 +76,13 @@ public partial class UserStartNodeEntitiesServiceMediaTests
_mediaByName["1-5"].Key,
2,
2,
BySortOrder)
BySortOrder,
out long totalBefore,
out long totalAfter)
.ToArray();
Assert.AreEqual(0, totalBefore);
Assert.AreEqual(0, totalAfter);
Assert.AreEqual(1, siblings.Length);
Assert.Multiple(() =>
{
@@ -82,18 +94,22 @@ public partial class UserStartNodeEntitiesServiceMediaTests
[Test]
public async Task SiblingUserAccessEntities_WithStartsNodesOfTargetAndSiblings_YieldsOnlyPermitted_AsAllowed()
{
var mediaStartNodePaths = await CreateUserAndGetStartNodePaths(_mediaByName["1-3"].Id, _mediaByName["1-5"].Id, _mediaByName["1-7"].Id);
var mediaStartNodePaths = await CreateUserAndGetStartNodePaths(_mediaByName["1-3"].Id, _mediaByName["1-5"].Id, _mediaByName["1-7"].Id, _mediaByName["1-10"].Id);
var siblings = UserStartNodeEntitiesService
.SiblingUserAccessEntities(
UmbracoObjectTypes.Media,
mediaStartNodePaths,
_mediaByName["1-5"].Key,
2,
2,
BySortOrder)
1,
1,
BySortOrder,
out long totalBefore,
out long totalAfter)
.ToArray();
Assert.AreEqual(0, totalBefore);
Assert.AreEqual(1, totalAfter);
Assert.AreEqual(3, siblings.Length);
Assert.Multiple(() =>
{
@@ -118,9 +134,13 @@ public partial class UserStartNodeEntitiesServiceMediaTests
_mediaByName["1-5"].Key,
2,
2,
BySortOrder)
BySortOrder,
out long totalBefore,
out long totalAfter)
.ToArray();
Assert.AreEqual(0, totalBefore);
Assert.AreEqual(0, totalAfter);
Assert.AreEqual(1, siblings.Length);
Assert.Multiple(() =>
{

View File

@@ -17,9 +17,13 @@ public partial class UserStartNodeEntitiesServiceTests
_contentByName["1-5"].Key,
2,
2,
BySortOrder)
BySortOrder,
out long totalBefore,
out long totalAfter)
.ToArray();
Assert.AreEqual(2, totalBefore);
Assert.AreEqual(3, totalAfter);
Assert.AreEqual(5, siblings.Length);
Assert.Multiple(() =>
{
@@ -45,9 +49,13 @@ public partial class UserStartNodeEntitiesServiceTests
_contentByName["1-5"].Key,
2,
2,
BySortOrder)
BySortOrder,
out long totalBefore,
out long totalAfter)
.ToArray();
Assert.AreEqual(0, totalBefore);
Assert.AreEqual(0, totalAfter);
Assert.AreEqual(1, siblings.Length);
Assert.Multiple(() =>
{
@@ -68,9 +76,13 @@ public partial class UserStartNodeEntitiesServiceTests
_contentByName["1-5"].Key,
2,
2,
BySortOrder)
BySortOrder,
out long totalBefore,
out long totalAfter)
.ToArray();
Assert.AreEqual(0, totalBefore);
Assert.AreEqual(0, totalAfter);
Assert.AreEqual(1, siblings.Length);
Assert.Multiple(() =>
{
@@ -82,19 +94,24 @@ public partial class UserStartNodeEntitiesServiceTests
[Test]
public async Task SiblingUserAccessEntities_WithStartsNodesOfTargetAndSiblings_YieldsOnlyPermitted_AsAllowed()
{
var contentStartNodePaths = await CreateUserAndGetStartNodePaths(_contentByName["1-3"].Id, _contentByName["1-5"].Id, _contentByName["1-7"].Id);
var contentStartNodePaths = await CreateUserAndGetStartNodePaths(_contentByName["1-3"].Id, _contentByName["1-5"].Id, _contentByName["1-7"].Id, _contentByName["1-10"].Id);
var siblings = UserStartNodeEntitiesService
.SiblingUserAccessEntities(
UmbracoObjectTypes.Document,
contentStartNodePaths,
_contentByName["1-5"].Key,
2,
2,
BySortOrder)
1,
1,
BySortOrder,
out long totalBefore,
out long totalAfter)
.ToArray();
Assert.AreEqual(0, totalBefore);
Assert.AreEqual(1, totalAfter);
Assert.AreEqual(3, siblings.Length);
Assert.Multiple(() =>
{
Assert.AreEqual(_contentByName[$"1-3"].Key, siblings[0].Entity.Key);
@@ -118,9 +135,13 @@ public partial class UserStartNodeEntitiesServiceTests
_contentByName["1-5"].Key,
2,
2,
BySortOrder)
BySortOrder,
out long totalBefore,
out long totalAfter)
.ToArray();
Assert.AreEqual(0, totalBefore);
Assert.AreEqual(0, totalAfter);
Assert.AreEqual(1, siblings.Length);
Assert.Multiple(() =>
{

View File

@@ -929,7 +929,6 @@ internal sealed class EntityServiceTests : UmbracoIntegrationTest
var result2 = EntityService.GetPathKeys(grandChild, omitSelf: true);
Assert.AreEqual($"{root.Key},{child.Key}", string.Join(",", result2));
}
[Test]
@@ -939,7 +938,9 @@ internal sealed class EntityServiceTests : UmbracoIntegrationTest
var target = children[1];
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 1).ToArray();
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 1, out long totalBefore, out long totalAfter).ToArray();
Assert.AreEqual(0, totalBefore);
Assert.AreEqual(7, totalAfter);
Assert.AreEqual(3, result.Length);
Assert.IsTrue(result[0].Key == children[0].Key);
Assert.IsTrue(result[1].Key == children[1].Key);
@@ -955,7 +956,9 @@ internal sealed class EntityServiceTests : UmbracoIntegrationTest
ContentService.MoveToRecycleBin(trash);
var target = children[2];
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 1).ToArray();
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 1, out long totalBefore, out long totalAfter).ToArray();
Assert.AreEqual(0, totalBefore);
Assert.AreEqual(6, totalAfter);
Assert.AreEqual(3, result.Length);
Assert.IsFalse(result.Any(x => x.Key == trash.Key));
Assert.IsTrue(result[0].Key == children[0].Key);
@@ -974,7 +977,9 @@ internal sealed class EntityServiceTests : UmbracoIntegrationTest
IQuery<IUmbracoEntity> filter = ScopeProvider.CreateQuery<IUmbracoEntity>().Where(x => !keysToExclude.Contains(x.Key));
var target = children[2];
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 1, filter).ToArray();
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 1, out long totalBefore, out long totalAfter, filter).ToArray();
Assert.AreEqual(0, totalBefore);
Assert.AreEqual(6, totalAfter);
Assert.AreEqual(3, result.Length);
Assert.IsFalse(result.Any(x => x.Key == keysToExclude[0]));
Assert.IsTrue(result[0].Key == children[0].Key);
@@ -993,7 +998,9 @@ internal sealed class EntityServiceTests : UmbracoIntegrationTest
IQuery<IUmbracoEntity> filter = ScopeProvider.CreateQuery<IUmbracoEntity>().Where(x => x.Key != keyToExclude);
var target = children[2];
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 1, filter).ToArray();
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 1, out long totalBefore, out long totalAfter, filter).ToArray();
Assert.AreEqual(0, totalBefore);
Assert.AreEqual(6, totalAfter);
Assert.AreEqual(3, result.Length);
Assert.IsFalse(result.Any(x => x.Key == keyToExclude));
Assert.IsTrue(result[0].Key == children[0].Key);
@@ -1010,7 +1017,9 @@ internal sealed class EntityServiceTests : UmbracoIntegrationTest
children = children.OrderBy(x => x.Name).ToList();
var target = children[1];
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 1, ordering: Ordering.By(nameof(NodeDto.Text))).ToArray();
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 1, out long totalBefore, out long totalAfter, ordering: Ordering.By(nameof(NodeDto.Text))).ToArray();
Assert.AreEqual(0, totalBefore);
Assert.AreEqual(7, totalAfter);
Assert.AreEqual(3, result.Length);
Assert.IsTrue(result[0].Key == children[0].Key);
Assert.IsTrue(result[1].Key == children[1].Key);
@@ -1023,7 +1032,9 @@ internal sealed class EntityServiceTests : UmbracoIntegrationTest
var children = CreateSiblingsTestData();
var target = children[1];
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 100, 1).ToArray();
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 100, 1, out long totalBefore, out long totalAfter).ToArray();
Assert.AreEqual(0, totalBefore);
Assert.AreEqual(7, totalAfter);
Assert.AreEqual(3, result.Length);
Assert.IsTrue(result[0].Key == children[0].Key);
Assert.IsTrue(result[1].Key == children[1].Key);
@@ -1036,7 +1047,9 @@ internal sealed class EntityServiceTests : UmbracoIntegrationTest
var children = CreateSiblingsTestData();
var target = children[^2];
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 100).ToArray();
var result = EntityService.GetSiblings(target.Key, UmbracoObjectTypes.Document, 1, 100, out long totalBefore, out long totalAfter).ToArray();
Assert.AreEqual(7, totalBefore);
Assert.AreEqual(0, totalAfter);
Assert.AreEqual(3, result.Length);
Assert.IsTrue(result[^1].Key == children[^1].Key);
Assert.IsTrue(result[^2].Key == children[^2].Key);

View File

@@ -23,7 +23,7 @@ public class EntityServiceTests
if (shouldThrow)
{
Assert.Throws<ArgumentOutOfRangeException>(() => sut.GetSiblings(Guid.NewGuid(), UmbracoObjectTypes.Document, before, after));
Assert.Throws<ArgumentOutOfRangeException>(() => sut.GetSiblings(Guid.NewGuid(), UmbracoObjectTypes.Document, before, after, out _, out _));
}
}