fixed tests and adding new sessions when it not needed

This commit is contained in:
Artemy
2026-02-22 19:34:43 +07:00
parent b1eff9c696
commit aa4c4a0685
8 changed files with 48 additions and 28 deletions
@@ -157,16 +157,6 @@ private Mock<ILogger<ProfileController>> _mockLogger = null!;
)), Times.Once);
_mockProfileService.Verify(s => s.SetNewIcon(_userId, mediaId), Times.Once);
_mockClientProxy.Verify(
c => c.SendCoreAsync("AvatarUpdated", It.Is<object?[]>(
args => args.Length == 1 &&
JObject.FromObject(args[0]!).Value<Guid>("userId") == _userId &&
JObject.FromObject(args[0]!).Value<Guid>("iconId") == mediaId
), It.IsAny<CancellationToken>()),
Times.Once,
"Hub SendAsync must be called to notify clients."
);
}
[Test]
@@ -70,7 +70,6 @@ public class ProfileController : ControllerBase
var mediaInfo = await _mediaService.UploadMediaAsync(media);
await _profileService.SetNewIcon(userId, mediaInfo.MediaId);
var iconId = mediaInfo.MediaId;
return Ok(mediaInfo);
}
+9
View File
@@ -3,6 +3,7 @@ using Govor.API.Common.Extensions;
using Govor.API.Hubs;
using Govor.Application.Services.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
@@ -13,7 +14,12 @@ var services = builder.Services;
builder.AddLogger();// Serilog
#if DEBUG
builder.Configuration.AddJsonFile("appsettings.Development.json", optional: false, reloadOnChange: true);
#else
builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
#endif
builder.Services.AddCors(options =>
{
@@ -125,6 +131,9 @@ app.UseAuthorization();
app.MapControllers();
app.Map("/server/ping",
() => new OkResult());
app.MapHub<ChatsHub>("/hubs/chats");
app.MapHub<FriendsHub>("/hubs/friends");
app.MapHub<ProfileHub>("/hubs/profiles");
+1 -1
View File
@@ -5,7 +5,7 @@
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://0.0.0.0:8080;",
"applicationUrl": "http://0.0.0.0:8080;http://localhost:7155",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
+15
View File
@@ -4,5 +4,20 @@
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"ConnectionStrings": {
"GovorDbContext": "Host=localhost;Port=5432;Database=GovorDb;Username=postgres;Password=stalcker;"
},
"UseMySql": false,
"AllowedHosts": "*",
"JwtAccessOption": {
"SecretKey": "Q89eY7zP7C4+TqLmHF4kw9xkF1E8Ru4Zpg+up9wFt9g=",
"Minutes": 10
},
"JwtRefreshOption": {
"RefreshTokenLifetimeDays": 30
},
"EncryptionOption": {
"Secret": "8B2j9kkw9xP5m7nQwE2zY3A-=Q8zP7C4+TqLZpg"
}
}
@@ -75,6 +75,7 @@ public class UserSessionRefresherTests
{
// Arrange
_sessionsRepoMock.Setup(r => r.GetByHashedRefreshTokenAsync(OldRefreshToken)).ReturnsAsync(_session);
_jwtTokenHasherMock.Setup(h => h.HashToken(It.IsAny<string>())).Returns(OldRefreshToken);
_usersRepoMock.Setup(r => r.FindByIdAsync(_user.Id)).ReturnsAsync(_user);
_jwtServiceMock.Setup(j => j.GenerateAccessTokenAsync(_user, _session.Id)).ReturnsAsync(NewAccessToken);
_jwtServiceMock.Setup(j => j.GenerateRefreshTokenAsync(_user)).ReturnsAsync(NewRefreshToken);
@@ -83,15 +84,21 @@ public class UserSessionRefresherTests
var result = await _refresher.RefreshTokenAsync(OldRefreshToken);
// Assert
Assert.Multiple(() =>
{
Assert.That(result.accessToken, Is.EqualTo(NewAccessToken));
Assert.That(result.refreshToken, Is.EqualTo(NewRefreshToken));
Assert.That(_session.IsRevoked, Is.True);
});
_sessionsRepoMock.Verify(r => r.UpdateAsync(_session), Times.Once);
_sessionsRepoMock.Verify(r => r.AddAsync(It.Is<UserSession>(s =>
_sessionsRepoMock.Verify(
r => r.UpdateAsync(
It.Is<UserSession>(s =>
s.Id == _session.Id &&
s.UserId == _user.Id &&
s.RefreshTokenHash == NewRefreshToken &&
s.DeviceInfo == _session.DeviceInfo)), Times.Once);
s.IsRevoked == false
)),
Times.Once);
_sessionsRepoMock.Verify(r => r.AddAsync(It.IsAny<UserSession>()), Times.Never);
}
[Test]
@@ -100,6 +107,7 @@ public class UserSessionRefresherTests
// Arrange
_session.IsRevoked = true;
_sessionsRepoMock.Setup(r => r.GetByHashedRefreshTokenAsync(OldRefreshToken)).ReturnsAsync(_session);
_jwtTokenHasherMock.Setup(h => h.HashToken(It.IsAny<string>())).Returns(OldRefreshToken);
// Act & Assert
var ex = Assert.ThrowsAsync<UnauthorizedAccessException>(async () =>
@@ -114,6 +122,7 @@ public class UserSessionRefresherTests
// Arrange
_session.ExpiresAt = DateTime.UtcNow.AddMinutes(-1);
_sessionsRepoMock.Setup(r => r.GetByHashedRefreshTokenAsync(OldRefreshToken)).ReturnsAsync(_session);
_jwtTokenHasherMock.Setup(h => h.HashToken(It.IsAny<string>())).Returns(OldRefreshToken);
// Act & Assert
var ex = Assert.ThrowsAsync<UnauthorizedAccessException>(async () =>
@@ -128,6 +137,7 @@ public class UserSessionRefresherTests
// Arrange
_sessionsRepoMock.Setup(r => r.GetByHashedRefreshTokenAsync(OldRefreshToken))
.ThrowsAsync(new NotFoundByKeyException<string>("token", OldRefreshToken));
_jwtTokenHasherMock.Setup(h => h.HashToken(It.IsAny<string>())).Returns(OldRefreshToken);
// Act & Assert
var ex = Assert.ThrowsAsync<UnauthorizedAccessException>(async () =>
await _refresher.RefreshTokenAsync(OldRefreshToken));
@@ -38,14 +38,14 @@ public class UserSessionOpener : IUserSessionOpener
try
{
var sessions = await _repository.GetByUserIdAsync(user.Id);
var existingSession = sessions.FirstOrDefault(s => s.DeviceInfo == deviceInfo);
var existingSession = sessions.FirstOrDefault(s => s.DeviceInfo == deviceInfo );
if (existingSession is not null)
return await UpdateExistingSessionAsync(user, deviceInfo, existingSession);
}
catch (NotFoundByKeyException<Guid> ex)
{
_logger.LogError(ex, "Could not find session for user {userId}", user.Id);
}
return await CreateNewSessionAsync(user, deviceInfo);
@@ -39,15 +39,11 @@ public class UserSessionRefresher : IUserSessionRefresher
{
try
{
var session = await _sessionsRepository.GetByHashedRefreshTokenAsync(_jwtTokenHasher.HashToken(refreshToken));
if (session.IsRevoked || session.ExpiresAt <= DateTime.UtcNow)
throw new UnauthorizedAccessException("Refresh token is invalid or expired");
session.IsRevoked = true;
await _sessionsRepository.UpdateAsync(session);
// Find user
var user = await _usersRepository.FindByIdAsync(session.UserId);
@@ -60,6 +56,7 @@ public class UserSessionRefresher : IUserSessionRefresher
// Opening new session
var newSession = new UserSession
{
Id = session.Id,
UserId = user.Id,
RefreshTokenHash = newRefreshTokenHash,
DeviceInfo = session.DeviceInfo,
@@ -67,7 +64,7 @@ public class UserSessionRefresher : IUserSessionRefresher
ExpiresAt = DateTime.UtcNow.AddDays(_options.RefreshTokenLifetimeDays)
};
await _sessionsRepository.AddAsync(newSession);
await _sessionsRepository.UpdateAsync(newSession);
return new RefreshResult(newRefreshToken, newAccessToken);
}