refactor(central-ui): contextual errors, parallel recipient load, delete-path test for Notification Lists
This commit is contained in:
@@ -104,14 +104,18 @@
|
||||
{
|
||||
_lists = (await NotificationRepository.GetAllNotificationListsAsync()).ToList();
|
||||
_recipients.Clear();
|
||||
foreach (var list in _lists)
|
||||
var recipientTasks = _lists.ToDictionary(
|
||||
list => list.Id,
|
||||
list => NotificationRepository.GetRecipientsByListIdAsync(list.Id));
|
||||
await Task.WhenAll(recipientTasks.Values);
|
||||
foreach (var (id, task) in recipientTasks)
|
||||
{
|
||||
_recipients[list.Id] = await NotificationRepository.GetRecipientsByListIdAsync(list.Id);
|
||||
_recipients[id] = task.Result;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_errorMessage = ex.Message;
|
||||
_errorMessage = $"Failed to load notification lists: {ex.Message}";
|
||||
}
|
||||
_loading = false;
|
||||
}
|
||||
@@ -131,7 +135,7 @@
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_toast.ShowError(ex.Message);
|
||||
_toast.ShowError($"Failed to delete notification list: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +44,11 @@ public class NotificationListsPageTests : BunitContext
|
||||
|
||||
var cut = Render<NotificationListsPage>();
|
||||
|
||||
cut.WaitForAssertion(() =>
|
||||
{
|
||||
Assert.Contains("Ops On-Call", cut.Markup);
|
||||
Assert.Contains("jane@example.com", cut.Markup);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -60,7 +63,38 @@ public class NotificationListsPageTests : BunitContext
|
||||
|
||||
var cut = Render<NotificationListsPage>();
|
||||
|
||||
Assert.Contains("No notification lists", cut.Markup);
|
||||
cut.WaitForAssertion(() =>
|
||||
Assert.Contains("No notification lists", cut.Markup));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DeleteList_ConfirmsThenDeletesAndReloads()
|
||||
{
|
||||
var repo = Substitute.For<INotificationRepository>();
|
||||
repo.GetAllNotificationListsAsync()
|
||||
.Returns(Task.FromResult<IReadOnlyList<NotificationList>>(
|
||||
new List<NotificationList> { new("Ops On-Call") { Id = 1 } }));
|
||||
repo.GetRecipientsByListIdAsync(1)
|
||||
.Returns(Task.FromResult<IReadOnlyList<NotificationRecipient>>(
|
||||
new List<NotificationRecipient>()));
|
||||
Services.AddSingleton(repo);
|
||||
WireAuthAndDialog();
|
||||
|
||||
var cut = Render<NotificationListsPage>();
|
||||
|
||||
cut.WaitForState(() => cut.Markup.Contains("Ops On-Call"));
|
||||
|
||||
var deleteButton = cut.FindAll("tbody tr button")
|
||||
.First(b => b.TextContent.Contains("Delete"));
|
||||
deleteButton.Click();
|
||||
|
||||
cut.WaitForAssertion(() =>
|
||||
{
|
||||
repo.Received().DeleteNotificationListAsync(1);
|
||||
repo.Received().SaveChangesAsync();
|
||||
// Reload re-invokes the list query (once on init, once after delete).
|
||||
repo.Received(2).GetAllNotificationListsAsync();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>A dialog service that auto-confirms, so action paths run end-to-end.</summary>
|
||||
|
||||
Reference in New Issue
Block a user