using DD.Persistence.Client; using DD.Persistence.Client.Clients; using DD.Persistence.Client.Clients.Interfaces; using DD.Persistence.Client.Clients.Interfaces.Refit; using DD.Persistence.Database.Entity; using DD.Persistence.Models; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System.Text.Json; using Xunit; namespace DD.Persistence.IntegrationTests.Controllers; public class TimestampedValuesControllerTest : BaseIntegrationTest { private readonly ITimestampedValuesClient timestampedValuesClient; private readonly IMemoryCache memoryCache; private IEnumerable discriminatorIds = []; public TimestampedValuesControllerTest(WebAppFactoryFixture factory) : base(factory) { var refitClientFactory = scope.ServiceProvider .GetRequiredService>(); var logger = scope.ServiceProvider.GetRequiredService>(); timestampedValuesClient = scope.ServiceProvider .GetRequiredService(); memoryCache = scope.ServiceProvider.GetRequiredService(); } [Fact] public async Task AddRange_returns_success() { var discriminatorId = Guid.NewGuid(); discriminatorIds.Append(discriminatorId); await AddRange(discriminatorId); } [Fact] public async Task Get_returns_success() { //arrange Cleanup(); var discriminatorId = Guid.NewGuid(); discriminatorIds.Append(discriminatorId); //act var response = await timestampedValuesClient.Get(discriminatorId, null, null, 0, 1, CancellationToken.None); //assert Assert.Null(response); } [Fact] public async Task Get_AfterSave_returns_success() { //arrange Cleanup(); var discriminatorId = Guid.NewGuid(); discriminatorIds.Append(discriminatorId); var timestampBegin = DateTimeOffset.UtcNow.AddDays(-1); var columnNames = new List() { "A", "C" }; var skip = 5; var take = 5; var dtos = await AddRange(discriminatorId); //act var response = await timestampedValuesClient.Get(discriminatorId, timestampBegin, columnNames, skip, take, CancellationToken.None); //assert Assert.NotNull(response); Assert.NotEmpty(response); var actualCount = response.Count(); Assert.Equal(take, actualCount); var actualColumnNames = response.SelectMany(e => e.Values.Keys).Distinct().ToList(); Assert.Equal(columnNames, actualColumnNames); var expectedValueKind = JsonValueKind.Number; var actualValueKind = ((JsonElement) response.First().Values["A"]).ValueKind; Assert.Equal(expectedValueKind, actualValueKind); expectedValueKind = JsonValueKind.String; actualValueKind = ((JsonElement)response.First().Values["C"]).ValueKind; Assert.Equal(expectedValueKind, actualValueKind); } [Fact] public async Task GetGtDate_returns_success() { //arrange Cleanup(); var discriminatorId = Guid.NewGuid(); discriminatorIds.Append(discriminatorId); var timestampBegin = DateTimeOffset.UtcNow.AddDays(-1); //act var response = await timestampedValuesClient.GetGtDate(discriminatorId, timestampBegin, CancellationToken.None); //assert Assert.Null(response); } [Fact] public async Task GetGtDate_AfterSave_returns_success() { //arrange Cleanup(); var discriminatorId = Guid.NewGuid(); discriminatorIds.Append(discriminatorId); var dtos = await AddRange(discriminatorId); var timestampBegin = DateTimeOffset.UtcNow.AddSeconds(-5); //act var response = await timestampedValuesClient.GetGtDate(discriminatorId, timestampBegin, CancellationToken.None); //assert Assert.NotNull(response); Assert.NotEmpty(response); var expectedCount = dtos.Count(dto => dto.Timestamp.ToUniversalTime() > timestampBegin); var actualCount = response.Count(); Assert.Equal(expectedCount, actualCount); } [Fact] public async Task GetFirst_returns_success() { //arrange Cleanup(); var discriminatorId = Guid.NewGuid(); discriminatorIds.Append(discriminatorId); var take = 1; //act var response = await timestampedValuesClient.GetFirst(discriminatorId, take, CancellationToken.None); //assert Assert.Null(response); } [Fact] public async Task GetFirst_AfterSave_returns_success() { //arrange Cleanup(); var discriminatorId = Guid.NewGuid(); discriminatorIds.Append(discriminatorId); var dtos = await AddRange(discriminatorId); var take = 1; //act var response = await timestampedValuesClient.GetFirst(discriminatorId, take, CancellationToken.None); //assert Assert.NotNull(response); Assert.NotEmpty(response); var expectedTimestampString = dtos .OrderBy(dto => dto.Timestamp) .First().Timestamp .ToUniversalTime() .ToString(); var actualTimestampString = response .First().Timestamp .ToUniversalTime() .ToString(); Assert.Equal(expectedTimestampString, actualTimestampString); } [Fact] public async Task GetLast_returns_success() { //arrange Cleanup(); var discriminatorId = Guid.NewGuid(); discriminatorIds.Append(discriminatorId); var take = 1; //act var response = await timestampedValuesClient.GetLast(discriminatorId, take, CancellationToken.None); //assert Assert.Null(response); } [Fact] public async Task GetLast_AfterSave_returns_success() { //arrange Cleanup(); var discriminatorId = Guid.NewGuid(); discriminatorIds.Append(discriminatorId); var dtos = await AddRange(discriminatorId); var take = 1; //act var response = await timestampedValuesClient.GetLast(discriminatorId, take, CancellationToken.None); //assert Assert.NotNull(response); Assert.NotEmpty(response); var expectedTimestampString = dtos .OrderByDescending(dto => dto.Timestamp) .First().Timestamp .ToUniversalTime() .ToString(); var actualTimestampString = response .First().Timestamp .ToUniversalTime() .ToString(); Assert.Equal(expectedTimestampString, actualTimestampString); } [Fact] public async Task GetResampledData_returns_success() { //arrange Cleanup(); var discriminatorId = Guid.NewGuid(); discriminatorIds.Append(discriminatorId); var timestampBegin = DateTimeOffset.UtcNow; //act var response = await timestampedValuesClient.GetResampledData(discriminatorId, timestampBegin); //assert Assert.Null(response); } [Fact] public async Task GetResampledData_AfterSave_returns_success() { //arrange Cleanup(); var discriminatorId = Guid.NewGuid(); discriminatorIds.Append(discriminatorId); var count = 2048; var timestampBegin = DateTimeOffset.UtcNow; var dtos = await AddRange(discriminatorId, count); //act var response = await timestampedValuesClient.GetResampledData(discriminatorId, timestampBegin, count); //assert Assert.NotNull(response); Assert.NotEmpty(response); var expectedCount = count / 2; var actualCount = response.Count(); Assert.Equal(expectedCount, actualCount); } [Fact] public async Task Count_returns_success() { //arrange Cleanup(); var discriminatorId = Guid.NewGuid(); discriminatorIds.Append(discriminatorId); //act var response = await timestampedValuesClient.Count(discriminatorId, CancellationToken.None); //assert Assert.Equal(0, response); } [Fact] public async Task Count_AfterSave_returns_success() { //arrange Cleanup(); var discriminatorId = Guid.NewGuid(); discriminatorIds.Append(discriminatorId); var dtos = await AddRange(discriminatorId); //act var response = await timestampedValuesClient.Count(discriminatorId, CancellationToken.None); //assert var expectedCount = dtos.Count(); Assert.Equal(expectedCount, response); } [Fact] public async Task GetDatesRange_returns_success() { //arrange Cleanup(); var discriminatorId = Guid.NewGuid(); discriminatorIds.Append(discriminatorId); //act var response = await timestampedValuesClient.GetDatesRange(discriminatorId, CancellationToken.None); //assert Assert.Null(response); } [Fact] public async Task GetDatesRange_AfterSave_returns_success() { //arrange Cleanup(); var discriminatorId = Guid.NewGuid(); discriminatorIds.Append(discriminatorId); var dtos = await AddRange(discriminatorId); //act var response = await timestampedValuesClient.GetDatesRange(discriminatorId, CancellationToken.None); //assert Assert.NotNull(response); var expectedDateFromString = dtos .OrderBy(dto => dto.Timestamp) .First().Timestamp .ToUniversalTime() .ToString(); var actualDateFromString = response.From .ToUniversalTime() .ToString(); Assert.Equal(expectedDateFromString, actualDateFromString); var expectedDateToString = dtos .OrderByDescending(dto => dto.Timestamp) .First().Timestamp .ToUniversalTime() .ToString(); var actualDateToString = response.To .ToUniversalTime() .ToString(); Assert.Equal(expectedDateToString, actualDateToString); } private async Task> AddRange(Guid discriminatorId, int countToCreate = 10) { // arrange IEnumerable generatedDtos = Generate(countToCreate, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7))); // act var response = await timestampedValuesClient.AddRange(discriminatorId, generatedDtos, CancellationToken.None); // assert Assert.Equal(generatedDtos.Count(), response); return generatedDtos; } private static IEnumerable Generate(int countToCreate, DateTimeOffset from) { var result = new List(); for (int i = 0; i < countToCreate; i++) { var values = new Dictionary() { { "A", i }, { "B", i * 1.1 }, { "C", $"Any{i}" }, { "D", DateTimeOffset.Now }, }; yield return new TimestampedValuesDto() { Timestamp = from.AddSeconds(i), Values = values }; } } private void Cleanup() { discriminatorIds = []; dbContext.CleanupDbSet(); dbContext.CleanupDbSet(); } }