Merge branch 'feature/api-abstraction' into 'dev'

Resolve "Web API abstraction"

Closes #22

See merge request leon.hoppe/hopframe!21
This commit was merged in pull request #59.
This commit is contained in:
2025-01-27 16:35:20 +00:00
16 changed files with 259 additions and 37 deletions

View File

@@ -3,14 +3,24 @@
<component name="AutoGeneratedRunConfigurationManager">
<projectFile profileName="http">HopFrame.Testing/HopFrame.Testing.csproj</projectFile>
<projectFile profileName="https">HopFrame.Testing/HopFrame.Testing.csproj</projectFile>
<projectFile profileName="http">testing/HopFrame.Testing.Api/HopFrame.Testing.Api.csproj</projectFile>
<projectFile profileName="https">testing/HopFrame.Testing.Api/HopFrame.Testing.Api.csproj</projectFile>
<projectFile profileName="http">testing/HopFrame.Testing/HopFrame.Testing.csproj</projectFile>
</component>
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="0648788e-7696-4e60-bf12-5d5601f33d8c" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/.idea/.idea.HopFrame/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.HopFrame/.idea/workspace.xml" afterDir="false" />
<list default="true" id="0648788e-7696-4e60-bf12-5d5601f33d8c" name="Changes" comment="Added missing files">
<change afterPath="$PROJECT_DIR$/src/HopFrame.Web/Components/App.razor" afterDir="false" />
<change afterPath="$PROJECT_DIR$/testing/HopFrame.Testing.Api/HopFrame.Testing.Api.csproj" afterDir="false" />
<change afterPath="$PROJECT_DIR$/testing/HopFrame.Testing.Api/Program.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/testing/HopFrame.Testing.Api/Properties/launchSettings.json" afterDir="false" />
<change afterPath="$PROJECT_DIR$/testing/HopFrame.Testing.Api/appsettings.Development.json" afterDir="false" />
<change afterPath="$PROJECT_DIR$/testing/HopFrame.Testing.Api/appsettings.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/HopFrame.sln" beforeDir="false" afterPath="$PROJECT_DIR$/HopFrame.sln" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/HopFrame.Web/Components/Layout/HopFrameLayout.razor" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Web/Components/Layout/HopFrameLayout.razor" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/HopFrame.Web/ServiceCollectionExtensions.cs" beforeDir="false" afterPath="$PROJECT_DIR$/src/HopFrame.Web/ServiceCollectionExtensions.cs" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -30,7 +40,7 @@
<component name="Git.Settings">
<option name="RECENT_BRANCH_BY_REPOSITORY">
<map>
<entry key="$PROJECT_DIR$" value="release/v3.0.0" />
<entry key="$PROJECT_DIR$" value="fix/missing-styles" />
</map>
</option>
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
@@ -81,26 +91,28 @@
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;.NET Launch Settings Profile.HopFrame.Testing.executor&quot;: &quot;Run&quot;,
&quot;.NET Launch Settings Profile.HopFrame.Testing: https.executor&quot;: &quot;Run&quot;,
&quot;.NET Project.HopFrame.Testing.executor&quot;: &quot;Run&quot;,
&quot;72b118b0-a6fc-4561-acdf-74f0b454dbb8.executor&quot;: &quot;Debug&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
&quot;dcdf1689-dc07-47e4-8824-2e60a4fbf301.executor&quot;: &quot;Debug&quot;,
&quot;git-widget-placeholder&quot;: &quot;dev&quot;,
&quot;list.type.of.created.stylesheet&quot;: &quot;CSS&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;preferences.environmentSetup&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
".NET Launch Settings Profile.HopFrame.Testing.Api: https.executor": "Run",
".NET Launch Settings Profile.HopFrame.Testing.executor": "Run",
".NET Launch Settings Profile.HopFrame.Testing: https.executor": "Run",
".NET Project.HopFrame.Testing.executor": "Run",
"72b118b0-a6fc-4561-acdf-74f0b454dbb8.executor": "Debug",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.git.unshallow": "true",
"b5f11219-dfc4-47a1-b02c-90ab603034fb.executor": "Debug",
"dcdf1689-dc07-47e4-8824-2e60a4fbf301.executor": "Debug",
"git-widget-placeholder": "!21 on feature/api-abstraction",
"list.type.of.created.stylesheet": "CSS",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"settings.editor.selected.configurable": "preferences.environmentSetup",
"vue.rearranger.settings.migration": "true"
}
}</component>
}]]></component>
<component name="RunManager" selected=".NET Launch Settings Profile.HopFrame.Testing: https">
<configuration name="HopFrame.Testing: http" type="LaunchSettings" factoryName=".NET Launch Settings Profile">
<option name="LAUNCH_PROFILE_PROJECT_FILE_PATH" value="$PROJECT_DIR$/testing/HopFrame.Testing/HopFrame.Testing.csproj" />
@@ -132,7 +144,39 @@
<option name="Build" />
</method>
</configuration>
<configuration name="HopFrame.Testing.Api: http" type="LaunchSettings" factoryName=".NET Launch Settings Profile">
<option name="LAUNCH_PROFILE_PROJECT_FILE_PATH" value="$PROJECT_DIR$/testing/HopFrame.Testing.Api/HopFrame.Testing.Api.csproj" />
<option name="LAUNCH_PROFILE_TFM" value="net9.0" />
<option name="LAUNCH_PROFILE_NAME" value="http" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="USE_MONO" value="0" />
<option name="RUNTIME_ARGUMENTS" value="" />
<option name="GENERATE_APPLICATIONHOST_CONFIG" value="1" />
<option name="SHOW_IIS_EXPRESS_OUTPUT" value="0" />
<option name="SEND_DEBUG_REQUEST" value="1" />
<option name="ADDITIONAL_IIS_EXPRESS_ARGUMENTS" value="" />
<method v="2">
<option name="Build" />
</method>
</configuration>
<configuration name="HopFrame.Testing.Api: https" type="LaunchSettings" factoryName=".NET Launch Settings Profile">
<option name="LAUNCH_PROFILE_PROJECT_FILE_PATH" value="$PROJECT_DIR$/testing/HopFrame.Testing.Api/HopFrame.Testing.Api.csproj" />
<option name="LAUNCH_PROFILE_TFM" value="net9.0" />
<option name="LAUNCH_PROFILE_NAME" value="https" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="USE_MONO" value="0" />
<option name="RUNTIME_ARGUMENTS" value="" />
<option name="GENERATE_APPLICATIONHOST_CONFIG" value="1" />
<option name="SHOW_IIS_EXPRESS_OUTPUT" value="0" />
<option name="SEND_DEBUG_REQUEST" value="1" />
<option name="ADDITIONAL_IIS_EXPRESS_ARGUMENTS" value="" />
<method v="2">
<option name="Build" />
</method>
</configuration>
<list>
<item itemvalue=".NET Launch Settings Profile.HopFrame.Testing.Api: http" />
<item itemvalue=".NET Launch Settings Profile.HopFrame.Testing.Api: https" />
<item itemvalue=".NET Launch Settings Profile.HopFrame.Testing: https" />
<item itemvalue=".NET Launch Settings Profile.HopFrame.Testing: http" />
</list>
@@ -163,6 +207,7 @@
<workItem from="1737293153907" duration="8953000" />
<workItem from="1737390240714" duration="60000" />
<workItem from="1737390360987" duration="601000" />
<workItem from="1737993570961" duration="1590000" />
</task>
<task id="LOCAL-00001" summary="Added basic configuration">
<option name="closed" value="true" />
@@ -340,7 +385,15 @@
<option name="project" value="LOCAL" />
<updated>1737301230493</updated>
</task>
<option name="localTasksCounter" value="23" />
<task id="LOCAL-00023" summary="Added missing files">
<option name="closed" value="true" />
<created>1737994074137</created>
<option name="number" value="00023" />
<option name="presentableId" value="LOCAL-00023" />
<option name="project" value="LOCAL" />
<updated>1737994074137</updated>
</task>
<option name="localTasksCounter" value="24" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
@@ -413,6 +466,7 @@
<MESSAGE value="Tested login functionality" />
<MESSAGE value="prepared project for release" />
<MESSAGE value="Included readme file in projects" />
<option name="LAST_COMMIT_MESSAGE" value="Included readme file in projects" />
<MESSAGE value="Added missing files" />
<option name="LAST_COMMIT_MESSAGE" value="Added missing files" />
</component>
</project>

