Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breaking change: Blazor StateManager does not use the provided timeout parameter #3910

Merged
merged 15 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Source/Csla.AspNetCore/Blazor/State/SessionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ public void PurgeSessions(TimeSpan expiration)
}

// wasm client-side methods
Task<Session> ISessionManager.RetrieveSession() => throw new NotImplementedException();
Task<Session> ISessionManager.RetrieveSession(TimeSpan timeout) => throw new NotImplementedException();
Session ISessionManager.GetCachedSession() => throw new NotImplementedException();
Task ISessionManager.SendSession() => throw new NotImplementedException();
Task ISessionManager.SendSession(TimeSpan timeout) => throw new NotImplementedException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<IsPackable>false</IsPackable>
<ApplicationIcon />
<OutputType>Library</OutputType>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.3.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.3.1" />
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NSubstitute" Version="5.1.0" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)'=='netcoreapp3.1'">
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Csla.AspNetCore\Csla.AspNetCore.csproj" />
<ProjectReference Include="..\Csla.Blazor.WebAssembly\Csla.Blazor.WebAssembly.csproj" />
<ProjectReference Include="..\Csla.Blazor\Csla.Blazor.csproj" />
<ProjectReference Include="..\Csla.TestHelpers\Csla.TestHelpers.csproj" />
<ProjectReference Include="..\Csla\Csla.csproj" />
</ItemGroup>

</Project>
201 changes: 201 additions & 0 deletions Source/Csla.Blazor.WebAssembly.Tests/SessionManagerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Threading;
using System.Threading.Tasks;
using Csla.Blazor.WebAssembly.State;
using Csla.State;
using System.Net.Http;
using Csla.Blazor.WebAssembly.Configuration;
using Csla.Core;
using Csla.Runtime;
using System.Net;
using Csla.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using Csla.Serialization.Mobile;
using Microsoft.AspNetCore.Components.Authorization;
using NSubstitute;

namespace Csla.Test.State
{
[TestClass]
public class SessionManagerTests
{
private SessionManager _sessionManager;
private SessionMessage _sessionValue;

[TestInitialize]
public void Initialize()
{
var mockServiceProvider = Substitute.For<IServiceProvider>();

// Mock AuthenticationStateProvider
var mockAuthStateProvider = Substitute.For<AuthenticationStateProvider>();

// Mock IServiceProvider
mockServiceProvider.GetService(typeof(AuthenticationStateProvider)).Returns(mockAuthStateProvider);

_sessionValue = new SessionMessage
{
// Set properties here
// For example:
Principal = new Security.CslaClaimsPrincipal() { },
Session = []
};

// Mock ISerializationFormatter
var mockFormatter = Substitute.For<ISerializationFormatter>();
mockFormatter.Serialize(Arg.Any<Stream>(), Arg.Any<object>());
mockFormatter.Deserialize(Arg.Any<Stream>()).Returns(_sessionValue);

// Mock IServiceProvider
mockServiceProvider.GetService(typeof(Csla.Serialization.Mobile.MobileFormatter)).Returns(mockFormatter);

var mockActivator = Substitute.For<Csla.Server.IDataPortalActivator>();
mockActivator.CreateInstance(Arg.Is<Type>(t => t == typeof(Csla.Serialization.Mobile.MobileFormatter))).Returns(mockFormatter);
mockActivator.InitializeInstance(Arg.Any<object>());

// Mock IServiceProvider
luizfbicalho marked this conversation as resolved.
Show resolved Hide resolved
mockServiceProvider.GetService(typeof(Csla.Server.IDataPortalActivator)).Returns(mockActivator);

// Mock IContextManager
var mockContextManager = Substitute.For<IContextManager>();
mockContextManager.IsValid.Returns(true);

// Mock IContextManagerLocal
var mockLocalContextManager = Substitute.For<IContextManagerLocal>();

// Mock IServiceProvider
mockServiceProvider.GetService(typeof(IRuntimeInfo)).Returns(new RuntimeInfo());

// Mock IEnumerable<IContextManager>
var mockContextManagerList = new List<IContextManager> { mockContextManager };

// Mock ApplicationContextAccessor
var mockApplicationContextAccessor = Substitute.For<ApplicationContextAccessor>(mockContextManagerList, mockLocalContextManager, mockServiceProvider);

var _applicationContext = new ApplicationContext(mockApplicationContextAccessor);

_sessionManager = new SessionManager(_applicationContext, GetHttpClient(_sessionValue, _applicationContext), new BlazorWebAssemblyConfigurationOptions { SyncContextWithServer = true });
}

public class TestHttpMessageHandler(SessionMessage session, ApplicationContext _applicationContext) : HttpMessageHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var response = new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("{\"ResultStatus\":0, \"SessionData\":\"" + Convert.ToBase64String(GetSession(session, _applicationContext)) + "\"}"),
};
return Task.FromResult(response);
}
}
private static HttpClient GetHttpClient(SessionMessage session, ApplicationContext _applicationContext)
{
var handlerMock = new TestHttpMessageHandler(session,_applicationContext);
// use real http client with mocked handler here
var httpClient = new HttpClient(handlerMock)
{
BaseAddress = new Uri("http://test.com/"),
};
return httpClient;
}

