1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-30 23:52:50 -05:00
Files
bitwarden/test/Core.Test/NotificationCenter/Commands/MarkNotificationReadCommandTest.cs
Maciej Zieniuk fcf346985f PM-10564: Sync notification push type separation for notification updates
Sync notification push type is now used for both Notification create and update.
Renamed the event types to specifically mention the purpose of status for notification status updates.
2024-11-25 20:45:41 +00:00

207 lines
10 KiB
C#

#nullable enable
using System.Security.Claims;
using Bit.Core.Context;
using Bit.Core.Exceptions;
using Bit.Core.NotificationCenter.Authorization;
using Bit.Core.NotificationCenter.Commands;
using Bit.Core.NotificationCenter.Entities;
using Bit.Core.NotificationCenter.Repositories;
using Bit.Core.Services;
using Bit.Core.Test.NotificationCenter.AutoFixture;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
using Microsoft.AspNetCore.Authorization;
using NSubstitute;
using Xunit;
namespace Bit.Core.Test.NotificationCenter.Commands;
[SutProviderCustomize]
[NotificationCustomize]
[NotificationStatusCustomize]
public class MarkNotificationReadCommandTest
{
private static void Setup(SutProvider<MarkNotificationReadCommand> sutProvider,
Guid notificationId, Guid? userId, Notification? notification, NotificationStatus? notificationStatus,
bool authorizedNotification = false, bool authorizedCreate = false, bool authorizedUpdate = false)
{
sutProvider.GetDependency<ICurrentContext>().UserId.Returns(userId);
sutProvider.GetDependency<INotificationRepository>()
.GetByIdAsync(notificationId)
.Returns(notification);
sutProvider.GetDependency<INotificationStatusRepository>()
.GetByNotificationIdAndUserIdAsync(notificationId, userId ?? Arg.Any<Guid>())
.Returns(notificationStatus);
sutProvider.GetDependency<INotificationStatusRepository>()
.CreateAsync(Arg.Any<NotificationStatus>());
sutProvider.GetDependency<INotificationStatusRepository>()
.UpdateAsync(notificationStatus ?? Arg.Any<NotificationStatus>());
sutProvider.GetDependency<IAuthorizationService>()
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(), notification ?? Arg.Any<Notification>(),
Arg.Is<IEnumerable<IAuthorizationRequirement>>(reqs =>
reqs.Contains(NotificationOperations.Read)))
.Returns(authorizedNotification ? AuthorizationResult.Success() : AuthorizationResult.Failed());
sutProvider.GetDependency<IAuthorizationService>()
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(), notificationStatus ?? Arg.Any<NotificationStatus>(),
Arg.Is<IEnumerable<IAuthorizationRequirement>>(reqs =>
reqs.Contains(NotificationStatusOperations.Create)))
.Returns(authorizedCreate ? AuthorizationResult.Success() : AuthorizationResult.Failed());
sutProvider.GetDependency<IAuthorizationService>()
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(), notificationStatus ?? Arg.Any<NotificationStatus>(),
Arg.Is<IEnumerable<IAuthorizationRequirement>>(reqs =>
reqs.Contains(NotificationStatusOperations.Update)))
.Returns(authorizedUpdate ? AuthorizationResult.Success() : AuthorizationResult.Failed());
sutProvider.GetDependency<INotificationStatusRepository>().ClearReceivedCalls();
}
[Theory]
[BitAutoData]
public async Task MarkReadAsync_NotLoggedIn_NotFoundException(
SutProvider<MarkNotificationReadCommand> sutProvider,
Guid notificationId, Notification notification, NotificationStatus notificationStatus)
{
Setup(sutProvider, notificationId, userId: null, notification, notificationStatus, true, true, true);
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
await sutProvider.GetDependency<IPushNotificationService>()
.Received(0)
.PushSyncNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
await sutProvider.GetDependency<IPushNotificationService>()
.Received(0)
.PushSyncNotificationAsync(Arg.Any<Notification>());
}
[Theory]
[BitAutoData]
public async Task MarkReadAsync_NotificationNotFound_NotFoundException(
SutProvider<MarkNotificationReadCommand> sutProvider,
Guid notificationId, Guid userId, NotificationStatus notificationStatus)
{
Setup(sutProvider, notificationId, userId, notification: null, notificationStatus, true, true, true);
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
await sutProvider.GetDependency<IPushNotificationService>()
.Received(0)
.PushSyncNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
await sutProvider.GetDependency<IPushNotificationService>()
.Received(0)
.PushSyncNotificationAsync(Arg.Any<Notification>());
}
[Theory]
[BitAutoData]
public async Task MarkReadAsync_ReadRequirementNotificationNotAuthorized_NotFoundException(
SutProvider<MarkNotificationReadCommand> sutProvider,
Guid notificationId, Guid userId, Notification notification, NotificationStatus notificationStatus)
{
Setup(sutProvider, notificationId, userId, notification, notificationStatus, authorizedNotification: false,
true, true);
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
await sutProvider.GetDependency<IPushNotificationService>()
.Received(0)
.PushSyncNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
await sutProvider.GetDependency<IPushNotificationService>()
.Received(0)
.PushSyncNotificationAsync(Arg.Any<Notification>());
}
[Theory]
[BitAutoData]
public async Task MarkReadAsync_CreateRequirementNotAuthorized_NotFoundException(
SutProvider<MarkNotificationReadCommand> sutProvider,
Guid notificationId, Guid userId, Notification notification)
{
Setup(sutProvider, notificationId, userId, notification, notificationStatus: null, true,
authorizedCreate: false, true);
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
await sutProvider.GetDependency<IPushNotificationService>()
.Received(0)
.PushSyncNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
await sutProvider.GetDependency<IPushNotificationService>()
.Received(0)
.PushSyncNotificationAsync(Arg.Any<Notification>());
}
[Theory]
[BitAutoData]
public async Task MarkReadAsync_UpdateRequirementNotAuthorized_NotFoundException(
SutProvider<MarkNotificationReadCommand> sutProvider,
Guid notificationId, Guid userId, Notification notification, NotificationStatus notificationStatus)
{
Setup(sutProvider, notificationId, userId, notification, notificationStatus, true, true,
authorizedUpdate: false);
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
await sutProvider.GetDependency<IPushNotificationService>()
.Received(0)
.PushSyncNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
await sutProvider.GetDependency<IPushNotificationService>()
.Received(0)
.PushSyncNotificationAsync(Arg.Any<Notification>());
}
[Theory]
[BitAutoData]
public async Task MarkReadAsync_NotificationStatusNotFoundCreateAuthorized_NotificationStatusCreated(
SutProvider<MarkNotificationReadCommand> sutProvider,
Guid notificationId, Guid userId, Notification notification)
{
Setup(sutProvider, notificationId, userId, notification, notificationStatus: null, true, true, true);
var expectedNotificationStatus = new NotificationStatus
{
NotificationId = notificationId,
UserId = userId,
ReadDate = DateTime.UtcNow,
DeletedDate = null
};
await sutProvider.Sut.MarkReadAsync(notificationId);
await sutProvider.GetDependency<INotificationStatusRepository>().Received(1)
.CreateAsync(Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(expectedNotificationStatus, ns)));
await sutProvider.GetDependency<IPushNotificationService>()
.Received(1)
.PushSyncNotificationStatusAsync(notification,
Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(expectedNotificationStatus, ns)));
await sutProvider.GetDependency<IPushNotificationService>()
.Received(0)
.PushSyncNotificationAsync(Arg.Any<Notification>());
}
[Theory]
[BitAutoData]
public async Task MarkReadAsync_NotificationStatusFoundCreateAuthorized_NotificationStatusUpdated(
SutProvider<MarkNotificationReadCommand> sutProvider,
Guid notificationId, Guid userId, Notification notification, NotificationStatus notificationStatus)
{
Setup(sutProvider, notificationId, userId, notification, notificationStatus, true, true, true);
await sutProvider.Sut.MarkReadAsync(notificationId);
await sutProvider.GetDependency<INotificationStatusRepository>().Received(1)
.UpdateAsync(Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(notificationStatus, ns)));
await sutProvider.GetDependency<IPushNotificationService>()
.Received(1)
.PushSyncNotificationStatusAsync(notification,
Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(notificationStatus, ns)));
await sutProvider.GetDependency<IPushNotificationService>()
.Received(0)
.PushSyncNotificationAsync(Arg.Any<Notification>());
}
private static void AssertNotificationStatus(NotificationStatus expectedNotificationStatus,
NotificationStatus? actualNotificationStatus)
{
Assert.NotNull(actualNotificationStatus);
Assert.Equal(expectedNotificationStatus.NotificationId, actualNotificationStatus.NotificationId);
Assert.Equal(expectedNotificationStatus.UserId, actualNotificationStatus.UserId);
Assert.NotEqual(expectedNotificationStatus.ReadDate, actualNotificationStatus.ReadDate);
Assert.NotNull(actualNotificationStatus.ReadDate);
Assert.Equal(DateTime.UtcNow, actualNotificationStatus.ReadDate.Value, TimeSpan.FromMinutes(1));
Assert.Equal(expectedNotificationStatus.DeletedDate, actualNotificationStatus.DeletedDate);
}
}