using Omika.Core.Compatibility;
using Omika.Core.Contracts.Clients;
using Omika.Core.Contracts.Common;
using Omika.Core.Contracts.Documents;
using Omika.Core.Contracts.Interventions;
using Omika.Core.Contracts.Mobile.Interventions;
using Omika.Core.Contracts.Mobile.Sync;
using Omika.Core.Contracts.Organisation;
using Omika.Core.Contracts.Planning;
using Omika.Core.Contracts.Sites;
using Omika.Core.Interfaces;
using Omika.Core.Interfaces.Mobile;
using Omika.Core.Services.Mobile;
using Omika.Core.Domain;
namespace Omika.Tests.Mobile.Local;
///
/// Tests du service d'enrichissement mobile (MobileInterventionSearchService) :
/// recherche par numéro ciblée, identité canonique, lien rendez-vous/site/client,
/// sans full scan.
///
public class MobileInterventionSearchServiceTests
{
private static readonly Guid SiteGuid = Guid.Parse("dddddddd-dddd-dddd-dddd-dddddddddddd");
private static readonly Guid ClientGuid = Guid.Parse("cccccccc-cccc-cccc-cccc-cccccccccccc");
[Fact]
public async Task Search_ForceFiltreNonArchive()
{
var interventions = new FakeInterventionService();
var service = NewService(interventions, new FakeRendezVousService(), new FakeSiteService(), new FakeClientService());
await service.SearchAsync(new MobileInterventionSearchRequest(), null, new Dictionary());
Assert.False(interventions.LastRequest?.EstArchive);
}
[Fact]
public async Task Search_NumeroNumerique_ResteReferencePartielle()
{
var interventions = new FakeInterventionService();
var service = NewService(interventions, new FakeRendezVousService(), new FakeSiteService(), new FakeClientService());
await service.SearchAsync(new MobileInterventionSearchRequest { Reference = "105" }, null, new Dictionary());
// Le champ N° d'intervention cible IN_RefInterne (recherche partielle) :
// « 105 » est transmis tel quel à Reference, jamais à NumIntervention.
Assert.Equal("105", interventions.LastRequest?.Reference);
Assert.Null(interventions.LastRequest?.NumIntervention);
}
[Fact]
public async Task Search_Numero105EtTous_ReferencePasseEtIdsNull()
{
var interventions = new FakeInterventionService();
var service = NewService(interventions, new FakeRendezVousService(), new FakeSiteService(), new FakeClientService());
await service.SearchAsync(new MobileInterventionSearchRequest
{
Reference = "105",
ClientId = "",
SiteId = " ",
CollaborateurId = Guid.Empty.ToString(),
AvecRendezVous = null,
RendezVousDate = null
}, null, new Dictionary());
Assert.Equal("105", interventions.LastRequest?.Reference);
Assert.Null(interventions.LastRequest?.NumIntervention);
Assert.Null(interventions.LastRequest?.ClientId);
Assert.Null(interventions.LastRequest?.SiteId);
Assert.Null(interventions.LastRequest?.CollaborateurId);
Assert.False(interventions.LastRequest?.EstArchive);
}
[Fact]
public async Task Search_NumeroNonNumerique_ResteReferenceTexte()
{
var interventions = new FakeInterventionService();
var service = NewService(interventions, new FakeRendezVousService(), new FakeSiteService(), new FakeClientService());
await service.SearchAsync(new MobileInterventionSearchRequest { Reference = "D000105-1" }, null, new Dictionary());
Assert.Null(interventions.LastRequest?.NumIntervention);
Assert.Equal("D000105-1", interventions.LastRequest?.Reference);
}
[Fact]
public async Task Search_CibleRendezVousParInterventionId()
{
var intervention = new InterventionDetailsDto
{
Id = "intervention-dto-id",
Reference = "105",
SourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105)
};
var interventions = new FakeInterventionService { Results = [intervention] };
var rdv = new FakeRendezVousService();
var service = NewService(interventions, rdv, new FakeSiteService(), new FakeClientService());
await service.SearchAsync(new MobileInterventionSearchRequest(), null, new Dictionary());
// Une SEULE requête bulk : Ids porte les PK numériques (jamais un
// InterventionId par intervention, ni un N+1).
var request = Assert.Single(rdv.Requests);
Assert.Equal("105", Assert.Single(request.Ids!));
Assert.Null(request.InterventionId);
}
[Fact]
public async Task Search_DetailPorteIdentiteCanonique()
{
// L'identité interne du DTO source est aléatoire (EntityBase.Id) ; le
// résultat mobile doit porter le GUID public canonique résolu (GUID
// physique Omika), afin que la fiche retrouve le snapshot et les
// rendez-vous/contacts liés par identité.
Guid canonical = Guid.Parse("aaaaaaaa-bbbb-cccc-dddd-eeeeeeee0000");
var intervention = new InterventionDetailsDto
{
Id = Guid.NewGuid().ToString(),
Reference = "105",
SourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, EntityGuid: canonical)
};
var interventions = new FakeInterventionService { Results = [intervention] };
var service = NewService(interventions, new FakeRendezVousService(), new FakeSiteService(), new FakeClientService());
var results = await service.SearchAsync(new MobileInterventionSearchRequest(), null, new Dictionary());
var item = Assert.Single(results);
Assert.Equal(canonical.ToString("D"), item.Detail.Id);
}
[Fact]
public async Task Search_ZeroIntervention_NeChargeRien()
{
var interventions = new FakeInterventionService { Results = [] };
var rdv = new FakeRendezVousService();
var sites = new FakeSiteService();
var clients = new FakeClientService();
var service = NewService(interventions, rdv, sites, clients);
await service.SearchAsync(new MobileInterventionSearchRequest(), null, new Dictionary());
Assert.Empty(rdv.Requests);
Assert.Empty(sites.RequestedIds);
Assert.Empty(clients.RequestedIds);
}
[Fact]
public async Task Search_ResoutSiteClientEtAdresse()
{
var contactGuid = Guid.Parse("eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee");
var intervention = new InterventionDetailsDto
{
Id = "intervention-dto-id",
// Les noms client/site, l'adresse et les contacts sont désormais
// dénormalisés par le repository via une jointure SQL unique : le
// service mobile les lit directement, sans appel site/client.
SiteNom = "Site A",
SiteAdresse = "12 rue Exemple, 75000 Paris",
ClientNom = "Client A",
Contacts =
[
new ContactDto
{
Id = contactGuid.ToString(),
Nom = "Dupont",
Prenom = "Jean",
NomAffiche = "Jean Dupont"
}
]
};
var interventions = new FakeInterventionService { Results = [intervention] };
var service = NewService(interventions, new FakeRendezVousService(), new FakeSiteService(), new FakeClientService());
var results = await service.SearchAsync(new MobileInterventionSearchRequest(), null, new Dictionary());
var item = Assert.Single(results);
Assert.Equal("Site A", item.SiteNom);
Assert.Equal("12 rue Exemple, 75000 Paris", item.SiteAddressDisplay);
Assert.Equal("Client A", item.ClientNom);
Assert.Equal("Jean Dupont", item.ContactNom);
}
[Fact]
public async Task Search_RendezVousSansDate_ExcluDuCompteur()
{
var intervention = new InterventionDetailsDto
{
Id = "intervention-dto-id",
SourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105)
};
var interventions = new FakeInterventionService { Results = [intervention] };
var rdv = new FakeRendezVousService
{
Results =
[
new RendezVousDetailsDto
{
Debut = new DateTime(2026, 8, 19, 10, 0, 0),
InterventionSourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105)
},
new RendezVousDetailsDto { Debut = default }
]
};
var service = NewService(interventions, rdv, new FakeSiteService(), new FakeClientService());
var results = await service.SearchAsync(new MobileInterventionSearchRequest(), null, new Dictionary());
// 1 RDV daté + 1 RDV sans date → seul le daté compte (éligibilité mobile).
var item = Assert.Single(results);
Assert.Equal(1, item.NbRendezVous);
}
[Fact]
public async Task Search_InterventionSansRdv_NbRendezVousZero()
{
var intervention = new InterventionDetailsDto
{
Id = "intervention-dto-id",
SourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105)
};
var interventions = new FakeInterventionService { Results = [intervention] };
var rdv = new FakeRendezVousService { Results = [] };
var service = NewService(interventions, rdv, new FakeSiteService(), new FakeClientService());
var results = await service.SearchAsync(new MobileInterventionSearchRequest(), null, new Dictionary());
var item = Assert.Single(results);
Assert.Equal(0, item.NbRendezVous);
}
[Fact]
public async Task Search_InterventionAvecUnRdvDate_NbRendezVousUn()
{
var intervention = new InterventionDetailsDto
{
Id = "intervention-dto-id",
SourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105)
};
var interventions = new FakeInterventionService { Results = [intervention] };
var rdv = new FakeRendezVousService
{
Results =
[
new RendezVousDetailsDto
{
Debut = new DateTime(2026, 8, 19, 10, 0, 0),
InterventionSourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105)
}
]
};
var service = NewService(interventions, rdv, new FakeSiteService(), new FakeClientService());
var results = await service.SearchAsync(new MobileInterventionSearchRequest(), null, new Dictionary());
var item = Assert.Single(results);
Assert.Equal(1, item.NbRendezVous);
}
[Fact]
public async Task Search_InterventionAvecPlusieursRdv_NbRendezVousCorrect()
{
var intervention = new InterventionDetailsDto
{
Id = "intervention-dto-id",
SourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105)
};
var interventions = new FakeInterventionService { Results = [intervention] };
var rdv = new FakeRendezVousService
{
Results =
[
new RendezVousDetailsDto
{
Debut = new DateTime(2026, 8, 19, 10, 0, 0),
InterventionSourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105)
},
new RendezVousDetailsDto
{
Debut = new DateTime(2026, 8, 20, 11, 0, 0),
InterventionSourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105)
}
]
};
var service = NewService(interventions, rdv, new FakeSiteService(), new FakeClientService());
var results = await service.SearchAsync(new MobileInterventionSearchRequest(), null, new Dictionary());
var item = Assert.Single(results);
Assert.Equal(2, item.NbRendezVous);
}
[Fact]
public async Task Search_RdvDateUniquementSurAffectation_CompteDansLeCompteur()
{
// Omika : RV_Date (racine) vide → Debut = default, mais l'affectation
// porte la date réelle (RVC_DateDeb / RVC_DateFin). Le RDV doit compter.
var intervention = new InterventionDetailsDto
{
Id = "intervention-dto-id",
SourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105)
};
var interventions = new FakeInterventionService { Results = [intervention] };
var rdv = new FakeRendezVousService
{
Results =
[
new RendezVousDetailsDto
{
Debut = default,
InterventionSourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105),
Collaborateurs =
[
new AffectationCollaborateurDto
{
CollaborateurId = Guid.NewGuid().ToString(),
PeriodeDebut = new DateTime(2026, 8, 19, 10, 0, 0),
PeriodeFin = new DateTime(2026, 8, 19, 11, 30, 0)
}
]
}
]
};
var service = NewService(interventions, rdv, new FakeSiteService(), new FakeClientService());
var results = await service.SearchAsync(new MobileInterventionSearchRequest(), null, new Dictionary());
var item = Assert.Single(results);
Assert.Equal(1, item.NbRendezVous);
}
[Fact]
public async Task Search_RdvGroupeMultipleAffectations_CompteCommeUnSeulRdv()
{
// Un RDV groupe Omika = un noyau RDV_Planning + plusieurs affectations.
// Le compteur doit compter 1 (le noyau), jamais le nombre d'affectations.
var intervention = new InterventionDetailsDto
{
Id = "intervention-dto-id",
SourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105)
};
var interventions = new FakeInterventionService { Results = [intervention] };
var rdv = new FakeRendezVousService
{
Results =
[
new RendezVousDetailsDto
{
Debut = default,
InterventionSourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105),
Collaborateurs =
[
new AffectationCollaborateurDto
{
CollaborateurId = Guid.NewGuid().ToString(),
PeriodeDebut = new DateTime(2026, 8, 19, 10, 0, 0)
},
new AffectationCollaborateurDto
{
CollaborateurId = Guid.NewGuid().ToString(),
PeriodeDebut = new DateTime(2026, 8, 19, 10, 0, 0)
}
]
}
]
};
var service = NewService(interventions, rdv, new FakeSiteService(), new FakeClientService());
var results = await service.SearchAsync(new MobileInterventionSearchRequest(), null, new Dictionary());
var item = Assert.Single(results);
Assert.Equal(1, item.NbRendezVous);
}
[Fact]
public async Task GetRendezVousAsync_RdvDateSurAffectation_RestitueLeRdvRabattu()
{
// Omika : RV_Date (racine) vide → Debut = default. Le détail de la fiche
// intervention doit rabattre la date de l'affectation (RVC_DateDeb) AVANT
// l'éligibilité, exactement comme le compteur NbRendezVous. Sans cela, un
// rendez-vous réellement daté est écarté (liste vide) alors que la liste
// des interventions affiche un compteur non nul.
var intervention = new InterventionDetailsDto
{
Id = "intervention-dto-id",
SourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105)
};
var interventions = new FakeInterventionService { GetByIdResult = intervention };
DateTime debutAffectation = new DateTime(2026, 8, 19, 10, 0, 0);
var rdv = new FakeRendezVousService
{
Results =
[
new RendezVousDetailsDto
{
Id = Guid.NewGuid().ToString(),
Debut = default,
SourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 200),
InterventionSourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105),
Collaborateurs =
[
new AffectationCollaborateurDto
{
CollaborateurId = Guid.NewGuid().ToString(),
PeriodeDebut = debutAffectation,
PeriodeFin = debutAffectation.AddHours(1.5)
}
]
}
]
};
var service = NewService(interventions, rdv, new FakeSiteService(), new FakeClientService());
IReadOnlyList result = await service.GetRendezVousAsync("intervention-dto-id");
RendezVousDetailsDto item = Assert.Single(result);
Assert.Equal(debutAffectation, item.Debut);
}
[Fact]
public async Task GetRendezVousAsync_TrieDuPlusRecentAuPlusAncien()
{
// Règle produit : la liste des rendez-vous d'une intervention est triée
// par date décroissante (le plus récent d'abord), comme Batik.
var intervention = new InterventionDetailsDto
{
Id = "intervention-dto-id",
SourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105)
};
var interventions = new FakeInterventionService { GetByIdResult = intervention };
var rdv = new FakeRendezVousService
{
Results =
[
new RendezVousDetailsDto { Id = Guid.NewGuid().ToString(), Debut = new DateTime(2026, 8, 19, 10, 0, 0) },
new RendezVousDetailsDto { Id = Guid.NewGuid().ToString(), Debut = new DateTime(2026, 8, 21, 10, 0, 0) },
new RendezVousDetailsDto { Id = Guid.NewGuid().ToString(), Debut = new DateTime(2026, 8, 20, 10, 0, 0) }
]
};
var service = NewService(interventions, rdv, new FakeSiteService(), new FakeClientService());
IReadOnlyList result = await service.GetRendezVousAsync("intervention-dto-id");
Assert.Equal(3, result.Count);
Assert.Equal(new DateTime(2026, 8, 21, 10, 0, 0), result[0].Debut);
Assert.Equal(new DateTime(2026, 8, 20, 10, 0, 0), result[1].Debut);
Assert.Equal(new DateTime(2026, 8, 19, 10, 0, 0), result[2].Debut);
}
[Fact]
public async Task Search_RdvSansAucuneDate_ExcluDuCompteur()
{
// Un RDV sans date sur la racine ET sans affectation datée est
// « à attribuer » : il ne doit pas compter.
var intervention = new InterventionDetailsDto
{
Id = "intervention-dto-id",
SourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105)
};
var interventions = new FakeInterventionService { Results = [intervention] };
var rdv = new FakeRendezVousService
{
Results =
[
new RendezVousDetailsDto
{
Debut = default,
InterventionSourceReference = new LegacyEntityReference(DatabaseSchemaVersion.Omika, NumericId: 105)
}
]
};
var service = NewService(interventions, rdv, new FakeSiteService(), new FakeClientService());
var results = await service.SearchAsync(new MobileInterventionSearchRequest(), null, new Dictionary());
var item = Assert.Single(results);
Assert.Equal(0, item.NbRendezVous);
}
private static MobileInterventionSearchService NewService(
IInterventionService interventions,
IRendezVousService rdv,
ISiteService sites,
IClientService clients)
=> new(interventions, rdv, sites, clients, new FakeCollaborateurService(), new FakeIdentityResolver());
private sealed class FakeCollaborateurService : ICollaborateurService
{
public Task> SearchAsync(SearchCollaborateurRequest request, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task> SearchDetailsAsync(SearchCollaborateurRequest request, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task GetByIdAsync(string id, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task CreateAsync(CreateCollaborateurRequest request, CancellationToken cancellationToken = default, AuditActor? auteur = null)
=> throw new NotSupportedException();
public Task UpdateAsync(string id, UpdateCollaborateurRequest request, CancellationToken cancellationToken = default, AuditActor? auteur = null)
=> throw new NotSupportedException();
public Task ArchiveAsync(string id, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task> GetSocieteIdsAsync(long collaborateurId, CancellationToken cancellationToken = default)
=> Task.FromResult>([]);
public Task> GetAllowedCollaborateurIdsAsync(long collaborateurId, bool includeSocietePrincipale, bool includeSocietes, bool includeEquipe, CancellationToken cancellationToken = default)
=> Task.FromResult>([]);
public Task> GetRendezVousAsync(string collaborateurId, DateTime debutMin, DateTime debutMax, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task> GetRendezVousForCollaborateursAsync(IReadOnlyList collaborateurIds, DateTime debutMin, DateTime debutMax, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
}
private sealed class FakeIdentityResolver : IMobileEntityIdentityResolver
{
public Guid CreateCanonicalIdentity(string entityType, PhysicalEntityIdentity physical)
=> physical.Guid ?? Guid.NewGuid();
public PhysicalEntityIdentity? ResolvePhysicalIdentity(string entityType, Guid publicGuid)
=> new PhysicalEntityIdentity { Guid = publicGuid };
public bool IsCanonical(string entityType, Guid publicGuid)
=> publicGuid != Guid.Empty;
}
private sealed class FakeInterventionService : IInterventionService
{
public List Results { get; set; } = [];
public InterventionDetailsDto? GetByIdResult { get; set; }
public SearchInterventionsRequest? LastRequest { get; set; }
public Task> SearchAsync(SearchInterventionsRequest request, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task> SearchDetailsAsync(SearchInterventionsRequest request, CancellationToken cancellationToken = default)
{
LastRequest = request;
return Task.FromResult(new PagedResult(Results, 1, Results.Count, Results.Count, 1));
}
public Task GetByIdAsync(string id, CancellationToken cancellationToken = default)
=> Task.FromResult(GetByIdResult);
public Task CreateAsync(CreateInterventionRequest request, CancellationToken cancellationToken = default, AuditActor? auteur = null)
=> throw new NotSupportedException();
public Task UpdateAsync(string id, UpdateInterventionRequest request, CancellationToken cancellationToken = default, AuditActor? auteur = null)
=> throw new NotSupportedException();
public Task ArchiveAsync(string id, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task> GetNotesAsync(string interventionId, CancellationToken cancellationToken = default)
=> Task.FromResult>([]);
public Task> GetNotesAdministrativesAsync(string interventionId, CancellationToken cancellationToken = default)
=> Task.FromResult>([]);
public Task AddNoteAsync(string interventionId, string contenu, AuditActor? auteur, CancellationToken cancellationToken = default)
=> Task.FromResult(new NoteInterneDto());
public Task> GetEmailsAsync(string interventionId, CancellationToken cancellationToken = default)
=> Task.FromResult>([]);
public Task AddEmailAsync(string interventionId, CreateEmailInterventionRequest request, AuditActor? auteur, CancellationToken cancellationToken = default)
=> Task.FromResult(new EmailInterventionDto());
}
private sealed class FakeRendezVousService : IRendezVousService
{
public List Requests { get; } = [];
public List Results { get; set; } = [];
public Task> SearchAsync(SearchRendezVousRequest request, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task> SearchDetailsAsync(SearchRendezVousRequest request, CancellationToken cancellationToken = default)
{
Requests.Add(request);
return Task.FromResult(new PagedResult(Results, 1, Results.Count, Results.Count, 1));
}
public Task GetByIdAsync(string id, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task CreateAsync(CreateRendezVousRequest request, CancellationToken cancellationToken = default, AuditActor? auteur = null)
=> throw new NotSupportedException();
public Task UpdateAsync(string id, UpdateRendezVousRequest request, CancellationToken cancellationToken = default, AuditActor? auteur = null)
=> throw new NotSupportedException();
public Task CancelAsync(string id, AnnulationRendezVousDto annulation, CancellationToken cancellationToken = default, AuditActor? auteur = null)
=> throw new NotSupportedException();
public Task ArchiveAsync(string id, CancellationToken cancellationToken = default, AuditActor? auteur = null)
=> throw new NotSupportedException();
public Task SetTempsValideAsync(string rendezVousId, string collaborateurId, bool tempsValide, CancellationToken cancellationToken = default, AuditActor? auteur = null)
=> Task.FromResult(true);
}
private sealed class FakeSiteService : ISiteService
{
public Dictionary ById { get; set; } = new(StringComparer.OrdinalIgnoreCase);
public List RequestedIds { get; } = [];
public Task> SearchAsync(SearchSitesRequest request, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task> SearchDetailsAsync(SearchSitesRequest request, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task GetByIdAsync(string id, CancellationToken cancellationToken = default)
{
RequestedIds.Add(id);
ById.TryGetValue(id, out SiteDetailsDto? site);
return Task.FromResult(site);
}
public Task> GetContactsAsync(string id, CancellationToken cancellationToken = default)
=> Task.FromResult>([]);
public Task> GetRendezVousAsync(string id, CancellationToken cancellationToken = default)
=> Task.FromResult>([]);
public Task> GetClientsAsync(string id, CancellationToken cancellationToken = default)
=> Task.FromResult>([]);
public Task CreateAsync(CreateSiteRequest request, CancellationToken cancellationToken = default, AuditActor? auteur = null)
=> throw new NotSupportedException();
public Task UpdateAsync(string id, UpdateSiteRequest request, CancellationToken cancellationToken = default, AuditActor? auteur = null)
=> throw new NotSupportedException();
public Task ArchiveAsync(string id, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
}
private sealed class FakeClientService : IClientService
{
public Dictionary ById { get; set; } = new(StringComparer.OrdinalIgnoreCase);
public List RequestedIds { get; } = [];
public Task> SearchAsync(SearchClientsRequest request, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task> SearchDetailsAsync(SearchClientsRequest request, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task GetByIdAsync(string id, CancellationToken cancellationToken = default)
{
RequestedIds.Add(id);
ById.TryGetValue(id, out ClientDetailsDto? client);
return Task.FromResult(client);
}
public Task CreateAsync(CreateClientRequest request, CancellationToken cancellationToken = default, AuditActor? auteur = null)
=> throw new NotSupportedException();
public Task UpdateAsync(string id, UpdateClientRequest request, CancellationToken cancellationToken = default, AuditActor? auteur = null)
=> throw new NotSupportedException();
public Task ArchiveAsync(string id, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
}
}