Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions src/CommunityToolkit.Maui.Core/AppBuilderExtensions.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ namespace CommunityToolkit.Maui.Core;
[SupportedOSPlatform("Tizen6.5")]
public static class AppBuilderExtensions
{
static readonly WeakEventManager weakEventManager = new();

// This is an internal event used by Unit Tests to confirm when the code enters the `if (Options.ShouldUseStatusBarBehaviorOnAndroidModalPage)` block
internal static event EventHandler ShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted
{
add => weakEventManager.AddEventHandler(value);
remove => weakEventManager.RemoveEventHandler(value);
}

/// <summary>
/// Initializes the .NET MAUI Community Toolkit Core Library
/// </summary>
Expand All @@ -27,9 +36,10 @@ public static MauiAppBuilder UseMauiCommunityToolkitCore(this MauiAppBuilder bui
{
options?.Invoke(new Options());

if (Options.ShouldUseStatusBarBehaviorOnAndroidModalPage)
{

#if ANDROID
if (Options.ShouldUseStatusBarBehaviorOnAndroidModalPage)
{
builder.Services.AddSingleton<IDialogFragmentService, DialogFragmentService>();

builder.ConfigureLifecycleEvents(static lifecycleBuilder =>
Expand Down Expand Up @@ -58,9 +68,11 @@ public static MauiAppBuilder UseMauiCommunityToolkitCore(this MauiAppBuilder bui
});
});
});
}
#endif

weakEventManager.HandleEvent(null, EventArgs.Empty, nameof(ShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted));
}

return builder;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ static bool TryConvertToDialogFragment(Fragment fragment, [NotNullWhen(true)] ou
dialogFragment = dialog;
return true;
}

