Added web module tests

This commit is contained in:
2025-01-19 16:00:33 +01:00
parent 8d63910aae
commit 80aa650a2c
26 changed files with 587 additions and 71 deletions

View File

@@ -0,0 +1,221 @@
using HopFrame.Core.Config;
using HopFrame.Core.Services.Implementations;
using HopFrame.Tests.Core.Models;
using Microsoft.Extensions.Logging;
using Moq;
namespace HopFrame.Tests.Core.Services;
public class ContextExplorerTests {
[Fact]
public void GetTables_ReturnsNonIgnoredTables() {
// Arrange
var config = new HopFrameConfig();
var contextConfig = new DbContextConfig(typeof(MockDbContext));
var tableConfig1 = contextConfig.Tables[0];
var tableConfig2 = contextConfig.Tables[1];
config.Contexts.Add(contextConfig);
tableConfig2.Ignored = true;
var provider = new Mock<IServiceProvider>();
var contextExplorer = new ContextExplorer(config, provider.Object, new Logger<ContextExplorer>(new LoggerFactory()));
// Act
var tables = contextExplorer.GetTables().ToList();
// Assert
Assert.Single(tables);
Assert.Contains(tableConfig1, tables);
Assert.DoesNotContain(tableConfig2, tables);
}
[Fact]
public void GetTable_ByDisplayName_ReturnsCorrectTable() {
// Arrange
var config = new HopFrameConfig();
var contextConfig = new DbContextConfig(typeof(MockDbContext));
var tableConfig = contextConfig.Tables[0];
config.Contexts.Add(contextConfig);
tableConfig.DisplayName = "TestTable";
var provider = new Mock<IServiceProvider>();
provider.Setup(p => p.GetService(typeof(MockDbContext))).Returns(new MockDbContext());
var contextExplorer = new ContextExplorer(config, provider.Object, new Logger<ContextExplorer>(new LoggerFactory()));
// Act
var result = contextExplorer.GetTable("TestTable");
// Assert
Assert.NotNull(result);
Assert.Equal(tableConfig, result);
}
[Fact]
public void GetTable_ByDisplayName_ReturnsNullIfTableNotFound() {
// Arrange
var config = new HopFrameConfig();
var contextConfig = new DbContextConfig(typeof(MockDbContext));
var tableConfig = contextConfig.Tables[0];
config.Contexts.Add(contextConfig);
tableConfig.DisplayName = "TestTable";
var provider = new Mock<IServiceProvider>();
provider.Setup(p => p.GetService(typeof(MockDbContext))).Returns(new MockDbContext());
var contextExplorer = new ContextExplorer(config, provider.Object, new Logger<ContextExplorer>(new LoggerFactory()));
// Act
var result = contextExplorer.GetTable("InvalidTable");
// Assert
Assert.Null(result);
}
[Fact]
public void GetTable_ByType_ReturnsCorrectTable() {
// Arrange
var config = new HopFrameConfig();
var contextConfig = new DbContextConfig(typeof(MockDbContext));
var tableConfig = contextConfig.Tables[0];
config.Contexts.Add(contextConfig);
var provider = new Mock<IServiceProvider>();
provider.Setup(p => p.GetService(typeof(MockDbContext))).Returns(new MockDbContext());
var contextExplorer = new ContextExplorer(config, provider.Object, new Logger<ContextExplorer>(new LoggerFactory()));
// Act
var result = contextExplorer.GetTable(typeof(MockModel));
// Assert
Assert.NotNull(result);
Assert.Equal(tableConfig, result);
}
[Fact]
public void GetTable_ByType_ReturnsNullIfTableNotFound() {
// Arrange
var config = new HopFrameConfig();
var contextConfig = new DbContextConfig(typeof(MockDbContext));
var tableConfig = contextConfig.Tables[0];
config.Contexts.Add(contextConfig);
var provider = new Mock<IServiceProvider>();
provider.Setup(p => p.GetService(typeof(MockDbContext))).Returns(new MockDbContext());
var contextExplorer = new ContextExplorer(config, provider.Object, new Logger<ContextExplorer>(new LoggerFactory()));
// Act
var result = contextExplorer.GetTable(typeof(ContextExplorerTests));
// Assert
Assert.Null(result);
}
[Fact]
public void GetTableManager_ReturnsCorrectTableManager() {
// Arrange
var config = new HopFrameConfig();
var contextConfig = new DbContextConfig(typeof(MockDbContext));
var tableConfig = new TableConfig(contextConfig, typeof(MockModel), "Models", 0);
contextConfig.Tables.Add(tableConfig);
config.Contexts.Add(contextConfig);
var dbContext = new MockDbContext();
var provider = new Mock<IServiceProvider>();
provider.Setup(p => p.GetService(typeof(MockDbContext))).Returns(dbContext);
var contextExplorer = new ContextExplorer(config, provider.Object, new Logger<ContextExplorer>(new LoggerFactory()));
// Act
var tableManager = contextExplorer.GetTableManager("Models");
// Assert
Assert.NotNull(tableManager);
Assert.IsType<TableManager<MockModel>>(tableManager);
}
[Fact]
public void GetTableManager_ReturnsNullIfDbContextNotFound() {
// Arrange
var config = new HopFrameConfig();
var contextConfig = new DbContextConfig(typeof(MockDbContext));
var tableConfig = new TableConfig(contextConfig, typeof(MockModel), "MockModels", 0);
contextConfig.Tables.Add(tableConfig);
config.Contexts.Add(contextConfig);
var provider = new Mock<IServiceProvider>();
var contextExplorer = new ContextExplorer(config, provider.Object, new Logger<ContextExplorer>(new LoggerFactory()));
// Act
var tableManager = contextExplorer.GetTableManager("Models");
// Assert
Assert.Null(tableManager);
}
[Fact]
public void GetTableManager_ReturnsNullIfTableNotFound() {
// Arrange
var config = new HopFrameConfig();
var contextConfig = new DbContextConfig(typeof(MockDbContext));
var tableConfig = new TableConfig(contextConfig, typeof(MockModel), "Models", 0);
contextConfig.Tables.Add(tableConfig);
config.Contexts.Add(contextConfig);
var dbContext = new MockDbContext();
var provider = new Mock<IServiceProvider>();
provider.Setup(p => p.GetService(typeof(MockDbContext))).Returns(dbContext);
var contextExplorer = new ContextExplorer(config, provider.Object, new Logger<ContextExplorer>(new LoggerFactory()));
// Act
var tableManager = contextExplorer.GetTableManager("InvalidTable");
// Assert
Assert.Null(tableManager);
}
[Fact]
public void SeedTableData_SetsTableSeededFlag() {
// Arrange
var config = new HopFrameConfig();
var contextConfig = new DbContextConfig(typeof(MockDbContext));
var tableConfig = contextConfig.Tables[0];
config.Contexts.Add(contextConfig);
var provider = new Mock<IServiceProvider>();
provider.Setup(p => p.GetService(typeof(MockDbContext))).Returns(new MockDbContext());
var contextExplorer = new ContextExplorer(config, provider.Object, new Logger<ContextExplorer>(new LoggerFactory()));
// Act
contextExplorer.GetTable("Models");
// Assert
Assert.True(tableConfig.Seeded);
}
[Fact]
public void SeedTableData_SetsTablePropertiesCorrectly() {
// Arrange
var config = new HopFrameConfig();
var contextConfig = new DbContextConfig(typeof(MockDbContext));
var tableConfig = contextConfig.Tables[0];
var tableConfig2 = contextConfig.Tables[1];
config.Contexts.Add(contextConfig);
var provider = new Mock<IServiceProvider>();
provider.Setup(p => p.GetService(typeof(MockDbContext))).Returns(new MockDbContext());
var contextExplorer = new ContextExplorer(config, provider.Object, new Logger<ContextExplorer>(new LoggerFactory()));
// Act
contextExplorer.GetTable("Models");
contextExplorer.GetTable("Models2");
// Assert
var relationProp = tableConfig.Properties.SingleOrDefault(prop => prop.Info.Name == nameof(MockModel.Model2));
var keyProp = tableConfig2.Properties.SingleOrDefault(prop => prop.Info.Name == nameof(MockModel2.Id));
Assert.NotNull(relationProp);
Assert.NotNull(keyProp);
Assert.True(relationProp.IsRelation);
Assert.True(relationProp.IsEnumerable);
Assert.True(keyProp.IsRequired);
Assert.False(keyProp.IsRelation);
Assert.False(keyProp.IsEnumerable);
}
}

