Skip to content

Commit

Permalink
Implemented and tested ClearQueue (Issue #175) (#176)
Browse files Browse the repository at this point in the history
* added possibility to clear queued toasts (#175)

* implemented clearqueue tests (#175)

* added clearqueue to ui (#175)

Co-authored-by: Samuel Flatscher <[email protected]>
Co-authored-by: Chris Sainty <[email protected]>
  • Loading branch information
3 people authored Nov 8, 2022
1 parent b98176e commit 4f98e1e
Show file tree
Hide file tree
Showing 15 changed files with 397 additions and 4 deletions.
16 changes: 16 additions & 0 deletions samples/BlazorServer/Pages/Index.razor
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
<button class="btn btn-warning" @onclick="ClearWarnings">Clear Warning Toasts</button>
<button class="btn btn-info" @onclick="ClearInfos">Clear Info Toasts</button>
<button class="btn btn-secondary" @onclick="ClearCustom">Clear Custom Toasts</button>
<hr />

<h1>Blazored Toasts - Remove queued Toasts</h1>

<button class="btn btn-primary" @onclick="ClearQueue">Clear all queued Toasts</button>
<button class="btn btn-warning" @onclick="ClearQueueWarnings">Clear queued Warning Toasts</button>
<button class="btn btn-info" @onclick="ClearQueueInfos">Clear queued Info Toasts</button>

@code
{
Expand Down Expand Up @@ -56,4 +63,13 @@

private void ClearCustom()
=> toastService.ClearCustomToasts();

private void ClearQueue()
=> toastService.ClearQueue();

private void ClearQueueWarnings()
=> toastService.ClearQueueToasts(ToastLevel.Warning);

private void ClearQueueInfos()
=> toastService.ClearQueueInfoToasts();
}
3 changes: 2 additions & 1 deletion samples/BlazorServer/Shared/MainLayout.razor
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
SuccessIcon="done_outline"
WarningIcon="warning"
ShowProgressBar="@true"
ShowCloseButton="@true">
ShowCloseButton="@true"
MaxToastCount="3">
<CloseButtonContent>
<div>
<span class="myCloseButtonStyleClass">&times;</span>
Expand Down
16 changes: 16 additions & 0 deletions samples/BlazorWebAssembly/Pages/Index.razor
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@
<button class="btn btn-warning" @onclick="ClearWarnings">Clear Warning Toasts</button>
<button class="btn btn-info" @onclick="ClearInfos">Clear Info Toasts</button>
<button class="btn btn-secondary" @onclick="ClearCustom">Clear Custom Toasts</button>
<hr />

<h1>Blazored Toasts - Remove queued Toasts</h1>

<button class="btn btn-primary" @onclick="ClearQueue">Clear all queued Toasts</button>
<button class="btn btn-warning" @onclick="ClearQueueWarnings">Clear queued Warning Toasts</button>
<button class="btn btn-info" @onclick="ClearQueueInfos">Clear queued Info Toasts</button>

@code
{
Expand Down Expand Up @@ -57,4 +64,13 @@

private void ClearCustom()
=> ToastService.ClearCustomToasts();

private void ClearQueue()
=> ToastService.ClearQueue();

private void ClearQueueWarnings()
=> ToastService.ClearQueueToasts(ToastLevel.Warning);

private void ClearQueueInfos()
=> ToastService.ClearQueueInfoToasts();
}
20 changes: 20 additions & 0 deletions src/Blazored.Toast.TestExtensions/InMemoryToastService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public class InMemoryToastService : IToastService
public event Action OnClearAll;
public event Action<ToastLevel> OnClearToasts;
public event Action OnClearCustomToasts;
public event Action? OnClearQueue;
public event Action<ToastLevel>? OnClearQueueToasts;

public void ShowToast<TComponent>() where TComponent : IComponent
{
Expand Down Expand Up @@ -99,4 +101,22 @@ public void ClearErrorToasts()

public void ClearCustomToasts()
=> toasts.RemoveAll(x => x.ToastType != typeof(Configuration.ToastInstance));

public void ClearQueue()
=> throw new NotImplementedException();

public void ClearQueueToasts(ToastLevel toastLevel)
=> throw new NotImplementedException();

public void ClearQueueWarningToasts()
=> throw new NotImplementedException();

public void ClearQueueInfoToasts()
=> throw new NotImplementedException();

public void ClearQueueSuccessToasts()
=> throw new NotImplementedException();

public void ClearQueueErrorToasts()
=> throw new NotImplementedException();
}
23 changes: 21 additions & 2 deletions src/Blazored.Toast/BlazoredToasts.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ protected override void OnInitialized()
ToastService.OnClearAll += ClearAll;
ToastService.OnClearToasts += ClearToasts;
ToastService.OnClearCustomToasts += ClearCustomToasts;

ToastService.OnClearQueue += ClearQueue;
ToastService.OnClearQueueToasts += ClearQueueToasts;

if (RemoveToastsOnNavigation)
{
Expand All @@ -101,7 +102,7 @@ public void RemoveToast(Guid toastId)
InvokeAsync(() =>
{
var toastInstance = ToastList.SingleOrDefault(x => x.Id == toastId);
if (toastInstance is not null)
{
ToastList.Remove(toastInstance);
Expand Down Expand Up @@ -236,4 +237,22 @@ private void ClearCustomToasts()
StateHasChanged();
});
}

private void ClearQueue()
{
InvokeAsync(() =>
{
ToastWaitingQueue.Clear();
StateHasChanged();
});
}

private void ClearQueueToasts(ToastLevel toastLevel)
{
InvokeAsync(() =>
{
ToastWaitingQueue = new(ToastWaitingQueue.Where(x => x.ToastSettings?.ToastLevel != toastLevel));
StateHasChanged();
});
}
}
39 changes: 39 additions & 0 deletions src/Blazored.Toast/Services/IToastService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ public interface IToastService
/// </summary>
event Action<Type, ToastParameters?, ToastInstanceSettings?> OnShowComponent;

/// <summary>
/// A event that will be invoked to clear all queued toasts
/// </summary>
event Action? OnClearQueue;

/// <summary>
/// A event that will be invoked to clear queue toast of specified level
/// </summary>
event Action<ToastLevel>? OnClearQueueToasts;

/// <summary>
/// Shows a information toast
/// </summary>
Expand Down Expand Up @@ -170,4 +180,33 @@ public interface IToastService
/// </summary>
void ClearCustomToasts();

/// <summary>
/// Removes all queued toasts
/// </summary>
void ClearQueue();

/// <summary>
/// Removes all queued toasts with a specified <paramref name="toastLevel"/>.
/// </summary>
void ClearQueueToasts(ToastLevel toastLevel);

/// <summary>
/// Removes all queued toasts with toast level warning
/// </summary>
void ClearQueueWarningToasts();

/// <summary>
/// Removes all queued toasts with toast level Info
/// </summary>
void ClearQueueInfoToasts();

/// <summary>
/// Removes all queued toasts with toast level Success
/// </summary>
void ClearQueueSuccessToasts();

/// <summary>
/// Removes all queued toasts with toast level Error
/// </summary>
void ClearQueueErrorToasts();
}
49 changes: 48 additions & 1 deletion src/Blazored.Toast/Services/ToastService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ public class ToastService : IToastService
/// </summary>
public event Action? OnClearCustomToasts;

/// <summary>
/// A event that will be invoked to clear all queued toasts
/// </summary>
public event Action? OnClearQueue;

/// <summary>
/// A event that will be invoked to clear queued toast of specified level
/// </summary>
public event Action<ToastLevel>? OnClearQueueToasts;

/// <summary>
/// Shows a information toast
/// </summary>
Expand Down Expand Up @@ -141,7 +151,7 @@ public void ShowToast(Type contentComponent, ToastParameters? parameters, ToastI
{
throw new ArgumentException($"{contentComponent.FullName} must be a Blazor Component");
}

OnShowComponent?.Invoke(contentComponent, parameters, settings);
}

Expand Down Expand Up @@ -209,4 +219,41 @@ public void ClearErrorToasts()
/// </summary>
public void ClearCustomToasts()
=> OnClearCustomToasts?.Invoke();

/// <summary>
/// Removes all queued toasts
/// </summary>
///
public void ClearQueue()
=> OnClearQueue?.Invoke();

/// <summary>
/// Removes all queued toasts with a specified <paramref name="toastLevel"/>.
/// </summary>
public void ClearQueueToasts(ToastLevel toastLevel)
=> OnClearQueueToasts?.Invoke(toastLevel);

/// <summary>
/// Removes all queued toasts with toast level warning
/// </summary>
public void ClearQueueWarningToasts()
=> OnClearQueueToasts?.Invoke(ToastLevel.Warning);

/// <summary>
/// Removes all queued toasts with toast level info
/// </summary>
public void ClearQueueInfoToasts()
=> OnClearQueueToasts?.Invoke(ToastLevel.Info);

/// <summary>
/// Removes all queued toasts with toast level success
/// </summary>
public void ClearQueueSuccessToasts()
=> OnClearQueueToasts?.Invoke(ToastLevel.Success);

/// <summary>
/// Removes all queued toasts with toast level error
/// </summary>
public void ClearQueueErrorToasts()
=> OnClearQueueToasts?.Invoke(ToastLevel.Error);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Blazored.Toast.Services;
using Xunit;

namespace Blazored.Toast.Tests.ToastServiceTests.Base
{
public abstract class BaseClearQueueTest : BaseClearTest
{
protected abstract ToastLevel _toastLevel { get; }

protected Action<Action<ToastLevel>?> _eventAction;

protected BaseClearQueueTest() : base()
{
_eventAction = x => _sut.OnClearQueueToasts += x;
}
}
}
76 changes: 76 additions & 0 deletions tests/Blazored.Toast.Tests/ToastServiceTests/Base/BaseClearTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using Blazored.Toast.Services;
using System.Reflection.Metadata;
using Xunit;

namespace Blazored.Toast.Tests.ToastServiceTests.Base
{
public abstract class BaseClearTest
{
protected readonly ToastService _sut;

protected BaseClearTest()
{
_sut = new ToastService();
}

#region OnClearInvoked
protected void OnClearInvoked_When_ClearCalled(Action<Action?> eventAction, Action call)
{
// arrange
var onClearCalled = false;
eventAction(() => onClearCalled = true);

// act
call();

// assert
Assert.True(onClearCalled);
}

protected void OnClearInvoked_When_ClearCalled(Action<Action<ToastLevel>?> eventAction, Action call)
{
// arrange
var onClearCalled = false;
eventAction((_) => onClearCalled = true);

// act
call();

// assert
Assert.True(onClearCalled);
}

protected void OnClearInvoked_When_ClearCalled(Action<Action<ToastLevel>?> eventAction, Action<ToastLevel> call, ToastLevel level)
{
// arrange
var onClearCalled = false;
eventAction((_) => onClearCalled = true);

// act
call(level);

// assert
Assert.True(onClearCalled);
}
#endregion

#region
protected void OnClearToastsContainsToastLevel_When_ClearCalled(Action<Action<ToastLevel>?> eventAction, Action call, ToastLevel level)
{
// arrange
var toastLevel = "";

eventAction((argToastlevel) => toastLevel = argToastlevel.ToString());

// act
call();

// assert
Assert.Equal(level.ToString(), toastLevel);
}

protected void OnClearToastsContainsToastLevel_When_ClearCalled(Action<Action<ToastLevel>?> eventAction, Action<ToastLevel> call, ToastLevel level)
=> OnClearToastsContainsToastLevel_When_ClearCalled(eventAction, () => call(level), level);
#endregion
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Blazored.Toast.Services;
using Blazored.Toast.Tests.ToastServiceTests.Base;
using Xunit;

namespace Blazored.Toast.Tests.ToastServiceTests.ClearQueueTests
{
public class ClearQueue : BaseClearTest
{
public ClearQueue() : base()
{
}

[Fact]
public void OnClearQueueInvoked_When_ClearQueueCalled()
=> OnClearInvoked_When_ClearCalled(x => _sut.OnClearQueue += x, _sut.ClearQueue);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Blazored.Toast.Services;
using Blazored.Toast.Tests.ToastServiceTests.Base;
using Xunit;

namespace Blazored.Toast.Tests.ToastServiceTests.ClearQueueTests;

public class ClearQueueErrorToasts : BaseClearQueueTest
{
protected override ToastLevel _toastLevel => ToastLevel.Error;

protected Action _call;

public ClearQueueErrorToasts() : base()
{
_call = _sut.ClearQueueErrorToasts;
}

[Fact]
public void OnClearQueueToastsInvoked_When_ClearQueueErrorToastsCalled()
=> OnClearInvoked_When_ClearCalled(_eventAction, _call);

[Fact]
public void OnClearQueueToastsContainsToastLevelError_When_ClearQueueErrorToastsCalled()
=> OnClearToastsContainsToastLevel_When_ClearCalled(_eventAction, _call, _toastLevel);
}
Loading

0 comments on commit 4f98e1e

Please sign in to comment.