Refactor project files for improved readability and structure
- Cleaned up whitespace in Directory.Build.props and Directory.Packages.props for consistency. - Reformatted project file references in PnvPanel.Api.csproj for better clarity. - Enhanced code readability in various endpoint files by adjusting line breaks and indentation. - Standardized method signatures and improved formatting in ResultExtensions and multiple endpoint classes for better maintainability.
This commit is contained in:
+56
-12
@@ -27,15 +27,28 @@ public class ApproveActivationCommandHandlerTests
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_currentUser.UserId.Returns(adminId);
|
||||
_identityService.ActivateUserAsync(request.UserId, adminId, Arg.Any<CancellationToken>()).Returns(Result.Success());
|
||||
_identityService
|
||||
.ActivateUserAsync(request.UserId, adminId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success());
|
||||
|
||||
var handler = new ApproveActivationCommandHandler(dbContext, _identityService, _notifier, _telegramNotifier, _currentUser);
|
||||
var handler = new ApproveActivationCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
_currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new ApproveActivationCommand(request.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ApproveActivationCommand(request.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(ActivationStatus.Approved, request.Status);
|
||||
await _notifier.Received(1).NotifyUserActivatedAsync(request.UserId, Arg.Any<CancellationToken>());
|
||||
await _notifier
|
||||
.Received(1)
|
||||
.NotifyUserActivatedAsync(request.UserId, Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -44,9 +57,18 @@ public class ApproveActivationCommandHandlerTests
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
_currentUser.UserId.Returns(Guid.NewGuid());
|
||||
|
||||
var handler = new ApproveActivationCommandHandler(dbContext, _identityService, _notifier, _telegramNotifier, _currentUser);
|
||||
var handler = new ApproveActivationCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
_currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new ApproveActivationCommand(Guid.NewGuid()), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ApproveActivationCommand(Guid.NewGuid()),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(ActivationErrors.NotFound, result.Error);
|
||||
@@ -63,9 +85,18 @@ public class ApproveActivationCommandHandlerTests
|
||||
|
||||
_currentUser.UserId.Returns(Guid.NewGuid());
|
||||
|
||||
var handler = new ApproveActivationCommandHandler(dbContext, _identityService, _notifier, _telegramNotifier, _currentUser);
|
||||
var handler = new ApproveActivationCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
_currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new ApproveActivationCommand(request.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ApproveActivationCommand(request.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(ActivationErrors.AlreadyDecided, result.Error);
|
||||
@@ -82,14 +113,27 @@ public class ApproveActivationCommandHandlerTests
|
||||
|
||||
_currentUser.UserId.Returns(adminId);
|
||||
var failure = Error.NotFound("User.NotFound", "Пользователь не найден.");
|
||||
_identityService.ActivateUserAsync(request.UserId, adminId, Arg.Any<CancellationToken>()).Returns(Result.Failure(failure));
|
||||
_identityService
|
||||
.ActivateUserAsync(request.UserId, adminId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Failure(failure));
|
||||
|
||||
var handler = new ApproveActivationCommandHandler(dbContext, _identityService, _notifier, _telegramNotifier, _currentUser);
|
||||
var handler = new ApproveActivationCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
_currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new ApproveActivationCommand(request.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ApproveActivationCommand(request.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(failure, result.Error);
|
||||
await _notifier.DidNotReceive().NotifyUserActivatedAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>());
|
||||
await _notifier
|
||||
.DidNotReceive()
|
||||
.NotifyUserActivatedAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>());
|
||||
}
|
||||
}
|
||||
|
||||
+12
-3
@@ -25,7 +25,10 @@ public class RejectActivationCommandHandlerTests
|
||||
|
||||
var handler = new RejectActivationCommandHandler(dbContext, _currentUser);
|
||||
|
||||
var result = await handler.Handle(new RejectActivationCommand(request.Id, "недостаточно информации"), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RejectActivationCommand(request.Id, "недостаточно информации"),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(ActivationStatus.Rejected, request.Status);
|
||||
@@ -40,7 +43,10 @@ public class RejectActivationCommandHandlerTests
|
||||
|
||||
var handler = new RejectActivationCommandHandler(dbContext, _currentUser);
|
||||
|
||||
var result = await handler.Handle(new RejectActivationCommand(Guid.NewGuid(), null), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RejectActivationCommand(Guid.NewGuid(), null),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(ActivationErrors.NotFound, result.Error);
|
||||
@@ -59,7 +65,10 @@ public class RejectActivationCommandHandlerTests
|
||||
|
||||
var handler = new RejectActivationCommandHandler(dbContext, _currentUser);
|
||||
|
||||
var result = await handler.Handle(new RejectActivationCommand(request.Id, null), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RejectActivationCommand(request.Id, null),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(ActivationErrors.AlreadyDecided, result.Error);
|
||||
|
||||
+58
-12
@@ -22,18 +22,40 @@ public class RequestActivationCommandHandlerTests
|
||||
_currentUser.UserId.Returns(userId);
|
||||
_currentUser.UserName.Returns("alice");
|
||||
|
||||
var handler = new RequestActivationCommandHandler(dbContext, _notifier, _telegramNotifier, _currentUser);
|
||||
var handler = new RequestActivationCommandHandler(
|
||||
dbContext,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
_currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new RequestActivationCommand("Please activate"), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RequestActivationCommand("Please activate"),
|
||||
CancellationToken.None
|
||||
);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal("Please activate", result.Value.Comment);
|
||||
Assert.Single(dbContext.ActivationRequests);
|
||||
await _notifier.Received(1).NotifyActivationRequestedAsync(
|
||||
Arg.Any<Guid>(), userId, "alice", "Please activate", Arg.Any<DateTimeOffset>(), Arg.Any<CancellationToken>());
|
||||
await _telegramNotifier.Received(1).NotifyAdminsActivationRequestedAsync(
|
||||
Arg.Any<Guid>(), "alice", "Please activate", Arg.Any<CancellationToken>());
|
||||
await _notifier
|
||||
.Received(1)
|
||||
.NotifyActivationRequestedAsync(
|
||||
Arg.Any<Guid>(),
|
||||
userId,
|
||||
"alice",
|
||||
"Please activate",
|
||||
Arg.Any<DateTimeOffset>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
await _telegramNotifier
|
||||
.Received(1)
|
||||
.NotifyAdminsActivationRequestedAsync(
|
||||
Arg.Any<Guid>(),
|
||||
"alice",
|
||||
"Please activate",
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -47,14 +69,30 @@ public class RequestActivationCommandHandlerTests
|
||||
_currentUser.UserId.Returns(userId);
|
||||
_currentUser.UserName.Returns("alice");
|
||||
|
||||
var handler = new RequestActivationCommandHandler(dbContext, _notifier, _telegramNotifier, _currentUser);
|
||||
var handler = new RequestActivationCommandHandler(
|
||||
dbContext,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
_currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new RequestActivationCommand(null), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RequestActivationCommand(null),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(ActivationErrors.AlreadyPending, result.Error);
|
||||
await _notifier.DidNotReceive().NotifyActivationRequestedAsync(
|
||||
Arg.Any<Guid>(), Arg.Any<Guid>(), Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<DateTimeOffset>(), Arg.Any<CancellationToken>());
|
||||
await _notifier
|
||||
.DidNotReceive()
|
||||
.NotifyActivationRequestedAsync(
|
||||
Arg.Any<Guid>(),
|
||||
Arg.Any<Guid>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<string?>(),
|
||||
Arg.Any<DateTimeOffset>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -63,9 +101,17 @@ public class RequestActivationCommandHandlerTests
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
_currentUser.UserId.Returns((Guid?)null);
|
||||
|
||||
var handler = new RequestActivationCommandHandler(dbContext, _notifier, _telegramNotifier, _currentUser);
|
||||
var handler = new RequestActivationCommandHandler(
|
||||
dbContext,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
_currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new RequestActivationCommand(null), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RequestActivationCommand(null),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(AuthErrors.Unauthorized, result.Error);
|
||||
|
||||
+36
-9
@@ -19,7 +19,12 @@ public class ListAllConfigsQueryHandlerTests
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var userId = Guid.NewGuid();
|
||||
|
||||
var node = Node.Register("node-1", new Uri("https://node1.example.com"), new NodeCredentials("admin", "protected"), null);
|
||||
var node = Node.Register(
|
||||
"node-1",
|
||||
new Uri("https://node1.example.com"),
|
||||
new NodeCredentials("admin", "protected"),
|
||||
null
|
||||
);
|
||||
var inbound = Inbound.FromRemote(node.Id, "1", VpnProtocol.Vless, "remark", 443);
|
||||
inbound.Publish("Germany", [], null);
|
||||
var config = VpnConfig.Create(userId, inbound.Id, VpnProtocol.Vless, "my-config");
|
||||
@@ -29,12 +34,16 @@ public class ListAllConfigsQueryHandlerTests
|
||||
dbContext.VpnConfigs.Add(config);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_identityService.GetUserNamesAsync(Arg.Any<IReadOnlyCollection<Guid>>(), Arg.Any<CancellationToken>())
|
||||
_identityService
|
||||
.GetUserNamesAsync(Arg.Any<IReadOnlyCollection<Guid>>(), Arg.Any<CancellationToken>())
|
||||
.Returns(new Dictionary<Guid, string> { [userId] = "alice" });
|
||||
|
||||
var handler = new ListAllConfigsQueryHandler(dbContext, _identityService);
|
||||
|
||||
var result = await handler.Handle(new ListAllConfigsQuery(1, 20, Search: null, Status: null), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ListAllConfigsQuery(1, 20, Search: null, Status: null),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
var item = Assert.Single(result.Value.Items);
|
||||
@@ -52,7 +61,12 @@ public class ListAllConfigsQueryHandlerTests
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var userId = Guid.NewGuid();
|
||||
|
||||
var node = Node.Register("node-1", new Uri("https://node1.example.com"), new NodeCredentials("admin", "protected"), null);
|
||||
var node = Node.Register(
|
||||
"node-1",
|
||||
new Uri("https://node1.example.com"),
|
||||
new NodeCredentials("admin", "protected"),
|
||||
null
|
||||
);
|
||||
var inbound = Inbound.FromRemote(node.Id, "1", VpnProtocol.Vless, "remark", 443);
|
||||
var matching = VpnConfig.Create(userId, inbound.Id, VpnProtocol.Vless, "phone-config");
|
||||
var other = VpnConfig.Create(userId, inbound.Id, VpnProtocol.Vless, "laptop-config");
|
||||
@@ -62,12 +76,16 @@ public class ListAllConfigsQueryHandlerTests
|
||||
dbContext.VpnConfigs.AddRange(matching, other);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_identityService.GetUserNamesAsync(Arg.Any<IReadOnlyCollection<Guid>>(), Arg.Any<CancellationToken>())
|
||||
_identityService
|
||||
.GetUserNamesAsync(Arg.Any<IReadOnlyCollection<Guid>>(), Arg.Any<CancellationToken>())
|
||||
.Returns(new Dictionary<Guid, string> { [userId] = "alice" });
|
||||
|
||||
var handler = new ListAllConfigsQueryHandler(dbContext, _identityService);
|
||||
|
||||
var result = await handler.Handle(new ListAllConfigsQuery(1, 20, Search: "phone", Status: null), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ListAllConfigsQuery(1, 20, Search: "phone", Status: null),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
var item = Assert.Single(result.Value.Items);
|
||||
@@ -80,7 +98,12 @@ public class ListAllConfigsQueryHandlerTests
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var userId = Guid.NewGuid();
|
||||
|
||||
var node = Node.Register("node-1", new Uri("https://node1.example.com"), new NodeCredentials("admin", "protected"), null);
|
||||
var node = Node.Register(
|
||||
"node-1",
|
||||
new Uri("https://node1.example.com"),
|
||||
new NodeCredentials("admin", "protected"),
|
||||
null
|
||||
);
|
||||
var inbound = Inbound.FromRemote(node.Id, "1", VpnProtocol.Vless, "remark", 443);
|
||||
var active = VpnConfig.Create(userId, inbound.Id, VpnProtocol.Vless, "active-config");
|
||||
var revoked = VpnConfig.Create(userId, inbound.Id, VpnProtocol.Vless, "revoked-config");
|
||||
@@ -91,12 +114,16 @@ public class ListAllConfigsQueryHandlerTests
|
||||
dbContext.VpnConfigs.AddRange(active, revoked);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_identityService.GetUserNamesAsync(Arg.Any<IReadOnlyCollection<Guid>>(), Arg.Any<CancellationToken>())
|
||||
_identityService
|
||||
.GetUserNamesAsync(Arg.Any<IReadOnlyCollection<Guid>>(), Arg.Any<CancellationToken>())
|
||||
.Returns(new Dictionary<Guid, string> { [userId] = "alice" });
|
||||
|
||||
var handler = new ListAllConfigsQueryHandler(dbContext, _identityService);
|
||||
|
||||
var result = await handler.Handle(new ListAllConfigsQuery(1, 20, Search: null, Status: ConfigStatus.Revoked), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ListAllConfigsQuery(1, 20, Search: null, Status: ConfigStatus.Revoked),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
var item = Assert.Single(result.Value.Items);
|
||||
|
||||
+43
-7
@@ -21,9 +21,20 @@ public class RegisterNodeCommandHandlerTests
|
||||
_gateway.ValidateBaseAddress(Arg.Any<Uri>()).Returns(Result.Success());
|
||||
_secretProtector.Protect("secret-password").Returns("protected-secret-password");
|
||||
|
||||
var handler = new RegisterNodeCommandHandler(dbContext, _gateway, _secretProtector, _currentUser);
|
||||
var handler = new RegisterNodeCommandHandler(
|
||||
dbContext,
|
||||
_gateway,
|
||||
_secretProtector,
|
||||
_currentUser
|
||||
);
|
||||
|
||||
var command = new RegisterNodeCommand("node-1", "https://node1.example.com", "admin", "secret-password", "eu-west");
|
||||
var command = new RegisterNodeCommand(
|
||||
"node-1",
|
||||
"https://node1.example.com",
|
||||
"admin",
|
||||
"secret-password",
|
||||
"eu-west"
|
||||
);
|
||||
|
||||
var result = await handler.Handle(command, CancellationToken.None);
|
||||
|
||||
@@ -31,7 +42,10 @@ public class RegisterNodeCommandHandlerTests
|
||||
Assert.Equal("node-1", result.Value.Name);
|
||||
Assert.Equal("admin", result.Value.Username);
|
||||
Assert.Single(dbContext.Nodes.Local);
|
||||
Assert.Equal("protected-secret-password", dbContext.Nodes.Local.Single().Credentials.ProtectedPassword);
|
||||
Assert.Equal(
|
||||
"protected-secret-password",
|
||||
dbContext.Nodes.Local.Single().Credentials.ProtectedPassword
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -39,9 +53,20 @@ public class RegisterNodeCommandHandlerTests
|
||||
{
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
|
||||
var handler = new RegisterNodeCommandHandler(dbContext, _gateway, _secretProtector, _currentUser);
|
||||
var handler = new RegisterNodeCommandHandler(
|
||||
dbContext,
|
||||
_gateway,
|
||||
_secretProtector,
|
||||
_currentUser
|
||||
);
|
||||
|
||||
var command = new RegisterNodeCommand("node-1", "not-a-uri", "admin", "secret-password", null);
|
||||
var command = new RegisterNodeCommand(
|
||||
"node-1",
|
||||
"not-a-uri",
|
||||
"admin",
|
||||
"secret-password",
|
||||
null
|
||||
);
|
||||
|
||||
var result = await handler.Handle(command, CancellationToken.None);
|
||||
|
||||
@@ -59,9 +84,20 @@ public class RegisterNodeCommandHandlerTests
|
||||
var error = Error.Validation("Nodes.SchemeNotAllowed", "Разрешён только HTTPS.");
|
||||
_gateway.ValidateBaseAddress(Arg.Any<Uri>()).Returns(Result.Failure(error));
|
||||
|
||||
var handler = new RegisterNodeCommandHandler(dbContext, _gateway, _secretProtector, _currentUser);
|
||||
var handler = new RegisterNodeCommandHandler(
|
||||
dbContext,
|
||||
_gateway,
|
||||
_secretProtector,
|
||||
_currentUser
|
||||
);
|
||||
|
||||
var command = new RegisterNodeCommand("node-1", "http://node1.example.com", "admin", "secret-password", null);
|
||||
var command = new RegisterNodeCommand(
|
||||
"node-1",
|
||||
"http://node1.example.com",
|
||||
"admin",
|
||||
"secret-password",
|
||||
null
|
||||
);
|
||||
|
||||
var result = await handler.Handle(command, CancellationToken.None);
|
||||
|
||||
|
||||
+58
-14
@@ -25,20 +25,38 @@ public class ApproveRoleRequestCommandHandlerTests
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
var newRoleId = Guid.NewGuid();
|
||||
_roleService.CreateRoleAsync("premium", 10, 5, Arg.Any<CancellationToken>())
|
||||
_roleService
|
||||
.CreateRoleAsync("premium", 10, 5, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success(new RoleDto(newRoleId, "premium", 10, 5, false)));
|
||||
_roleService.ChangeUserRoleAsync(userId, newRoleId, Arg.Any<CancellationToken>()).Returns(Result.Success());
|
||||
_roleService
|
||||
.ChangeUserRoleAsync(userId, newRoleId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success());
|
||||
|
||||
var currentUser = FakeCurrentUser.Authenticated(Guid.NewGuid(), "admin");
|
||||
var handler = new ApproveRoleRequestCommandHandler(dbContext, _roleService, _notifier, _telegramNotifier, currentUser);
|
||||
var handler = new ApproveRoleRequestCommandHandler(
|
||||
dbContext,
|
||||
_roleService,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new ApproveRoleRequestCommand(ticket.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ApproveRoleRequestCommand(ticket.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(TicketStatus.Resolved, ticket.Status);
|
||||
await _roleService.Received(1).CreateRoleAsync("premium", 10, 5, Arg.Any<CancellationToken>());
|
||||
await _roleService.Received(1).ChangeUserRoleAsync(userId, newRoleId, Arg.Any<CancellationToken>());
|
||||
await _telegramNotifier.Received(1).NotifyUserAsync(userId, Arg.Any<string>(), Arg.Any<CancellationToken>());
|
||||
await _roleService
|
||||
.Received(1)
|
||||
.CreateRoleAsync("premium", 10, 5, Arg.Any<CancellationToken>());
|
||||
await _roleService
|
||||
.Received(1)
|
||||
.ChangeUserRoleAsync(userId, newRoleId, Arg.Any<CancellationToken>());
|
||||
await _telegramNotifier
|
||||
.Received(1)
|
||||
.NotifyUserAsync(userId, Arg.Any<string>(), Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -51,16 +69,33 @@ public class ApproveRoleRequestCommandHandlerTests
|
||||
dbContext.SupportTickets.Add(ticket);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_roleService.ChangeUserRoleAsync(userId, roleId, Arg.Any<CancellationToken>()).Returns(Result.Success());
|
||||
_roleService
|
||||
.ChangeUserRoleAsync(userId, roleId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success());
|
||||
|
||||
var currentUser = FakeCurrentUser.Authenticated(Guid.NewGuid());
|
||||
var handler = new ApproveRoleRequestCommandHandler(dbContext, _roleService, _notifier, _telegramNotifier, currentUser);
|
||||
var handler = new ApproveRoleRequestCommandHandler(
|
||||
dbContext,
|
||||
_roleService,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new ApproveRoleRequestCommand(ticket.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ApproveRoleRequestCommand(ticket.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
await _roleService.DidNotReceive().CreateRoleAsync(
|
||||
Arg.Any<string>(), Arg.Any<int>(), Arg.Any<int>(), Arg.Any<CancellationToken>());
|
||||
await _roleService
|
||||
.DidNotReceive()
|
||||
.CreateRoleAsync(
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<int>(),
|
||||
Arg.Any<int>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -72,9 +107,18 @@ public class ApproveRoleRequestCommandHandlerTests
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
var currentUser = FakeCurrentUser.Authenticated(Guid.NewGuid());
|
||||
var handler = new ApproveRoleRequestCommandHandler(dbContext, _roleService, _notifier, _telegramNotifier, currentUser);
|
||||
var handler = new ApproveRoleRequestCommandHandler(
|
||||
dbContext,
|
||||
_roleService,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new ApproveRoleRequestCommand(ticket.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ApproveRoleRequestCommand(ticket.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(SupportErrors.NotRoleRequest, result.Error);
|
||||
|
||||
+132
-29
@@ -18,7 +18,9 @@ public class BlockUserCommandHandlerTests
|
||||
private readonly IRealtimeNotifier _notifier = Substitute.For<IRealtimeNotifier>();
|
||||
private readonly ITelegramNotifier _telegramNotifier = Substitute.For<ITelegramNotifier>();
|
||||
private readonly ICurrentUser _currentUser = Substitute.For<ICurrentUser>();
|
||||
private readonly ILogger<BlockUserCommandHandler> _logger = Substitute.For<ILogger<BlockUserCommandHandler>>();
|
||||
private readonly ILogger<BlockUserCommandHandler> _logger = Substitute.For<
|
||||
ILogger<BlockUserCommandHandler>
|
||||
>();
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_IdentityServiceFails_ReturnsFailureWithoutTouchingConfigs()
|
||||
@@ -26,17 +28,35 @@ public class BlockUserCommandHandlerTests
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var userId = Guid.NewGuid();
|
||||
var failure = UserErrors.NotFound;
|
||||
_identityService.BlockUserAsync(userId, Arg.Any<CancellationToken>()).Returns(Result.Failure(failure));
|
||||
_identityService
|
||||
.BlockUserAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Failure(failure));
|
||||
|
||||
var handler = new BlockUserCommandHandler(dbContext, _identityService, _gateway, _notifier, _telegramNotifier, _currentUser, _logger);
|
||||
var handler = new BlockUserCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_gateway,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
_currentUser,
|
||||
_logger
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new BlockUserCommand(userId), CancellationToken.None);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(failure, result.Error);
|
||||
await _gateway.DidNotReceive().UpdateClientAsync(
|
||||
Arg.Any<Node>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<VpnProtocol>(),
|
||||
Arg.Any<string>(), Arg.Any<bool>(), Arg.Any<CancellationToken>());
|
||||
await _gateway
|
||||
.DidNotReceive()
|
||||
.UpdateClientAsync(
|
||||
Arg.Any<Node>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<VpnProtocol>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<bool>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -46,7 +66,12 @@ public class BlockUserCommandHandlerTests
|
||||
var userId = Guid.NewGuid();
|
||||
var adminId = Guid.NewGuid();
|
||||
|
||||
var node = Node.Register("node-1", new Uri("https://node1.example.com"), new NodeCredentials("admin", "protected"), null);
|
||||
var node = Node.Register(
|
||||
"node-1",
|
||||
new Uri("https://node1.example.com"),
|
||||
new NodeCredentials("admin", "protected"),
|
||||
null
|
||||
);
|
||||
var inbound = Inbound.FromRemote(node.Id, "1", VpnProtocol.Vless, "remark", 443);
|
||||
var config = VpnConfig.Create(userId, inbound.Id, VpnProtocol.Vless, "my-config");
|
||||
|
||||
@@ -55,24 +80,56 @@ public class BlockUserCommandHandlerTests
|
||||
dbContext.VpnConfigs.Add(config);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_identityService.BlockUserAsync(userId, Arg.Any<CancellationToken>()).Returns(Result.Success());
|
||||
_identityService
|
||||
.BlockUserAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success());
|
||||
_currentUser.UserId.Returns(adminId);
|
||||
_gateway.UpdateClientAsync(
|
||||
Arg.Any<Node>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<VpnProtocol>(),
|
||||
Arg.Any<string>(), Arg.Any<bool>(), Arg.Any<CancellationToken>())
|
||||
_gateway
|
||||
.UpdateClientAsync(
|
||||
Arg.Any<Node>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<VpnProtocol>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<bool>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
)
|
||||
.Returns(Result.Success());
|
||||
|
||||
var handler = new BlockUserCommandHandler(dbContext, _identityService, _gateway, _notifier, _telegramNotifier, _currentUser, _logger);
|
||||
var handler = new BlockUserCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_gateway,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
_currentUser,
|
||||
_logger
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new BlockUserCommand(userId), CancellationToken.None);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(ConfigStatus.Disabled, config.Status);
|
||||
|
||||
await _gateway.Received(1).UpdateClientAsync(
|
||||
Arg.Is<Node>(n => n.Id == node.Id), inbound.RemoteInboundId, config.ClientExternalId, config.Protocol,
|
||||
"my-config", enable: false, Arg.Any<CancellationToken>());
|
||||
await _notifier.Received(1).NotifyConfigStatusChangedAsync(userId, config.Id, ConfigStatus.Disabled, Arg.Any<CancellationToken>());
|
||||
await _gateway
|
||||
.Received(1)
|
||||
.UpdateClientAsync(
|
||||
Arg.Is<Node>(n => n.Id == node.Id),
|
||||
inbound.RemoteInboundId,
|
||||
config.ClientExternalId,
|
||||
config.Protocol,
|
||||
"my-config",
|
||||
enable: false,
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
await _notifier
|
||||
.Received(1)
|
||||
.NotifyConfigStatusChangedAsync(
|
||||
userId,
|
||||
config.Id,
|
||||
ConfigStatus.Disabled,
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
|
||||
var audit = Assert.Single(dbContext.AuditLogs.Local);
|
||||
Assert.Equal("UserBlocked", audit.Action);
|
||||
@@ -85,17 +142,35 @@ public class BlockUserCommandHandlerTests
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var userId = Guid.NewGuid();
|
||||
|
||||
_identityService.BlockUserAsync(userId, Arg.Any<CancellationToken>()).Returns(Result.Success());
|
||||
_identityService
|
||||
.BlockUserAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success());
|
||||
_currentUser.UserId.Returns(Guid.NewGuid());
|
||||
|
||||
var handler = new BlockUserCommandHandler(dbContext, _identityService, _gateway, _notifier, _telegramNotifier, _currentUser, _logger);
|
||||
var handler = new BlockUserCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_gateway,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
_currentUser,
|
||||
_logger
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new BlockUserCommand(userId), CancellationToken.None);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
await _gateway.DidNotReceive().UpdateClientAsync(
|
||||
Arg.Any<Node>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<VpnProtocol>(),
|
||||
Arg.Any<string>(), Arg.Any<bool>(), Arg.Any<CancellationToken>());
|
||||
await _gateway
|
||||
.DidNotReceive()
|
||||
.UpdateClientAsync(
|
||||
Arg.Any<Node>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<VpnProtocol>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<bool>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -105,7 +180,12 @@ public class BlockUserCommandHandlerTests
|
||||
var userId = Guid.NewGuid();
|
||||
var adminId = Guid.NewGuid();
|
||||
|
||||
var node = Node.Register("node-1", new Uri("https://node1.example.com"), new NodeCredentials("admin", "protected"), null);
|
||||
var node = Node.Register(
|
||||
"node-1",
|
||||
new Uri("https://node1.example.com"),
|
||||
new NodeCredentials("admin", "protected"),
|
||||
null
|
||||
);
|
||||
var inbound = Inbound.FromRemote(node.Id, "1", VpnProtocol.Vless, "remark", 443);
|
||||
var config = VpnConfig.Create(userId, inbound.Id, VpnProtocol.Vless, "my-config");
|
||||
|
||||
@@ -114,20 +194,43 @@ public class BlockUserCommandHandlerTests
|
||||
dbContext.VpnConfigs.Add(config);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_identityService.BlockUserAsync(userId, Arg.Any<CancellationToken>()).Returns(Result.Success());
|
||||
_identityService
|
||||
.BlockUserAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success());
|
||||
_currentUser.UserId.Returns(adminId);
|
||||
_gateway.UpdateClientAsync(
|
||||
Arg.Any<Node>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<VpnProtocol>(),
|
||||
Arg.Any<string>(), Arg.Any<bool>(), Arg.Any<CancellationToken>())
|
||||
_gateway
|
||||
.UpdateClientAsync(
|
||||
Arg.Any<Node>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<VpnProtocol>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<bool>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
)
|
||||
.Returns(Result.Failure(Error.Failure("Xui.UpdateClientFailed", "Нода недоступна.")));
|
||||
|
||||
var handler = new BlockUserCommandHandler(dbContext, _identityService, _gateway, _notifier, _telegramNotifier, _currentUser, _logger);
|
||||
var handler = new BlockUserCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_gateway,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
_currentUser,
|
||||
_logger
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new BlockUserCommand(userId), CancellationToken.None);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(ConfigStatus.Active, config.Status);
|
||||
await _notifier.DidNotReceive().NotifyConfigStatusChangedAsync(
|
||||
Arg.Any<Guid>(), Arg.Any<Guid>(), Arg.Any<ConfigStatus>(), Arg.Any<CancellationToken>());
|
||||
await _notifier
|
||||
.DidNotReceive()
|
||||
.NotifyConfigStatusChangedAsync(
|
||||
Arg.Any<Guid>(),
|
||||
Arg.Any<Guid>(),
|
||||
Arg.Any<ConfigStatus>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+17
-5
@@ -19,14 +19,21 @@ public class ChangeUserRoleCommandHandlerTests
|
||||
|
||||
var userId = Guid.NewGuid();
|
||||
var roleId = Guid.NewGuid();
|
||||
_roleService.ChangeUserRoleAsync(userId, roleId, Arg.Any<CancellationToken>()).Returns(Result.Success());
|
||||
_roleService
|
||||
.ChangeUserRoleAsync(userId, roleId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success());
|
||||
|
||||
var handler = new ChangeUserRoleCommandHandler(_roleService, dbContext, _currentUser);
|
||||
|
||||
var result = await handler.Handle(new ChangeUserRoleCommand(userId, roleId), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ChangeUserRoleCommand(userId, roleId),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
await _roleService.Received(1).ChangeUserRoleAsync(userId, roleId, Arg.Any<CancellationToken>());
|
||||
await _roleService
|
||||
.Received(1)
|
||||
.ChangeUserRoleAsync(userId, roleId, Arg.Any<CancellationToken>());
|
||||
Assert.Single(dbContext.AuditLogs.Local);
|
||||
}
|
||||
|
||||
@@ -38,11 +45,16 @@ public class ChangeUserRoleCommandHandlerTests
|
||||
var userId = Guid.NewGuid();
|
||||
var roleId = Guid.NewGuid();
|
||||
var error = UserErrors.NotFound;
|
||||
_roleService.ChangeUserRoleAsync(userId, roleId, Arg.Any<CancellationToken>()).Returns(Result.Failure(error));
|
||||
_roleService
|
||||
.ChangeUserRoleAsync(userId, roleId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Failure(error));
|
||||
|
||||
var handler = new ChangeUserRoleCommandHandler(_roleService, dbContext, _currentUser);
|
||||
|
||||
var result = await handler.Handle(new ChangeUserRoleCommand(userId, roleId), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ChangeUserRoleCommand(userId, roleId),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(error, result.Error);
|
||||
|
||||
+75
-15
@@ -24,13 +24,21 @@ public class DeleteUserCommandHandlerTests
|
||||
var adminId = Guid.NewGuid();
|
||||
_currentUser.UserId.Returns(adminId);
|
||||
|
||||
var handler = new DeleteUserCommandHandler(dbContext, _identityService, _gateway, _telegramNotifier, _currentUser);
|
||||
var handler = new DeleteUserCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_gateway,
|
||||
_telegramNotifier,
|
||||
_currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new DeleteUserCommand(adminId), CancellationToken.None);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(UserErrors.CannotDeleteSelf, result.Error);
|
||||
await _identityService.DidNotReceive().DeleteUserAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>());
|
||||
await _identityService
|
||||
.DidNotReceive()
|
||||
.DeleteUserAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -40,7 +48,12 @@ public class DeleteUserCommandHandlerTests
|
||||
var userId = Guid.NewGuid();
|
||||
var adminId = Guid.NewGuid();
|
||||
|
||||
var node = Node.Register("node-1", new Uri("https://node1.example.com"), new NodeCredentials("admin", "protected"), null);
|
||||
var node = Node.Register(
|
||||
"node-1",
|
||||
new Uri("https://node1.example.com"),
|
||||
new NodeCredentials("admin", "protected"),
|
||||
null
|
||||
);
|
||||
var inbound = Inbound.FromRemote(node.Id, "1", VpnProtocol.Vless, "remark", 443);
|
||||
var config = VpnConfig.Create(userId, inbound.Id, VpnProtocol.Vless, "my-config");
|
||||
config.AssignRemoteClient("external-id");
|
||||
@@ -51,20 +64,44 @@ public class DeleteUserCommandHandlerTests
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_currentUser.UserId.Returns(adminId);
|
||||
_gateway.RemoveClientAsync(Arg.Any<Node>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<VpnProtocol>(), Arg.Any<CancellationToken>())
|
||||
_gateway
|
||||
.RemoveClientAsync(
|
||||
Arg.Any<Node>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<VpnProtocol>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
)
|
||||
.Returns(Result.Success());
|
||||
_identityService
|
||||
.DeleteUserAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success());
|
||||
_identityService.DeleteUserAsync(userId, Arg.Any<CancellationToken>()).Returns(Result.Success());
|
||||
|
||||
var handler = new DeleteUserCommandHandler(dbContext, _identityService, _gateway, _telegramNotifier, _currentUser);
|
||||
var handler = new DeleteUserCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_gateway,
|
||||
_telegramNotifier,
|
||||
_currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new DeleteUserCommand(userId), CancellationToken.None);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(ConfigStatus.Revoked, config.Status);
|
||||
|
||||
await _gateway.Received(1).RemoveClientAsync(
|
||||
Arg.Is<Node>(n => n.Id == node.Id), inbound.RemoteInboundId, "external-id", config.Protocol, Arg.Any<CancellationToken>());
|
||||
await _telegramNotifier.Received(1).NotifyUserAsync(userId, Arg.Any<string>(), Arg.Any<CancellationToken>());
|
||||
await _gateway
|
||||
.Received(1)
|
||||
.RemoveClientAsync(
|
||||
Arg.Is<Node>(n => n.Id == node.Id),
|
||||
inbound.RemoteInboundId,
|
||||
"external-id",
|
||||
config.Protocol,
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
await _telegramNotifier
|
||||
.Received(1)
|
||||
.NotifyUserAsync(userId, Arg.Any<string>(), Arg.Any<CancellationToken>());
|
||||
await _identityService.Received(1).DeleteUserAsync(userId, Arg.Any<CancellationToken>());
|
||||
|
||||
var audit = Assert.Single(dbContext.AuditLogs.Local);
|
||||
@@ -79,15 +116,30 @@ public class DeleteUserCommandHandlerTests
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var userId = Guid.NewGuid();
|
||||
_currentUser.UserId.Returns(Guid.NewGuid());
|
||||
_identityService.DeleteUserAsync(userId, Arg.Any<CancellationToken>()).Returns(Result.Success());
|
||||
_identityService
|
||||
.DeleteUserAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success());
|
||||
|
||||
var handler = new DeleteUserCommandHandler(dbContext, _identityService, _gateway, _telegramNotifier, _currentUser);
|
||||
var handler = new DeleteUserCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_gateway,
|
||||
_telegramNotifier,
|
||||
_currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new DeleteUserCommand(userId), CancellationToken.None);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
await _gateway.DidNotReceive().RemoveClientAsync(
|
||||
Arg.Any<Node>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<VpnProtocol>(), Arg.Any<CancellationToken>());
|
||||
await _gateway
|
||||
.DidNotReceive()
|
||||
.RemoveClientAsync(
|
||||
Arg.Any<Node>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<VpnProtocol>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -96,9 +148,17 @@ public class DeleteUserCommandHandlerTests
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var userId = Guid.NewGuid();
|
||||
_currentUser.UserId.Returns(Guid.NewGuid());
|
||||
_identityService.DeleteUserAsync(userId, Arg.Any<CancellationToken>()).Returns(Result.Failure(UserErrors.NotFound));
|
||||
_identityService
|
||||
.DeleteUserAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Failure(UserErrors.NotFound));
|
||||
|
||||
var handler = new DeleteUserCommandHandler(dbContext, _identityService, _gateway, _telegramNotifier, _currentUser);
|
||||
var handler = new DeleteUserCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_gateway,
|
||||
_telegramNotifier,
|
||||
_currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new DeleteUserCommand(userId), CancellationToken.None);
|
||||
|
||||
|
||||
+95
-21
@@ -17,7 +17,9 @@ public class UnblockUserCommandHandlerTests
|
||||
private readonly IXuiPanelGateway _gateway = Substitute.For<IXuiPanelGateway>();
|
||||
private readonly IRealtimeNotifier _notifier = Substitute.For<IRealtimeNotifier>();
|
||||
private readonly ICurrentUser _currentUser = Substitute.For<ICurrentUser>();
|
||||
private readonly ILogger<UnblockUserCommandHandler> _logger = Substitute.For<ILogger<UnblockUserCommandHandler>>();
|
||||
private readonly ILogger<UnblockUserCommandHandler> _logger = Substitute.For<
|
||||
ILogger<UnblockUserCommandHandler>
|
||||
>();
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_WhenUnblockSucceeds_ReEnablesDisabledConfigsAndWritesAudit()
|
||||
@@ -26,7 +28,12 @@ public class UnblockUserCommandHandlerTests
|
||||
var userId = Guid.NewGuid();
|
||||
var adminId = Guid.NewGuid();
|
||||
|
||||
var node = Node.Register("node-1", new Uri("https://node1.example.com"), new NodeCredentials("admin", "protected"), null);
|
||||
var node = Node.Register(
|
||||
"node-1",
|
||||
new Uri("https://node1.example.com"),
|
||||
new NodeCredentials("admin", "protected"),
|
||||
null
|
||||
);
|
||||
var inbound = Inbound.FromRemote(node.Id, "1", VpnProtocol.Vless, "remark", 443);
|
||||
var config = VpnConfig.Create(userId, inbound.Id, VpnProtocol.Vless, "my-config");
|
||||
config.Disable();
|
||||
@@ -37,22 +44,53 @@ public class UnblockUserCommandHandlerTests
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_currentUser.UserId.Returns(adminId);
|
||||
_identityService.UnblockUserAsync(userId, Arg.Any<CancellationToken>()).Returns(Result.Success());
|
||||
_gateway.UpdateClientAsync(
|
||||
Arg.Any<Node>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<VpnProtocol>(),
|
||||
Arg.Any<string>(), Arg.Any<bool>(), Arg.Any<CancellationToken>())
|
||||
_identityService
|
||||
.UnblockUserAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success());
|
||||
_gateway
|
||||
.UpdateClientAsync(
|
||||
Arg.Any<Node>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<VpnProtocol>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<bool>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
)
|
||||
.Returns(Result.Success());
|
||||
|
||||
var handler = new UnblockUserCommandHandler(dbContext, _identityService, _gateway, _notifier, _currentUser, _logger);
|
||||
var handler = new UnblockUserCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_gateway,
|
||||
_notifier,
|
||||
_currentUser,
|
||||
_logger
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new UnblockUserCommand(userId), CancellationToken.None);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(ConfigStatus.Active, config.Status);
|
||||
await _gateway.Received(1).UpdateClientAsync(
|
||||
node, inbound.RemoteInboundId, config.ClientExternalId, config.Protocol,
|
||||
Arg.Any<string>(), true, Arg.Any<CancellationToken>());
|
||||
await _notifier.Received(1).NotifyConfigStatusChangedAsync(userId, config.Id, ConfigStatus.Active, Arg.Any<CancellationToken>());
|
||||
await _gateway
|
||||
.Received(1)
|
||||
.UpdateClientAsync(
|
||||
node,
|
||||
inbound.RemoteInboundId,
|
||||
config.ClientExternalId,
|
||||
config.Protocol,
|
||||
Arg.Any<string>(),
|
||||
true,
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
await _notifier
|
||||
.Received(1)
|
||||
.NotifyConfigStatusChangedAsync(
|
||||
userId,
|
||||
config.Id,
|
||||
ConfigStatus.Active,
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
Assert.Single(dbContext.AuditLogs.Local);
|
||||
Assert.Equal("UserUnblocked", dbContext.AuditLogs.Local.Single().Action);
|
||||
}
|
||||
@@ -64,9 +102,18 @@ public class UnblockUserCommandHandlerTests
|
||||
var userId = Guid.NewGuid();
|
||||
var error = UserErrors.NotFound;
|
||||
|
||||
_identityService.UnblockUserAsync(userId, Arg.Any<CancellationToken>()).Returns(Result.Failure(error));
|
||||
_identityService
|
||||
.UnblockUserAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Failure(error));
|
||||
|
||||
var handler = new UnblockUserCommandHandler(dbContext, _identityService, _gateway, _notifier, _currentUser, _logger);
|
||||
var handler = new UnblockUserCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_gateway,
|
||||
_notifier,
|
||||
_currentUser,
|
||||
_logger
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new UnblockUserCommand(userId), CancellationToken.None);
|
||||
|
||||
@@ -82,7 +129,12 @@ public class UnblockUserCommandHandlerTests
|
||||
var userId = Guid.NewGuid();
|
||||
var adminId = Guid.NewGuid();
|
||||
|
||||
var node = Node.Register("node-1", new Uri("https://node1.example.com"), new NodeCredentials("admin", "protected"), null);
|
||||
var node = Node.Register(
|
||||
"node-1",
|
||||
new Uri("https://node1.example.com"),
|
||||
new NodeCredentials("admin", "protected"),
|
||||
null
|
||||
);
|
||||
var inbound = Inbound.FromRemote(node.Id, "1", VpnProtocol.Vless, "remark", 443);
|
||||
var config = VpnConfig.Create(userId, inbound.Id, VpnProtocol.Vless, "my-config");
|
||||
config.Disable();
|
||||
@@ -93,19 +145,41 @@ public class UnblockUserCommandHandlerTests
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_currentUser.UserId.Returns(adminId);
|
||||
_identityService.UnblockUserAsync(userId, Arg.Any<CancellationToken>()).Returns(Result.Success());
|
||||
_gateway.UpdateClientAsync(
|
||||
Arg.Any<Node>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<VpnProtocol>(),
|
||||
Arg.Any<string>(), Arg.Any<bool>(), Arg.Any<CancellationToken>())
|
||||
_identityService
|
||||
.UnblockUserAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success());
|
||||
_gateway
|
||||
.UpdateClientAsync(
|
||||
Arg.Any<Node>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<VpnProtocol>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<bool>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
)
|
||||
.Returns(Result.Failure(Error.Failure("Xui.UpdateClientFailed", "Нода недоступна.")));
|
||||
|
||||
var handler = new UnblockUserCommandHandler(dbContext, _identityService, _gateway, _notifier, _currentUser, _logger);
|
||||
var handler = new UnblockUserCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_gateway,
|
||||
_notifier,
|
||||
_currentUser,
|
||||
_logger
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new UnblockUserCommand(userId), CancellationToken.None);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(ConfigStatus.Disabled, config.Status);
|
||||
await _notifier.DidNotReceive().NotifyConfigStatusChangedAsync(
|
||||
Arg.Any<Guid>(), Arg.Any<Guid>(), Arg.Any<ConfigStatus>(), Arg.Any<CancellationToken>());
|
||||
await _notifier
|
||||
.DidNotReceive()
|
||||
.NotifyConfigStatusChangedAsync(
|
||||
Arg.Any<Guid>(),
|
||||
Arg.Any<Guid>(),
|
||||
Arg.Any<ConfigStatus>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+39
-11
@@ -15,29 +15,50 @@ public class ChangePasswordCommandHandlerTests
|
||||
[Fact]
|
||||
public async Task Handle_Unauthenticated_ReturnsUnauthorized()
|
||||
{
|
||||
var handler = new ChangePasswordCommandHandler(_identityService, FakeCurrentUser.Anonymous());
|
||||
var handler = new ChangePasswordCommandHandler(
|
||||
_identityService,
|
||||
FakeCurrentUser.Anonymous()
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new ChangePasswordCommand("old", "new"), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ChangePasswordCommand("old", "new"),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(AuthErrors.Unauthorized, result.Error);
|
||||
await _identityService.DidNotReceive().ChangePasswordAsync(
|
||||
Arg.Any<Guid>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<CancellationToken>());
|
||||
await _identityService
|
||||
.DidNotReceive()
|
||||
.ChangePasswordAsync(
|
||||
Arg.Any<Guid>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_Authenticated_DelegatesToIdentityService()
|
||||
{
|
||||
var userId = Guid.NewGuid();
|
||||
_identityService.ChangePasswordAsync(userId, "old-pass", "new-pass", Arg.Any<CancellationToken>())
|
||||
_identityService
|
||||
.ChangePasswordAsync(userId, "old-pass", "new-pass", Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success());
|
||||
|
||||
var handler = new ChangePasswordCommandHandler(_identityService, FakeCurrentUser.Authenticated(userId));
|
||||
var handler = new ChangePasswordCommandHandler(
|
||||
_identityService,
|
||||
FakeCurrentUser.Authenticated(userId)
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new ChangePasswordCommand("old-pass", "new-pass"), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ChangePasswordCommand("old-pass", "new-pass"),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
await _identityService.Received(1).ChangePasswordAsync(userId, "old-pass", "new-pass", Arg.Any<CancellationToken>());
|
||||
await _identityService
|
||||
.Received(1)
|
||||
.ChangePasswordAsync(userId, "old-pass", "new-pass", Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -45,12 +66,19 @@ public class ChangePasswordCommandHandlerTests
|
||||
{
|
||||
var userId = Guid.NewGuid();
|
||||
var error = Error.Validation("Auth.WrongCurrentPassword", "Текущий пароль неверен.");
|
||||
_identityService.ChangePasswordAsync(userId, "wrong", "new-pass", Arg.Any<CancellationToken>())
|
||||
_identityService
|
||||
.ChangePasswordAsync(userId, "wrong", "new-pass", Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Failure(error));
|
||||
|
||||
var handler = new ChangePasswordCommandHandler(_identityService, FakeCurrentUser.Authenticated(userId));
|
||||
var handler = new ChangePasswordCommandHandler(
|
||||
_identityService,
|
||||
FakeCurrentUser.Authenticated(userId)
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new ChangePasswordCommand("wrong", "new-pass"), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ChangePasswordCommand("wrong", "new-pass"),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(error, result.Error);
|
||||
|
||||
@@ -27,9 +27,14 @@ public class GetCurrentUserQueryHandlerTests
|
||||
public async Task Handle_ProfileMissing_ReturnsUnauthorized()
|
||||
{
|
||||
var userId = Guid.NewGuid();
|
||||
_identityService.GetProfileAsync(userId, Arg.Any<CancellationToken>()).Returns((CurrentUserProfile?)null);
|
||||
_identityService
|
||||
.GetProfileAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns((CurrentUserProfile?)null);
|
||||
|
||||
var handler = new GetCurrentUserQueryHandler(_identityService, FakeCurrentUser.Authenticated(userId));
|
||||
var handler = new GetCurrentUserQueryHandler(
|
||||
_identityService,
|
||||
FakeCurrentUser.Authenticated(userId)
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new GetCurrentUserQuery(), CancellationToken.None);
|
||||
|
||||
@@ -41,12 +46,26 @@ public class GetCurrentUserQueryHandlerTests
|
||||
public async Task Handle_AuthenticatedWithProfile_ReturnsCurrentUserDto()
|
||||
{
|
||||
var userId = Guid.NewGuid();
|
||||
var profile = new CurrentUserProfile(userId, "alice", Guid.NewGuid(), "user", true, false, 3, RoleQuota.Unlimited, "sub-token");
|
||||
var profile = new CurrentUserProfile(
|
||||
userId,
|
||||
"alice",
|
||||
Guid.NewGuid(),
|
||||
"user",
|
||||
true,
|
||||
false,
|
||||
3,
|
||||
RoleQuota.Unlimited,
|
||||
"sub-token"
|
||||
);
|
||||
_identityService.GetProfileAsync(userId, Arg.Any<CancellationToken>()).Returns(profile);
|
||||
_identityService.GetTelegramLinkInfoAsync(userId, Arg.Any<CancellationToken>())
|
||||
_identityService
|
||||
.GetTelegramLinkInfoAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(new TelegramLinkInfo(true, 42, "alice_tg"));
|
||||
|
||||
var handler = new GetCurrentUserQueryHandler(_identityService, FakeCurrentUser.Authenticated(userId, "alice"));
|
||||
var handler = new GetCurrentUserQueryHandler(
|
||||
_identityService,
|
||||
FakeCurrentUser.Authenticated(userId, "alice")
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new GetCurrentUserQuery(), CancellationToken.None);
|
||||
|
||||
|
||||
@@ -11,9 +11,11 @@ public class LoginCommandHandlerTests
|
||||
{
|
||||
private readonly IIdentityService _identityService = Substitute.For<IIdentityService>();
|
||||
private readonly IJwtTokenService _jwtTokenService = Substitute.For<IJwtTokenService>();
|
||||
private readonly IRefreshTokenService _refreshTokenService = Substitute.For<IRefreshTokenService>();
|
||||
private readonly IRefreshTokenService _refreshTokenService =
|
||||
Substitute.For<IRefreshTokenService>();
|
||||
|
||||
private LoginCommandHandler CreateHandler() => new(_identityService, _jwtTokenService, _refreshTokenService);
|
||||
private LoginCommandHandler CreateHandler() =>
|
||||
new(_identityService, _jwtTokenService, _refreshTokenService);
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_WithValidCredentials_ReturnsAuthResult()
|
||||
@@ -21,20 +23,33 @@ public class LoginCommandHandlerTests
|
||||
var userId = Guid.NewGuid();
|
||||
var authUser = new AuthenticatedUser(userId, "alice", "user");
|
||||
var profile = new CurrentUserProfile(
|
||||
userId, "alice", Guid.NewGuid(), "user", IsActivated: true, IsBlocked: false, MaxConfigs: 3,
|
||||
MaxIpLimit: RoleQuota.Unlimited, SubscriptionToken: "sub-token");
|
||||
userId,
|
||||
"alice",
|
||||
Guid.NewGuid(),
|
||||
"user",
|
||||
IsActivated: true,
|
||||
IsBlocked: false,
|
||||
MaxConfigs: 3,
|
||||
MaxIpLimit: RoleQuota.Unlimited,
|
||||
SubscriptionToken: "sub-token"
|
||||
);
|
||||
|
||||
_identityService.ValidateCredentialsAsync("alice", "P@ssw0rd", Arg.Any<CancellationToken>())
|
||||
_identityService
|
||||
.ValidateCredentialsAsync("alice", "P@ssw0rd", Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success(authUser));
|
||||
_identityService.GetProfileAsync(userId, Arg.Any<CancellationToken>()).Returns(profile);
|
||||
_identityService.GetTelegramLinkInfoAsync(userId, Arg.Any<CancellationToken>())
|
||||
_identityService
|
||||
.GetTelegramLinkInfoAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(new TelegramLinkInfo(true, 123456, "alice_tg"));
|
||||
_jwtTokenService.GenerateAccessToken(Arg.Any<AuthenticatedUser>())
|
||||
_jwtTokenService
|
||||
.GenerateAccessToken(Arg.Any<AuthenticatedUser>())
|
||||
.Returns(("access-token", DateTimeOffset.UtcNow.AddMinutes(15)));
|
||||
_refreshTokenService.IssueAsync(userId, Arg.Any<CancellationToken>())
|
||||
_refreshTokenService
|
||||
.IssueAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(new IssuedRefreshToken("refresh-token", DateTimeOffset.UtcNow.AddDays(30)));
|
||||
|
||||
var result = await CreateHandler().Handle(new LoginCommand("alice", "P@ssw0rd"), CancellationToken.None);
|
||||
var result = await CreateHandler()
|
||||
.Handle(new LoginCommand("alice", "P@ssw0rd"), CancellationToken.None);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal("access-token", result.Value.AccessToken);
|
||||
@@ -46,14 +61,18 @@ public class LoginCommandHandlerTests
|
||||
[Fact]
|
||||
public async Task Handle_WithInvalidCredentials_ReturnsFailureWithoutIssuingTokens()
|
||||
{
|
||||
_identityService.ValidateCredentialsAsync("alice", "wrong", Arg.Any<CancellationToken>())
|
||||
_identityService
|
||||
.ValidateCredentialsAsync("alice", "wrong", Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Failure<AuthenticatedUser>(AuthErrors.InvalidCredentials));
|
||||
|
||||
var result = await CreateHandler().Handle(new LoginCommand("alice", "wrong"), CancellationToken.None);
|
||||
var result = await CreateHandler()
|
||||
.Handle(new LoginCommand("alice", "wrong"), CancellationToken.None);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(AuthErrors.InvalidCredentials, result.Error);
|
||||
await _refreshTokenService.DidNotReceive().IssueAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>());
|
||||
await _refreshTokenService
|
||||
.DidNotReceive()
|
||||
.IssueAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -62,11 +81,15 @@ public class LoginCommandHandlerTests
|
||||
var userId = Guid.NewGuid();
|
||||
var authUser = new AuthenticatedUser(userId, "alice", "user");
|
||||
|
||||
_identityService.ValidateCredentialsAsync("alice", "P@ssw0rd", Arg.Any<CancellationToken>())
|
||||
_identityService
|
||||
.ValidateCredentialsAsync("alice", "P@ssw0rd", Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success(authUser));
|
||||
_identityService.GetProfileAsync(userId, Arg.Any<CancellationToken>()).Returns((CurrentUserProfile?)null);
|
||||
_identityService
|
||||
.GetProfileAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns((CurrentUserProfile?)null);
|
||||
|
||||
var result = await CreateHandler().Handle(new LoginCommand("alice", "P@ssw0rd"), CancellationToken.None);
|
||||
var result = await CreateHandler()
|
||||
.Handle(new LoginCommand("alice", "P@ssw0rd"), CancellationToken.None);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(AuthErrors.InvalidCredentials, result.Error);
|
||||
|
||||
@@ -11,27 +11,46 @@ public class RefreshCommandHandlerTests
|
||||
{
|
||||
private readonly IIdentityService _identityService = Substitute.For<IIdentityService>();
|
||||
private readonly IJwtTokenService _jwtTokenService = Substitute.For<IJwtTokenService>();
|
||||
private readonly IRefreshTokenService _refreshTokenService = Substitute.For<IRefreshTokenService>();
|
||||
private readonly IRefreshTokenService _refreshTokenService =
|
||||
Substitute.For<IRefreshTokenService>();
|
||||
|
||||
private RefreshCommandHandler CreateHandler() => new(_identityService, _jwtTokenService, _refreshTokenService);
|
||||
private RefreshCommandHandler CreateHandler() =>
|
||||
new(_identityService, _jwtTokenService, _refreshTokenService);
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_WithValidToken_RotatesAndReturnsNewAuthResult()
|
||||
{
|
||||
var userId = Guid.NewGuid();
|
||||
var profile = new CurrentUserProfile(
|
||||
userId, "alice", Guid.NewGuid(), "user", IsActivated: true, IsBlocked: false, MaxConfigs: 3,
|
||||
MaxIpLimit: RoleQuota.Unlimited, SubscriptionToken: "sub-token");
|
||||
var rotated = new RotatedRefreshToken(userId, "new-refresh-token", DateTimeOffset.UtcNow.AddDays(30));
|
||||
userId,
|
||||
"alice",
|
||||
Guid.NewGuid(),
|
||||
"user",
|
||||
IsActivated: true,
|
||||
IsBlocked: false,
|
||||
MaxConfigs: 3,
|
||||
MaxIpLimit: RoleQuota.Unlimited,
|
||||
SubscriptionToken: "sub-token"
|
||||
);
|
||||
var rotated = new RotatedRefreshToken(
|
||||
userId,
|
||||
"new-refresh-token",
|
||||
DateTimeOffset.UtcNow.AddDays(30)
|
||||
);
|
||||
|
||||
_refreshTokenService.RotateAsync("old-token", Arg.Any<CancellationToken>()).Returns(Result.Success(rotated));
|
||||
_refreshTokenService
|
||||
.RotateAsync("old-token", Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success(rotated));
|
||||
_identityService.GetProfileAsync(userId, Arg.Any<CancellationToken>()).Returns(profile);
|
||||
_identityService.GetTelegramLinkInfoAsync(userId, Arg.Any<CancellationToken>())
|
||||
_identityService
|
||||
.GetTelegramLinkInfoAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(new TelegramLinkInfo(false, null, null));
|
||||
_jwtTokenService.GenerateAccessToken(Arg.Any<AuthenticatedUser>())
|
||||
_jwtTokenService
|
||||
.GenerateAccessToken(Arg.Any<AuthenticatedUser>())
|
||||
.Returns(("new-access-token", DateTimeOffset.UtcNow.AddMinutes(15)));
|
||||
|
||||
var result = await CreateHandler().Handle(new RefreshCommand("old-token"), CancellationToken.None);
|
||||
var result = await CreateHandler()
|
||||
.Handle(new RefreshCommand("old-token"), CancellationToken.None);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal("new-access-token", result.Value.AccessToken);
|
||||
@@ -41,26 +60,39 @@ public class RefreshCommandHandlerTests
|
||||
[Fact]
|
||||
public async Task Handle_WithInvalidOrReusedToken_ReturnsFailure()
|
||||
{
|
||||
_refreshTokenService.RotateAsync("stolen-token", Arg.Any<CancellationToken>())
|
||||
_refreshTokenService
|
||||
.RotateAsync("stolen-token", Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Failure<RotatedRefreshToken>(AuthErrors.InvalidRefreshToken));
|
||||
|
||||
var result = await CreateHandler().Handle(new RefreshCommand("stolen-token"), CancellationToken.None);
|
||||
var result = await CreateHandler()
|
||||
.Handle(new RefreshCommand("stolen-token"), CancellationToken.None);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(AuthErrors.InvalidRefreshToken, result.Error);
|
||||
await _identityService.DidNotReceive().GetProfileAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>());
|
||||
await _identityService
|
||||
.DidNotReceive()
|
||||
.GetProfileAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_WhenProfileNoLongerExists_ReturnsInvalidRefreshToken()
|
||||
{
|
||||
var userId = Guid.NewGuid();
|
||||
var rotated = new RotatedRefreshToken(userId, "new-refresh-token", DateTimeOffset.UtcNow.AddDays(30));
|
||||
var rotated = new RotatedRefreshToken(
|
||||
userId,
|
||||
"new-refresh-token",
|
||||
DateTimeOffset.UtcNow.AddDays(30)
|
||||
);
|
||||
|
||||
_refreshTokenService.RotateAsync("old-token", Arg.Any<CancellationToken>()).Returns(Result.Success(rotated));
|
||||
_identityService.GetProfileAsync(userId, Arg.Any<CancellationToken>()).Returns((CurrentUserProfile?)null);
|
||||
_refreshTokenService
|
||||
.RotateAsync("old-token", Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success(rotated));
|
||||
_identityService
|
||||
.GetProfileAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns((CurrentUserProfile?)null);
|
||||
|
||||
var result = await CreateHandler().Handle(new RefreshCommand("old-token"), CancellationToken.None);
|
||||
var result = await CreateHandler()
|
||||
.Handle(new RefreshCommand("old-token"), CancellationToken.None);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(AuthErrors.InvalidRefreshToken, result.Error);
|
||||
|
||||
+50
-20
@@ -15,21 +15,37 @@ public class RequireActivationBehaviorTests
|
||||
private readonly ICurrentUser _currentUser = Substitute.For<ICurrentUser>();
|
||||
private readonly IIdentityService _identityService = Substitute.For<IIdentityService>();
|
||||
|
||||
private RequireActivationBehavior<DummyRequest, Result<string>> CreateBehavior() => new(_currentUser, _identityService);
|
||||
private RequireActivationBehavior<DummyRequest, Result<string>> CreateBehavior() =>
|
||||
new(_currentUser, _identityService);
|
||||
|
||||
private static CurrentUserProfile CreateProfile(Guid userId, bool isActivated) =>
|
||||
new(userId, "alice", Guid.NewGuid(), "user", IsActivated: isActivated, IsBlocked: false, MaxConfigs: 3,
|
||||
MaxIpLimit: RoleQuota.Unlimited, SubscriptionToken: "sub-token");
|
||||
new(
|
||||
userId,
|
||||
"alice",
|
||||
Guid.NewGuid(),
|
||||
"user",
|
||||
IsActivated: isActivated,
|
||||
IsBlocked: false,
|
||||
MaxConfigs: 3,
|
||||
MaxIpLimit: RoleQuota.Unlimited,
|
||||
SubscriptionToken: "sub-token"
|
||||
);
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_WhenActivated_CallsNext()
|
||||
{
|
||||
var userId = Guid.NewGuid();
|
||||
_currentUser.UserId.Returns(userId);
|
||||
_identityService.GetProfileAsync(userId, Arg.Any<CancellationToken>()).Returns(CreateProfile(userId, isActivated: true));
|
||||
_identityService
|
||||
.GetProfileAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(CreateProfile(userId, isActivated: true));
|
||||
|
||||
var result = await CreateBehavior().Handle(
|
||||
new DummyRequest(), () => Task.FromResult(Result.Success("ok")), CancellationToken.None);
|
||||
var result = await CreateBehavior()
|
||||
.Handle(
|
||||
new DummyRequest(),
|
||||
() => Task.FromResult(Result.Success("ok")),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal("ok", result.Value);
|
||||
@@ -40,17 +56,21 @@ public class RequireActivationBehaviorTests
|
||||
{
|
||||
var userId = Guid.NewGuid();
|
||||
_currentUser.UserId.Returns(userId);
|
||||
_identityService.GetProfileAsync(userId, Arg.Any<CancellationToken>()).Returns(CreateProfile(userId, isActivated: false));
|
||||
_identityService
|
||||
.GetProfileAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(CreateProfile(userId, isActivated: false));
|
||||
var nextCalled = false;
|
||||
|
||||
var result = await CreateBehavior().Handle(
|
||||
new DummyRequest(),
|
||||
() =>
|
||||
{
|
||||
nextCalled = true;
|
||||
return Task.FromResult(Result.Success("ok"));
|
||||
},
|
||||
CancellationToken.None);
|
||||
var result = await CreateBehavior()
|
||||
.Handle(
|
||||
new DummyRequest(),
|
||||
() =>
|
||||
{
|
||||
nextCalled = true;
|
||||
return Task.FromResult(Result.Success("ok"));
|
||||
},
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(AuthErrors.NotActivated, result.Error);
|
||||
@@ -62,8 +82,12 @@ public class RequireActivationBehaviorTests
|
||||
{
|
||||
_currentUser.UserId.Returns((Guid?)null);
|
||||
|
||||
var result = await CreateBehavior().Handle(
|
||||
new DummyRequest(), () => Task.FromResult(Result.Success("ok")), CancellationToken.None);
|
||||
var result = await CreateBehavior()
|
||||
.Handle(
|
||||
new DummyRequest(),
|
||||
() => Task.FromResult(Result.Success("ok")),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(AuthErrors.Unauthorized, result.Error);
|
||||
@@ -74,10 +98,16 @@ public class RequireActivationBehaviorTests
|
||||
{
|
||||
var userId = Guid.NewGuid();
|
||||
_currentUser.UserId.Returns(userId);
|
||||
_identityService.GetProfileAsync(userId, Arg.Any<CancellationToken>()).Returns((CurrentUserProfile?)null);
|
||||
_identityService
|
||||
.GetProfileAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns((CurrentUserProfile?)null);
|
||||
|
||||
var result = await CreateBehavior().Handle(
|
||||
new DummyRequest(), () => Task.FromResult(Result.Success("ok")), CancellationToken.None);
|
||||
var result = await CreateBehavior()
|
||||
.Handle(
|
||||
new DummyRequest(),
|
||||
() => Task.FromResult(Result.Success("ok")),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(AuthErrors.Unauthorized, result.Error);
|
||||
|
||||
+35
-6
@@ -27,16 +27,35 @@ public class GetMyConfigsQueryHandlerTests
|
||||
var activeConfig = VpnConfig.Create(userId, inbound.Id, VpnProtocol.Vless, "Active");
|
||||
var revokedConfig = VpnConfig.Create(userId, inbound.Id, VpnProtocol.Vless, "Revoked");
|
||||
revokedConfig.Revoke();
|
||||
var otherUsersConfig = VpnConfig.Create(otherUserId, inbound.Id, VpnProtocol.Vless, "Other");
|
||||
var otherUsersConfig = VpnConfig.Create(
|
||||
otherUserId,
|
||||
inbound.Id,
|
||||
VpnProtocol.Vless,
|
||||
"Other"
|
||||
);
|
||||
|
||||
dbContext.Inbounds.Add(inbound);
|
||||
dbContext.VpnConfigs.AddRange(activeConfig, revokedConfig, otherUsersConfig);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
var profile = new CurrentUserProfile(userId, "alice", Guid.NewGuid(), "user", true, false, 5, RoleQuota.Unlimited, "sub-token");
|
||||
var profile = new CurrentUserProfile(
|
||||
userId,
|
||||
"alice",
|
||||
Guid.NewGuid(),
|
||||
"user",
|
||||
true,
|
||||
false,
|
||||
5,
|
||||
RoleQuota.Unlimited,
|
||||
"sub-token"
|
||||
);
|
||||
_identityService.GetProfileAsync(userId, Arg.Any<CancellationToken>()).Returns(profile);
|
||||
|
||||
var handler = new GetMyConfigsQueryHandler(dbContext, _identityService, FakeCurrentUser.Authenticated(userId));
|
||||
var handler = new GetMyConfigsQueryHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
FakeCurrentUser.Authenticated(userId)
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new GetMyConfigsQuery(), CancellationToken.None);
|
||||
|
||||
@@ -51,7 +70,11 @@ public class GetMyConfigsQueryHandlerTests
|
||||
{
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
|
||||
var handler = new GetMyConfigsQueryHandler(dbContext, _identityService, FakeCurrentUser.Anonymous());
|
||||
var handler = new GetMyConfigsQueryHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
FakeCurrentUser.Anonymous()
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new GetMyConfigsQuery(), CancellationToken.None);
|
||||
|
||||
@@ -64,9 +87,15 @@ public class GetMyConfigsQueryHandlerTests
|
||||
{
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var userId = Guid.NewGuid();
|
||||
_identityService.GetProfileAsync(userId, Arg.Any<CancellationToken>()).Returns((CurrentUserProfile?)null);
|
||||
_identityService
|
||||
.GetProfileAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns((CurrentUserProfile?)null);
|
||||
|
||||
var handler = new GetMyConfigsQueryHandler(dbContext, _identityService, FakeCurrentUser.Authenticated(userId));
|
||||
var handler = new GetMyConfigsQueryHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
FakeCurrentUser.Authenticated(userId)
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new GetMyConfigsQuery(), CancellationToken.None);
|
||||
|
||||
|
||||
+72
-14
@@ -21,7 +21,12 @@ public class RevokeVpnConfigCommandHandlerTests
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var userId = Guid.NewGuid();
|
||||
|
||||
var node = Node.Register("node-1", new Uri("https://node1.example.com"), new NodeCredentials("admin", "protected"), null);
|
||||
var node = Node.Register(
|
||||
"node-1",
|
||||
new Uri("https://node1.example.com"),
|
||||
new NodeCredentials("admin", "protected"),
|
||||
null
|
||||
);
|
||||
var inbound = Inbound.FromRemote(node.Id, "1", VpnProtocol.Vless, "remark", 443);
|
||||
var config = VpnConfig.Create(userId, inbound.Id, VpnProtocol.Vless, null);
|
||||
config.AssignRemoteClient("external-id");
|
||||
@@ -31,15 +36,37 @@ public class RevokeVpnConfigCommandHandlerTests
|
||||
dbContext.VpnConfigs.Add(config);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
var handler = new RevokeVpnConfigCommandHandler(dbContext, _gateway, _notifier, FakeCurrentUser.Authenticated(userId));
|
||||
var handler = new RevokeVpnConfigCommandHandler(
|
||||
dbContext,
|
||||
_gateway,
|
||||
_notifier,
|
||||
FakeCurrentUser.Authenticated(userId)
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new RevokeVpnConfigCommand(config.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RevokeVpnConfigCommand(config.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(ConfigStatus.Revoked, config.Status);
|
||||
await _gateway.Received(1).RemoveClientAsync(
|
||||
Arg.Any<Node>(), inbound.RemoteInboundId, "external-id", config.Protocol, Arg.Any<CancellationToken>());
|
||||
await _notifier.Received(1).NotifyConfigStatusChangedAsync(userId, config.Id, ConfigStatus.Revoked, Arg.Any<CancellationToken>());
|
||||
await _gateway
|
||||
.Received(1)
|
||||
.RemoveClientAsync(
|
||||
Arg.Any<Node>(),
|
||||
inbound.RemoteInboundId,
|
||||
"external-id",
|
||||
config.Protocol,
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
await _notifier
|
||||
.Received(1)
|
||||
.NotifyConfigStatusChangedAsync(
|
||||
userId,
|
||||
config.Id,
|
||||
ConfigStatus.Revoked,
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -56,13 +83,28 @@ public class RevokeVpnConfigCommandHandlerTests
|
||||
dbContext.VpnConfigs.Add(config);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
var handler = new RevokeVpnConfigCommandHandler(dbContext, _gateway, _notifier, FakeCurrentUser.Authenticated(userId));
|
||||
var handler = new RevokeVpnConfigCommandHandler(
|
||||
dbContext,
|
||||
_gateway,
|
||||
_notifier,
|
||||
FakeCurrentUser.Authenticated(userId)
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new RevokeVpnConfigCommand(config.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RevokeVpnConfigCommand(config.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
await _gateway.DidNotReceive().RemoveClientAsync(
|
||||
Arg.Any<PnvPanel.Domain.Nodes.Node>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<VpnProtocol>(), Arg.Any<CancellationToken>());
|
||||
await _gateway
|
||||
.DidNotReceive()
|
||||
.RemoveClientAsync(
|
||||
Arg.Any<PnvPanel.Domain.Nodes.Node>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<VpnProtocol>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -71,9 +113,17 @@ public class RevokeVpnConfigCommandHandlerTests
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var userId = Guid.NewGuid();
|
||||
|
||||
var handler = new RevokeVpnConfigCommandHandler(dbContext, _gateway, _notifier, FakeCurrentUser.Authenticated(userId));
|
||||
var handler = new RevokeVpnConfigCommandHandler(
|
||||
dbContext,
|
||||
_gateway,
|
||||
_notifier,
|
||||
FakeCurrentUser.Authenticated(userId)
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new RevokeVpnConfigCommand(Guid.NewGuid()), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RevokeVpnConfigCommand(Guid.NewGuid()),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(ConfigErrors.NotFound, result.Error);
|
||||
@@ -84,9 +134,17 @@ public class RevokeVpnConfigCommandHandlerTests
|
||||
{
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
|
||||
var handler = new RevokeVpnConfigCommandHandler(dbContext, _gateway, _notifier, FakeCurrentUser.Anonymous());
|
||||
var handler = new RevokeVpnConfigCommandHandler(
|
||||
dbContext,
|
||||
_gateway,
|
||||
_notifier,
|
||||
FakeCurrentUser.Anonymous()
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new RevokeVpnConfigCommand(Guid.NewGuid()), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RevokeVpnConfigCommand(Guid.NewGuid()),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(PnvPanel.Application.Auth.AuthErrors.Unauthorized, result.Error);
|
||||
|
||||
+108
-23
@@ -18,16 +18,33 @@ public class RotateVpnConfigCommandHandlerTests
|
||||
private readonly IIdentityService _identityService = Substitute.For<IIdentityService>();
|
||||
|
||||
private static CurrentUserProfile MakeProfile(Guid userId) =>
|
||||
new(userId, "alice", Guid.NewGuid(), "user", true, false, 3, RoleQuota.Unlimited, "sub-token");
|
||||
new(
|
||||
userId,
|
||||
"alice",
|
||||
Guid.NewGuid(),
|
||||
"user",
|
||||
true,
|
||||
false,
|
||||
3,
|
||||
RoleQuota.Unlimited,
|
||||
"sub-token"
|
||||
);
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_WhenActiveConfigOwnedByUser_RotatesAndAddsNewClient()
|
||||
{
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var userId = Guid.NewGuid();
|
||||
_identityService.GetProfileAsync(userId, Arg.Any<CancellationToken>()).Returns(MakeProfile(userId));
|
||||
_identityService
|
||||
.GetProfileAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(MakeProfile(userId));
|
||||
|
||||
var node = Node.Register("node-1", new Uri("https://node1.example.com"), new NodeCredentials("admin", "protected"), null);
|
||||
var node = Node.Register(
|
||||
"node-1",
|
||||
new Uri("https://node1.example.com"),
|
||||
new NodeCredentials("admin", "protected"),
|
||||
null
|
||||
);
|
||||
var inbound = Inbound.FromRemote(node.Id, "1", VpnProtocol.Vless, "remark", 443);
|
||||
var config = VpnConfig.Create(userId, inbound.Id, VpnProtocol.Vless, "my-config");
|
||||
config.AssignRemoteClient("old-external-id");
|
||||
@@ -37,19 +54,41 @@ public class RotateVpnConfigCommandHandlerTests
|
||||
dbContext.VpnConfigs.Add(config);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_gateway.AddClientAsync(
|
||||
Arg.Any<Node>(), inbound.RemoteInboundId, config.Protocol, Arg.Any<string>(),
|
||||
Arg.Any<string>(), Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
_gateway
|
||||
.AddClientAsync(
|
||||
Arg.Any<Node>(),
|
||||
inbound.RemoteInboundId,
|
||||
config.Protocol,
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<int>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
)
|
||||
.Returns(Result.Success("new-external-id"));
|
||||
|
||||
var handler = new RotateVpnConfigCommandHandler(dbContext, _gateway, _identityService, FakeCurrentUser.Authenticated(userId));
|
||||
var handler = new RotateVpnConfigCommandHandler(
|
||||
dbContext,
|
||||
_gateway,
|
||||
_identityService,
|
||||
FakeCurrentUser.Authenticated(userId)
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new RotateVpnConfigCommand(config.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RotateVpnConfigCommand(config.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal("new-external-id", config.ClientExternalId);
|
||||
await _gateway.Received(1).RemoveClientAsync(
|
||||
Arg.Any<Node>(), inbound.RemoteInboundId, "old-external-id", config.Protocol, Arg.Any<CancellationToken>());
|
||||
await _gateway
|
||||
.Received(1)
|
||||
.RemoveClientAsync(
|
||||
Arg.Any<Node>(),
|
||||
inbound.RemoteInboundId,
|
||||
"old-external-id",
|
||||
config.Protocol,
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -58,9 +97,17 @@ public class RotateVpnConfigCommandHandlerTests
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var userId = Guid.NewGuid();
|
||||
|
||||
var handler = new RotateVpnConfigCommandHandler(dbContext, _gateway, _identityService, FakeCurrentUser.Authenticated(userId));
|
||||
var handler = new RotateVpnConfigCommandHandler(
|
||||
dbContext,
|
||||
_gateway,
|
||||
_identityService,
|
||||
FakeCurrentUser.Authenticated(userId)
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new RotateVpnConfigCommand(Guid.NewGuid()), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RotateVpnConfigCommand(Guid.NewGuid()),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(ConfigErrors.NotFound, result.Error);
|
||||
@@ -80,9 +127,17 @@ public class RotateVpnConfigCommandHandlerTests
|
||||
dbContext.VpnConfigs.Add(config);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
var handler = new RotateVpnConfigCommandHandler(dbContext, _gateway, _identityService, FakeCurrentUser.Authenticated(otherUserId));
|
||||
var handler = new RotateVpnConfigCommandHandler(
|
||||
dbContext,
|
||||
_gateway,
|
||||
_identityService,
|
||||
FakeCurrentUser.Authenticated(otherUserId)
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new RotateVpnConfigCommand(config.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RotateVpnConfigCommand(config.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(ConfigErrors.NotFound, result.Error);
|
||||
@@ -102,9 +157,17 @@ public class RotateVpnConfigCommandHandlerTests
|
||||
dbContext.VpnConfigs.Add(config);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
var handler = new RotateVpnConfigCommandHandler(dbContext, _gateway, _identityService, FakeCurrentUser.Authenticated(userId));
|
||||
var handler = new RotateVpnConfigCommandHandler(
|
||||
dbContext,
|
||||
_gateway,
|
||||
_identityService,
|
||||
FakeCurrentUser.Authenticated(userId)
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new RotateVpnConfigCommand(config.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RotateVpnConfigCommand(config.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(ConfigErrors.NotFound, result.Error);
|
||||
@@ -115,9 +178,16 @@ public class RotateVpnConfigCommandHandlerTests
|
||||
{
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var userId = Guid.NewGuid();
|
||||
_identityService.GetProfileAsync(userId, Arg.Any<CancellationToken>()).Returns(MakeProfile(userId));
|
||||
_identityService
|
||||
.GetProfileAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(MakeProfile(userId));
|
||||
|
||||
var node = Node.Register("node-1", new Uri("https://node1.example.com"), new NodeCredentials("admin", "protected"), null);
|
||||
var node = Node.Register(
|
||||
"node-1",
|
||||
new Uri("https://node1.example.com"),
|
||||
new NodeCredentials("admin", "protected"),
|
||||
null
|
||||
);
|
||||
var inbound = Inbound.FromRemote(node.Id, "1", VpnProtocol.Vless, "remark", 443);
|
||||
var config = VpnConfig.Create(userId, inbound.Id, VpnProtocol.Vless, null);
|
||||
config.AssignRemoteClient("old-external-id");
|
||||
@@ -128,14 +198,29 @@ public class RotateVpnConfigCommandHandlerTests
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
var gatewayError = Error.Failure("Xui.Unreachable", "Панель недоступна.");
|
||||
_gateway.AddClientAsync(
|
||||
Arg.Any<Node>(), inbound.RemoteInboundId, config.Protocol, Arg.Any<string>(),
|
||||
Arg.Any<string>(), Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
_gateway
|
||||
.AddClientAsync(
|
||||
Arg.Any<Node>(),
|
||||
inbound.RemoteInboundId,
|
||||
config.Protocol,
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<string>(),
|
||||
Arg.Any<int>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
)
|
||||
.Returns(Result.Failure<string>(gatewayError));
|
||||
|
||||
var handler = new RotateVpnConfigCommandHandler(dbContext, _gateway, _identityService, FakeCurrentUser.Authenticated(userId));
|
||||
var handler = new RotateVpnConfigCommandHandler(
|
||||
dbContext,
|
||||
_gateway,
|
||||
_identityService,
|
||||
FakeCurrentUser.Authenticated(userId)
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new RotateVpnConfigCommand(config.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RotateVpnConfigCommand(config.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(gatewayError, result.Error);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
@@ -24,5 +23,4 @@
|
||||
<ProjectReference Include="..\..\src\PnvPanel.Application\PnvPanel.Application.csproj" />
|
||||
<ProjectReference Include="..\..\src\PnvPanel.Infrastructure\PnvPanel.Infrastructure.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
+77
-16
@@ -16,8 +16,17 @@ public class AddTicketCommentCommandHandlerTests
|
||||
private readonly IRealtimeNotifier _notifier = Substitute.For<IRealtimeNotifier>();
|
||||
|
||||
private static CurrentUserProfile Profile(Guid userId, string role) =>
|
||||
new(userId, "user", Guid.NewGuid(), role, IsActivated: true, IsBlocked: false, MaxConfigs: 3,
|
||||
MaxIpLimit: RoleQuota.Unlimited, SubscriptionToken: "token");
|
||||
new(
|
||||
userId,
|
||||
"user",
|
||||
Guid.NewGuid(),
|
||||
role,
|
||||
IsActivated: true,
|
||||
IsBlocked: false,
|
||||
MaxConfigs: 3,
|
||||
MaxIpLimit: RoleQuota.Unlimited,
|
||||
SubscriptionToken: "token"
|
||||
);
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_WhenOwnerComments_AddsCommentAndDoesNotNotifySelf()
|
||||
@@ -28,16 +37,33 @@ public class AddTicketCommentCommandHandlerTests
|
||||
dbContext.SupportTickets.Add(ticket);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_identityService.GetProfileAsync(userId, Arg.Any<CancellationToken>()).Returns(Profile(userId, "user"));
|
||||
_identityService
|
||||
.GetProfileAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(Profile(userId, "user"));
|
||||
var currentUser = FakeCurrentUser.Authenticated(userId, "alice");
|
||||
|
||||
var handler = new AddTicketCommentCommandHandler(dbContext, _identityService, _fileStorage, _notifier, currentUser);
|
||||
var handler = new AddTicketCommentCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_fileStorage,
|
||||
_notifier,
|
||||
currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new AddTicketCommentCommand(ticket.Id, "апдейт", []), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new AddTicketCommentCommand(ticket.Id, "апдейт", []),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal("апдейт", result.Value.Body);
|
||||
await _notifier.DidNotReceive().NotifyTicketUpdatedAsync(Arg.Any<Guid>(), Arg.Any<Guid>(), Arg.Any<CancellationToken>());
|
||||
await _notifier
|
||||
.DidNotReceive()
|
||||
.NotifyTicketUpdatedAsync(
|
||||
Arg.Any<Guid>(),
|
||||
Arg.Any<Guid>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -50,15 +76,28 @@ public class AddTicketCommentCommandHandlerTests
|
||||
dbContext.SupportTickets.Add(ticket);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_identityService.GetProfileAsync(adminId, Arg.Any<CancellationToken>()).Returns(Profile(adminId, "admin"));
|
||||
_identityService
|
||||
.GetProfileAsync(adminId, Arg.Any<CancellationToken>())
|
||||
.Returns(Profile(adminId, "admin"));
|
||||
var currentUser = FakeCurrentUser.Authenticated(adminId, "admin");
|
||||
|
||||
var handler = new AddTicketCommentCommandHandler(dbContext, _identityService, _fileStorage, _notifier, currentUser);
|
||||
var handler = new AddTicketCommentCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_fileStorage,
|
||||
_notifier,
|
||||
currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new AddTicketCommentCommand(ticket.Id, "ответ админа", []), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new AddTicketCommentCommand(ticket.Id, "ответ админа", []),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
await _notifier.Received(1).NotifyTicketUpdatedAsync(ticket.Id, ownerId, Arg.Any<CancellationToken>());
|
||||
await _notifier
|
||||
.Received(1)
|
||||
.NotifyTicketUpdatedAsync(ticket.Id, ownerId, Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -71,12 +110,23 @@ public class AddTicketCommentCommandHandlerTests
|
||||
dbContext.SupportTickets.Add(ticket);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_identityService.GetProfileAsync(strangerId, Arg.Any<CancellationToken>()).Returns(Profile(strangerId, "user"));
|
||||
_identityService
|
||||
.GetProfileAsync(strangerId, Arg.Any<CancellationToken>())
|
||||
.Returns(Profile(strangerId, "user"));
|
||||
var currentUser = FakeCurrentUser.Authenticated(strangerId);
|
||||
|
||||
var handler = new AddTicketCommentCommandHandler(dbContext, _identityService, _fileStorage, _notifier, currentUser);
|
||||
var handler = new AddTicketCommentCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_fileStorage,
|
||||
_notifier,
|
||||
currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new AddTicketCommentCommand(ticket.Id, "текст", []), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new AddTicketCommentCommand(ticket.Id, "текст", []),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(SupportErrors.NotFound, result.Error);
|
||||
@@ -92,12 +142,23 @@ public class AddTicketCommentCommandHandlerTests
|
||||
dbContext.SupportTickets.Add(ticket);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_identityService.GetProfileAsync(userId, Arg.Any<CancellationToken>()).Returns(Profile(userId, "user"));
|
||||
_identityService
|
||||
.GetProfileAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(Profile(userId, "user"));
|
||||
var currentUser = FakeCurrentUser.Authenticated(userId);
|
||||
|
||||
var handler = new AddTicketCommentCommandHandler(dbContext, _identityService, _fileStorage, _notifier, currentUser);
|
||||
var handler = new AddTicketCommentCommandHandler(
|
||||
dbContext,
|
||||
_identityService,
|
||||
_fileStorage,
|
||||
_notifier,
|
||||
currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new AddTicketCommentCommand(ticket.Id, "текст", []), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new AddTicketCommentCommand(ticket.Id, "текст", []),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(SupportErrors.TicketClosed, result.Error);
|
||||
|
||||
+47
-10
@@ -21,9 +21,18 @@ public class CreateBugReportTicketCommandHandlerTests
|
||||
var userId = Guid.NewGuid();
|
||||
var currentUser = FakeCurrentUser.Authenticated(userId, "alice");
|
||||
|
||||
var handler = new CreateBugReportTicketCommandHandler(dbContext, _fileStorage, _notifier, _telegramNotifier, currentUser);
|
||||
var handler = new CreateBugReportTicketCommandHandler(
|
||||
dbContext,
|
||||
_fileStorage,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new CreateBugReportTicketCommand("Что-то сломалось", []), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new CreateBugReportTicketCommand("Что-то сломалось", []),
|
||||
CancellationToken.None
|
||||
);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
@@ -33,8 +42,14 @@ public class CreateBugReportTicketCommandHandlerTests
|
||||
Assert.Equal("Что-то сломалось", result.Value.Comments[0].Body);
|
||||
Assert.Single(dbContext.SupportTickets);
|
||||
Assert.Single(dbContext.TicketComments);
|
||||
await _telegramNotifier.Received(1).NotifyAdminsBugReportCreatedAsync(
|
||||
Arg.Any<Guid>(), "alice", "Что-то сломалось", Arg.Any<CancellationToken>());
|
||||
await _telegramNotifier
|
||||
.Received(1)
|
||||
.NotifyAdminsBugReportCreatedAsync(
|
||||
Arg.Any<Guid>(),
|
||||
"alice",
|
||||
"Что-то сломалось",
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -42,13 +57,23 @@ public class CreateBugReportTicketCommandHandlerTests
|
||||
{
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var currentUser = FakeCurrentUser.Authenticated(Guid.NewGuid());
|
||||
var attachments = Enumerable.Range(0, 6)
|
||||
var attachments = Enumerable
|
||||
.Range(0, 6)
|
||||
.Select(_ => new TicketAttachmentUpload(new MemoryStream(), "a.png", "image/png", 10))
|
||||
.ToList();
|
||||
|
||||
var handler = new CreateBugReportTicketCommandHandler(dbContext, _fileStorage, _notifier, _telegramNotifier, currentUser);
|
||||
var handler = new CreateBugReportTicketCommandHandler(
|
||||
dbContext,
|
||||
_fileStorage,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new CreateBugReportTicketCommand("текст", attachments), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new CreateBugReportTicketCommand("текст", attachments),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(SupportErrors.TooManyAttachments, result.Error);
|
||||
@@ -59,11 +84,23 @@ public class CreateBugReportTicketCommandHandlerTests
|
||||
{
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var currentUser = FakeCurrentUser.Authenticated(Guid.NewGuid());
|
||||
var attachments = new[] { new TicketAttachmentUpload(new MemoryStream(), "a.exe", "application/x-msdownload", 10) };
|
||||
var attachments = new[]
|
||||
{
|
||||
new TicketAttachmentUpload(new MemoryStream(), "a.exe", "application/x-msdownload", 10),
|
||||
};
|
||||
|
||||
var handler = new CreateBugReportTicketCommandHandler(dbContext, _fileStorage, _notifier, _telegramNotifier, currentUser);
|
||||
var handler = new CreateBugReportTicketCommandHandler(
|
||||
dbContext,
|
||||
_fileStorage,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new CreateBugReportTicketCommand("текст", attachments), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new CreateBugReportTicketCommand("текст", attachments),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(SupportErrors.UnsupportedAttachmentType, result.Error);
|
||||
|
||||
+53
-12
@@ -21,20 +21,36 @@ public class CreateRoleRequestTicketCommandHandlerTests
|
||||
var userId = Guid.NewGuid();
|
||||
var roleId = Guid.NewGuid();
|
||||
var currentUser = FakeCurrentUser.Authenticated(userId, "alice");
|
||||
_roleService.ListRolesAsync(Arg.Any<CancellationToken>())
|
||||
_roleService
|
||||
.ListRolesAsync(Arg.Any<CancellationToken>())
|
||||
.Returns(new List<RoleDto> { new(roleId, "premium", 5, 2, false) });
|
||||
|
||||
var handler = new CreateRoleRequestTicketCommandHandler(dbContext, _roleService, _notifier, _telegramNotifier, currentUser);
|
||||
var handler = new CreateRoleRequestTicketCommandHandler(
|
||||
dbContext,
|
||||
_roleService,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(
|
||||
new CreateRoleRequestTicketCommand(roleId, null, null, null, "нужно больше конфигов"), CancellationToken.None);
|
||||
new CreateRoleRequestTicketCommand(roleId, null, null, null, "нужно больше конфигов"),
|
||||
CancellationToken.None
|
||||
);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(roleId, result.Value.RequestedRoleId);
|
||||
Assert.Equal("premium", result.Value.RequestedRoleName);
|
||||
await _telegramNotifier.Received(1).NotifyAdminsRoleRequestCreatedAsync(
|
||||
Arg.Any<Guid>(), "alice", "premium", "нужно больше конфигов", Arg.Any<CancellationToken>());
|
||||
await _telegramNotifier
|
||||
.Received(1)
|
||||
.NotifyAdminsRoleRequestCreatedAsync(
|
||||
Arg.Any<Guid>(),
|
||||
"alice",
|
||||
"premium",
|
||||
"нужно больше конфигов",
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -43,13 +59,22 @@ public class CreateRoleRequestTicketCommandHandlerTests
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var roleId = Guid.NewGuid();
|
||||
var currentUser = FakeCurrentUser.Authenticated(Guid.NewGuid());
|
||||
_roleService.ListRolesAsync(Arg.Any<CancellationToken>())
|
||||
_roleService
|
||||
.ListRolesAsync(Arg.Any<CancellationToken>())
|
||||
.Returns(new List<RoleDto> { new(roleId, "admin", -1, -1, true) });
|
||||
|
||||
var handler = new CreateRoleRequestTicketCommandHandler(dbContext, _roleService, _notifier, _telegramNotifier, currentUser);
|
||||
var handler = new CreateRoleRequestTicketCommandHandler(
|
||||
dbContext,
|
||||
_roleService,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(
|
||||
new CreateRoleRequestTicketCommand(roleId, null, null, null, "хочу быть админом"), CancellationToken.None);
|
||||
new CreateRoleRequestTicketCommand(roleId, null, null, null, "хочу быть админом"),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(SupportErrors.CannotRequestAdminRole, result.Error);
|
||||
@@ -61,10 +86,18 @@ public class CreateRoleRequestTicketCommandHandlerTests
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var currentUser = FakeCurrentUser.Authenticated(Guid.NewGuid(), "bob");
|
||||
|
||||
var handler = new CreateRoleRequestTicketCommandHandler(dbContext, _roleService, _notifier, _telegramNotifier, currentUser);
|
||||
var handler = new CreateRoleRequestTicketCommandHandler(
|
||||
dbContext,
|
||||
_roleService,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(
|
||||
new CreateRoleRequestTicketCommand(null, "custom", 10, 4, "нужна кастомная роль"), CancellationToken.None);
|
||||
new CreateRoleRequestTicketCommand(null, "custom", 10, 4, "нужна кастомная роль"),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal("custom", result.Value.ProposedRoleName);
|
||||
@@ -81,10 +114,18 @@ public class CreateRoleRequestTicketCommandHandlerTests
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
var currentUser = FakeCurrentUser.Authenticated(userId);
|
||||
var handler = new CreateRoleRequestTicketCommandHandler(dbContext, _roleService, _notifier, _telegramNotifier, currentUser);
|
||||
var handler = new CreateRoleRequestTicketCommandHandler(
|
||||
dbContext,
|
||||
_roleService,
|
||||
_notifier,
|
||||
_telegramNotifier,
|
||||
currentUser
|
||||
);
|
||||
|
||||
var result = await handler.Handle(
|
||||
new CreateRoleRequestTicketCommand(null, "y", 2, 2, "ещё заявка"), CancellationToken.None);
|
||||
new CreateRoleRequestTicketCommand(null, "y", 2, 2, "ещё заявка"),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(SupportErrors.RoleRequestAlreadyPending, result.Error);
|
||||
|
||||
+20
-5
@@ -25,12 +25,21 @@ public class ReopenTicketCommandHandlerTests
|
||||
var currentUser = FakeCurrentUser.Authenticated(userId);
|
||||
var handler = new ReopenTicketCommandHandler(dbContext, _telegramNotifier, currentUser);
|
||||
|
||||
var result = await handler.Handle(new ReopenTicketCommand(ticket.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ReopenTicketCommand(ticket.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(TicketStatus.Open, ticket.Status);
|
||||
await _telegramNotifier.Received(1).NotifyAdminsTicketReopenedAsync(
|
||||
ticket.Id, Arg.Any<string>(), TicketType.BugReport, Arg.Any<CancellationToken>());
|
||||
await _telegramNotifier
|
||||
.Received(1)
|
||||
.NotifyAdminsTicketReopenedAsync(
|
||||
ticket.Id,
|
||||
Arg.Any<string>(),
|
||||
TicketType.BugReport,
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -45,7 +54,10 @@ public class ReopenTicketCommandHandlerTests
|
||||
var currentUser = FakeCurrentUser.Authenticated(userId);
|
||||
var handler = new ReopenTicketCommandHandler(dbContext, _telegramNotifier, currentUser);
|
||||
|
||||
var result = await handler.Handle(new ReopenTicketCommand(ticket.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ReopenTicketCommand(ticket.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(SupportErrors.NotResolved, result.Error);
|
||||
@@ -63,7 +75,10 @@ public class ReopenTicketCommandHandlerTests
|
||||
var currentUser = FakeCurrentUser.Authenticated(Guid.NewGuid());
|
||||
var handler = new ReopenTicketCommandHandler(dbContext, _telegramNotifier, currentUser);
|
||||
|
||||
var result = await handler.Handle(new ReopenTicketCommand(ticket.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ReopenTicketCommand(ticket.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(SupportErrors.NotFound, result.Error);
|
||||
|
||||
+34
-10
@@ -23,11 +23,16 @@ public class ApproveTelegramLoginCommandHandlerTests
|
||||
dbContext.TelegramLoginRequests.Add(request);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_identityService.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>()).Returns(userId);
|
||||
_identityService
|
||||
.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>())
|
||||
.Returns(userId);
|
||||
|
||||
var handler = new ApproveTelegramLoginCommandHandler(dbContext, _identityService);
|
||||
|
||||
var result = await handler.Handle(new ApproveTelegramLoginCommand(request.Id, telegramUserId), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ApproveTelegramLoginCommand(request.Id, telegramUserId),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(TelegramLoginStatus.Approved, request.Status);
|
||||
@@ -40,12 +45,16 @@ public class ApproveTelegramLoginCommandHandlerTests
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
const long telegramUserId = 123456L;
|
||||
|
||||
_identityService.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>())
|
||||
_identityService
|
||||
.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>())
|
||||
.Returns((Guid?)null);
|
||||
|
||||
var handler = new ApproveTelegramLoginCommandHandler(dbContext, _identityService);
|
||||
|
||||
var result = await handler.Handle(new ApproveTelegramLoginCommand(Guid.NewGuid(), telegramUserId), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ApproveTelegramLoginCommand(Guid.NewGuid(), telegramUserId),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(TelegramErrors.NotLinked, result.Error);
|
||||
@@ -58,11 +67,16 @@ public class ApproveTelegramLoginCommandHandlerTests
|
||||
var userId = Guid.NewGuid();
|
||||
const long telegramUserId = 123456L;
|
||||
|
||||
_identityService.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>()).Returns(userId);
|
||||
_identityService
|
||||
.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>())
|
||||
.Returns(userId);
|
||||
|
||||
var handler = new ApproveTelegramLoginCommandHandler(dbContext, _identityService);
|
||||
|
||||
var result = await handler.Handle(new ApproveTelegramLoginCommand(Guid.NewGuid(), telegramUserId), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ApproveTelegramLoginCommand(Guid.NewGuid(), telegramUserId),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(TelegramErrors.LoginRequestNotFound, result.Error);
|
||||
@@ -80,11 +94,16 @@ public class ApproveTelegramLoginCommandHandlerTests
|
||||
dbContext.TelegramLoginRequests.Add(request);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_identityService.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>()).Returns(userId);
|
||||
_identityService
|
||||
.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>())
|
||||
.Returns(userId);
|
||||
|
||||
var handler = new ApproveTelegramLoginCommandHandler(dbContext, _identityService);
|
||||
|
||||
var result = await handler.Handle(new ApproveTelegramLoginCommand(request.Id, telegramUserId), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ApproveTelegramLoginCommand(request.Id, telegramUserId),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal("Telegram.LoginRequestInvalid", result.Error.Code);
|
||||
@@ -101,11 +120,16 @@ public class ApproveTelegramLoginCommandHandlerTests
|
||||
dbContext.TelegramLoginRequests.Add(request);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_identityService.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>()).Returns(userId);
|
||||
_identityService
|
||||
.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>())
|
||||
.Returns(userId);
|
||||
|
||||
var handler = new ApproveTelegramLoginCommandHandler(dbContext, _identityService);
|
||||
|
||||
var result = await handler.Handle(new ApproveTelegramLoginCommand(request.Id, telegramUserId), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new ApproveTelegramLoginCommand(request.Id, telegramUserId),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal("Telegram.LoginRequestInvalid", result.Error.Code);
|
||||
|
||||
+36
-10
@@ -22,12 +22,16 @@ public class LinkTelegramCommandHandlerTests
|
||||
dbContext.TelegramLinkTokens.Add(token);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_identityService.LinkTelegramAsync(userId, 123456L, "alice_tg", Arg.Any<CancellationToken>())
|
||||
_identityService
|
||||
.LinkTelegramAsync(userId, 123456L, "alice_tg", Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success());
|
||||
|
||||
var handler = new LinkTelegramCommandHandler(dbContext, _identityService);
|
||||
|
||||
var result = await handler.Handle(new LinkTelegramCommand(token.Token, 123456L, "alice_tg"), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new LinkTelegramCommand(token.Token, 123456L, "alice_tg"),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(userId, result.Value);
|
||||
@@ -41,7 +45,10 @@ public class LinkTelegramCommandHandlerTests
|
||||
|
||||
var handler = new LinkTelegramCommandHandler(dbContext, _identityService);
|
||||
|
||||
var result = await handler.Handle(new LinkTelegramCommand("missing-token", 123456L, null), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new LinkTelegramCommand("missing-token", 123456L, null),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(TelegramErrors.LinkTokenNotFound, result.Error);
|
||||
@@ -59,12 +66,21 @@ public class LinkTelegramCommandHandlerTests
|
||||
|
||||
var handler = new LinkTelegramCommandHandler(dbContext, _identityService);
|
||||
|
||||
var result = await handler.Handle(new LinkTelegramCommand(token.Token, 123456L, null), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new LinkTelegramCommand(token.Token, 123456L, null),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(TelegramErrors.LinkTokenNotFound, result.Error);
|
||||
await _identityService.DidNotReceive().LinkTelegramAsync(
|
||||
Arg.Any<Guid>(), Arg.Any<long>(), Arg.Any<string?>(), Arg.Any<CancellationToken>());
|
||||
await _identityService
|
||||
.DidNotReceive()
|
||||
.LinkTelegramAsync(
|
||||
Arg.Any<Guid>(),
|
||||
Arg.Any<long>(),
|
||||
Arg.Any<string?>(),
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -78,7 +94,10 @@ public class LinkTelegramCommandHandlerTests
|
||||
|
||||
var handler = new LinkTelegramCommandHandler(dbContext, _identityService);
|
||||
|
||||
var result = await handler.Handle(new LinkTelegramCommand(token.Token, 123456L, null), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new LinkTelegramCommand(token.Token, 123456L, null),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(TelegramErrors.LinkTokenNotFound, result.Error);
|
||||
@@ -93,13 +112,20 @@ public class LinkTelegramCommandHandlerTests
|
||||
dbContext.TelegramLinkTokens.Add(token);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
var error = Error.Conflict("Telegram.AlreadyLinked", "Этот Telegram уже привязан к другому аккаунту.");
|
||||
_identityService.LinkTelegramAsync(userId, 123456L, null, Arg.Any<CancellationToken>())
|
||||
var error = Error.Conflict(
|
||||
"Telegram.AlreadyLinked",
|
||||
"Этот Telegram уже привязан к другому аккаунту."
|
||||
);
|
||||
_identityService
|
||||
.LinkTelegramAsync(userId, 123456L, null, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Failure(error));
|
||||
|
||||
var handler = new LinkTelegramCommandHandler(dbContext, _identityService);
|
||||
|
||||
var result = await handler.Handle(new LinkTelegramCommand(token.Token, 123456L, null), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new LinkTelegramCommand(token.Token, 123456L, null),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(error, result.Error);
|
||||
|
||||
+27
-8
@@ -23,11 +23,16 @@ public class RejectTelegramLoginCommandHandlerTests
|
||||
dbContext.TelegramLoginRequests.Add(request);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_identityService.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>()).Returns(userId);
|
||||
_identityService
|
||||
.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>())
|
||||
.Returns(userId);
|
||||
|
||||
var handler = new RejectTelegramLoginCommandHandler(dbContext, _identityService);
|
||||
|
||||
var result = await handler.Handle(new RejectTelegramLoginCommand(request.Id, telegramUserId), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RejectTelegramLoginCommand(request.Id, telegramUserId),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(TelegramLoginStatus.Rejected, request.Status);
|
||||
@@ -39,12 +44,16 @@ public class RejectTelegramLoginCommandHandlerTests
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
const long telegramUserId = 123456L;
|
||||
|
||||
_identityService.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>())
|
||||
_identityService
|
||||
.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>())
|
||||
.Returns((Guid?)null);
|
||||
|
||||
var handler = new RejectTelegramLoginCommandHandler(dbContext, _identityService);
|
||||
|
||||
var result = await handler.Handle(new RejectTelegramLoginCommand(Guid.NewGuid(), telegramUserId), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RejectTelegramLoginCommand(Guid.NewGuid(), telegramUserId),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(TelegramErrors.NotLinked, result.Error);
|
||||
@@ -57,11 +66,16 @@ public class RejectTelegramLoginCommandHandlerTests
|
||||
var userId = Guid.NewGuid();
|
||||
const long telegramUserId = 123456L;
|
||||
|
||||
_identityService.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>()).Returns(userId);
|
||||
_identityService
|
||||
.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>())
|
||||
.Returns(userId);
|
||||
|
||||
var handler = new RejectTelegramLoginCommandHandler(dbContext, _identityService);
|
||||
|
||||
var result = await handler.Handle(new RejectTelegramLoginCommand(Guid.NewGuid(), telegramUserId), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RejectTelegramLoginCommand(Guid.NewGuid(), telegramUserId),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(TelegramErrors.LoginRequestNotFound, result.Error);
|
||||
@@ -79,11 +93,16 @@ public class RejectTelegramLoginCommandHandlerTests
|
||||
dbContext.TelegramLoginRequests.Add(request);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_identityService.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>()).Returns(userId);
|
||||
_identityService
|
||||
.FindUserIdByTelegramUserIdAsync(telegramUserId, Arg.Any<CancellationToken>())
|
||||
.Returns(userId);
|
||||
|
||||
var handler = new RejectTelegramLoginCommandHandler(dbContext, _identityService);
|
||||
|
||||
var result = await handler.Handle(new RejectTelegramLoginCommand(request.Id, telegramUserId), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new RejectTelegramLoginCommand(request.Id, telegramUserId),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal("Telegram.LoginRequestInvalid", result.Error.Code);
|
||||
|
||||
+4
-1
@@ -13,7 +13,10 @@ public class CreateLinkTokenCommandHandlerTests
|
||||
using var dbContext = InMemoryDbContextFactory.Create();
|
||||
var userId = Guid.NewGuid();
|
||||
|
||||
var handler = new CreateLinkTokenCommandHandler(dbContext, FakeCurrentUser.Authenticated(userId));
|
||||
var handler = new CreateLinkTokenCommandHandler(
|
||||
dbContext,
|
||||
FakeCurrentUser.Authenticated(userId)
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new CreateLinkTokenCommand(), CancellationToken.None);
|
||||
|
||||
|
||||
+46
-13
@@ -13,10 +13,12 @@ public class GetLoginRequestStatusQueryHandlerTests
|
||||
{
|
||||
private readonly IIdentityService _identityService = Substitute.For<IIdentityService>();
|
||||
private readonly IJwtTokenService _jwtTokenService = Substitute.For<IJwtTokenService>();
|
||||
private readonly IRefreshTokenService _refreshTokenService = Substitute.For<IRefreshTokenService>();
|
||||
private readonly IRefreshTokenService _refreshTokenService =
|
||||
Substitute.For<IRefreshTokenService>();
|
||||
|
||||
private TelegramNs.GetLoginRequestStatusQueryHandler CreateHandler(PnvPanel.Infrastructure.Persistence.AppDbContext dbContext)
|
||||
=> new(dbContext, _identityService, _jwtTokenService, _refreshTokenService);
|
||||
private TelegramNs.GetLoginRequestStatusQueryHandler CreateHandler(
|
||||
PnvPanel.Infrastructure.Persistence.AppDbContext dbContext
|
||||
) => new(dbContext, _identityService, _jwtTokenService, _refreshTokenService);
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_WhenRequestNotFound_ReturnsNotFound()
|
||||
@@ -25,7 +27,10 @@ public class GetLoginRequestStatusQueryHandlerTests
|
||||
|
||||
var handler = CreateHandler(dbContext);
|
||||
|
||||
var result = await handler.Handle(new TelegramNs.GetLoginRequestStatusQuery(Guid.NewGuid()), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new TelegramNs.GetLoginRequestStatusQuery(Guid.NewGuid()),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(TelegramNs.TelegramErrors.LoginRequestNotFound, result.Error);
|
||||
@@ -41,12 +46,17 @@ public class GetLoginRequestStatusQueryHandlerTests
|
||||
|
||||
var handler = CreateHandler(dbContext);
|
||||
|
||||
var result = await handler.Handle(new TelegramNs.GetLoginRequestStatusQuery(request.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new TelegramNs.GetLoginRequestStatusQuery(request.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(TelegramLoginStatus.Expired, result.Value.Status);
|
||||
Assert.Null(result.Value.Auth);
|
||||
await _refreshTokenService.DidNotReceive().IssueAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>());
|
||||
await _refreshTokenService
|
||||
.DidNotReceive()
|
||||
.IssueAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -59,7 +69,10 @@ public class GetLoginRequestStatusQueryHandlerTests
|
||||
|
||||
var handler = CreateHandler(dbContext);
|
||||
|
||||
var result = await handler.Handle(new TelegramNs.GetLoginRequestStatusQuery(request.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new TelegramNs.GetLoginRequestStatusQuery(request.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(TelegramLoginStatus.Pending, result.Value.Status);
|
||||
@@ -76,16 +89,31 @@ public class GetLoginRequestStatusQueryHandlerTests
|
||||
dbContext.TelegramLoginRequests.Add(request);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
var profile = new CurrentUserProfile(userId, "alice", Guid.NewGuid(), "user", true, false, 3, RoleQuota.Unlimited, "sub-token");
|
||||
var profile = new CurrentUserProfile(
|
||||
userId,
|
||||
"alice",
|
||||
Guid.NewGuid(),
|
||||
"user",
|
||||
true,
|
||||
false,
|
||||
3,
|
||||
RoleQuota.Unlimited,
|
||||
"sub-token"
|
||||
);
|
||||
_identityService.GetProfileAsync(userId, Arg.Any<CancellationToken>()).Returns(profile);
|
||||
_jwtTokenService.GenerateAccessToken(Arg.Any<AuthenticatedUser>())
|
||||
_jwtTokenService
|
||||
.GenerateAccessToken(Arg.Any<AuthenticatedUser>())
|
||||
.Returns(("access-token", DateTimeOffset.UtcNow.AddMinutes(15)));
|
||||
_refreshTokenService.IssueAsync(userId, Arg.Any<CancellationToken>())
|
||||
_refreshTokenService
|
||||
.IssueAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(new IssuedRefreshToken("refresh-token", DateTimeOffset.UtcNow.AddDays(30)));
|
||||
|
||||
var handler = CreateHandler(dbContext);
|
||||
|
||||
var result = await handler.Handle(new TelegramNs.GetLoginRequestStatusQuery(request.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new TelegramNs.GetLoginRequestStatusQuery(request.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(TelegramLoginStatus.Approved, result.Value.Status);
|
||||
@@ -105,11 +133,16 @@ public class GetLoginRequestStatusQueryHandlerTests
|
||||
dbContext.TelegramLoginRequests.Add(request);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
|
||||
_identityService.GetProfileAsync(userId, Arg.Any<CancellationToken>()).Returns((CurrentUserProfile?)null);
|
||||
_identityService
|
||||
.GetProfileAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns((CurrentUserProfile?)null);
|
||||
|
||||
var handler = CreateHandler(dbContext);
|
||||
|
||||
var result = await handler.Handle(new TelegramNs.GetLoginRequestStatusQuery(request.Id), CancellationToken.None);
|
||||
var result = await handler.Handle(
|
||||
new TelegramNs.GetLoginRequestStatusQuery(request.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(AuthErrors.Unauthorized, result.Error);
|
||||
|
||||
+24
-7
@@ -16,26 +16,38 @@ public class UnlinkTelegramCommandHandlerTests
|
||||
public async Task Handle_WhenAuthenticated_DelegatesToIdentityService()
|
||||
{
|
||||
var userId = Guid.NewGuid();
|
||||
_identityService.UnlinkTelegramAsync(userId, Arg.Any<CancellationToken>()).Returns(Result.Success());
|
||||
_identityService
|
||||
.UnlinkTelegramAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Success());
|
||||
|
||||
var handler = new UnlinkTelegramCommandHandler(_identityService, FakeCurrentUser.Authenticated(userId));
|
||||
var handler = new UnlinkTelegramCommandHandler(
|
||||
_identityService,
|
||||
FakeCurrentUser.Authenticated(userId)
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new UnlinkTelegramCommand(), CancellationToken.None);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
await _identityService.Received(1).UnlinkTelegramAsync(userId, Arg.Any<CancellationToken>());
|
||||
await _identityService
|
||||
.Received(1)
|
||||
.UnlinkTelegramAsync(userId, Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handle_WhenNotAuthenticated_ReturnsUnauthorized()
|
||||
{
|
||||
var handler = new UnlinkTelegramCommandHandler(_identityService, FakeCurrentUser.Anonymous());
|
||||
var handler = new UnlinkTelegramCommandHandler(
|
||||
_identityService,
|
||||
FakeCurrentUser.Anonymous()
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new UnlinkTelegramCommand(), CancellationToken.None);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(AuthErrors.Unauthorized, result.Error);
|
||||
await _identityService.DidNotReceive().UnlinkTelegramAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>());
|
||||
await _identityService
|
||||
.DidNotReceive()
|
||||
.UnlinkTelegramAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -43,9 +55,14 @@ public class UnlinkTelegramCommandHandlerTests
|
||||
{
|
||||
var userId = Guid.NewGuid();
|
||||
var error = TelegramErrors.NotLinked;
|
||||
_identityService.UnlinkTelegramAsync(userId, Arg.Any<CancellationToken>()).Returns(Result.Failure(error));
|
||||
_identityService
|
||||
.UnlinkTelegramAsync(userId, Arg.Any<CancellationToken>())
|
||||
.Returns(Result.Failure(error));
|
||||
|
||||
var handler = new UnlinkTelegramCommandHandler(_identityService, FakeCurrentUser.Authenticated(userId));
|
||||
var handler = new UnlinkTelegramCommandHandler(
|
||||
_identityService,
|
||||
FakeCurrentUser.Authenticated(userId)
|
||||
);
|
||||
|
||||
var result = await handler.Handle(new UnlinkTelegramCommand(), CancellationToken.None);
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ public sealed class FakeCurrentUser : ICurrentUser
|
||||
|
||||
public bool IsAuthenticated => UserId is not null;
|
||||
|
||||
public static FakeCurrentUser Authenticated(Guid userId, string userName = "testuser")
|
||||
=> new() { UserId = userId, UserName = userName };
|
||||
public static FakeCurrentUser Authenticated(Guid userId, string userName = "testuser") =>
|
||||
new() { UserId = userId, UserName = userName };
|
||||
|
||||
public static FakeCurrentUser Anonymous() => new();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user