View File

@@ -0,0 +1,41 @@
using HopFrame.Core.Services.Implementations;
namespace HopFrame.Tests.Core.Services;
public class DefaultAuthHandlerTests {
[Fact]
public async Task IsAuthenticatedAsync_ReturnsTrue() {
// Arrange
var authHandler = new DefaultAuthHandler();
// Act
var result = await authHandler.IsAuthenticatedAsync(null);
// Assert
Assert.True(result);
}
[Fact]
public async Task IsAuthenticatedAsync_WithPolicy_ReturnsTrue() {
// Arrange
var authHandler = new DefaultAuthHandler();
// Act
var result = await authHandler.IsAuthenticatedAsync("TestPolicy");
// Assert
Assert.True(result);
}
[Fact]
public async Task GetCurrentUserDisplayNameAsync_ReturnsEmptyString() {
// Arrange
var authHandler = new DefaultAuthHandler();
// Act
var result = await authHandler.GetCurrentUserDisplayNameAsync();
// Assert
Assert.Equal(string.Empty, result);
}
}

View File

@@ -0,0 +1,199 @@
using HopFrame.Core.Config;
using HopFrame.Core.Services;
using HopFrame.Core.Services.Implementations;
using HopFrame.Tests.Core.Models;
using Microsoft.EntityFrameworkCore;
using Moq;
namespace HopFrame.Tests.Core.Services;
public class DisplayPropertyTests {
private readonly Mock<IServiceProvider> _providerMock;
private readonly Mock<IContextExplorer> _explorerMock;
private readonly TableConfig _config;
private readonly TableManager<object> _tableManager;
public DisplayPropertyTests() {
var contextMock = new Mock<DbContext>();
_providerMock = new Mock<IServiceProvider>();
_explorerMock = new Mock<IContextExplorer>();
_config = new TableConfig(new DbContextConfig(typeof(MockDbContext)), typeof(MockModel), "Models", 0);
_tableManager =
new TableManager<object>(contextMock.Object, _config, _explorerMock.Object, _providerMock.Object);
}
[Fact]
public void DisplayProperty_ReturnsEmptyString_WhenItemIsNull() {
// Arrange
var prop = new PropertyConfig(typeof(string).GetProperty("Length")!, _config, 0);
// Act
var result = _tableManager.DisplayProperty(null, prop);
// Assert
Assert.Equal(string.Empty, result);
}
[Fact]
public void DisplayProperty_UsesFormatter_WhenListingProperty() {
// Arrange
var item = "test";
var prop = new PropertyConfig(typeof(string).GetProperty("Length")!, _config, 0) {
IsListingProperty = true,
Formatter = (obj, provider) => ((string)obj).ToUpper()
};
// Act
var result = _tableManager.DisplayProperty(item, prop);
// Assert
Assert.Equal("TEST", result);
}
[Fact]
public void DisplayProperty_UsesValueFormatter_WhenNotListingProperty() {
// Arrange
var item = "test";
var prop = new PropertyConfig(typeof(string).GetProperty("Length")!, _config, 0) {
Formatter = (obj, provider) => ((int)obj).ToString("D4")
};
// Act
var result = _tableManager.DisplayProperty(item, prop);
// Assert
Assert.Equal("0004", result);
}
[Fact]
public void DisplayProperty_ReturnsValueAsString_WhenNoFormatter() {
// Arrange
var item = "test";
var prop = new PropertyConfig(typeof(string).GetProperty("Length")!, _config, 0);
// Act
var result = _tableManager.DisplayProperty(item, prop);
// Assert
Assert.Equal("4", result);
}
[Fact]
public void DisplayProperty_ReturnsEnumerableCount_WhenEnumerableProperty() {
// Arrange
var item = new { List = new List<int> { 1, 2, 3 } };
var prop = new PropertyConfig(item.GetType().GetProperty("List")!, _config, 0) {
IsEnumerable = true
};
// Act
var result = _tableManager.DisplayProperty(item, prop);
// Assert
Assert.Equal("3", result);
}
[Fact]
public void DisplayProperty_UsesDisplayedProperty_WhenNoDirectFormatter() {
// Arrange
var item = new { Inner = new { Key = 42 } };
var innerPropInfo = item.Inner.GetType().GetProperty("Key");
var innerPropConfig = new PropertyConfig(innerPropInfo!, _config, 0);
var propInfo = item.GetType().GetProperty("Inner");
var prop = new PropertyConfig(propInfo!, _config, 0) {
DisplayedProperty = innerPropInfo
};
_explorerMock
.Setup(e => e.GetTable(item.Inner.GetType()))
.Returns(new TableConfig(new DbContextConfig(typeof(MockDbContext)), typeof(MockModel), "Models", 0) {
Properties = { innerPropConfig }
});
// Act
var result = _tableManager.DisplayProperty(item, prop);
// Assert
Assert.Equal("42", result);
}
[Fact]
public void DisplayProperty_ReturnsEmptyString_WhenPropValueIsNull() {
// Arrange
var item = new { Name = (string?)null };
var prop = new PropertyConfig(item.GetType().GetProperty("Name")!, _config, 0);
// Act
var result = _tableManager.DisplayProperty(item, prop);
// Assert
Assert.Equal(string.Empty, result);
}
[Fact]
public void DisplayProperty_UsesEnumerableFormatter_WhenEnumerableAndValueProvided() {
// Arrange
var item = new { List = new List<int> { 1, 2, 3 } };
var prop = new PropertyConfig(item.GetType().GetProperty("List")!, _config, 0) {
IsEnumerable = true,
EnumerableFormatter = (obj, provider) => string.Join(",", ((IEnumerable<int>)obj))
};
// Act
var result = _tableManager.DisplayProperty(item, prop, item.List);
// Assert
Assert.Equal("1,2,3", result);
}
[Fact]
public void DisplayProperty_ReturnsEmptyString_WhenDisplayedPropertyAndInnerConfigIsNull() {
// Arrange
var item = new { Inner = new { Key = 42 } };
var innerPropInfo = item.Inner.GetType().GetProperty("Key");
var propInfo = item.GetType().GetProperty("Inner");
var prop = new PropertyConfig(propInfo!, _config, 0) {
DisplayedProperty = innerPropInfo
};
_explorerMock
.Setup(e => e.GetTable(item.Inner.GetType()))
.Returns((TableConfig?)null);
// Act
var result = _tableManager.DisplayProperty(item, prop);
// Assert
Assert.Equal("{ Key = 42 }", result); // Returns the value as string if inner config is null
}
[Fact]
public void DisplayProperty_ReturnsKeyValue_WhenDisplayedPropertyIsNull() {
// Arrange
var item = new { Inner = new { Key = 42 } };
var propInfo = item.GetType().GetProperty("Inner");
var prop = new PropertyConfig(propInfo!, _config, 0);
var keyProperty = item.Inner.GetType().GetProperty("Key");
// Act
var result = _tableManager.DisplayProperty(item, prop);
// Assert
Assert.Equal("{ Key = 42 }", result); // Returns key value as string if DisplayedProperty is null
}
[Fact]
public void DisplayProperty_ReturnsToStringValue_WhenNoKeyOrDisplayedProperty() {
// Arrange
var item = new { Inner = new { Name = "Test" } };
var propInfo = item.GetType().GetProperty("Inner");
var prop = new PropertyConfig(propInfo!, _config, 0);
// Act
var result = _tableManager.DisplayProperty(item, prop);
// Assert
Assert.Equal("{ Name = Test }", result); // Returns ToString value of inner property
}
}

