using JSMR.Application.Common.Search; using JSMR.Application.VoiceWorks.Queries.Search; using JSMR.Infrastructure.Data; using JSMR.Infrastructure.Data.Repositories.VoiceWorks; using JSMR.Tests.Fixtures; using Shouldly; namespace JSMR.Tests.Integration; public class VoiceWorkSearchProviderTests(VoiceWorkSearchProviderFixture fixture) : IClassFixture { private VoiceWorkSearchProvider InitializeVoiceWorkSearchProvider(AppDbContext context) { MySqlVoiceWorkFullTextSearch fullTextSearch = new(); VoiceWorkSearchProvider provider = new(context, fullTextSearch); return provider; } [Fact] public async Task Filter_Default() { await using AppDbContext context = fixture.CreateDbContext(); VoiceWorkSearchProvider provider = InitializeVoiceWorkSearchProvider(context); var options = new SearchOptions() { Criteria = new() { SaleStatus = SaleStatus.Available, CircleStatus = CircleStatus.NotBlacklisted } }; var result = await provider.SearchAsync(options); result.Items.Length.ShouldBe(2); result.TotalItems.ShouldBe(2); result.Items.ShouldAllBe(item => item.SalesDate != null); result.Items.ShouldNotContain(item => item.ExpectedDate != null); } [Fact] public async Task Filter_Upcoming_Favorite() { await using AppDbContext context = fixture.CreateDbContext(); VoiceWorkSearchProvider provider = InitializeVoiceWorkSearchProvider(context); var options = new SearchOptions() { Criteria = new() { SaleStatus = SaleStatus.Upcoming, CircleStatus = CircleStatus.Favorited } }; var result = await provider.SearchAsync(options); result.Items.Length.ShouldBe(1); result.TotalItems.ShouldBe(1); result.Items.ShouldAllBe(item => item.ExpectedDate != null); result.Items.ShouldNotContain(item => item.SalesDate != null); } [Fact] public async Task Filter_Availble_Blacklisted() { await using AppDbContext context = fixture.CreateDbContext(); VoiceWorkSearchProvider provider = InitializeVoiceWorkSearchProvider(context); var options = new SearchOptions() { Criteria = new() { SaleStatus = SaleStatus.Available, CircleStatus = CircleStatus.Blacklisted } }; var result = await provider.SearchAsync(options); result.Items.Length.ShouldBe(1); result.TotalItems.ShouldBe(1); result.Items.ShouldAllBe(item => item.SalesDate != null); result.Items.ShouldNotContain(item => item.ExpectedDate != null); } [Fact] public async Task Filter_Keywords_Basic() { await using AppDbContext context = fixture.CreateDbContext(); VoiceWorkSearchProvider provider = InitializeVoiceWorkSearchProvider(context); var options = new SearchOptions() { Criteria = new() { Keywords = "ASMR" } }; var result = await provider.SearchAsync(options); result.Items.Length.ShouldBe(3); result.TotalItems.ShouldBe(3); result.Items.ShouldAllBe(item => item.Tags.Any(tag => tag.Name == "ASMR") || item.ProductName.Contains("ASMR") || (item.Description ?? string.Empty).Contains("ASMR")); } [Fact] public async Task Filter_Keywords_Not_Good() { await using AppDbContext context = fixture.CreateDbContext(); VoiceWorkSearchProvider provider = InitializeVoiceWorkSearchProvider(context); var options = new SearchOptions() { Criteria = new() { Keywords = "ASMR -Good" } }; var result = await provider.SearchAsync(options); result.Items.Length.ShouldBe(2); result.TotalItems.ShouldBe(2); result.Items.ShouldAllBe(item => item.Tags.Any(tag => tag.Name == "ASMR") || item.ProductName.Contains("ASMR") || (item.Description ?? string.Empty).Contains("ASMR")); result.Items.ShouldAllBe(item => !item.Tags.Any(tag => tag.Name == "Good") || !item.ProductName.Contains("Good") || !(item.Description ?? string.Empty).Contains("Good")); } [Fact] public async Task Filter_Keywords_Dreams_And_Amazing_Or_Favorite() { await using AppDbContext context = fixture.CreateDbContext(); VoiceWorkSearchProvider provider = InitializeVoiceWorkSearchProvider(context); var options = new SearchOptions() { Criteria = new() { Keywords = "Dreams + (Amazing|Favorite)" } }; var result = await provider.SearchAsync(options); result.Items.Length.ShouldBe(2); result.TotalItems.ShouldBe(2); result.Items .OrderBy(item => item.ProductId) .Select(item => item.ProductId) .ShouldBe(["RJ0000002", "RJ0000005"]); } [Fact] public async Task Filter_Keywords_Phrase_Search() { await using AppDbContext context = fixture.CreateDbContext(); VoiceWorkSearchProvider provider = InitializeVoiceWorkSearchProvider(context); var options = new SearchOptions() { Criteria = new() { Keywords = "\"All Your Favorite\"" } }; var result = await provider.SearchAsync(options); result.Items.Length.ShouldBe(1); result.TotalItems.ShouldBe(1); result.Items.ShouldAllBe(item => (item.Description ?? string.Empty).Contains("All Your Favorite", StringComparison.OrdinalIgnoreCase)); } }