Fixed date time assignments when testing ingestions. Added more ingestion tests. Fixed voice work updater bugs.

This commit is contained in:
2025-10-29 00:49:53 -04:00
parent 6d090390b0
commit 512da985fa
8 changed files with 242 additions and 58 deletions

View File

@@ -5,6 +5,7 @@ using JSMR.Infrastructure.Data;
using JSMR.Infrastructure.Ingestion;
using JSMR.Tests.Fixtures;
using NSubstitute;
using System.Runtime.InteropServices;
namespace JSMR.Tests.Ingestion.Japanese;
@@ -19,8 +20,10 @@ public abstract class IngestionTestsBase(MariaDbContainerFixture container)
protected static async Task<VoiceWorkUpsertResult[]> UpsertAsync(AppDbContext dbContext, DateTime dateTime, VoiceWorkIngest[] ingests)
{
DateTime utcDateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc);
IClock clock = Substitute.For<IClock>();
clock.UtcNow.Returns(new DateTimeOffset(dateTime));
clock.UtcNow.Returns(new DateTimeOffset(utcDateTime));
TokyoTimeProvider timeProvider = new(clock);
@@ -28,4 +31,15 @@ public abstract class IngestionTestsBase(MariaDbContainerFixture container)
return await updater.UpsertAsync(ingests, TestContext.Current.CancellationToken);
}
protected static DateTime TokyoLocalToUtc(int year, int month, int day, int hour, int minute, int second)
{
var tokyo = TimeZoneInfo.FindSystemTimeZoneById(
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "Tokyo Standard Time" : "Asia/Tokyo");
var localUnspec = new DateTime(year, month, day, hour, minute, second, DateTimeKind.Unspecified);
var utc = TimeZoneInfo.ConvertTimeToUtc(localUnspec, tokyo);
return utc;
}
}

View File

@@ -0,0 +1,54 @@
using JSMR.Application.Common;
using JSMR.Application.Scanning.Contracts;
using JSMR.Domain.Entities;
using JSMR.Infrastructure.Common.SupportedLanguages;
using JSMR.Infrastructure.Data;
using JSMR.Tests.Fixtures;
using Microsoft.EntityFrameworkCore;
using Shouldly;
namespace JSMR.Tests.Ingestion.Japanese;
public class Insert_New_Release_And_Scan_Again_Later_Tests(MariaDbContainerFixture container) : IngestionTestsBase(container)
{
[Fact]
public async Task Insert_New_Release_And_Scan_Again_Later()
{
await using AppDbContext dbContext = await GetAppDbContextAsync();
VoiceWorkIngest ingest = new()
{
MakerId = "RG10001",
MakerName = "New Dreams",
ProductId = "RJ2000001",
Title = "Day One Release",
Description = "Releasing now.",
Tags = ["アイドル", "メガネ"],
Creators = ["かの仔"],
WishlistCount = 50,
Downloads = 10,
HasTrial = false,
HasDLPlay = false,
StarRating = null,
Votes = null,
AgeRating = AgeRating.AllAges,
HasImage = true,
SupportedLanguages = [new JapaneseLanguage()],
SalesDate = new DateOnly(2025, 1, 15),
ExpectedDate = null
};
await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 15, 00, 00, 00), ingest, VoiceWorkStatus.NewRelease);
await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 15, 15, 59, 59), ingest, VoiceWorkStatus.NewRelease);
await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 15, 16, 00, 00), ingest, VoiceWorkStatus.Available);
await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 16, 00, 00, 00), ingest, VoiceWorkStatus.Available);
}
private static async Task UpsertAndVerify(AppDbContext dbContext, DateTime dateTime, VoiceWorkIngest ingest, VoiceWorkStatus status)
{
await UpsertAsync(dbContext, dateTime, [ingest]);
VoiceWork? voiceWork = await dbContext.VoiceWorks.SingleAsync(v => v.ProductId == ingest.ProductId, TestContext.Current.CancellationToken);
voiceWork.Status.ShouldBe((byte)status);
}
}

View File

