- Updated the `UpdateClientAsync` method in `IXuiPanelGateway` to accept nullable parameters for `name` and `expiresAt`, allowing for more flexible client management without unintended modifications. - Adjusted the `BlockUserCommandHandler`, `UnblockUserCommandHandler`, and other related command handlers to utilize the new nullable parameters, ensuring that client names remain unchanged during block/unblock operations and that expiration dates are managed correctly. - Enhanced the billing and configuration handling to reflect the new logic for managing client states based on expiration rather than enabling/disabling, improving reliability in client status management. - Updated tests to cover the new behavior and ensure proper functionality across the application.
84 lines
2.8 KiB
C#
84 lines
2.8 KiB
C#
using PnvPanel.Application.Common.Interfaces;
|
|
using PnvPanel.Application.Common.Models;
|
|
using PnvPanel.Domain.Inbounds;
|
|
using PnvPanel.Domain.Nodes;
|
|
|
|
namespace PnvPanel.IntegrationTests.TestSupport;
|
|
|
|
/// <summary>
|
|
/// Заглушка 3x-ui для интеграционных тестов — реальной панели нет. Возвращает успех для проб/CRUD
|
|
/// клиентов, отдаёт один синтетический inbound на ноду для сценариев с SyncNode.
|
|
/// </summary>
|
|
public sealed class FakeXuiPanelGateway : IXuiPanelGateway
|
|
{
|
|
public Result ValidateBaseAddress(Uri baseAddress) => Result.Success();
|
|
|
|
public Task<NodeProbeResult> ProbeAsync(Node node, CancellationToken cancellationToken) =>
|
|
Task.FromResult(new NodeProbeResult(true, null));
|
|
|
|
public Task<Result<IReadOnlyList<RemoteInboundInfo>>> ListInboundsAsync(
|
|
Node node,
|
|
CancellationToken cancellationToken
|
|
)
|
|
{
|
|
IReadOnlyList<RemoteInboundInfo> inbounds =
|
|
[
|
|
new RemoteInboundInfo("1", VpnProtocol.Vless, "Test inbound", 443),
|
|
];
|
|
|
|
return Task.FromResult(Result.Success(inbounds));
|
|
}
|
|
|
|
public void InvalidateClient(Guid nodeId) { }
|
|
|
|
public Task<Result<string>> AddClientAsync(
|
|
Node node,
|
|
string inboundRemoteId,
|
|
VpnProtocol protocol,
|
|
string clientEmail,
|
|
string clientName,
|
|
int limitIp,
|
|
DateTimeOffset? expiresAt,
|
|
CancellationToken cancellationToken
|
|
) => Task.FromResult(Result.Success(Guid.NewGuid().ToString()));
|
|
|
|
public Task<Result> RemoveClientAsync(
|
|
Node node,
|
|
string inboundRemoteId,
|
|
string clientExternalId,
|
|
VpnProtocol protocol,
|
|
CancellationToken cancellationToken
|
|
) => Task.FromResult(Result.Success());
|
|
|
|
public Task<Result> UpdateClientAsync(
|
|
Node node,
|
|
string inboundRemoteId,
|
|
string clientExternalId,
|
|
VpnProtocol protocol,
|
|
string? name,
|
|
bool? enable,
|
|
DateTimeOffset? expiresAt,
|
|
CancellationToken cancellationToken
|
|
) => Task.FromResult(Result.Success());
|
|
|
|
public Task<Result<string>> BuildConnectionStringAsync(
|
|
Node node,
|
|
Inbound inbound,
|
|
string clientExternalId,
|
|
string clientName,
|
|
string publicHost,
|
|
CancellationToken cancellationToken
|
|
) => Task.FromResult(Result.Success("vless://fake-connection-string"));
|
|
|
|
public Task<Result<IReadOnlyDictionary<string, ClientTrafficInfo>>> GetClientTrafficAsync(
|
|
Node node,
|
|
string inboundRemoteId,
|
|
CancellationToken cancellationToken
|
|
)
|
|
{
|
|
IReadOnlyDictionary<string, ClientTrafficInfo> traffic =
|
|
new Dictionary<string, ClientTrafficInfo>();
|
|
return Task.FromResult(Result.Success(traffic));
|
|
}
|
|
}
|