using Microsoft.Extensions.DependencyInjection; using Persistence.Client; using Persistence.Client.Clients; using Persistence.Models; using Xunit; namespace Persistence.IntegrationTests.Controllers; public class TimestampedSetControllerTest : BaseIntegrationTest { private readonly ITimestampedSetClient client; public TimestampedSetControllerTest(WebAppFactoryFixture factory) : base(factory) { var persistenceClientFactory = scope.ServiceProvider .GetRequiredService(); client = persistenceClientFactory.GetClient(); } [Fact] public async Task InsertRange() { // arrange Guid idDiscriminator = Guid.NewGuid(); IEnumerable testSets = Generate(10, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7))); // act var response = await client.InsertRange(idDiscriminator, testSets); // assert Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); Assert.Equal(testSets.Count(), response.Content); } [Fact] public async Task Get_without_filter() { // arrange Guid idDiscriminator = Guid.NewGuid(); int count = 10; IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7))); var insertResponse = await client.InsertRange(idDiscriminator, testSets); // act var response = await client.Get(idDiscriminator, null, null, 0, int.MaxValue); // assert Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); Assert.NotNull(response.Content); var items = response.Content!; Assert.Equal(count, items.Count()); } [Fact] public async Task Get_with_filter_props() { // arrange Guid idDiscriminator = Guid.NewGuid(); int count = 10; IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7))); var insertResponse = await client.InsertRange(idDiscriminator, testSets); string[] props = ["A"]; // act var response = await client.Get(idDiscriminator, null, props, 0, int.MaxValue); // assert Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); Assert.NotNull(response.Content); var items = response.Content!; Assert.Equal(count, items.Count()); foreach ( var item in items ) { Assert.Single(item.Set); var kv = item.Set.First(); Assert.Equal("A", kv.Key); } } [Fact] public async Task Get_geDate() { // arrange Guid idDiscriminator = Guid.NewGuid(); int count = 10; var dateMin = DateTimeOffset.Now; var dateMax = DateTimeOffset.Now.AddSeconds(count); IEnumerable testSets = Generate(count, dateMin.ToOffset(TimeSpan.FromHours(7))); var insertResponse = await client.InsertRange(idDiscriminator, testSets); var tail = testSets.OrderBy(t => t.Timestamp).Skip(count / 2).Take(int.MaxValue); var geDate = tail.First().Timestamp; var tolerance = TimeSpan.FromSeconds(1); var expectedCount = tail.Count(); // act var response = await client.Get(idDiscriminator, geDate, null, 0, int.MaxValue); // assert Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); Assert.NotNull(response.Content); var items = response.Content!; Assert.Equal(expectedCount, items.Count()); var minDate = items.Min(t => t.Timestamp); Assert.Equal(geDate, geDate, tolerance); } [Fact] public async Task Get_with_skip_take() { // arrange Guid idDiscriminator = Guid.NewGuid(); int count = 10; IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7))); var insertResponse = await client.InsertRange(idDiscriminator, testSets); var expectedCount = count / 2; // act var response = await client.Get(idDiscriminator, null, null, 2, expectedCount); // assert Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); Assert.NotNull(response.Content); var items = response.Content!; Assert.Equal(expectedCount, items.Count()); } [Fact] public async Task Get_with_big_skip_take() { // arrange Guid idDiscriminator = Guid.NewGuid(); var expectedCount = 1; int count = 10 + expectedCount; IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7))); var insertResponse = await client.InsertRange(idDiscriminator, testSets); // act var response = await client.Get(idDiscriminator, null, null, count - expectedCount, count); // assert Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); Assert.NotNull(response.Content); var items = response.Content!; Assert.Equal(expectedCount, items.Count()); } [Fact] public async Task GetLast() { // arrange Guid idDiscriminator = Guid.NewGuid(); int count = 10; IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7))); var insertResponse = await client.InsertRange(idDiscriminator, testSets); var expectedCount = 8; // act var response = await client.GetLast(idDiscriminator, null, expectedCount); // assert Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); Assert.NotNull(response.Content); var items = response.Content!; Assert.Equal(expectedCount, items.Count()); } [Fact] public async Task GetDatesRange() { // arrange Guid idDiscriminator = Guid.NewGuid(); int count = 10; var dateMin = DateTimeOffset.Now; var dateMax = DateTimeOffset.Now.AddSeconds(count-1); IEnumerable testSets = Generate(count, dateMin.ToOffset(TimeSpan.FromHours(7))); var insertResponse = await client.InsertRange(idDiscriminator, testSets); var tolerance = TimeSpan.FromSeconds(1); // act var response = await client.GetDatesRange(idDiscriminator); // assert Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); Assert.NotNull(response.Content); var range = response.Content!; Assert.Equal(dateMin, range.From, tolerance); Assert.Equal(dateMax, range.To, tolerance); } [Fact] public async Task Count() { // arrange Guid idDiscriminator = Guid.NewGuid(); int count = 144; IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7))); var insertResponse = await client.InsertRange(idDiscriminator, testSets); // act var response = await client.Count(idDiscriminator); // assert Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode); Assert.Equal(count, response.Content); } private static IEnumerable Generate(int n, DateTimeOffset from) { for (int i = 0; i < n; i++) yield return new TimestampedSetDto ( from.AddSeconds(i), new Dictionary{ {"A", i }, {"B", i * 1.1 }, {"C", $"Any{i}" }, {"D", DateTimeOffset.Now}, } ); } }