diff --git a/starsky/starskytest/Controllers/MetaReplaceControllerTest.cs b/starsky/starskytest/Controllers/MetaReplaceControllerTest.cs index 056b5b3b0..47948117a 100644 --- a/starsky/starskytest/Controllers/MetaReplaceControllerTest.cs +++ b/starsky/starskytest/Controllers/MetaReplaceControllerTest.cs @@ -290,15 +290,15 @@ public async Task Replace_ChangedFileIndexItemNameContent() var expected = "{\"" + createAnImage.DbPath + "\":[\"tags\"]}"; Assert.AreEqual(expected, actual); } - - + [TestMethod] public async Task Replace_ReturnsBadRequest() { // Arrange var controller = new MetaReplaceController(new FakeIMetaReplaceService(), new FakeIUpdateBackgroundTaskQueue(), - new FakeIRealtimeConnectionsService(), new FakeIWebLogger(), new FakeIServiceScopeFactory()); + new FakeIRealtimeConnectionsService(), new FakeIWebLogger(), + new FakeIServiceScopeFactory()); controller.ModelState.AddModelError("Key", "ErrorMessage"); // Act @@ -307,13 +307,4 @@ public async Task Replace_ReturnsBadRequest() // Assert Assert.IsInstanceOfType(result, typeof(BadRequestObjectResult)); } - -} - -internal class FakeIServiceScopeFactory : IServiceScopeFactory -{ - public IServiceScope CreateScope() - { - throw new NotImplementedException(); - } } diff --git a/starsky/starskytest/FakeMocks/FakeIServiceScopeFactory.cs b/starsky/starskytest/FakeMocks/FakeIServiceScopeFactory.cs new file mode 100644 index 000000000..abd198ef4 --- /dev/null +++ b/starsky/starskytest/FakeMocks/FakeIServiceScopeFactory.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using starsky.foundation.database.Data; + +namespace starskytest.FakeMocks; + +public class FakeIServiceScopeFactory : IServiceScopeFactory +{ + private readonly IServiceScopeFactory _serviceScopeFactory; + + public FakeIServiceScopeFactory(string? name = null) + { + var dbName = name ?? nameof(FakeIServiceScopeFactory); + var services = new ServiceCollection(); + services.AddDbContext(options => + options.UseInMemoryDatabase(dbName)); + var serviceProvider = services.BuildServiceProvider(); + _serviceScopeFactory = serviceProvider.GetRequiredService(); + } + + public IServiceScope CreateScope() + { + return _serviceScopeFactory.CreateScope(); + } +} diff --git a/starsky/starskytest/starsky.foundation.database/QueryTest/QueryGetNextPrevInFolderTest.cs b/starsky/starskytest/starsky.foundation.database/QueryTest/QueryGetNextPrevInFolderTest.cs index d11d0d602..932faca35 100644 --- a/starsky/starskytest/starsky.foundation.database/QueryTest/QueryGetNextPrevInFolderTest.cs +++ b/starsky/starskytest/starsky.foundation.database/QueryTest/QueryGetNextPrevInFolderTest.cs @@ -1,13 +1,16 @@ +using System; using System.Collections.Generic; +using System.Reflection; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; using Microsoft.VisualStudio.TestTools.UnitTesting; +using MySqlConnector; using starsky.foundation.database.Data; using starsky.foundation.database.Models; using starsky.foundation.database.Query; using starsky.foundation.platform.Helpers; using starsky.foundation.platform.Models; -using starskytest.Controllers; using starskytest.FakeMocks; namespace starskytest.starsky.foundation.database.QueryTest; @@ -24,7 +27,8 @@ public QueryGetNextPrevInFolderTest() var builder = new DbContextOptionsBuilder(); builder.UseInMemoryDatabase(nameof(QueryGetNextPrevInFolderTest)); _context = new ApplicationDbContext(builder.Options); - _query = new Query(_context, new AppSettings(), new FakeIServiceScopeFactory(), + _query = new Query(_context, new AppSettings(), + new FakeIServiceScopeFactory(nameof(QueryGetNextPrevInFolderTest)), new FakeIWebLogger(), new FakeMemoryCache()); } @@ -166,4 +170,70 @@ public async Task QueryGetNextPrevInFolder_DoesNotIncludeMetaJsonOrXmp() await _query.RemoveItemAsync(items); } + + [TestMethod] + public void QueryGetNextPrevInFolder_HandlesMySqlProtocolException() + { + // Arrange + var builder = new DbContextOptionsBuilder(); + var customContext = new MySqlProtocolExceptionDbContext(builder.Options); + var serviceScopeFactory = new FakeIServiceScopeFactory(); + var query = new Query(customContext, new AppSettings(), serviceScopeFactory, + new FakeIWebLogger(), new FakeMemoryCache()); + + const string parentFolderPath = "/collection"; + const string currentFolder = "/collection/20241106_155758_DSC00338"; + var items = new List + { + new() + { + FilePath = "/collection/20241106_155758_DSC00338.arw", + ParentDirectory = parentFolderPath, + ImageFormat = ExtensionRolesHelper.ImageFormat.tiff + } + }; + + var serviceScope = serviceScopeFactory.CreateScope(); + var dbContext = serviceScope.ServiceProvider.GetRequiredService(); + + dbContext.FileIndex.AddRange(items); + dbContext.SaveChanges(); + + // Act + var result = query.QueryGetNextPrevInFolder(parentFolderPath, currentFolder); + + // Assert + Assert.IsNotNull(result); + Assert.AreEqual(items.Count, result.Count); + Assert.AreEqual(items[0].FilePath, result[0].FilePath); + + // Cleanup + dbContext.Remove(items[0]); + dbContext.SaveChanges(); + } + + private class MySqlProtocolExceptionDbContext(DbContextOptions options) + : ApplicationDbContext(options) + { + public override DbSet FileIndex + { + get + { + var exceptionType = typeof(MySqlProtocolException); + var constructor = exceptionType.GetConstructor( + BindingFlags.NonPublic | BindingFlags.Instance, + null, + [typeof(string)], + null + ) ?? throw new InvalidOperationException("Constructor not found."); + + var exceptionInstance = + ( MySqlProtocolException ) constructor.Invoke(new object[] + { + "Test exception" + }); + throw exceptionInstance; + } + } + } }