View File

@@ -0,0 +1,192 @@
// ReSharper disable GenericEnumeratorNotDisposed
using HopFrame.Core.Config;
using HopFrame.Core.Services;
using HopFrame.Core.Services.Implementations;
using HopFrame.Tests.Core.Models;
using Microsoft.EntityFrameworkCore;
using Moq;
namespace HopFrame.Tests.Core.Services;
public class TableManagerTests {
private Mock<DbContext> CreateMockDbContext<TModel>(List<TModel> data) where TModel : class {
var dbContext = new Mock<DbContext>();
var dbSet = CreateMockDbSet(data);
dbContext.Setup(m => m.Set<TModel>()).Returns(dbSet.Object);
dbContext.Setup(m => m.Entry(It.IsAny<MockModel>())).Returns<MockModel>(entry => new MockDbContext().Entry(entry));
return dbContext;
}
private Mock<DbSet<TModel>> CreateMockDbSet<TModel>(List<TModel> data) where TModel : class {
var queryableData = data.AsQueryable();
var dbSet = new Mock<DbSet<TModel>>();
dbSet.As<IQueryable<TModel>>().Setup(m => m.Provider)
.Returns(new TestAsyncQueryProvider<TModel>(queryableData.Provider));
dbSet.As<IQueryable<TModel>>().Setup(m => m.Expression).Returns(queryableData.Expression);
dbSet.As<IQueryable<TModel>>().Setup(m => m.ElementType).Returns(queryableData.ElementType);
dbSet.As<IQueryable<TModel>>().Setup(m => m.GetEnumerator()).Returns(queryableData.GetEnumerator());
dbSet.As<IAsyncEnumerable<TModel>>().Setup(m => m.GetAsyncEnumerator(It.IsAny<CancellationToken>()))
.Returns(new TestAsyncEnumerator<TModel>(queryableData.GetEnumerator()));
dbSet.As<IQueryable<TModel>>().Setup(m => m.Provider)
.Returns(new TestAsyncQueryProvider<TModel>(queryableData.Provider));
dbSet.Setup(m => m.FindAsync(It.IsAny<object[]>())).ReturnsAsync((object[] ids) =>
data.FirstOrDefault(d => ids.Contains(d.GetType().GetProperty("Id")!.GetValue(d, null))));
return dbSet;
}
[Fact]
public void LoadPage_ReturnsPagedData() {
// Arrange
var data = new List<MockModel> {
new MockModel { Id = 1, Name = "Item1" },
new MockModel { Id = 2, Name = "Item2" },
new MockModel { Id = 3, Name = "Item3" }
};
var dbContext = CreateMockDbContext(data);
var config = new TableConfig(new DbContextConfig(typeof(MockDbContext)), typeof(MockModel), "Models", 0);
var explorer = new Mock<IContextExplorer>();
var provider = new Mock<IServiceProvider>();
var manager = new TableManager<MockModel>(dbContext.Object, config, explorer.Object, provider.Object);
// Act
var result = manager.LoadPage(1, 2).ToList();
// Assert
Assert.Single(result);
Assert.Equal("Item3", ((MockModel)result[0]).Name);
}
[Fact]
public async Task Search_ReturnsMatchingData() {
// Arrange
var data = new List<MockModel> {
new MockModel { Id = 1, Name = "Item1" },
new MockModel { Id = 2, Name = "Item2" },
new MockModel { Id = 3, Name = "TestItem" }
};
var dbContext = CreateMockDbContext(data);
var config = new TableConfig(new DbContextConfig(typeof(MockDbContext)), typeof(MockModel), "Models", 0);
config.Properties.Add(new PropertyConfig(typeof(MockModel).GetProperty("Name")!, config, 0)
{ Searchable = true });
var explorer = new Mock<IContextExplorer>();
var provider = new Mock<IServiceProvider>();
var manager = new TableManager<MockModel>(dbContext.Object, config, explorer.Object, provider.Object);
// Act
var (result, totalPages) = await manager.Search("Test", 0, 2);
// Assert
var collection = result as object[] ?? result.ToArray();
Assert.Single(collection);
Assert.Equal("TestItem", ((MockModel)collection.First()).Name);
Assert.Equal(1, totalPages);
}
[Fact]
public async Task TotalPages_ReturnsCorrectPageCount() {
// Arrange
var data = new List<MockModel> {
new MockModel { Id = 1, Name = "Item1" },
new MockModel { Id = 2, Name = "Item2" },
new MockModel { Id = 3, Name = "Item3" }
};
var dbContext = new MockDbContext();
var config = new TableConfig(new DbContextConfig(typeof(MockDbContext)), typeof(MockModel), "Models", 0);
var explorer = new Mock<IContextExplorer>();
var provider = new Mock<IServiceProvider>();
var manager = new TableManager<MockModel>(dbContext, config, explorer.Object, provider.Object);
await dbContext.Models.AddRangeAsync(data);
await dbContext.SaveChangesAsync();
// Act
var totalPages = await manager.TotalPages(2);
// Assert
Assert.Equal(2, totalPages);
}
[Fact]
public async Task DeleteItem_RemovesItemFromDbSet() {
// Arrange
var data = new List<MockModel> {
new MockModel { Id = 1, Name = "Item1" },
new MockModel { Id = 2, Name = "Item2" }
};
var dbContext = CreateMockDbContext(data);
var config = new TableConfig(new DbContextConfig(typeof(MockDbContext)), typeof(MockModel), "Models", 0);
var explorer = new Mock<IContextExplorer>();
var provider = new Mock<IServiceProvider>();
var manager = new TableManager<MockModel>(dbContext.Object, config, explorer.Object, provider.Object);
var item = data.First();
// Act
await manager.DeleteItem(item);
// Assert
dbContext.Verify(m => m.SaveChangesAsync(It.IsAny<CancellationToken>()), Times.Once);
dbContext.Verify(m => m.Set<MockModel>().Remove(item), Times.Once);
}
[Fact]
public async Task EditItem_SavesChanges() {
// Arrange
var data = new List<MockModel> {
new MockModel { Id = 1, Name = "Item1" }
};
var dbContext = CreateMockDbContext(data);
var config = new TableConfig(new DbContextConfig(typeof(MockDbContext)), typeof(MockModel), "Models", 0);
var explorer = new Mock<IContextExplorer>();
var provider = new Mock<IServiceProvider>();
var manager = new TableManager<MockModel>(dbContext.Object, config, explorer.Object, provider.Object);
// Act
await manager.EditItem(data.First());
// Assert
dbContext.Verify(m => m.SaveChangesAsync(It.IsAny<CancellationToken>()), Times.Once);
}
[Fact]
public async Task AddItem_AddsItemToDbSet() {
// Arrange
var data = new List<MockModel>();
var dbContext = CreateMockDbContext(data);
var config = new TableConfig(new DbContextConfig(typeof(MockDbContext)), typeof(MockModel), "Models", 0);
var explorer = new Mock<IContextExplorer>();
var provider = new Mock<IServiceProvider>();
var manager = new TableManager<MockModel>(dbContext.Object, config, explorer.Object, provider.Object);
var newItem = new MockModel { Id = 3, Name = "NewItem" };
// Act
await manager.AddItem(newItem);
// Assert
dbContext.Verify(m => m.SaveChangesAsync(It.IsAny<CancellationToken>()), Times.Once);
dbContext.Verify(m => m.Set<MockModel>().AddAsync(newItem, It.IsAny<CancellationToken>()), Times.Once);
}
[Fact]
public async Task RevertChanges_ReloadsItem() {
// Arrange
var data = new List<MockModel> {
new MockModel { Id = 1, Name = "Item1" }
};
var dbContext = CreateMockDbContext(data);
var config = new TableConfig(new DbContextConfig(typeof(MockDbContext)), typeof(MockModel), "Models", 0);
var explorer = new Mock<IContextExplorer>();
var provider = new Mock<IServiceProvider>();
var manager = new TableManager<MockModel>(dbContext.Object, config, explorer.Object, provider.Object);
var item = data.First();
// Act
await manager.RevertChanges(item);
// Assert
dbContext.Verify(m => m.Entry(item), Times.Once);
}
}