Skip to content

Commit de6f7eb

Browse files
committed
Add unit tests for plugins, queries, and server synchronization
- Implement tests for Plugin functionality including registration, configuration, and dependency validation. - Add tests for Mutation operations covering initial state, execution, error handling, and retry logic. - Create tests for Query operations focusing on initial state, data fetching, and error handling. - Introduce tests for QueryClient methods to ensure data storage and retrieval functionality. - Implement tests for ServerSync operations, including state updates, conflict resolution, and options validation.
1 parent 2c05207 commit de6f7eb

35 files changed

Lines changed: 7403 additions & 15 deletions
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright (c) EasyAppDev. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using EasyAppDev.Blazor.Store.Core;
5+
using Microsoft.Extensions.DependencyInjection;
6+
using Microsoft.Extensions.Logging;
7+
8+
namespace EasyAppDev.Blazor.Store.DevTools;
9+
10+
/// <summary>
11+
/// Extension methods for configuring enhanced DevTools in the store builder.
12+
/// </summary>
13+
public static class DevToolsBuilderExtensions
14+
{
15+
/// <summary>
16+
/// Enables enhanced Redux DevTools integration with full time-travel support.
17+
/// </summary>
18+
/// <typeparam name="TState">The type of state.</typeparam>
19+
/// <param name="builder">The store builder.</param>
20+
/// <param name="serviceProvider">Service provider for IJSRuntime resolution.</param>
21+
/// <param name="configure">Action to configure DevTools options.</param>
22+
/// <returns>The builder for chaining.</returns>
23+
/// <example>
24+
/// <code>
25+
/// builder.WithEnhancedDevTools(sp, options =>
26+
/// {
27+
/// options.Name = "MyStore";
28+
/// options.EnableStateEditing = true;
29+
/// options.MaxHistory = 50;
30+
/// options.StateSanitizer = state => state with { Password = "***" };
31+
/// });
32+
/// </code>
33+
/// </example>
34+
public static StoreBuilder<TState> WithEnhancedDevTools<TState>(
35+
this StoreBuilder<TState> builder,
36+
IServiceProvider serviceProvider,
37+
Action<DevToolsOptions<TState>>? configure = null)
38+
where TState : notnull
39+
{
40+
ArgumentNullException.ThrowIfNull(builder);
41+
ArgumentNullException.ThrowIfNull(serviceProvider);
42+
43+
var options = DevToolsOptions<TState>.Default();
44+
configure?.Invoke(options);
45+
46+
var logger = serviceProvider.GetService<ILogger<EnhancedDevToolsMiddleware<TState>>>();
47+
var middleware = new EnhancedDevToolsMiddleware<TState>(serviceProvider, options, logger);
48+
49+
return builder.WithMiddleware(middleware);
50+
}
51+
52+
/// <summary>
53+
/// Enables enhanced Redux DevTools with default configuration.
54+
/// </summary>
55+
/// <typeparam name="TState">The type of state.</typeparam>
56+
/// <param name="builder">The store builder.</param>
57+
/// <param name="serviceProvider">Service provider for IJSRuntime resolution.</param>
58+
/// <param name="storeName">The name to display in DevTools.</param>
59+
/// <returns>The builder for chaining.</returns>
60+
public static StoreBuilder<TState> WithEnhancedDevTools<TState>(
61+
this StoreBuilder<TState> builder,
62+
IServiceProvider serviceProvider,
63+
string storeName)
64+
where TState : notnull
65+
{
66+
return builder.WithEnhancedDevTools(serviceProvider, options =>
67+
{
68+
options.Name = storeName;
69+
});
70+
}
71+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright (c) EasyAppDev. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
namespace EasyAppDev.Blazor.Store.DevTools;
5+
6+
/// <summary>
7+
/// Configuration options for Redux DevTools integration with enhanced time-travel support.
8+
/// </summary>
9+
/// <typeparam name="TState">The type of state managed by the store.</typeparam>
10+
public class DevToolsOptions<TState> where TState : notnull
11+
{
12+
/// <summary>
13+
/// Gets or sets the name to display in Redux DevTools.
14+
/// Defaults to the state type name.
15+
/// </summary>
16+
public string? Name { get; set; }
17+
18+
/// <summary>
19+
/// Gets or sets whether time-travel debugging is enabled.
20+
/// Default is true.
21+
/// </summary>
22+
public bool EnableTimeTravel { get; set; } = true;
23+
24+
/// <summary>
25+
/// Gets or sets the maximum number of actions to keep in history.
26+
/// Default is 100.
27+
/// </summary>
28+
public int MaxHistory { get; set; } = 100;
29+
30+
/// <summary>
31+
/// Gets or sets whether action replay is enabled.
32+
/// Default is true.
33+
/// </summary>
34+
public bool EnableActionReplay { get; set; } = true;
35+
36+
/// <summary>
37+
/// Gets or sets whether state editing from DevTools is enabled.
38+
/// Default is false for safety.
39+
/// </summary>
40+
public bool EnableStateEditing { get; set; } = false;
41+
42+
/// <summary>
43+
/// Gets or sets a filter function for actions.
44+
/// Actions returning false are not sent to DevTools.
45+
/// </summary>
46+
public Func<string, bool>? ActionFilter { get; set; }
47+
48+
/// <summary>
49+
/// Gets or sets a function to sanitize state before sending to DevTools.
50+
/// Useful for hiding sensitive data.
51+
/// </summary>
52+
public Func<TState, TState>? StateSanitizer { get; set; }
53+
54+
/// <summary>
55+
/// Gets or sets a function to transform actions before sending to DevTools.
56+
/// </summary>
57+
public Func<string, object>? ActionTransformer { get; set; }
58+
59+
/// <summary>
60+
/// Gets or sets whether to trace action performance.
61+
/// Default is false.
62+
/// </summary>
63+
public bool TracePerformance { get; set; } = false;
64+
65+
/// <summary>
66+
/// Gets or sets actions that should not be recorded.
67+
/// </summary>
68+
public HashSet<string> IgnoredActions { get; set; } = new()
69+
{
70+
"@@INIT"
71+
};
72+
73+
/// <summary>
74+
/// Gets or sets whether to serialize state with indentation.
75+
/// Default is false for performance.
76+
/// </summary>
77+
public bool SerializeIndented { get; set; } = false;
78+
79+
/// <summary>
80+
/// Gets or sets whether to pause recording.
81+
/// Can be toggled at runtime.
82+
/// </summary>
83+
public bool Paused { get; set; } = false;
84+
85+
/// <summary>
86+
/// Gets or sets the callback invoked when time-travel jump occurs.
87+
/// </summary>
88+
public Action<TState>? OnJump { get; set; }
89+
90+
/// <summary>
91+
/// Gets or sets the callback invoked when an action is replayed.
92+
/// </summary>
93+
public Action<string>? OnActionReplay { get; set; }
94+
95+
/// <summary>
96+
/// Gets or sets the callback invoked when state is imported.
97+
/// </summary>
98+
public Action<TState>? OnStateImport { get; set; }
99+
100+
/// <summary>
101+
/// Creates default options with the given store name.
102+
/// </summary>
103+
public static DevToolsOptions<TState> Default(string? name = null) => new()
104+
{
105+
Name = name ?? typeof(TState).Name
106+
};
107+
}

0 commit comments

Comments
 (0)