static void HandleStatusBarColor(DialogFragment dialogFragment, AppCompatActivity activity)
{
if (activity.Window is null)
Expand Down
3 changes: 3 additions & 0 deletions src/CommunityToolkit.Maui.UnitTests/BaseTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ protected virtual void Dispose(bool isDisposing)
DeviceDisplay.SetCurrent(null);
DispatcherProvider.SetCurrent(null);

// Restore default options
var options = new Options();
options.SetShouldUseStatusBarBehaviorOnAndroidModalPage(true);
options.SetShouldEnableSnackbarOnWindows(false);
options.SetShouldSuppressExceptionsInAnimations(false);
options.SetShouldSuppressExceptionsInBehaviors(false);
options.SetShouldSuppressExceptionsInConverters(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
using CommunityToolkit.Maui.Core;
using Xunit;

namespace CommunityToolkit.Maui.UnitTests.Extensions;

#pragma warning disable CA1416
public class AppBuilderExtensionsTests : BaseTest
{
[Fact]
public void ConfirmOptionsDefaultValue()
{
// Arrange
bool isAndroidDialogFragmentServiceInitialized = false;
Core.AppBuilderExtensions.ShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted += HandleShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted;

// Assert
Assert.True(Core.Options.ShouldUseStatusBarBehaviorOnAndroidModalPage);
Assert.False(Options.ShouldEnableSnackbarOnWindows);
Assert.False(Options.ShouldSuppressExceptionsInAnimations);
Assert.False(Options.ShouldSuppressExceptionsInBehaviors);
Assert.False(Options.ShouldSuppressExceptionsInConverters);
Assert.False(isAndroidDialogFragmentServiceInitialized);

Core.AppBuilderExtensions.ShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted -= HandleShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted;

void HandleShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted(object? sender, EventArgs e)
{
Core.AppBuilderExtensions.ShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted -= HandleShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted;
isAndroidDialogFragmentServiceInitialized = true;
}
}

[Fact]
public void ConfirmDefaultValueRemainWhenOptionsNull()
{
// Arrange
var builder = MauiApp.CreateBuilder();
bool isAndroidDialogFragmentServiceInitialized = false;

Core.AppBuilderExtensions.ShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted += HandleShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted;

// Act
builder.UseMauiCommunityToolkit(null);

// Assert
Assert.True(Core.Options.ShouldUseStatusBarBehaviorOnAndroidModalPage);
Assert.False(Options.ShouldEnableSnackbarOnWindows);
Assert.False(Options.ShouldSuppressExceptionsInAnimations);
Assert.False(Options.ShouldSuppressExceptionsInBehaviors);
Assert.False(Options.ShouldSuppressExceptionsInConverters);
Assert.True(isAndroidDialogFragmentServiceInitialized);

void HandleShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted(object? sender, EventArgs e)
{
Core.AppBuilderExtensions.ShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted -= HandleShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted;
isAndroidDialogFragmentServiceInitialized = true;
}
}


[Fact]
public void UseMauiCommunityToolkit_ShouldRegisterServices()
{
// Arrange
var builder = MauiApp.CreateBuilder();
bool isAndroidDialogFragmentServiceInitialized = false;
Core.AppBuilderExtensions.ShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted += HandleShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted;

// Act
builder.UseMauiCommunityToolkit();

// Assert
var serviceProvider = builder.Services.BuildServiceProvider();
Assert.NotNull(serviceProvider.GetService<IPopupService>());
Assert.True(isAndroidDialogFragmentServiceInitialized);

void HandleShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted(object? sender, EventArgs e)
{
Core.AppBuilderExtensions.ShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted -= HandleShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted;
isAndroidDialogFragmentServiceInitialized = true;
}
}

[Fact]
public void UseMauiCommunityToolkit_ShouldAssignValues()
{
// Arrange
var builder = MauiApp.CreateBuilder();
bool isAndroidDialogFragmentServiceInitialized = false;
Core.AppBuilderExtensions.ShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted += HandleShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted;

// Act
builder.UseMauiCommunityToolkit(options =>
{
options.SetShouldEnableSnackbarOnWindows(!Options.ShouldEnableSnackbarOnWindows);
options.SetShouldSuppressExceptionsInAnimations(!Options.ShouldSuppressExceptionsInAnimations);
options.SetShouldSuppressExceptionsInBehaviors(!Options.ShouldSuppressExceptionsInBehaviors);
options.SetShouldSuppressExceptionsInConverters(!Options.ShouldSuppressExceptionsInConverters);
options.SetShouldUseStatusBarBehaviorOnAndroidModalPage(!Core.Options.ShouldUseStatusBarBehaviorOnAndroidModalPage);
});

// Assert
Assert.False(Core.Options.ShouldUseStatusBarBehaviorOnAndroidModalPage);
Assert.True(Options.ShouldEnableSnackbarOnWindows);
Assert.True(Options.ShouldSuppressExceptionsInAnimations);
Assert.True(Options.ShouldSuppressExceptionsInBehaviors);
Assert.True(Options.ShouldSuppressExceptionsInConverters);
Assert.False(isAndroidDialogFragmentServiceInitialized);

Core.AppBuilderExtensions.ShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted -= HandleShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted;

void HandleShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted(object? sender, EventArgs e)
{
Core.AppBuilderExtensions.ShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted -= HandleShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted;
isAndroidDialogFragmentServiceInitialized = true;
}
}
}
#pragma warning restore CA1416
7 changes: 4 additions & 3 deletions src/CommunityToolkit.Maui/AppBuilderExtensions.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@
/// <returns><see cref="MauiAppBuilder"/> initialized for <see cref="CommunityToolkit.Maui"/></returns>
public static MauiAppBuilder UseMauiCommunityToolkit(this MauiAppBuilder builder, Action<Options>? options = null)
{
// Pass `null` because `options?.Invoke()` will set options on both `CommunityToolkit.Maui` and `CommunityToolkit.Maui.Core`
builder.UseMauiCommunityToolkitCore(null);

// Invokes options for both `CommunityToolkit.Maui` and `CommunityToolkit.Maui.Core`
options?.Invoke(new Options(builder));

// Pass `null` because `options?.Invoke()` will set options on both `CommunityToolkit.Maui` and `CommunityToolkit.Maui.Core`
// Be sure to call `.UseMauiCommunityToolkitCore(null)` after `options.Invoke(new Options(builder))` to ensure `CommunityToolkit.Maui.Core.Options` have already been set
builder.UseMauiCommunityToolkitCore(null);

builder.Services.AddSingleton<IPopupService, PopupService>();

builder.ConfigureMauiHandlers(static h =>
Expand All @@ -42,7 +43,7 @@
Popup.RemapForControls();

#if ANDROID
NavigationBar.RemapForControls();

Check warning on line 46 in src/CommunityToolkit.Maui/AppBuilderExtensions.shared.cs

View workflow job for this annotation

GitHub Actions / Build Library (windows-latest)

This call site is reachable on: 'Android' 21.0 and later, 'iOS' 15.0 and later, 'maccatalyst' 15.0 and later, 'Tizen' 6.5 and later, 'Windows' 10.0.17763 and later. 'NavigationBar.RemapForControls()' is only supported on: 'Android' 23.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416)
#endif
return builder;
}
Expand Down
Loading