372 lines
11 KiB
C#
372 lines
11 KiB
C#
|
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 static readonly string SystemCacheKey = $"{typeof(ValuesIdentity).FullName}CacheKey";
|
||
|
private readonly ITimestampedValuesClient timestampedValuesClient;
|
||
|
private readonly IMemoryCache memoryCache;
|
||
|
|
||
|
public TimestampedValuesControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||
|
{
|
||
|
var refitClientFactory = scope.ServiceProvider
|
||
|
.GetRequiredService<IRefitClientFactory<IRefitTimestampedValuesClient>>();
|
||
|
var logger = scope.ServiceProvider.GetRequiredService<ILogger<TimestampedValuesClient>>();
|
||
|
|
||
|
timestampedValuesClient = scope.ServiceProvider
|
||
|
.GetRequiredService<ITimestampedValuesClient>();
|
||
|
memoryCache = scope.ServiceProvider.GetRequiredService<IMemoryCache>();
|
||
|
}
|
||
|
|
||
|
[Fact]
|
||
|
public async Task AddRange_returns_success()
|
||
|
{
|
||
|
var discriminatorId = Guid.NewGuid();
|
||
|
|
||
|
await AddRange(discriminatorId);
|
||
|
}
|
||
|
|
||
|
[Fact]
|
||
|
public async Task Get_returns_success()
|
||
|
{
|
||
|
//arrange
|
||
|
Cleanup();
|
||
|
|
||
|
var discriminatorId = Guid.NewGuid();
|
||
|
|
||
|
//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();
|
||
|
var timestampBegin = DateTimeOffset.UtcNow.AddDays(-1);
|
||
|
var columnNames = new List<string>() { "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();
|
||
|
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();
|
||
|
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();
|
||
|
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();
|
||
|
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();
|
||
|
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();
|
||
|
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();
|
||
|
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();
|
||
|
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();
|
||
|
|
||
|
//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();
|
||
|
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();
|
||
|
|
||
|
//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();
|
||
|
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<IEnumerable<TimestampedValuesDto>> AddRange(Guid discriminatorId, int countToCreate = 10)
|
||
|
{
|
||
|
// arrange
|
||
|
IEnumerable<TimestampedValuesDto> 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<TimestampedValuesDto> Generate(int countToCreate, DateTimeOffset from)
|
||
|
{
|
||
|
var result = new List<TimestampedValuesDto>();
|
||
|
for (int i = 0; i < countToCreate; i++)
|
||
|
{
|
||
|
var values = new Dictionary<string, object>()
|
||
|
{
|
||
|
{ "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()
|
||
|
{
|
||
|
memoryCache.Remove(SystemCacheKey);
|
||
|
dbContext.CleanupDbSet<TimestampedValues>();
|
||
|
dbContext.CleanupDbSet<ValuesIdentity>();
|
||
|
}
|
||
|
}
|