306 lines
13 KiB
C#
306 lines
13 KiB
C#
using System.Text.Json;
|
|
using Omika.App.Local.Abstractions;
|
|
using Omika.App.Local.Infrastructure;
|
|
using Omika.App.Local.Models;
|
|
using Omika.App.Local.Services;
|
|
using Omika.Core.Contracts.Clients;
|
|
using Omika.Core.Contracts.Interventions;
|
|
using Omika.Core.Contracts.Mobile.Bootstrap;
|
|
using Omika.Core.Contracts.Mobile.Documents;
|
|
using Omika.Core.Contracts.Mobile.Interventions;
|
|
using Omika.Core.Contracts.Mobile.License;
|
|
using Omika.Core.Contracts.Mobile.Snapshot;
|
|
using Omika.Core.Contracts.Mobile.Sync;
|
|
using Omika.Core.Contracts.Organisation;
|
|
using Omika.Core.Contracts.Sites;
|
|
|
|
namespace Omika.Tests.Mobile.Local;
|
|
|
|
public sealed class InterventionContextualRelationsTests : LocalTestBase
|
|
{
|
|
[Fact]
|
|
public async Task ClientDetail_IgnoreLaTableInterventionHistorique()
|
|
{
|
|
Guid clientId = Guid.NewGuid();
|
|
Guid interventionId = Guid.NewGuid();
|
|
await ClientRepository.UpsertAsync(Client(clientId, "Client A"));
|
|
await InterventionRepository.UpsertAsync(LocalIntervention(interventionId, clientId: clientId));
|
|
|
|
var service = new ClientLocalService(ClientRepository, DossierRepository, ContextInterventionCacheRepository, ClientStateRepository, ApiClient);
|
|
|
|
ClientDetail? result = await service.GetClientByIdAsync(clientId);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.False(result.InterventionsCacheAvailable);
|
|
Assert.Empty(result.Interventions);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ClientRefreshOnline_RechercheParClientId_EtNeTouchePasInterventionCache()
|
|
{
|
|
Guid clientId = Guid.NewGuid();
|
|
Guid interventionId = Guid.NewGuid();
|
|
await ClientRepository.UpsertAsync(Client(clientId, "Client A"));
|
|
|
|
var api = new RecordingApiClient([Result(Intervention(interventionId, clientId: clientId))]);
|
|
var service = new ClientLocalService(ClientRepository, DossierRepository, ContextInterventionCacheRepository, ClientStateRepository, api);
|
|
|
|
ClientDetail? result = await service.RefreshClientInterventionsAsync(clientId);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.Equal(clientId.ToString(), api.LastSearchRequest?.ClientId);
|
|
Assert.Null(api.LastSearchRequest?.SiteId);
|
|
Assert.Null(api.LastSearchRequest?.CollaborateurId);
|
|
var intervention = Assert.Single(result.Interventions);
|
|
Assert.Equal(interventionId, intervention.InterventionGuid);
|
|
Assert.Null(await InterventionCacheRepository.GetByIdAsync(interventionId));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ClientOffline_AvecCache_AfficheLeCache()
|
|
{
|
|
Guid clientId = Guid.NewGuid();
|
|
Guid interventionId = Guid.NewGuid();
|
|
await ClientRepository.UpsertAsync(Client(clientId, "Client A"));
|
|
await ContextInterventionCacheRepository.ReplaceAsync(
|
|
InterventionContextTypes.Client,
|
|
clientId,
|
|
[Intervention(interventionId, clientId: clientId)]);
|
|
|
|
var service = new ClientLocalService(ClientRepository, DossierRepository, ContextInterventionCacheRepository, ClientStateRepository, ApiClient);
|
|
|
|
ClientDetail? result = await service.GetClientByIdAsync(clientId);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.True(result.InterventionsCacheAvailable);
|
|
Assert.Equal(interventionId, Assert.Single(result.Interventions).InterventionGuid);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ClientOffline_SansCache_NeDeclarePasZeroCommeCertitude()
|
|
{
|
|
Guid clientId = Guid.NewGuid();
|
|
await ClientRepository.UpsertAsync(Client(clientId, "Client A"));
|
|
|
|
var service = new ClientLocalService(ClientRepository, DossierRepository, ContextInterventionCacheRepository, ClientStateRepository, ApiClient);
|
|
|
|
ClientDetail? result = await service.GetClientByIdAsync(clientId);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.False(result.InterventionsCacheAvailable);
|
|
Assert.Empty(result.Interventions);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task SiteRefreshOnline_RechercheParSiteId()
|
|
{
|
|
Guid siteId = Guid.NewGuid();
|
|
Guid interventionId = Guid.NewGuid();
|
|
await SiteRepository.UpsertAsync(Site(siteId, "Site A"));
|
|
|
|
var api = new RecordingApiClient([Result(Intervention(interventionId, siteId: siteId))]);
|
|
var service = new SiteLocalService(SiteRepository, ClientRepository, PersonneRepository, RendezVousRepository, InterventionRepository, ContextInterventionCacheRepository, SiteStateRepository, api);
|
|
|
|
SiteDetail? result = await service.RefreshSiteInterventionsAsync(siteId);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.Equal(siteId.ToString(), api.LastSearchRequest?.SiteId);
|
|
Assert.Null(api.LastSearchRequest?.ClientId);
|
|
Assert.Null(api.LastSearchRequest?.CollaborateurId);
|
|
Assert.Equal(interventionId, Assert.Single(result.Interventions).InterventionGuid);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CollaborateurRefreshOnline_RechercheParCollaborateurId()
|
|
{
|
|
Guid collaborateurId = Guid.NewGuid();
|
|
Guid interventionId = Guid.NewGuid();
|
|
await CollaborateurRepository.UpsertAsync(Collaborateur(collaborateurId));
|
|
|
|
var api = new RecordingApiClient([Result(Intervention(interventionId, collaborateurId: collaborateurId))]);
|
|
var service = new CollaborateurLocalService(CollaborateurRepository, RendezVousRepository, ContextInterventionCacheRepository, api, SessionService);
|
|
|
|
CollaborateurDetail? result = await service.RefreshCollaborateurInterventionsAsync(collaborateurId);
|
|
|
|
Assert.NotNull(result);
|
|
Assert.Equal(collaborateurId.ToString(), api.LastSearchRequest?.CollaborateurId);
|
|
Assert.Null(api.LastSearchRequest?.ClientId);
|
|
Assert.Null(api.LastSearchRequest?.SiteId);
|
|
Assert.Equal(interventionId, Assert.Single(result.Interventions).InterventionGuid);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task RechercheContextuelle_NeModifiePasDerniereRechercheNiFavoris()
|
|
{
|
|
Guid clientId = Guid.NewGuid();
|
|
Guid interventionId = Guid.NewGuid();
|
|
await ClientRepository.UpsertAsync(Client(clientId, "Client A"));
|
|
await InterventionCacheRepository.UpsertAsync(new CachedIntervention
|
|
{
|
|
Id = interventionId,
|
|
PayloadJson = JsonSerializer.Serialize(Intervention(interventionId, clientId: clientId)),
|
|
IsInLastSearch = false,
|
|
IsPinned = true
|
|
});
|
|
|
|
var api = new RecordingApiClient([Result(Intervention(interventionId, clientId: clientId))]);
|
|
var service = new ClientLocalService(ClientRepository, DossierRepository, ContextInterventionCacheRepository, ClientStateRepository, api);
|
|
|
|
await service.RefreshClientInterventionsAsync(clientId);
|
|
|
|
CachedIntervention? cached = await InterventionCacheRepository.GetByIdAsync(interventionId);
|
|
Assert.NotNull(cached);
|
|
Assert.False(cached.IsInLastSearch);
|
|
Assert.True(cached.IsPinned);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ListesPrincipales_NeDeclenchentAucuneRechercheIntervention()
|
|
{
|
|
var api = new RecordingApiClient([]);
|
|
await ClientRepository.UpsertAsync(Client(Guid.NewGuid(), "Client A"));
|
|
await SiteRepository.UpsertAsync(Site(Guid.NewGuid(), "Site A"));
|
|
await CollaborateurRepository.UpsertAsync(Collaborateur(Guid.NewGuid()));
|
|
|
|
var clientService = new ClientLocalService(ClientRepository, DossierRepository, ContextInterventionCacheRepository, ClientStateRepository, api);
|
|
var siteService = new SiteLocalService(SiteRepository, ClientRepository, PersonneRepository, RendezVousRepository, InterventionRepository, ContextInterventionCacheRepository, SiteStateRepository, api);
|
|
var collaborateurService = new CollaborateurLocalService(CollaborateurRepository, RendezVousRepository, ContextInterventionCacheRepository, api, SessionService);
|
|
|
|
await clientService.GetClientsAsync();
|
|
await siteService.GetSitesAsync();
|
|
await collaborateurService.GetCollaborateursAsync();
|
|
|
|
Assert.Equal(0, api.SearchCalls);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task InterventionContextuelle_OuvreLeDetailDepuisPayloadJson()
|
|
{
|
|
Guid clientId = Guid.NewGuid();
|
|
Guid interventionId = Guid.NewGuid();
|
|
await ClientRepository.UpsertAsync(Client(clientId, "Client A"));
|
|
await ContextInterventionCacheRepository.ReplaceAsync(
|
|
InterventionContextTypes.Client,
|
|
clientId,
|
|
[Intervention(interventionId, clientId: clientId, reference: "INT-CTX")]);
|
|
|
|
var service = new InterventionLocalService(
|
|
InterventionRepository, ClientRepository, SiteRepository, DossierRepository,
|
|
RendezVousRepository, DocumentMetadataRepository, CollaborateurRepository,
|
|
OutboxService, ReconciliationService, ApiClient, InterventionCacheRepository,
|
|
ContextInterventionCacheRepository, Database);
|
|
|
|
InterventionDetail? detail = await service.GetInterventionByIdAsync(interventionId);
|
|
|
|
Assert.NotNull(detail);
|
|
Assert.Equal("INT-CTX", detail.Reference);
|
|
Assert.Equal(clientId, detail.ClientGuid);
|
|
}
|
|
|
|
private static LocalClient Client(Guid id, string nom)
|
|
=> new()
|
|
{
|
|
Id = id,
|
|
PayloadJson = JsonSerializer.Serialize(new ClientDetailsDto { Id = id.ToString(), Nom = nom }),
|
|
UpdatedAtUtc = DateTimeOffset.UtcNow
|
|
};
|
|
|
|
private static LocalSite Site(Guid id, string nom)
|
|
=> new()
|
|
{
|
|
Id = id,
|
|
PayloadJson = JsonSerializer.Serialize(new SiteDetailsDto { Id = id.ToString(), Nom = nom }),
|
|
UpdatedAtUtc = DateTimeOffset.UtcNow
|
|
};
|
|
|
|
private static LocalCollaborateur Collaborateur(Guid id)
|
|
=> new()
|
|
{
|
|
Id = id,
|
|
PayloadJson = JsonSerializer.Serialize(new CollaborateurDetailsDto { Id = id.ToString(), Nom = "Dupont", Prenom = "Jean" }),
|
|
UpdatedAtUtc = DateTimeOffset.UtcNow
|
|
};
|
|
|
|
private static InterventionDetailsDto Intervention(
|
|
Guid id,
|
|
Guid? clientId = null,
|
|
Guid? siteId = null,
|
|
Guid? collaborateurId = null,
|
|
string reference = "INT-001")
|
|
=> new()
|
|
{
|
|
Id = id.ToString(),
|
|
Reference = reference,
|
|
Titre = "Intervention",
|
|
ClientId = clientId?.ToString(),
|
|
SiteId = siteId?.ToString(),
|
|
CollaborateurIds = collaborateurId is null ? [] : [collaborateurId.Value.ToString()],
|
|
EstArchive = false
|
|
};
|
|
|
|
private static LocalIntervention LocalIntervention(Guid id, Guid? clientId = null)
|
|
=> new()
|
|
{
|
|
Id = id,
|
|
ClientId = clientId,
|
|
PayloadJson = JsonSerializer.Serialize(Intervention(id, clientId: clientId)),
|
|
UpdatedAtUtc = DateTimeOffset.UtcNow
|
|
};
|
|
|
|
private static MobileInterventionSearchResult Result(InterventionDetailsDto detail)
|
|
=> new() { Detail = detail };
|
|
|
|
private sealed class RecordingApiClient : IMobileApiClient
|
|
{
|
|
private readonly IReadOnlyList<MobileInterventionSearchResult> _results;
|
|
|
|
public RecordingApiClient(IReadOnlyList<MobileInterventionSearchResult> results)
|
|
{
|
|
_results = results;
|
|
}
|
|
|
|
public string? AccessToken { get; set; }
|
|
public int SearchCalls { get; private set; }
|
|
public MobileInterventionSearchRequest? LastSearchRequest { get; private set; }
|
|
|
|
public Task<IReadOnlyList<MobileInterventionSearchResult>> SearchInterventionsAsync(
|
|
MobileInterventionSearchRequest request,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
SearchCalls++;
|
|
LastSearchRequest = request;
|
|
return Task.FromResult(_results);
|
|
}
|
|
|
|
public Task<MobileLicenseSessionResponse> ActivateAsync(LicenseActivateRequest request, CancellationToken cancellationToken = default)
|
|
=> throw new NotSupportedException();
|
|
|
|
public Task<MobileLicenseSessionResponse> ValidateAsync(LicenseValidateRequest request, CancellationToken cancellationToken = default)
|
|
=> throw new NotSupportedException();
|
|
|
|
public Task<MobileLicenseSessionResponse> GetDevelopmentSessionAsync(string deviceId, CancellationToken cancellationToken = default)
|
|
=> throw new NotSupportedException();
|
|
|
|
public Task<MobileBootstrapResponse> GetBootstrapAsync(CancellationToken cancellationToken = default)
|
|
=> throw new NotSupportedException();
|
|
|
|
public Task<SyncOperationReceipt> SendOperationAsync(SyncOperation operation, CancellationToken cancellationToken = default)
|
|
=> throw new NotSupportedException();
|
|
|
|
public Task<SyncStatusResponse> GetStatusAsync(Guid operationId, CancellationToken cancellationToken = default)
|
|
=> throw new NotSupportedException();
|
|
|
|
public Task<MobileSnapshotResponse> GetSnapshotAsync(CancellationToken cancellationToken = default)
|
|
=> throw new NotSupportedException();
|
|
|
|
public Task<IReadOnlyList<MobileInterventionSearchResult>> GetInterventionsByIdsAsync(MobileInterventionsByIdsRequest request, CancellationToken cancellationToken = default)
|
|
=> throw new NotSupportedException();
|
|
|
|
public Task<DocumentDownloadResponse> DownloadDocumentAsync(Guid documentGuid, CancellationToken cancellationToken = default)
|
|
=> throw new NotSupportedException();
|
|
|
|
public Task<DocumentUploadResponse> UploadDocumentAsync(DocumentUploadRequest request, CancellationToken cancellationToken = default)
|
|
=> throw new NotSupportedException();
|
|
}
|
|
}
|