using Omika.App.Local.Abstractions;
using Omika.Core.Constants;
using Omika.Core.Interfaces;
namespace Omika.Tests.Mobile.Local;
///
/// Double de test de .
///
/// Par défaut il reproduit le comportement « aucune optimisation » : le fichier
/// source est copié à l'identique vers la destination et le résultat indique que
/// rien n'a été modifié. C'est le comportement attendu pour une image déjà sous
/// la limite, et cela permet aux tests existants de rester valides.
///
/// Le test peut demander une optimisation simulée via .
///
public sealed class FakeImageOptimizer : IImageOptimizer
{
/// Nombre d'appels reçus.
public int Calls { get; private set; }
/// Dernière limite reçue, en kilo-octets.
public int LastMaxSizeKb { get; private set; } = -1;
///
/// Contenu à écrire lorsque l'optimisation est simulée.
/// signifie « copier la source telle quelle ».
///
public byte[]? OptimizedBytes { get; set; }
/// Qualité à reporter lorsque l'optimisation est simulée.
public int? ReportedQuality { get; set; } = 78;
///
public Task OptimizeFileAsync(
string sourcePath,
string destinationPath,
string? fileName,
string? mimeType,
int maxSizeKb,
CancellationToken cancellationToken = default)
{
Calls++;
LastMaxSizeKb = maxSizeKb;
long originalBytes = new FileInfo(sourcePath).Length;
if (OptimizedBytes is not null)
{
File.WriteAllBytes(destinationPath, OptimizedBytes);
return Task.FromResult(new ImageOptimizationResult
{
DestinationPath = destinationPath,
WasOptimized = true,
OriginalBytes = originalBytes,
FinalBytes = OptimizedBytes.LongLength,
OriginalWidth = 4000,
OriginalHeight = 3000,
FinalWidth = 2000,
FinalHeight = 1500,
Quality = ReportedQuality
});
}
File.Copy(sourcePath, destinationPath, overwrite: true);
return Task.FromResult(new ImageOptimizationResult
{
DestinationPath = destinationPath,
WasOptimized = false,
OriginalBytes = originalBytes,
FinalBytes = originalBytes
});
}
}
///
/// Double de test de : retourne une limite
/// fixe, configurable par le test.
///
public sealed class FakePhotoPolicyProvider : IPhotoPolicyProvider
{
/// Limite retournée, en kilo-octets (0 = aucune limite).
public int MaxSizeKb { get; set; } = 500;
/// Origine retournée.
public PhotoLimitSource Source { get; set; } = PhotoLimitSource.ApplicationParameter;
///
public Task GetResolutionAsync(CancellationToken cancellationToken = default)
=> Task.FromResult(new PhotoLimitResolution(MaxSizeKb, Source));
}
///
/// Double de test de adossé à un
/// dictionnaire en mémoire.
///
public sealed class FakeApplicationParameterRepository : IApplicationParameterRepository
{
/// Valeurs des paramètres applicatifs, indexées par code.
public Dictionary Values { get; } = new(StringComparer.Ordinal);
///
public Task GetValueAsync(string code, CancellationToken cancellationToken = default)
{
Values.TryGetValue(code, out string? value);
return Task.FromResult(value);
}
}
///
/// Double de test de .
///
/// Par défaut il reproduit le cas « aucune métadonnée fiable » : la date système
/// est retournée avec la source ,
/// ce qui correspond au comportement des tests existants (aucun fichier réel
/// porteur d'EXIF). Le test peut fixer une date explicite avec
/// , ou simuler un lecteur en échec avec
/// .
///
public sealed class FakeDocumentDateResolver : IDocumentDateResolver
{
/// Nombre d'appels reçus.
public int Calls { get; private set; }
/// Dernier chemin reçu.
public string? LastPath { get; private set; }
/// Date retournée lorsque la propriété est fixée.
public DateTime? ResolvedDate { get; set; }
/// Origine retournée (utilisée seulement si est fixée).
public DocumentDateSource Source { get; set; } = DocumentDateSource.ExifDateTimeOriginal;
/// Simule un lecteur en échec : la résolution lève une exception.
public bool ThrowOnResolve { get; set; }
///
public Task ResolveAsync(
string filePath,
string? fileName,
CancellationToken cancellationToken = default)
{
Calls++;
LastPath = filePath;
if (ThrowOnResolve)
{
throw new IOException("Métadonnées illisibles (simulation de test).");
}
return Task.FromResult(ResolvedDate is { } value
? new DocumentDateResolution(value, Source)
: new DocumentDateResolution(DateTime.Now, DocumentDateSource.SystemFallback));
}
}