private static byte[] GetSession(SessionMessage session, ApplicationContext _applicationContext)
{
var info = new MobileFormatter(_applicationContext).SerializeToDTO(session);
var ms = new MemoryStream();
new CslaBinaryWriter(_applicationContext).Write(ms, info);
ms.Position = 0;
var array = ms.ToArray();
return array;
}

[TestMethod]
public async Task RetrieveSession_WithTimeoutValue_ShouldNotThrowException()
{
var timeout = TimeSpan.FromHours(1);
var session = await _sessionManager.RetrieveSession(timeout);
Assert.AreEqual(session, _sessionValue.Session);
}

[TestMethod]
public async Task RetrieveSession_WithZeroTimeout_ShouldThrowTimeoutException()
{
var timeout = TimeSpan.Zero;
await Assert.ThrowsExceptionAsync<TimeoutException>(() => _sessionManager.RetrieveSession(timeout));
}

[TestMethod]
public async Task RetrieveSession_WithValidCancellationToken_ShouldNotThrowException()
{
var cts = new CancellationTokenSource();
var session = await _sessionManager.RetrieveSession(cts.Token);
Assert.AreEqual(session, _sessionValue.Session);
}

[TestMethod]
public async Task RetrieveSession_WithCancelledCancellationToken_ShouldThrowTaskCanceledException()
{
var cts = new CancellationTokenSource();
cts.Cancel();
await Assert.ThrowsExceptionAsync<TaskCanceledException>(() => _sessionManager.RetrieveSession(cts.Token));
}

[TestMethod]
public async Task SendSession_WithTimeoutValue_ShouldNotThrowException()
{
await _sessionManager.RetrieveSession(TimeSpan.FromHours(1));

var timeout = TimeSpan.FromHours(1);
await _sessionManager.SendSession(timeout);
Assert.IsTrue(true);
}

[TestMethod]
public async Task SendSession_WithZeroTimeout_ShouldThrowTimeoutException()
{
await _sessionManager.RetrieveSession(TimeSpan.FromHours(1));

var timeout = TimeSpan.Zero;
await Assert.ThrowsExceptionAsync<TimeoutException>(() => _sessionManager.SendSession(timeout));
}

[TestMethod]
public async Task SendSession_WithValidCancellationToken_ShouldNotThrowException()
{
await _sessionManager.RetrieveSession(TimeSpan.FromHours(1));

var cts = new CancellationTokenSource();
await _sessionManager.SendSession(cts.Token);
Assert.IsTrue(true);
}

[TestMethod]
public async Task SendSession_WithCancelledCancellationToken_ShouldThrowTaskCanceledException()
{
await _sessionManager.RetrieveSession(TimeSpan.FromHours(1));

var cts = new CancellationTokenSource();
cts.Cancel();
await Assert.ThrowsExceptionAsync<TaskCanceledException>(() => _sessionManager.SendSession(cts.Token));
}


[TestMethod]
public async Task RetrieveCachedSessionSession()
{
await _sessionManager.RetrieveSession(TimeSpan.FromHours(1));

var session = _sessionManager.GetCachedSession();
Assert.IsNotNull(session);
}
[TestMethod]
public void RetrieveNullCachedSessionSession()
{
var session = _sessionManager.GetCachedSession();
Assert.IsNull(session);
}
}
}
Loading
Loading