mirror of
https://github.com/Ikatono/ComiServ.git
synced 2025-10-28 20:45:35 -05:00
Added first controller unit test as well as several mock services
This commit is contained in:
@@ -313,6 +313,8 @@ public class ComicController(ComicsContext context, ILogger<ComicController> log
|
||||
var comic = await _context.Comics.SingleOrDefaultAsync(c => c.Handle == handle);
|
||||
if (comic is null)
|
||||
return NotFound(RequestError.ComicNotFound);
|
||||
//can't mock this easily, move to a service?
|
||||
//maybe IComicAnalyzer should be used even just to read a file
|
||||
var data = await System.IO.File.ReadAllBytesAsync(Path.Join(_config.LibraryRoot, comic.Filepath));
|
||||
return File(data, "application/octet-stream", new FileInfo(comic.Filepath).Name);
|
||||
}
|
||||
|
||||
87
ComiServUnitTest/ContollerTests/ComicControllerTests.cs
Normal file
87
ComiServUnitTest/ContollerTests/ComicControllerTests.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ComiServ;
|
||||
using ComiServ.Entities;
|
||||
using ComiServ.Services;
|
||||
using ComiServ.Controllers;
|
||||
using Microsoft.CodeAnalysis.Elfie.Diagnostics;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ComiServUnitTest.Mocks;
|
||||
using ComiServ.Background;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace ComiServUnitTest.ContollerTests;
|
||||
|
||||
[TestClass]
|
||||
public class ComicControllerTests
|
||||
{
|
||||
private ILoggerFactory? _factory;
|
||||
public ILoggerFactory factory
|
||||
{ get
|
||||
{
|
||||
_factory = _factory ?? LoggerFactory.Create(builder => builder.AddConsole());
|
||||
return _factory;
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task TestGetPage()
|
||||
{
|
||||
const int PAGE_NUMBER = 7;
|
||||
const string PAGE_FILEPATH = "Page File.jpg";
|
||||
const string PAGE_MIME = "image/jpeg";
|
||||
var context = DatabaseHelper.CreateDatabase();
|
||||
Comic comic = new()
|
||||
{
|
||||
Title = "Test Comic",
|
||||
Filepath = Path.Join("test", "filepath"),
|
||||
Handle = string.Join("", Enumerable.Repeat("A", ComicsContext.HANDLE_LENGTH)),
|
||||
Description = ""
|
||||
};
|
||||
context.Comics.Add(comic);
|
||||
User user = new()
|
||||
{
|
||||
Username = "user",
|
||||
UserTypeId = UserTypeEnum.User,
|
||||
Salt = User.MakeSalt(),
|
||||
HashedPassword = User.Hash([], []),
|
||||
};
|
||||
context.Users.Add(user);
|
||||
context.SaveChanges();
|
||||
Configuration config = new()
|
||||
{
|
||||
AutoScanPeriodHours = 24,
|
||||
DatabaseFile = "",
|
||||
LibraryRoot = "root",
|
||||
};
|
||||
ComicPage comicPage = new(PAGE_FILEPATH, PAGE_MIME, [1, 2, 3, 4, 5]);
|
||||
MockComicAnalyzer analyzer = new();
|
||||
analyzer.ComicPages.Add((Path.Join(config.LibraryRoot, comic.Filepath), PAGE_NUMBER), comicPage);
|
||||
IPictureConverter converter = new MockPictureConverter();
|
||||
AuthenticationService auth = new();
|
||||
auth.Authenticate(user);
|
||||
var controller = new ComicController(
|
||||
context,
|
||||
factory.CreateLogger<ComicController>(),
|
||||
new MockConfig(config),
|
||||
analyzer,
|
||||
converter,
|
||||
auth
|
||||
);
|
||||
//get actual page
|
||||
var result = await controller.GetComicPage(comic.Handle, PAGE_NUMBER, null, null, null);
|
||||
Assert.IsInstanceOfType<FileContentResult>(result);
|
||||
var contents = ((FileContentResult)result).FileContents;
|
||||
Assert.IsTrue(comicPage.Data.SequenceEqual(contents));
|
||||
//invalid handle (too short)
|
||||
var result2 = await controller.GetComicFile(string.Join("", Enumerable.Repeat("A", ComicsContext.HANDLE_LENGTH - 1)));
|
||||
Assert.IsInstanceOfType<BadRequestObjectResult>(result2);
|
||||
//valid handle but doesn't exist
|
||||
var result3 = await controller.GetComicFile(string.Join("", Enumerable.Repeat("B", ComicsContext.HANDLE_LENGTH)));
|
||||
Assert.IsInstanceOfType<NotFoundObjectResult>(result3);
|
||||
}
|
||||
}
|
||||
25
ComiServUnitTest/DatabaseHelper.cs
Normal file
25
ComiServUnitTest/DatabaseHelper.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using ComiServ;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ComiServUnitTest;
|
||||
|
||||
internal static class DatabaseHelper
|
||||
{
|
||||
public static ComicsContext CreateDatabase()
|
||||
{
|
||||
var connection = new SqliteConnection("Filename=:memory:");
|
||||
connection.Open();
|
||||
var contextOptions = new DbContextOptionsBuilder<ComicsContext>()
|
||||
.UseSqlite(connection)
|
||||
.Options;
|
||||
var context = new ComicsContext(contextOptions);
|
||||
context.Database.EnsureCreated();
|
||||
return context;
|
||||
}
|
||||
}
|
||||
75
ComiServUnitTest/Mocks/MockComicAnalyzer.cs
Normal file
75
ComiServUnitTest/Mocks/MockComicAnalyzer.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using ComiServ.Background;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ComiServUnitTest.Mocks
|
||||
{
|
||||
internal class MockComicAnalyzer : IComicAnalyzer
|
||||
{
|
||||
//preseed these
|
||||
public readonly Dictionary<string, ComicAnalysis> AnalysisResults = [];
|
||||
public readonly HashSet<string> ComicsThatExist = [];
|
||||
public readonly Dictionary<(string, int), ComicPage> ComicPages = [];
|
||||
|
||||
//check these afterwards
|
||||
public readonly List<string> Analyzed = [];
|
||||
public readonly List<string> CheckedForExistance = [];
|
||||
public readonly List<string> Deleted = [];
|
||||
public readonly List<(string, int)> RetreivedPages = [];
|
||||
public MockComicAnalyzer()
|
||||
{
|
||||
|
||||
}
|
||||
public void Clear()
|
||||
{
|
||||
Analyzed.Clear();
|
||||
CheckedForExistance.Clear();
|
||||
Deleted.Clear();
|
||||
RetreivedPages.Clear();
|
||||
}
|
||||
public ComicAnalysis? AnalyzeComic(string filename)
|
||||
{
|
||||
Analyzed.Add(filename);
|
||||
if (AnalysisResults.TryGetValue(filename, out var analysis))
|
||||
return analysis;
|
||||
return null;
|
||||
}
|
||||
|
||||
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
|
||||
public async Task<ComicAnalysis?> AnalyzeComicAsync(string filename)
|
||||
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
|
||||
{
|
||||
return AnalyzeComic(filename);
|
||||
}
|
||||
|
||||
public bool ComicFileExists(string filename)
|
||||
{
|
||||
CheckedForExistance.Add(filename);
|
||||
return ComicsThatExist.Contains(filename);
|
||||
}
|
||||
|
||||
public void DeleteComicFile(string filename)
|
||||
{
|
||||
Deleted.Add(filename);
|
||||
}
|
||||
|
||||
public ComicPage? GetComicPage(string filepath, int page)
|
||||
{
|
||||
var key = (filepath, page);
|
||||
RetreivedPages.Add(key);
|
||||
if (ComicPages.TryGetValue(key, out var comicPage))
|
||||
return comicPage;
|
||||
return null;
|
||||
}
|
||||
|
||||
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
|
||||
public async Task<ComicPage?> GetComicPageAsync(string filepath, int page)
|
||||
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
|
||||
{
|
||||
return GetComicPage(filepath, page);
|
||||
}
|
||||
}
|
||||
}
|
||||
20
ComiServUnitTest/Mocks/MockConfig.cs
Normal file
20
ComiServUnitTest/Mocks/MockConfig.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using ComiServ.Services;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ComiServUnitTest.Mocks;
|
||||
|
||||
internal class MockConfig : IConfigService
|
||||
{
|
||||
private readonly Configuration _Config;
|
||||
public Configuration Config => _Config.Copy();
|
||||
public MockConfig(Configuration config)
|
||||
{
|
||||
_Config = config;
|
||||
}
|
||||
}
|
||||
33
ComiServUnitTest/Mocks/MockPictureConverter.cs
Normal file
33
ComiServUnitTest/Mocks/MockPictureConverter.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using ComiServ.Background;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ComiServUnitTest.Mocks
|
||||
{
|
||||
internal class MockPictureConverter : IPictureConverter
|
||||
{
|
||||
public MockPictureConverter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Task<Stream> MakeThumbnail(Stream image)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<Stream> Resize(Stream image, Size newSize, PictureFormats? newFormat = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<Stream> ResizeIfBigger(Stream image, Size maxSize, PictureFormats? newFormat = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user