@@ -39,7 +39,7 @@ public class Insert_New_Release_With_New_Tags_And_Creators_Tests(MariaDbContaine
ExpectedDate = null
};
VoiceWorkUpsertResult[] results = await UpsertAsync(dbContext, new DateTime(2025, 01, 15, 9, 0, 0), [ingest]);
VoiceWorkUpsertResult[] results = await UpsertAsync(dbContext, TokyoLocalToUtc(2025, 01, 15, 9, 0, 0), [ingest]);
VoiceWork? voiceWork = await dbContext.VoiceWorks.SingleAsync(v => v.ProductId == "RJ2000001", TestContext.Current.CancellationToken);
voiceWork.ShouldNotBeNull();

View File

@@ -0,0 +1,53 @@
using JSMR.Application.Common;
using JSMR.Application.Scanning.Contracts;
using JSMR.Domain.Entities;
using JSMR.Infrastructure.Common.SupportedLanguages;
using JSMR.Infrastructure.Data;
using JSMR.Tests.Fixtures;
using Microsoft.EntityFrameworkCore;
using Shouldly;
namespace JSMR.Tests.Ingestion.Japanese;
public class Insert_New_Upcoming_And_Scan_Again_Later_Tests(MariaDbContainerFixture container) : IngestionTestsBase(container)
{
[Fact]
public async Task Insert_New_Upcoming_And_Scan_Again_Later()
{
await using AppDbContext dbContext = await GetAppDbContextAsync();
VoiceWorkIngest ingest = new()
{
MakerId = "RG00001",
MakerName = "Good Dreams",
ProductId = "RJ1000002",
Title = "Preview Only",
Description = "Still upcoming.",
Tags = [],
Creators = [],
WishlistCount = 100,
Downloads = 0,
HasTrial = false,
HasDLPlay = false,
AgeRating = AgeRating.AllAges,
HasImage = false,
SupportedLanguages = [new JapaneseLanguage()],
SalesDate = null,
ExpectedDate = new DateOnly(2025, 2, 1)
};
await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 09, 16, 00, 00), ingest, VoiceWorkStatus.NewAndUpcoming);
await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 10, 00, 00, 00), ingest, VoiceWorkStatus.NewAndUpcoming);
await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 10, 15, 59, 59), ingest, VoiceWorkStatus.NewAndUpcoming);
await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 10, 16, 00, 00), ingest, VoiceWorkStatus.Upcoming);
await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 11, 00, 00, 00), ingest, VoiceWorkStatus.Upcoming);
}
private static async Task UpsertAndVerify(AppDbContext dbContext, DateTime dateTime, VoiceWorkIngest ingest, VoiceWorkStatus status)
{
await UpsertAsync(dbContext, dateTime, [ingest]);
VoiceWork? voiceWork = await dbContext.VoiceWorks.SingleAsync(v => v.ProductId == ingest.ProductId, TestContext.Current.CancellationToken);
voiceWork.Status.ShouldBe((byte)status);
}
}

View File

