Premiere commit - Omika
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
using Omika.Diagnostics.Users;
|
||||
|
||||
namespace Omika.Diagnostics.Tests.Fakes;
|
||||
|
||||
/// <summary>
|
||||
/// Fake en mémoire de <see cref="IDiagnosticUserRepository"/> pour les tests sans PostgreSQL.
|
||||
/// Reproduit la sémantique du repository Npgsql : unicité insensible à la casse, tri par
|
||||
/// username, hash stocké (jamais de mot de passe en clair).
|
||||
/// </summary>
|
||||
public sealed class FakeDiagnosticUserRepository : IDiagnosticUserRepository
|
||||
{
|
||||
private readonly List<DiagnosticUserRecord> _users = [];
|
||||
private long _nextId = 1;
|
||||
|
||||
public IReadOnlyList<DiagnosticUserRecord> Seed(params DiagnosticUserRecord[] users)
|
||||
{
|
||||
foreach (DiagnosticUserRecord u in users)
|
||||
{
|
||||
if (u.Id == 0)
|
||||
{
|
||||
u.Id = _nextId++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_nextId = Math.Max(_nextId, u.Id + 1);
|
||||
}
|
||||
|
||||
_users.Add(u);
|
||||
}
|
||||
|
||||
return _users;
|
||||
}
|
||||
|
||||
public Task<DiagnosticUserRecord?> GetByUsernameAsync(
|
||||
string username,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
string? normalized = username?.Trim();
|
||||
DiagnosticUserRecord? found = _users.FirstOrDefault(u =>
|
||||
string.Equals(u.Username, normalized, StringComparison.OrdinalIgnoreCase));
|
||||
return Task.FromResult(found);
|
||||
}
|
||||
|
||||
public Task<IReadOnlyList<DiagnosticUserRecord>> ListAsync(
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
IReadOnlyList<DiagnosticUserRecord> ordered = _users
|
||||
.OrderBy(u => u.Username, StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
return Task.FromResult(ordered);
|
||||
}
|
||||
|
||||
public Task<DiagnosticUserRecord?> CreateAsync(
|
||||
string username,
|
||||
string passwordHash,
|
||||
string role,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
string? normalized = username?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(normalized))
|
||||
{
|
||||
return Task.FromResult<DiagnosticUserRecord?>(null);
|
||||
}
|
||||
|
||||
if (_users.Any(u => string.Equals(u.Username, normalized, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return Task.FromResult<DiagnosticUserRecord?>(null); // doublon.
|
||||
}
|
||||
|
||||
DateTimeOffset now = DateTimeOffset.UtcNow;
|
||||
var record = new DiagnosticUserRecord
|
||||
{
|
||||
Id = _nextId++,
|
||||
Username = normalized,
|
||||
PasswordHash = passwordHash,
|
||||
Role = role,
|
||||
Enabled = true,
|
||||
CreatedAtUtc = now,
|
||||
UpdatedAtUtc = now,
|
||||
PasswordChangedAtUtc = now,
|
||||
LastLoginAtUtc = null
|
||||
};
|
||||
_users.Add(record);
|
||||
return Task.FromResult<DiagnosticUserRecord?>(record);
|
||||
}
|
||||
|
||||
public Task<bool> SetEnabledAsync(
|
||||
long id,
|
||||
bool enabled,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
DiagnosticUserRecord? user = _users.FirstOrDefault(u => u.Id == id);
|
||||
if (user is null)
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
user.Enabled = enabled;
|
||||
user.UpdatedAtUtc = DateTimeOffset.UtcNow;
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
public Task<bool> SetRoleAsync(
|
||||
long id,
|
||||
string role,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
DiagnosticUserRecord? user = _users.FirstOrDefault(u => u.Id == id);
|
||||
if (user is null)
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
user.Role = role;
|
||||
user.UpdatedAtUtc = DateTimeOffset.UtcNow;
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
public Task<bool> UpdatePasswordHashAsync(
|
||||
long id,
|
||||
string passwordHash,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
DiagnosticUserRecord? user = _users.FirstOrDefault(u => u.Id == id);
|
||||
if (user is null)
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
user.PasswordHash = passwordHash;
|
||||
user.PasswordChangedAtUtc = DateTimeOffset.UtcNow;
|
||||
user.UpdatedAtUtc = DateTimeOffset.UtcNow;
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
public Task UpdateLastLoginAsync(
|
||||
string username,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
DiagnosticUserRecord? user = _users.FirstOrDefault(u =>
|
||||
string.Equals(u.Username, username?.Trim(), StringComparison.OrdinalIgnoreCase));
|
||||
if (user is not null)
|
||||
{
|
||||
user.LastLoginAtUtc = DateTimeOffset.UtcNow;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user