-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRazorIntegrationTests.cs
More file actions
118 lines (98 loc) · 5.1 KB
/
RazorIntegrationTests.cs
File metadata and controls
118 lines (98 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
using Code311.Tabler.Core.Assets;
using Code311.Tabler.Core.Widgets;
using Code311.Tabler.Razor.Assets;
using Code311.Tabler.Razor.Feedback;
using Code311.Tabler.Razor.Filters;
using Code311.Tabler.Razor.Theming;
using Code311.Ui.Abstractions.Options;
using Code311.Ui.Core.Feedback;
using Code311.Ui.Core.Loading;
using Code311.Ui.Core.Theming;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Options;
using Xunit;
namespace Code311.Tests.Integration.Razor;
/// <summary>
/// Validates Razor adapter request lifecycle integration behaviors.
/// </summary>
public sealed class RazorIntegrationTests
{
[Fact]
public async Task PageFeedbackFilter_ShouldCaptureModelErrors()
{
var channel = new InMemoryFeedbackChannel();
var scoped = new Code311RequestFeedbackStore();
var filter = new Code311PageFeedbackFilter(channel, scoped);
var actionContext = new Microsoft.AspNetCore.Mvc.ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor(), new ModelStateDictionary());
actionContext.ModelState.AddModelError("Email", "Email invalid");
var pageContext = new PageContext(actionContext);
var executing = new PageHandlerExecutingContext(pageContext, [], new HandlerMethodDescriptor(), new Dictionary<string, object?>(), new object());
await filter.OnPageHandlerExecutionAsync(executing, () => Task.FromResult(new PageHandlerExecutedContext(pageContext, [], new HandlerMethodDescriptor(), new object())));
Assert.Single(scoped.GetAll());
Assert.Single(channel.Drain());
}
[Fact]
public async Task BusyTransitionPageFilter_ShouldToggleRequestScope()
{
var busy = new BusyStateCoordinator();
var preloader = new PreloaderOrchestrator();
var filter = new Code311BusyTransitionPageFilter(busy, preloader);
var actionContext = new Microsoft.AspNetCore.Mvc.ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor(), new ModelStateDictionary());
var pageContext = new PageContext(actionContext);
var executing = new PageHandlerExecutingContext(pageContext, [], new HandlerMethodDescriptor(), new Dictionary<string, object?>(), new object());
await filter.OnPageHandlerExecutionAsync(executing, () =>
{
Assert.True(busy.IsBusy("razor-request"));
Assert.True(preloader.IsActive("razor-request"));
return Task.FromResult(new PageHandlerExecutedContext(pageContext, [], new HandlerMethodDescriptor(), new object()));
});
Assert.False(busy.IsBusy("razor-request"));
Assert.False(preloader.IsActive("razor-request"));
}
[Fact]
public async Task ThemePageFilter_ShouldSetThemeContext()
{
var registry = new ThemeRegistry();
registry.Register(new Code311.Ui.Abstractions.Theming.ThemeProfile { Name = "green" });
var resolver = new DefaultThemeProfileResolver(registry, Options.Create(new UiFrameworkOptions()));
var themeContext = new Code311ThemeRequestContext();
var filter = new Code311ThemePageFilter(resolver, themeContext);
var http = new DefaultHttpContext();
http.Request.QueryString = new QueryString("?theme=green");
var actionContext = new Microsoft.AspNetCore.Mvc.ActionContext(http, new RouteData(), new ActionDescriptor(), new ModelStateDictionary());
var pageContext = new PageContext(actionContext);
var executing = new PageHandlerExecutingContext(pageContext, [], new HandlerMethodDescriptor(), new Dictionary<string, object?>(), new object());
await filter.OnPageHandlerExecutionAsync(executing, () => Task.FromResult(new PageHandlerExecutedContext(pageContext, [], new HandlerMethodDescriptor(), new object())));
Assert.Equal("green", themeContext.Current?.Name);
}
[Fact]
public void AssetRequestStore_ShouldAcceptWidgetAssetContributions()
{
var store = new Code311AssetRequestStore();
var widget = new TestWidgetSlotParticipant();
store.AddWidgetAssets(widget);
var assets = store.GetAll();
Assert.Collection(
assets,
asset => Assert.False(asset.IsScript),
asset => Assert.True(asset.IsScript));
}
private sealed class TestWidgetSlotParticipant : ITablerWidgetSlotParticipant
{
public TablerWidgetSlotDefinition Slot { get; } = new("test", "panel-body", new TablerWidgetOptionsEnvelope(new Dictionary<string, object?>()));
public IReadOnlyList<TablerAssetDescriptor> GetAssetContributions()
=>
[
new("/scripts/test.js", TablerAssetType.Script, 20),
new("/styles/test.css", TablerAssetType.Style, 10)
];
public TablerWidgetInitializationRequest CreateInitialization(string elementId)
=> new(Slot.WidgetKey, elementId, "{}");
}
}