@@ -0,0 +1,62 @@
using JSMR.Application.Common;
using JSMR.Application.Scanning.Contracts;
using JSMR.Domain.Entities;
using JSMR.Infrastructure.Common.SupportedLanguages;
using JSMR.Infrastructure.Data;
using JSMR.Tests.Fixtures;
using Microsoft.EntityFrameworkCore;
using Shouldly;
namespace JSMR.Tests.Ingestion.Japanese;
public class Insert_New_Upcoming_Release_Same_Day_Tests(MariaDbContainerFixture container) : IngestionTestsBase(container)
{
[Fact]
public async Task Insert_New_Upcoming_Release_Same_Day()
{
await using AppDbContext dbContext = await GetAppDbContextAsync();
VoiceWorkIngest ingest = new()
{
MakerId = "RG00001",
MakerName = "Good Dreams",
ProductId = "RJ1000002",
Title = "Preview Only",
Description = "Still upcoming.",
Tags = [],
Creators = [],
WishlistCount = 100,
Downloads = 0,
HasTrial = false,
HasDLPlay = false,
AgeRating = AgeRating.AllAges,
HasImage = false,
SupportedLanguages = [new JapaneseLanguage()],
SalesDate = null,
ExpectedDate = new DateOnly(2025, 2, 1)
};
await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 09, 16, 00, 00), ingest, VoiceWorkStatus.NewAndUpcoming);
VoiceWorkIngest updatedIngest = ingest with
{
Title = "Released on the Same Day",
Description = "Should be indicated as a new release",
SalesDate = new DateOnly(2025, 1, 10),
ExpectedDate = null
};
await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 10, 00, 00, 00), updatedIngest, VoiceWorkStatus.NewRelease);
await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 10, 15, 59, 59), updatedIngest, VoiceWorkStatus.NewRelease);
await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 10, 16, 00, 00), updatedIngest, VoiceWorkStatus.Available);
await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 11, 00, 00, 00), updatedIngest, VoiceWorkStatus.Available);
}
private static async Task UpsertAndVerify(AppDbContext dbContext, DateTime dateTime, VoiceWorkIngest ingest, VoiceWorkStatus status)
{
await UpsertAsync(dbContext, dateTime, [ingest]);
VoiceWork? voiceWork = await dbContext.VoiceWorks.SingleAsync(v => v.ProductId == ingest.ProductId, TestContext.Current.CancellationToken);
voiceWork.Status.ShouldBe((byte)status);
}
}

View File

@@ -42,7 +42,7 @@ public class Insert_New_Upcoming_With_Existing_Tags_And_Creators_Tests(MariaDbCo
];
await using AppDbContext dbContext = await GetAppDbContextAsync();
DateTime currentDateTime = new(2025, 01, 05, 10, 0, 0);
DateTime currentDateTime = TokyoLocalToUtc(2025, 01, 05, 10, 0, 0);
VoiceWorkUpsertResult[] results = await UpsertAsync(dbContext, currentDateTime, insertNewUpcomingIngests);

View File

@@ -1,49 +0,0 @@
using JSMR.Application.Common;
using JSMR.Application.Scanning.Contracts;
using JSMR.Domain.Entities;
using JSMR.Infrastructure.Common.SupportedLanguages;
using JSMR.Infrastructure.Data;
using JSMR.Tests.Fixtures;
using Microsoft.EntityFrameworkCore;
using Shouldly;
namespace JSMR.Tests.Ingestion.Japanese;
public class Insert_Upcoming_And_Scan_Again_Later_Tests(MariaDbContainerFixture container) : IngestionTestsBase(container)
{
[Fact]
public async Task Insert_Upcoming_And_Scan_Again_Later()
{
await using AppDbContext dbContext = await GetAppDbContextAsync();
VoiceWorkIngest ingest = new()
{
MakerId = "RG00001",
MakerName = "Good Dreams",
ProductId = "RJ1000002",
Title = "Preview Only",
Description = "Still upcoming.",
Tags = Array.Empty<string>(),
Creators = Array.Empty<string>(),
WishlistCount = 100,
Downloads = 0,
HasTrial = false,
HasDLPlay = false,
AgeRating = AgeRating.AllAges,
HasImage = false,
SupportedLanguages = [new JapaneseLanguage()],
SalesDate = null,
ExpectedDate = new DateOnly(2025, 2, 1)
};
await UpsertAsync(dbContext, new DateTime(2025, 01, 10, 1, 0, 0), [ingest]);
VoiceWork? voiceWork = await dbContext.VoiceWorks.SingleAsync(v => v.ProductId == "RJ1000002", TestContext.Current.CancellationToken);
voiceWork.Status.ShouldBe((byte)VoiceWorkStatus.NewAndUpcoming);
await UpsertAsync(dbContext, new DateTime(2025, 01, 12, 10, 0, 0), [ingest]);
VoiceWork? updatedVoiceWork = await dbContext.VoiceWorks.SingleAsync(v => v.ProductId == "RJ1000002", TestContext.Current.CancellationToken);
updatedVoiceWork.Status.ShouldBe((byte)VoiceWorkStatus.Upcoming);
}
}