View File

@@ -16,6 +16,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HopFrame.Tests.Core", "test
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HopFrame.Tests.Web", "tests\HopFrame.Tests.Web\HopFrame.Tests.Web.csproj", "{7AB4F4FF-E938-4A40-A7EB-7B2063262896}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HopFrame.Testing.Api", "testing\HopFrame.Testing.Api\HopFrame.Testing.Api.csproj", "{B13D2C4E-3993-47CD-A525-FD0B83980F0A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -27,6 +29,7 @@ Global
{58490069-51DF-454C-8B54-7FB7D4BDFF81} = {9EB7FDBD-49C2-4872-9666-6F7AEBA541B2}
{2E2D29E0-53FA-462D-B4D2-4678CD106E29} = {141928CB-5977-4285-A986-5BD785F2883C}
{7AB4F4FF-E938-4A40-A7EB-7B2063262896} = {141928CB-5977-4285-A986-5BD785F2883C}
{B13D2C4E-3993-47CD-A525-FD0B83980F0A} = {9EB7FDBD-49C2-4872-9666-6F7AEBA541B2}
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4BFE21C2-EAAC-4662-8B97-500836651B2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -49,5 +52,9 @@ Global
{7AB4F4FF-E938-4A40-A7EB-7B2063262896}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7AB4F4FF-E938-4A40-A7EB-7B2063262896}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7AB4F4FF-E938-4A40-A7EB-7B2063262896}.Release|Any CPU.Build.0 = Release|Any CPU
{B13D2C4E-3993-47CD-A525-FD0B83980F0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B13D2C4E-3993-47CD-A525-FD0B83980F0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B13D2C4E-3993-47CD-A525-FD0B83980F0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B13D2C4E-3993-47CD-A525-FD0B83980F0A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,23 @@
@using HopFrame.Web.Components.Pages
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<base href="/"/>
<ImportMap/>
<HeadOutlet/>
</head>
<body>
<Router AppAssembly="typeof(HopFrameHome).Assembly">
<Found Context="routeData">
<RouteView RouteData="routeData"/>
</Found>
</Router>
<script src="_framework/blazor.web.js"></script>
</body>
</html>

View File

@@ -5,6 +5,7 @@
<link rel="stylesheet" type='text/css' href="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/devicon.min.css" />
<link rel="stylesheet" href="@Assets["_content/HopFrame.Web/hopframe.css"]"/>
<link rel="stylesheet" href="@Assets["_content/HopFrame.Web/HopFrame.Web.bundle.scp.css"]"/>
<link rel="stylesheet" href="@Assets["_content/Microsoft.FluentUI.AspNetCore.Components/css/reboot.css"]"/>
<link rel="stylesheet" href="@Assets["_content/Microsoft.FluentUI.AspNetCore.Components/Microsoft.FluentUI.AspNetCore.Components.bundle.scp.css"]">

View File

@@ -1,5 +1,6 @@
using HopFrame.Core;
using HopFrame.Core.Config;
using HopFrame.Web.Components;
using HopFrame.Web.Components.Pages;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.FluentUI.AspNetCore.Components;
@@ -15,11 +16,12 @@ public static class ServiceCollectionExtensions {
/// <param name="services">The service collection to add the services to</param>
/// <param name="configurator">The configurator used to build the HopFrame configuration</param>
/// <param name="fluentUiLibraryConfiguration">The configuration for the FluentUI components</param>
/// <param name="addRazorComponents">Set this to false if you don't want to automatically configure razor components with interactive server components</param>
/// <returns>The same service collection that is passed in</returns>
public static IServiceCollection AddHopFrame(this IServiceCollection services, Action<HopFrameConfigurator> configurator, LibraryConfiguration? fluentUiLibraryConfiguration = null) {
public static IServiceCollection AddHopFrame(this IServiceCollection services, Action<HopFrameConfigurator> configurator, LibraryConfiguration? fluentUiLibraryConfiguration = null, bool addRazorComponents = true) {
var config = new HopFrameConfig();
configurator.Invoke(new HopFrameConfigurator(config));
return AddHopFrame(services, config, fluentUiLibraryConfiguration);
return AddHopFrame(services, config, fluentUiLibraryConfiguration, addRazorComponents);
}
/// <summary>
@@ -28,22 +30,46 @@ public static class ServiceCollectionExtensions {
/// <param name="services">The service collection to add the services to</param>
/// <param name="config">The config used for the HopFrame admin ui</param>
/// <param name="fluentUiLibraryConfiguration">The configuration for the FluentUI components</param>
/// <param name="addRazorComponents">Set this to false if you don't want to automatically configure razor components with interactive server components</param>
/// <returns>The same service collection that is passed in</returns>
public static IServiceCollection AddHopFrame(this IServiceCollection services, HopFrameConfig config, LibraryConfiguration? fluentUiLibraryConfiguration = null) {
public static IServiceCollection AddHopFrame(this IServiceCollection services, HopFrameConfig config, LibraryConfiguration? fluentUiLibraryConfiguration = null, bool addRazorComponents = true) {
services.AddSingleton(config);
services.AddHopFrameServices();
services.AddFluentUIComponents(fluentUiLibraryConfiguration);
if (addRazorComponents) {
services.AddRazorComponents()
.AddInteractiveServerComponents();
}
return services;
}
/// <summary>
/// Maps the HopFrame admin ui endpoints
/// Adds the HopFrame admin ui endpoints
/// </summary>
/// <seealso cref="AddHopFramePages"/>
[Obsolete($"Use '{nameof(AddHopFramePages)}' instead")]
public static RazorComponentsEndpointConventionBuilder MapHopFramePages(this RazorComponentsEndpointConventionBuilder builder) {
return AddHopFramePages(builder);
}
/// <summary>
/// Adds the HopFrame admin ui endpoints
/// </summary>
public static RazorComponentsEndpointConventionBuilder AddHopFramePages(this RazorComponentsEndpointConventionBuilder builder) {
builder
.AddInteractiveServerRenderMode()
.AddAdditionalAssemblies(typeof(HopFrameHome).Assembly);
return builder;
}
public static WebApplication MapHopFrame(this WebApplication app) {
app.UseAntiforgery();
app.MapStaticAssets();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
return app;
}
}

View File

@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0"/>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\HopFrame.Testing\HopFrame.Testing.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,51 @@
using HopFrame.Testing;
using HopFrame.Web;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
builder.Services.AddHopFrame(options => {
options.AddDbContext<DatabaseContext>();
});
builder.Services.AddDbContext<DatabaseContext>(options => {
options.UseInMemoryDatabase("testing.web");
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) {
app.MapOpenApi();
}
app.UseHttpsRedirection();
var summaries = new[] {
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
app.MapGet("/weatherforecast", () => {
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
})
.WithName("GetWeatherForecast");
app.MapHopFrame();
app.Run();
record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) {
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}

View File

@@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5115",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:7129;http://localhost:5115",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -5,6 +5,8 @@ using HopFrame.Tests.Web.Models;
using HopFrame.Web;
using HopFrame.Web.Components.Dialogs;
using HopFrame.Web.Models;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.FluentUI.AspNetCore.Components;
using Moq;
@@ -34,7 +36,7 @@ public class HopFrameEditorTests : TestContext {
contextExplorerMock.Setup(e => e.GetTableManager("Table1")).Returns(Mock.Of<ITableManager>());
authHandlerMock.Setup(h => h.IsAuthenticatedAsync(It.IsAny<string>())).ReturnsAsync(true);
Services.AddHopFrame(config);
Services.AddHopFrame(config, null, false);
Services.AddSingleton(contextExplorerMock.Object);
Services.AddSingleton(authHandlerMock.Object);
Services.AddSingleton(dialogServiceMock.Object);

View File

@@ -25,7 +25,7 @@ public class HopFrameLayoutTests : TestContext {
.ReturnsAsync(true);
Services.AddSingleton(authHandlerMock.Object);
Services.AddHopFrame(config);
Services.AddHopFrame(config, null, false);
JSInterop.Mode = JSRuntimeMode.Loose;
@@ -61,7 +61,7 @@ public class HopFrameLayoutTests : TestContext {
.ReturnsAsync(false);
Services.AddSingleton(navMock);
Services.AddHopFrame(config);
Services.AddHopFrame(config, null, false);
Services.AddSingleton(authHandlerMock.Object);
JSInterop.Mode = JSRuntimeMode.Loose;

View File

@@ -22,7 +22,7 @@ public class HopFrameNavigationTests : TestContext {
.ReturnsAsync("John Doe");
Services.AddSingleton(authHandlerMock.Object);
Services.AddHopFrame(config);
Services.AddHopFrame(config, null, false);
JSInterop.Mode = JSRuntimeMode.Loose;
@@ -51,7 +51,7 @@ public class HopFrameNavigationTests : TestContext {
.ReturnsAsync("John Doe");
Services.AddSingleton(authHandlerMock.Object);
Services.AddHopFrame(config);
Services.AddHopFrame(config, null, false);
JSInterop.Mode = JSRuntimeMode.Loose;

View File

@@ -32,7 +32,7 @@ public class HopFrameSideMenuTests : TestContext {
Services.AddSingleton(contextExplorerMock.Object);
Services.AddSingleton(authHandlerMock.Object);
Services.AddHopFrame(config);
Services.AddHopFrame(config, null, false);
JSInterop.Mode = JSRuntimeMode.Loose;

View File

@@ -38,7 +38,7 @@ public class HopFrameHomeTests : TestContext {
authHandlerMock.Setup(h => h.IsAuthenticatedAsync(It.IsAny<string>()))
.ReturnsAsync(true);
Services.AddHopFrame(config);
Services.AddHopFrame(config, null, false);
Services.AddSingleton(contextExplorerMock.Object);
Services.AddSingleton(authHandlerMock.Object);

View File

@@ -35,7 +35,7 @@ public class HopFrameTablePageTests : TestContext {
authHandlerMock.Setup(h => h.IsAuthenticatedAsync(It.IsAny<string>())).ReturnsAsync(true);
managerMock.Setup(m => m.LoadPage(It.IsAny<int>(), It.IsAny<int>())).Returns(Enumerable.Empty<object>().AsAsyncQueryable());
Services.AddHopFrame(config);
Services.AddHopFrame(config, null, false);
Services.AddSingleton(contextExplorerMock.Object);
Services.AddSingleton(authHandlerMock.Object);
Services.AddSingleton(dialogServiceMock.Object);
@@ -77,7 +77,7 @@ public class HopFrameTablePageTests : TestContext {
contextExplorerMock.Setup(e => e.GetTableManager("Table1")).Returns(tableManagerMock.Object);
authHandlerMock.Setup(h => h.IsAuthenticatedAsync(It.IsAny<string>())).ReturnsAsync(true);
Services.AddHopFrame(new HopFrameConfig());
Services.AddHopFrame(new HopFrameConfig(), null, false);
Services.AddSingleton(contextExplorerMock.Object);
Services.AddSingleton(authHandlerMock.Object);
Services.AddSingleton(dialogServiceMock.Object);