Merge branch 'main' into v17/dev
# Conflicts: # src/Umbraco.Web.UI.Client/package-lock.json # src/Umbraco.Web.UI.Client/package.json # version.json
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using System.Threading;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Extensions;
|
||||
@@ -13,18 +12,21 @@ public abstract class RuntimeAppCacheTests : AppCacheTests
|
||||
internal abstract IAppPolicyCache AppPolicyCache { get; }
|
||||
|
||||
[Test]
|
||||
[Explicit("Testing for timeouts cannot work on VSTS.")]
|
||||
public void Can_Add_And_Expire_Struct_Strongly_Typed_With_Null()
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
AppPolicyCache.Insert("DateTimeTest", () => now, new TimeSpan(0, 0, 0, 0, 200));
|
||||
Assert.AreEqual(now, AppCache.GetCacheItem<DateTime>("DateTimeTest"));
|
||||
Assert.AreEqual(now, AppCache.GetCacheItem<DateTime?>("DateTimeTest"));
|
||||
AppPolicyCache.Insert("DateTimeTest", () => now, new TimeSpan(0, 0, 0, 0, 20));
|
||||
var cachedDateTime = AppCache.GetCacheItem<DateTime>("DateTimeTest");
|
||||
var cachedDateTimeNullable = AppCache.GetCacheItem<DateTime?>("DateTimeTest");
|
||||
Assert.AreEqual(now, cachedDateTime);
|
||||
Assert.AreEqual(now, cachedDateTimeNullable);
|
||||
|
||||
Thread.Sleep(300); // sleep longer than the cache expiration
|
||||
Thread.Sleep(30); // sleep longer than the cache expiration
|
||||
|
||||
Assert.AreEqual(default(DateTime), AppCache.GetCacheItem<DateTime>("DateTimeTest"));
|
||||
Assert.AreEqual(null, AppCache.GetCacheItem<DateTime?>("DateTimeTest"));
|
||||
cachedDateTime = AppCache.GetCacheItem<DateTime>("DateTimeTest");
|
||||
cachedDateTimeNullable = AppCache.GetCacheItem<DateTime?>("DateTimeTest");
|
||||
Assert.AreEqual(default(DateTime), cachedDateTime);
|
||||
Assert.AreEqual(null, cachedDateTimeNullable);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -28,8 +28,6 @@ public class SliderPropertyValueEditorTests
|
||||
true,
|
||||
new object(),
|
||||
new List<string> { "some", "values" },
|
||||
Guid.NewGuid(),
|
||||
new GuidUdi(Constants.UdiEntityType.Document, Guid.NewGuid())
|
||||
};
|
||||
|
||||
[TestCaseSource(nameof(InvalidCaseData))]
|
||||
@@ -39,6 +37,20 @@ public class SliderPropertyValueEditorTests
|
||||
Assert.IsNull(fromEditor);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Handle_Invalid_Values_From_Editor_Guid()
|
||||
{
|
||||
var fromEditor = FromEditor(Guid.NewGuid());
|
||||
Assert.IsNull(fromEditor);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Handle_Invalid_Values_From_Editor_Udi()
|
||||
{
|
||||
var fromEditor = FromEditor(new GuidUdi(Constants.UdiEntityType.Document, Guid.NewGuid()));
|
||||
Assert.IsNull(fromEditor);
|
||||
}
|
||||
|
||||
[TestCase("1", 1)]
|
||||
[TestCase("0", 0)]
|
||||
[TestCase("-1", -1)]
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PublishedCache;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing;
|
||||
|
||||
[TestFixture]
|
||||
public class ContentFinderByUrlNewTests
|
||||
{
|
||||
private const int DomainContentId = 1233;
|
||||
private const int ContentId = 1234;
|
||||
private static readonly Guid _contentKey = Guid.NewGuid();
|
||||
private const string ContentPath = "/test-page";
|
||||
private const string DomainHost = "example.com";
|
||||
|
||||
[TestCase(ContentPath, true)]
|
||||
[TestCase("/missing-page", false)]
|
||||
public async Task Can_Find_Invariant_Content(string path, bool expectSuccess)
|
||||
{
|
||||
var mockContent = CreateMockPublishedContent();
|
||||
|
||||
var mockUmbracoContextAccessor = CreateMockUmbracoContextAccessor();
|
||||
|
||||
var mockDocumentUrlService = CreateMockDocumentUrlService();
|
||||
|
||||
var mockPublishedContentCache = CreateMockPublishedContentCache(mockContent);
|
||||
|
||||
var sut = CreateContentFinder(mockUmbracoContextAccessor, mockDocumentUrlService, mockPublishedContentCache);
|
||||
|
||||
var publishedRequestBuilder = CreatePublishedRequestBuilder(path);
|
||||
|
||||
var result = await sut.TryFindContent(publishedRequestBuilder);
|
||||
|
||||
Assert.AreEqual(expectSuccess, result);
|
||||
if (expectSuccess)
|
||||
{
|
||||
Assert.IsNotNull(publishedRequestBuilder.PublishedContent);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsNull(publishedRequestBuilder.PublishedContent);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase(ContentPath, true, false, true)]
|
||||
[TestCase("/missing-page", true, false, false)]
|
||||
[TestCase(ContentPath, true, true, true)]
|
||||
[TestCase(ContentPath, false, true, false)]
|
||||
public async Task Can_Find_Invariant_Content_With_Domain(string path, bool setDomain, bool useStrictDomainMatching, bool expectSuccess)
|
||||
{
|
||||
var mockContent = CreateMockPublishedContent();
|
||||
|
||||
var mockUmbracoContextAccessor = CreateMockUmbracoContextAccessor();
|
||||
|
||||
var mockDocumentUrlService = CreateMockDocumentUrlService();
|
||||
|
||||
var mockPublishedContentCache = CreateMockPublishedContentCache(mockContent);
|
||||
|
||||
var sut = CreateContentFinder(
|
||||
mockUmbracoContextAccessor,
|
||||
mockDocumentUrlService,
|
||||
mockPublishedContentCache,
|
||||
new WebRoutingSettings
|
||||
{
|
||||
UseStrictDomainMatching = useStrictDomainMatching
|
||||
});
|
||||
|
||||
var publishedRequestBuilder = CreatePublishedRequestBuilder(path, withDomain: setDomain);
|
||||
|
||||
var result = await sut.TryFindContent(publishedRequestBuilder);
|
||||
|
||||
Assert.AreEqual(expectSuccess, result);
|
||||
if (expectSuccess)
|
||||
{
|
||||
Assert.IsNotNull(publishedRequestBuilder.PublishedContent);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsNull(publishedRequestBuilder.PublishedContent);
|
||||
}
|
||||
}
|
||||
|
||||
private static Mock<IPublishedContent> CreateMockPublishedContent()
|
||||
{
|
||||
var mockContent = new Mock<IPublishedContent>();
|
||||
mockContent
|
||||
.SetupGet(x => x.Id)
|
||||
.Returns(ContentId);
|
||||
mockContent
|
||||
.SetupGet(x => x.ContentType.ItemType)
|
||||
.Returns(PublishedItemType.Content);
|
||||
return mockContent;
|
||||
}
|
||||
|
||||
private static Mock<IUmbracoContextAccessor> CreateMockUmbracoContextAccessor()
|
||||
{
|
||||
var mockUmbracoContext = new Mock<IUmbracoContext>();
|
||||
var mockUmbracoContextAccessor = new Mock<IUmbracoContextAccessor>();
|
||||
var umbracoContext = mockUmbracoContext.Object;
|
||||
mockUmbracoContextAccessor
|
||||
.Setup(x => x.TryGetUmbracoContext(out umbracoContext))
|
||||
.Returns(true);
|
||||
return mockUmbracoContextAccessor;
|
||||
}
|
||||
|
||||
private static Mock<IDocumentUrlService> CreateMockDocumentUrlService()
|
||||
{
|
||||
var mockDocumentUrlService = new Mock<IDocumentUrlService>();
|
||||
mockDocumentUrlService
|
||||
.Setup(x => x.GetDocumentKeyByRoute(It.Is<string>(y => y == ContentPath), It.IsAny<string?>(), It.IsAny<int?>(), It.IsAny<bool>()))
|
||||
.Returns(_contentKey);
|
||||
return mockDocumentUrlService;
|
||||
}
|
||||
|
||||
private static Mock<IPublishedContentCache> CreateMockPublishedContentCache(Mock<IPublishedContent> mockContent)
|
||||
{
|
||||
var mockPublishedContentCache = new Mock<IPublishedContentCache>();
|
||||
mockPublishedContentCache
|
||||
.Setup(x => x.GetById(It.IsAny<bool>(), It.Is<Guid>(y => y == _contentKey)))
|
||||
.Returns(mockContent.Object);
|
||||
return mockPublishedContentCache;
|
||||
}
|
||||
|
||||
private static ContentFinderByUrlNew CreateContentFinder(
|
||||
Mock<IUmbracoContextAccessor> mockUmbracoContextAccessor,
|
||||
Mock<IDocumentUrlService> mockDocumentUrlService,
|
||||
Mock<IPublishedContentCache> mockPublishedContentCache,
|
||||
WebRoutingSettings? webRoutingSettings = null)
|
||||
=> new(
|
||||
new NullLogger<ContentFinderByUrlNew>(),
|
||||
mockUmbracoContextAccessor.Object,
|
||||
mockDocumentUrlService.Object,
|
||||
mockPublishedContentCache.Object,
|
||||
Mock.Of<IOptionsMonitor<WebRoutingSettings>>(x => x.CurrentValue == (webRoutingSettings ?? new WebRoutingSettings())));
|
||||
|
||||
private static PublishedRequestBuilder CreatePublishedRequestBuilder(string path, bool withDomain = false)
|
||||
{
|
||||
var publishedRequestBuilder = new PublishedRequestBuilder(new Uri($"https://example.com{path}"), Mock.Of<IFileService>());
|
||||
if (withDomain)
|
||||
{
|
||||
publishedRequestBuilder.SetDomain(new DomainAndUri(new Domain(1, $"https://{DomainHost}/", DomainContentId, "en-US", false, 0), new Uri($"https://{DomainHost}{path}")));
|
||||
}
|
||||
|
||||
return publishedRequestBuilder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Persistence.Repositories;
|
||||
|
||||
[TestFixture]
|
||||
internal sealed class SimilarNodeNameTests
|
||||
{
|
||||
public void Name_Is_Suffixed()
|
||||
{
|
||||
SimilarNodeName[] names = { new SimilarNodeName { Id = 1, Name = "Zulu" } };
|
||||
|
||||
var res = SimilarNodeName.GetUniqueName(names, 0, "Zulu");
|
||||
Assert.AreEqual("Zulu (1)", res);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Suffixed_Name_Is_Incremented()
|
||||
{
|
||||
SimilarNodeName[] names =
|
||||
{
|
||||
new SimilarNodeName {Id = 1, Name = "Zulu"}, new SimilarNodeName {Id = 2, Name = "Kilo (1)"},
|
||||
new SimilarNodeName {Id = 3, Name = "Kilo"}
|
||||
};
|
||||
|
||||
var res = SimilarNodeName.GetUniqueName(names, 0, "Kilo (1)");
|
||||
Assert.AreEqual("Kilo (2)", res);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Lower_Number_Suffix_Is_Inserted()
|
||||
{
|
||||
SimilarNodeName[] names =
|
||||
{
|
||||
new SimilarNodeName {Id = 1, Name = "Golf"}, new SimilarNodeName {Id = 2, Name = "Golf (2)"}
|
||||
};
|
||||
|
||||
var res = SimilarNodeName.GetUniqueName(names, 0, "Golf");
|
||||
Assert.AreEqual("Golf (1)", res);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase(0, "Alpha", "Alpha (3)")]
|
||||
[TestCase(0, "alpha", "alpha (3)")]
|
||||
public void Case_Is_Ignored(int nodeId, string nodeName, string expected)
|
||||
{
|
||||
SimilarNodeName[] names =
|
||||
{
|
||||
new SimilarNodeName {Id = 1, Name = "Alpha"}, new SimilarNodeName {Id = 2, Name = "Alpha (1)"},
|
||||
new SimilarNodeName {Id = 3, Name = "Alpha (2)"}
|
||||
};
|
||||
var res = SimilarNodeName.GetUniqueName(names, nodeId, nodeName);
|
||||
|
||||
Assert.AreEqual(expected, res);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Empty_List_Causes_Unchanged_Name()
|
||||
{
|
||||
var names = new SimilarNodeName[] { };
|
||||
|
||||
var res = SimilarNodeName.GetUniqueName(names, 0, "Charlie");
|
||||
|
||||
Assert.AreEqual("Charlie", res);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase(0, "", " (1)")]
|
||||
[TestCase(0, null, " (1)")]
|
||||
public void Empty_Name_Is_Suffixed(int nodeId, string nodeName, string expected)
|
||||
{
|
||||
var names = new SimilarNodeName[] { };
|
||||
|
||||
var res = SimilarNodeName.GetUniqueName(names, nodeId, nodeName);
|
||||
|
||||
Assert.AreEqual(expected, res);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Matching_NoedId_Causes_No_Change()
|
||||
{
|
||||
SimilarNodeName[] names =
|
||||
{
|
||||
new SimilarNodeName {Id = 1, Name = "Kilo (1)"}, new SimilarNodeName {Id = 2, Name = "Yankee"},
|
||||
new SimilarNodeName {Id = 3, Name = "Kilo"}
|
||||
};
|
||||
|
||||
var res = SimilarNodeName.GetUniqueName(names, 1, "Kilo (1)");
|
||||
|
||||
Assert.AreEqual("Kilo (1)", res);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Extra_MultiSuffixed_Name_Is_Ignored()
|
||||
{
|
||||
// Sequesnce is: Test, Test (1), Test (2)
|
||||
// Ignore: Test (1) (1)
|
||||
SimilarNodeName[] names =
|
||||
{
|
||||
new SimilarNodeName {Id = 1, Name = "Alpha (2)"}, new SimilarNodeName {Id = 2, Name = "Test"},
|
||||
new SimilarNodeName {Id = 3, Name = "Test (1)"}, new SimilarNodeName {Id = 4, Name = "Test (2)"},
|
||||
new SimilarNodeName {Id = 5, Name = "Test (1) (1)"}
|
||||
};
|
||||
|
||||
var res = SimilarNodeName.GetUniqueName(names, 0, "Test");
|
||||
|
||||
Assert.AreEqual("Test (3)", res);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Matched_Name_Is_Suffixed()
|
||||
{
|
||||
SimilarNodeName[] names = { new SimilarNodeName { Id = 1, Name = "Test" } };
|
||||
|
||||
var res = SimilarNodeName.GetUniqueName(names, 0, "Test");
|
||||
|
||||
Assert.AreEqual("Test (1)", res);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MultiSuffixed_Name_Is_Icremented()
|
||||
{
|
||||
// "Test (1)" is treated as the "original" version of the name.
|
||||
// "Test (1) (1)" is the suffixed result of a copy, and therefore is incremented
|
||||
// Hence this test result should be the same as Suffixed_Name_Is_Incremented
|
||||
SimilarNodeName[] names =
|
||||
{
|
||||
new SimilarNodeName {Id = 1, Name = "Test (1)"}, new SimilarNodeName {Id = 2, Name = "Test (1) (1)"}
|
||||
};
|
||||
|
||||
var res = SimilarNodeName.GetUniqueName(names, 0, "Test (1) (1)");
|
||||
|
||||
Assert.AreEqual("Test (1) (2)", res);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Suffixed_Name_Causes_Secondary_Suffix()
|
||||
{
|
||||
SimilarNodeName[] names = { new SimilarNodeName { Id = 6, Name = "Alpha (1)" } };
|
||||
var res = SimilarNodeName.GetUniqueName(names, 0, "Alpha (1)");
|
||||
|
||||
Assert.AreEqual("Alpha (1) (1)", res);
|
||||
}
|
||||
|
||||
[TestCase("Test (0)", "Test (0) (1)")]
|
||||
[TestCase("Test (-1)", "Test (-1) (1)")]
|
||||
[TestCase("Test (1) (-1)", "Test (1) (-1) (1)")]
|
||||
public void NonPositive_Suffix_Is_Ignored(string suffix, string expected)
|
||||
{
|
||||
SimilarNodeName[] names = { new SimilarNodeName { Id = 6, Name = suffix } };
|
||||
var res = SimilarNodeName.GetUniqueName(names, 0, suffix);
|
||||
|
||||
Assert.AreEqual(expected, res);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Handles_Many_Similar_Names()
|
||||
{
|
||||
SimilarNodeName[] names =
|
||||
{
|
||||
new SimilarNodeName {Id = 1, Name = "Alpha (2)"},
|
||||
new SimilarNodeName {Id = 2, Name = "Test"},
|
||||
new SimilarNodeName {Id = 3, Name = "Test (1)"},
|
||||
new SimilarNodeName {Id = 4, Name = "Test (2)"},
|
||||
new SimilarNodeName {Id = 22, Name = "Test (1) (1)"}
|
||||
};
|
||||
|
||||
var uniqueName = SimilarNodeName.GetUniqueName(names, 0, "Test");
|
||||
Assert.AreEqual("Test (3)", uniqueName);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
@@ -6,6 +6,7 @@ using Umbraco.Cms.Core.Services.Navigation;
|
||||
using Umbraco.Cms.Infrastructure.HybridCache.SeedKeyProviders.Document;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.PublishedCache.HybridCache;
|
||||
|
||||
[TestFixture]
|
||||
public class DocumentBreadthFirstKeyProviderTests
|
||||
{
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
using Microsoft.Extensions.Caching.Hybrid;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Infrastructure.HybridCache.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.PublishedCache.HybridCache.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// Provides tests to cover the <see cref="HybridCacheExtensions"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Hat-tip: https://github.com/dotnet/aspnetcore/discussions/57191
|
||||
/// </remarks>
|
||||
[TestFixture]
|
||||
public class HybridCacheExtensionsTests
|
||||
{
|
||||
private Mock<Microsoft.Extensions.Caching.Hybrid.HybridCache> _cacheMock;
|
||||
|
||||
[SetUp]
|
||||
public void TestInitialize()
|
||||
{
|
||||
_cacheMock = new Mock<Microsoft.Extensions.Caching.Hybrid.HybridCache>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ExistsAsync_WhenKeyExists_ShouldReturnTrue()
|
||||
{
|
||||
// Arrange
|
||||
string key = "test-key";
|
||||
var expectedValue = "test-value";
|
||||
|
||||
_cacheMock
|
||||
.Setup(cache => cache.GetOrCreateAsync(
|
||||
key,
|
||||
null!,
|
||||
It.IsAny<Func<object, CancellationToken, ValueTask<object>>>(),
|
||||
It.IsAny<HybridCacheEntryOptions>(),
|
||||
null,
|
||||
CancellationToken.None))
|
||||
.ReturnsAsync(expectedValue);
|
||||
|
||||
// Act
|
||||
var exists = await HybridCacheExtensions.ExistsAsync(_cacheMock.Object, key);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(exists);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ExistsAsync_WhenKeyDoesNotExist_ShouldReturnFalse()
|
||||
{
|
||||
// Arrange
|
||||
string key = "test-key";
|
||||
|
||||
_cacheMock
|
||||
.Setup(cache => cache.GetOrCreateAsync(
|
||||
key,
|
||||
null!,
|
||||
It.IsAny<Func<object, CancellationToken, ValueTask<object>>>(),
|
||||
It.IsAny<HybridCacheEntryOptions>(),
|
||||
null,
|
||||
CancellationToken.None))
|
||||
.Returns((
|
||||
string key,
|
||||
object? state,
|
||||
Func<object, CancellationToken, ValueTask<object>> factory,
|
||||
HybridCacheEntryOptions? options,
|
||||
IEnumerable<string>? tags,
|
||||
CancellationToken token) =>
|
||||
{
|
||||
return factory(state!, token);
|
||||
});
|
||||
|
||||
// Act
|
||||
var exists = await HybridCacheExtensions.ExistsAsync(_cacheMock.Object, key);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(exists);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TryGetValueAsync_WhenKeyExists_ShouldReturnTrueAndValueAsString()
|
||||
{
|
||||
// Arrange
|
||||
string key = "test-key";
|
||||
var expectedValue = "test-value";
|
||||
|
||||
_cacheMock
|
||||
.Setup(cache => cache.GetOrCreateAsync(
|
||||
key,
|
||||
null!,
|
||||
It.IsAny<Func<object, CancellationToken, ValueTask<string>>>(),
|
||||
It.IsAny<HybridCacheEntryOptions>(),
|
||||
null,
|
||||
CancellationToken.None))
|
||||
.ReturnsAsync(expectedValue);
|
||||
|
||||
// Act
|
||||
var (exists, value) = await HybridCacheExtensions.TryGetValueAsync<string>(_cacheMock.Object, key);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(exists);
|
||||
Assert.AreEqual(expectedValue, value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TryGetValueAsync_WhenKeyExists_ShouldReturnTrueAndValueAsInteger()
|
||||
{
|
||||
// Arrange
|
||||
string key = "test-key";
|
||||
var expectedValue = 5;
|
||||
|
||||
_cacheMock
|
||||
.Setup(cache => cache.GetOrCreateAsync(
|
||||
key,
|
||||
null!,
|
||||
It.IsAny<Func<object, CancellationToken, ValueTask<int>>>(),
|
||||
It.IsAny<HybridCacheEntryOptions>(),
|
||||
null,
|
||||
CancellationToken.None))
|
||||
.ReturnsAsync(expectedValue);
|
||||
|
||||
// Act
|
||||
var (exists, value) = await HybridCacheExtensions.TryGetValueAsync<int>(_cacheMock.Object, key);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(exists);
|
||||
Assert.AreEqual(expectedValue, value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TryGetValueAsync_WhenKeyExistsButValueIsNull_ShouldReturnTrueAndNullValue()
|
||||
{
|
||||
// Arrange
|
||||
string key = "test-key";
|
||||
|
||||
_cacheMock
|
||||
.Setup(cache => cache.GetOrCreateAsync(
|
||||
key,
|
||||
null!,
|
||||
It.IsAny<Func<object, CancellationToken, ValueTask<object>>>(),
|
||||
It.IsAny<HybridCacheEntryOptions>(),
|
||||
null,
|
||||
CancellationToken.None))
|
||||
.ReturnsAsync(null!);
|
||||
|
||||
// Act
|
||||
var (exists, value) = await HybridCacheExtensions.TryGetValueAsync<int?>(_cacheMock.Object, key);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(exists);
|
||||
Assert.IsNull(value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TryGetValueAsync_WhenKeyDoesNotExist_ShouldReturnFalseAndNull()
|
||||
{
|
||||
// Arrange
|
||||
string key = "test-key";
|
||||
|
||||
_cacheMock.Setup(cache => cache.GetOrCreateAsync(
|
||||
key,
|
||||
null,
|
||||
It.IsAny<Func<object?, CancellationToken, ValueTask<string>>>(),
|
||||
It.IsAny<HybridCacheEntryOptions>(),
|
||||
null,
|
||||
CancellationToken.None))
|
||||
.Returns((
|
||||
string key,
|
||||
object? state,
|
||||
Func<object?, CancellationToken, ValueTask<string>> factory,
|
||||
HybridCacheEntryOptions? options,
|
||||
IEnumerable<string>? tags,
|
||||
CancellationToken token) =>
|
||||
{
|
||||
return factory(state, token);
|
||||
});
|
||||
|
||||
// Act
|
||||
var (exists, value) = await HybridCacheExtensions.TryGetValueAsync<string>(_cacheMock.Object, key);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(exists);
|
||||
Assert.IsNull(value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user