mirror of
https://github.com/bitwarden/server.git
synced 2025-07-01 08:02:49 -05:00
[PM-10564] Push notification updates to other clients (#5057)
* PM-10600: Notification push notification * PM-10600: Sending to specific client types for relay push notifications * PM-10600: Sending to specific client types for other clients * PM-10600: Send push notification on notification creation * PM-10600: Explicit group names * PM-10600: Id typos * PM-10600: Revert global push notifications * PM-10600: Added DeviceType claim * PM-10600: Sent to organization typo * PM-10600: UT coverage * PM-10600: Small refactor, UTs coverage * PM-10600: UTs coverage * PM-10600: Startup fix * PM-10600: Test fix * PM-10600: Required attribute, organization group for push notification fix * PM-10600: UT coverage * PM-10600: Fix Mobile devices not registering to organization push notifications We only register devices for organization push notifications when the organization is being created. This does not work, since we have a use case (Notification Center) of delivering notifications to all users of organization. This fixes it, by adding the organization id tag when device registers for push notifications. * PM-10600: Unit Test coverage for NotificationHubPushRegistrationService Fixed IFeatureService substitute mocking for Android tests. Added user part of organization test with organizationId tags expectation. * PM-10600: Unit Tests fix to NotificationHubPushRegistrationService after merge conflict * PM-10600: Organization push notifications not sending to mobile device from self-hosted. Self-hosted instance uses relay to register the mobile device against Bitwarden Cloud Api. Only the self-hosted server knows client's organization membership, which means it needs to pass in the organization id's information to the relay. Similarly, for Bitwarden Cloud, the organizaton id will come directly from the server. * PM-10600: Fix self-hosted organization notification not being received by mobile device. When mobile device registers on self-hosted through the relay, every single id, like user id, device id and now organization id needs to be prefixed with the installation id. This have been missing in the PushController that handles this for organization id. * PM-10600: Broken NotificationsController integration test Device type is now part of JWT access token, so the notification center results in the integration test are now scoped to client type web and all. * PM-10600: Merge conflicts fix * merge conflict fix * PM-10600: Push notification with full notification center content. Notification Center push notification now includes all the fields. * PM-10564: Push notification updates to other clients Cherry-picked and squashed commits:d9711b6031
6e69c8a0ce
01c814595e
3885885d5f
1285a7e994
fcf346985f
28ff53c293
57804ae27c
1c9339b686
* null check fix * logging using template formatting
This commit is contained in:
@ -41,6 +41,12 @@ public class CreateNotificationCommandTest
|
||||
Setup(sutProvider, notification, authorized: false);
|
||||
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.CreateAsync(notification));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -59,5 +65,8 @@ public class CreateNotificationCommandTest
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(1)
|
||||
.PushNotificationAsync(newNotification);
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ using Bit.Core.NotificationCenter.Authorization;
|
||||
using Bit.Core.NotificationCenter.Commands;
|
||||
using Bit.Core.NotificationCenter.Entities;
|
||||
using Bit.Core.NotificationCenter.Repositories;
|
||||
using Bit.Core.Platform.Push;
|
||||
using Bit.Core.Test.NotificationCenter.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
@ -50,6 +51,12 @@ public class CreateNotificationStatusCommandTest
|
||||
Setup(sutProvider, notification: null, notificationStatus, true, true);
|
||||
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.CreateAsync(notificationStatus));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -61,6 +68,12 @@ public class CreateNotificationStatusCommandTest
|
||||
Setup(sutProvider, notification, notificationStatus, authorizedNotification: false, true);
|
||||
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.CreateAsync(notificationStatus));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -72,6 +85,12 @@ public class CreateNotificationStatusCommandTest
|
||||
Setup(sutProvider, notification, notificationStatus, true, authorizedCreate: false);
|
||||
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.CreateAsync(notificationStatus));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -85,5 +104,11 @@ public class CreateNotificationStatusCommandTest
|
||||
var newNotificationStatus = await sutProvider.Sut.CreateAsync(notificationStatus);
|
||||
|
||||
Assert.Equal(notificationStatus, newNotificationStatus);
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(1)
|
||||
.PushNotificationStatusAsync(notification, notificationStatus);
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using Bit.Core.NotificationCenter.Authorization;
|
||||
using Bit.Core.NotificationCenter.Commands;
|
||||
using Bit.Core.NotificationCenter.Entities;
|
||||
using Bit.Core.NotificationCenter.Repositories;
|
||||
using Bit.Core.Platform.Push;
|
||||
using Bit.Core.Test.NotificationCenter.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
@ -63,6 +64,12 @@ public class MarkNotificationDeletedCommandTest
|
||||
Setup(sutProvider, notificationId, userId: null, notification, notificationStatus, true, true, true);
|
||||
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkDeletedAsync(notificationId));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -74,6 +81,12 @@ public class MarkNotificationDeletedCommandTest
|
||||
Setup(sutProvider, notificationId, userId, notification: null, notificationStatus, true, true, true);
|
||||
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkDeletedAsync(notificationId));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -86,6 +99,12 @@ public class MarkNotificationDeletedCommandTest
|
||||
true, true);
|
||||
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkDeletedAsync(notificationId));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -98,6 +117,12 @@ public class MarkNotificationDeletedCommandTest
|
||||
authorizedCreate: false, true);
|
||||
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkDeletedAsync(notificationId));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -110,6 +135,12 @@ public class MarkNotificationDeletedCommandTest
|
||||
authorizedUpdate: false);
|
||||
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkDeletedAsync(notificationId));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -119,13 +150,25 @@ public class MarkNotificationDeletedCommandTest
|
||||
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 = null,
|
||||
DeletedDate = DateTime.UtcNow
|
||||
};
|
||||
|
||||
await sutProvider.Sut.MarkDeletedAsync(notificationId);
|
||||
|
||||
await sutProvider.GetDependency<INotificationStatusRepository>().Received(1)
|
||||
.CreateAsync(Arg.Is<NotificationStatus>(ns =>
|
||||
ns.NotificationId == notificationId && ns.UserId == userId && !ns.ReadDate.HasValue &&
|
||||
ns.DeletedDate.HasValue && DateTime.UtcNow - ns.DeletedDate.Value < TimeSpan.FromMinutes(1)));
|
||||
.CreateAsync(Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(expectedNotificationStatus, ns)));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(1)
|
||||
.PushNotificationStatusAsync(notification,
|
||||
Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(expectedNotificationStatus, ns)));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -134,18 +177,30 @@ public class MarkNotificationDeletedCommandTest
|
||||
SutProvider<MarkNotificationDeletedCommand> sutProvider,
|
||||
Guid notificationId, Guid userId, Notification notification, NotificationStatus notificationStatus)
|
||||
{
|
||||
var deletedDate = notificationStatus.DeletedDate;
|
||||
|
||||
Setup(sutProvider, notificationId, userId, notification, notificationStatus, true, true, true);
|
||||
|
||||
await sutProvider.Sut.MarkDeletedAsync(notificationId);
|
||||
|
||||
await sutProvider.GetDependency<INotificationStatusRepository>().Received(1)
|
||||
.UpdateAsync(Arg.Is<NotificationStatus>(ns =>
|
||||
ns.Equals(notificationStatus) &&
|
||||
ns.NotificationId == notificationStatus.NotificationId && ns.UserId == notificationStatus.UserId &&
|
||||
ns.ReadDate == notificationStatus.ReadDate && ns.DeletedDate != deletedDate &&
|
||||
ns.DeletedDate.HasValue &&
|
||||
DateTime.UtcNow - ns.DeletedDate.Value < TimeSpan.FromMinutes(1)));
|
||||
.UpdateAsync(Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(notificationStatus, ns)));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(1)
|
||||
.PushNotificationStatusAsync(notification,
|
||||
Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(notificationStatus, ns)));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(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.Equal(expectedNotificationStatus.ReadDate, actualNotificationStatus.ReadDate);
|
||||
Assert.NotEqual(expectedNotificationStatus.DeletedDate, actualNotificationStatus.DeletedDate);
|
||||
Assert.NotNull(actualNotificationStatus.DeletedDate);
|
||||
Assert.Equal(DateTime.UtcNow, actualNotificationStatus.DeletedDate.Value, TimeSpan.FromMinutes(1));
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using Bit.Core.NotificationCenter.Authorization;
|
||||
using Bit.Core.NotificationCenter.Commands;
|
||||
using Bit.Core.NotificationCenter.Entities;
|
||||
using Bit.Core.NotificationCenter.Repositories;
|
||||
using Bit.Core.Platform.Push;
|
||||
using Bit.Core.Test.NotificationCenter.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
@ -63,6 +64,12 @@ public class MarkNotificationReadCommandTest
|
||||
Setup(sutProvider, notificationId, userId: null, notification, notificationStatus, true, true, true);
|
||||
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -74,6 +81,12 @@ public class MarkNotificationReadCommandTest
|
||||
Setup(sutProvider, notificationId, userId, notification: null, notificationStatus, true, true, true);
|
||||
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -86,6 +99,12 @@ public class MarkNotificationReadCommandTest
|
||||
true, true);
|
||||
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -98,6 +117,12 @@ public class MarkNotificationReadCommandTest
|
||||
authorizedCreate: false, true);
|
||||
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -110,6 +135,12 @@ public class MarkNotificationReadCommandTest
|
||||
authorizedUpdate: false);
|
||||
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.MarkReadAsync(notificationId));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -119,13 +150,25 @@ public class MarkNotificationReadCommandTest
|
||||
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.Is<NotificationStatus>(ns =>
|
||||
ns.NotificationId == notificationId && ns.UserId == userId && !ns.DeletedDate.HasValue &&
|
||||
ns.ReadDate.HasValue && DateTime.UtcNow - ns.ReadDate.Value < TimeSpan.FromMinutes(1)));
|
||||
.CreateAsync(Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(expectedNotificationStatus, ns)));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(1)
|
||||
.PushNotificationStatusAsync(notification,
|
||||
Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(expectedNotificationStatus, ns)));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -134,18 +177,30 @@ public class MarkNotificationReadCommandTest
|
||||
SutProvider<MarkNotificationReadCommand> sutProvider,
|
||||
Guid notificationId, Guid userId, Notification notification, NotificationStatus notificationStatus)
|
||||
{
|
||||
var readDate = notificationStatus.ReadDate;
|
||||
|
||||
Setup(sutProvider, notificationId, userId, notification, notificationStatus, true, true, true);
|
||||
|
||||
await sutProvider.Sut.MarkReadAsync(notificationId);
|
||||
|
||||
await sutProvider.GetDependency<INotificationStatusRepository>().Received(1)
|
||||
.UpdateAsync(Arg.Is<NotificationStatus>(ns =>
|
||||
ns.Equals(notificationStatus) &&
|
||||
ns.NotificationId == notificationStatus.NotificationId && ns.UserId == notificationStatus.UserId &&
|
||||
ns.DeletedDate == notificationStatus.DeletedDate && ns.ReadDate != readDate &&
|
||||
ns.ReadDate.HasValue &&
|
||||
DateTime.UtcNow - ns.ReadDate.Value < TimeSpan.FromMinutes(1)));
|
||||
.UpdateAsync(Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(notificationStatus, ns)));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(1)
|
||||
.PushNotificationStatusAsync(notification,
|
||||
Arg.Do<NotificationStatus>(ns => AssertNotificationStatus(notificationStatus, ns)));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(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);
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ using Bit.Core.NotificationCenter.Commands;
|
||||
using Bit.Core.NotificationCenter.Entities;
|
||||
using Bit.Core.NotificationCenter.Enums;
|
||||
using Bit.Core.NotificationCenter.Repositories;
|
||||
using Bit.Core.Platform.Push;
|
||||
using Bit.Core.Test.NotificationCenter.AutoFixture;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
@ -45,6 +46,12 @@ public class UpdateNotificationCommandTest
|
||||
Setup(sutProvider, notification.Id, notification: null, true);
|
||||
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.UpdateAsync(notification));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -56,6 +63,12 @@ public class UpdateNotificationCommandTest
|
||||
Setup(sutProvider, notification.Id, notification, authorized: false);
|
||||
|
||||
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.UpdateAsync(notification));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationAsync(Arg.Any<Notification>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -91,5 +104,11 @@ public class UpdateNotificationCommandTest
|
||||
n.Priority == notificationToUpdate.Priority && n.ClientType == notificationToUpdate.ClientType &&
|
||||
n.Title == notificationToUpdate.Title && n.Body == notificationToUpdate.Body &&
|
||||
DateTime.UtcNow - n.RevisionDate < TimeSpan.FromMinutes(1)));
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(1)
|
||||
.PushNotificationAsync(notification);
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(0)
|
||||
.PushNotificationStatusAsync(Arg.Any<Notification>(), Arg.Any<NotificationStatus>());
|
||||
}
|
||||
}
|
||||
|
@ -15,12 +15,13 @@ using Xunit;
|
||||
namespace Bit.Core.Test.NotificationHub;
|
||||
|
||||
[SutProviderCustomize]
|
||||
[NotificationStatusCustomize]
|
||||
public class NotificationHubPushNotificationServiceTests
|
||||
{
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
[NotificationCustomize]
|
||||
public async void PushNotificationAsync_Global_NotSent(
|
||||
public async Task PushNotificationAsync_Global_NotSent(
|
||||
SutProvider<NotificationHubPushNotificationService> sutProvider, Notification notification)
|
||||
{
|
||||
await sutProvider.Sut.PushNotificationAsync(notification);
|
||||
@ -39,7 +40,7 @@ public class NotificationHubPushNotificationServiceTests
|
||||
[BitAutoData(false)]
|
||||
[BitAutoData(true)]
|
||||
[NotificationCustomize(false)]
|
||||
public async void PushNotificationAsync_UserIdProvidedClientTypeAll_SentToUser(
|
||||
public async Task PushNotificationAsync_UserIdProvidedClientTypeAll_SentToUser(
|
||||
bool organizationIdNull, SutProvider<NotificationHubPushNotificationService> sutProvider,
|
||||
Notification notification)
|
||||
{
|
||||
@ -49,11 +50,12 @@ public class NotificationHubPushNotificationServiceTests
|
||||
}
|
||||
|
||||
notification.ClientType = ClientType.All;
|
||||
var expectedSyncNotification = ToSyncNotificationPushNotification(notification);
|
||||
var expectedNotification = ToNotificationPushNotification(notification, null);
|
||||
|
||||
await sutProvider.Sut.PushNotificationAsync(notification);
|
||||
|
||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotification, expectedSyncNotification,
|
||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotification,
|
||||
expectedNotification,
|
||||
$"(template:payload_userId:{notification.UserId})");
|
||||
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||
.Received(0)
|
||||
@ -61,30 +63,46 @@ public class NotificationHubPushNotificationServiceTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(false, ClientType.Browser)]
|
||||
[BitAutoData(false, ClientType.Desktop)]
|
||||
[BitAutoData(false, ClientType.Web)]
|
||||
[BitAutoData(false, ClientType.Mobile)]
|
||||
[BitAutoData(true, ClientType.Browser)]
|
||||
[BitAutoData(true, ClientType.Desktop)]
|
||||
[BitAutoData(true, ClientType.Web)]
|
||||
[BitAutoData(true, ClientType.Mobile)]
|
||||
[BitAutoData(ClientType.Browser)]
|
||||
[BitAutoData(ClientType.Desktop)]
|
||||
[BitAutoData(ClientType.Web)]
|
||||
[BitAutoData(ClientType.Mobile)]
|
||||
[NotificationCustomize(false)]
|
||||
public async void PushNotificationAsync_UserIdProvidedClientTypeNotAll_SentToUser(bool organizationIdNull,
|
||||
public async Task PushNotificationAsync_UserIdProvidedOrganizationIdNullClientTypeNotAll_SentToUser(
|
||||
ClientType clientType, SutProvider<NotificationHubPushNotificationService> sutProvider,
|
||||
Notification notification)
|
||||
{
|
||||
if (organizationIdNull)
|
||||
{
|
||||
notification.OrganizationId = null;
|
||||
}
|
||||
|
||||
notification.OrganizationId = null;
|
||||
notification.ClientType = clientType;
|
||||
var expectedSyncNotification = ToSyncNotificationPushNotification(notification);
|
||||
var expectedNotification = ToNotificationPushNotification(notification, null);
|
||||
|
||||
await sutProvider.Sut.PushNotificationAsync(notification);
|
||||
|
||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotification, expectedSyncNotification,
|
||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotification,
|
||||
expectedNotification,
|
||||
$"(template:payload_userId:{notification.UserId} && clientType:{clientType})");
|
||||
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||
.Received(0)
|
||||
.UpsertAsync(Arg.Any<InstallationDeviceEntity>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(ClientType.Browser)]
|
||||
[BitAutoData(ClientType.Desktop)]
|
||||
[BitAutoData(ClientType.Web)]
|
||||
[BitAutoData(ClientType.Mobile)]
|
||||
[NotificationCustomize(false)]
|
||||
public async Task PushNotificationAsync_UserIdProvidedOrganizationIdProvidedClientTypeNotAll_SentToUser(
|
||||
ClientType clientType, SutProvider<NotificationHubPushNotificationService> sutProvider,
|
||||
Notification notification)
|
||||
{
|
||||
notification.ClientType = clientType;
|
||||
var expectedNotification = ToNotificationPushNotification(notification, null);
|
||||
|
||||
await sutProvider.Sut.PushNotificationAsync(notification);
|
||||
|
||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotification,
|
||||
expectedNotification,
|
||||
$"(template:payload_userId:{notification.UserId} && clientType:{clientType})");
|
||||
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||
.Received(0)
|
||||
@ -94,16 +112,17 @@ public class NotificationHubPushNotificationServiceTests
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
[NotificationCustomize(false)]
|
||||
public async void PushNotificationAsync_UserIdNullOrganizationIdProvidedClientTypeAll_SentToOrganization(
|
||||
public async Task PushNotificationAsync_UserIdNullOrganizationIdProvidedClientTypeAll_SentToOrganization(
|
||||
SutProvider<NotificationHubPushNotificationService> sutProvider, Notification notification)
|
||||
{
|
||||
notification.UserId = null;
|
||||
notification.ClientType = ClientType.All;
|
||||
var expectedSyncNotification = ToSyncNotificationPushNotification(notification);
|
||||
var expectedNotification = ToNotificationPushNotification(notification, null);
|
||||
|
||||
await sutProvider.Sut.PushNotificationAsync(notification);
|
||||
|
||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotification, expectedSyncNotification,
|
||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotification,
|
||||
expectedNotification,
|
||||
$"(template:payload && organizationId:{notification.OrganizationId})");
|
||||
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||
.Received(0)
|
||||
@ -116,18 +135,156 @@ public class NotificationHubPushNotificationServiceTests
|
||||
[BitAutoData(ClientType.Web)]
|
||||
[BitAutoData(ClientType.Mobile)]
|
||||
[NotificationCustomize(false)]
|
||||
public async void PushNotificationAsync_UserIdNullOrganizationIdProvidedClientTypeNotAll_SentToOrganization(
|
||||
public async Task PushNotificationAsync_UserIdNullOrganizationIdProvidedClientTypeNotAll_SentToOrganization(
|
||||
ClientType clientType, SutProvider<NotificationHubPushNotificationService> sutProvider,
|
||||
Notification notification)
|
||||
{
|
||||
notification.UserId = null;
|
||||
notification.ClientType = clientType;
|
||||
|
||||
var expectedSyncNotification = ToSyncNotificationPushNotification(notification);
|
||||
var expectedNotification = ToNotificationPushNotification(notification, null);
|
||||
|
||||
await sutProvider.Sut.PushNotificationAsync(notification);
|
||||
|
||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotification, expectedSyncNotification,
|
||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotification,
|
||||
expectedNotification,
|
||||
$"(template:payload && organizationId:{notification.OrganizationId} && clientType:{clientType})");
|
||||
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||
.Received(0)
|
||||
.UpsertAsync(Arg.Any<InstallationDeviceEntity>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
[NotificationCustomize]
|
||||
public async Task PushNotificationStatusAsync_Global_NotSent(
|
||||
SutProvider<NotificationHubPushNotificationService> sutProvider, Notification notification,
|
||||
NotificationStatus notificationStatus)
|
||||
{
|
||||
await sutProvider.Sut.PushNotificationStatusAsync(notification, notificationStatus);
|
||||
|
||||
await sutProvider.GetDependency<INotificationHubPool>()
|
||||
.Received(0)
|
||||
.AllClients
|
||||
.Received(0)
|
||||
.SendTemplateNotificationAsync(Arg.Any<IDictionary<string, string>>(), Arg.Any<string>());
|
||||
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||
.Received(0)
|
||||
.UpsertAsync(Arg.Any<InstallationDeviceEntity>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(false)]
|
||||
[BitAutoData(true)]
|
||||
[NotificationCustomize(false)]
|
||||
public async Task PushNotificationStatusAsync_UserIdProvidedClientTypeAll_SentToUser(
|
||||
bool organizationIdNull, SutProvider<NotificationHubPushNotificationService> sutProvider,
|
||||
Notification notification, NotificationStatus notificationStatus)
|
||||
{
|
||||
if (organizationIdNull)
|
||||
{
|
||||
notification.OrganizationId = null;
|
||||
}
|
||||
|
||||
notification.ClientType = ClientType.All;
|
||||
var expectedNotification = ToNotificationPushNotification(notification, notificationStatus);
|
||||
|
||||
await sutProvider.Sut.PushNotificationStatusAsync(notification, notificationStatus);
|
||||
|
||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotificationStatus,
|
||||
expectedNotification,
|
||||
$"(template:payload_userId:{notification.UserId})");
|
||||
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||
.Received(0)
|
||||
.UpsertAsync(Arg.Any<InstallationDeviceEntity>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(ClientType.Browser)]
|
||||
[BitAutoData(ClientType.Desktop)]
|
||||
[BitAutoData(ClientType.Web)]
|
||||
[BitAutoData(ClientType.Mobile)]
|
||||
[NotificationCustomize(false)]
|
||||
public async Task PushNotificationStatusAsync_UserIdProvidedOrganizationIdNullClientTypeNotAll_SentToUser(
|
||||
ClientType clientType, SutProvider<NotificationHubPushNotificationService> sutProvider,
|
||||
Notification notification, NotificationStatus notificationStatus)
|
||||
{
|
||||
notification.OrganizationId = null;
|
||||
notification.ClientType = clientType;
|
||||
var expectedNotification = ToNotificationPushNotification(notification, notificationStatus);
|
||||
|
||||
await sutProvider.Sut.PushNotificationStatusAsync(notification, notificationStatus);
|
||||
|
||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotificationStatus,
|
||||
expectedNotification,
|
||||
$"(template:payload_userId:{notification.UserId} && clientType:{clientType})");
|
||||
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||
.Received(0)
|
||||
.UpsertAsync(Arg.Any<InstallationDeviceEntity>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(ClientType.Browser)]
|
||||
[BitAutoData(ClientType.Desktop)]
|
||||
[BitAutoData(ClientType.Web)]
|
||||
[BitAutoData(ClientType.Mobile)]
|
||||
[NotificationCustomize(false)]
|
||||
public async Task PushNotificationStatusAsync_UserIdProvidedOrganizationIdProvidedClientTypeNotAll_SentToUser(
|
||||
ClientType clientType, SutProvider<NotificationHubPushNotificationService> sutProvider,
|
||||
Notification notification, NotificationStatus notificationStatus)
|
||||
{
|
||||
notification.ClientType = clientType;
|
||||
var expectedNotification = ToNotificationPushNotification(notification, notificationStatus);
|
||||
|
||||
await sutProvider.Sut.PushNotificationStatusAsync(notification, notificationStatus);
|
||||
|
||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotificationStatus,
|
||||
expectedNotification,
|
||||
$"(template:payload_userId:{notification.UserId} && clientType:{clientType})");
|
||||
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||
.Received(0)
|
||||
.UpsertAsync(Arg.Any<InstallationDeviceEntity>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
[NotificationCustomize(false)]
|
||||
public async Task PushNotificationStatusAsync_UserIdNullOrganizationIdProvidedClientTypeAll_SentToOrganization(
|
||||
SutProvider<NotificationHubPushNotificationService> sutProvider, Notification notification,
|
||||
NotificationStatus notificationStatus)
|
||||
{
|
||||
notification.UserId = null;
|
||||
notification.ClientType = ClientType.All;
|
||||
var expectedNotification = ToNotificationPushNotification(notification, notificationStatus);
|
||||
|
||||
await sutProvider.Sut.PushNotificationStatusAsync(notification, notificationStatus);
|
||||
|
||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotificationStatus,
|
||||
expectedNotification,
|
||||
$"(template:payload && organizationId:{notification.OrganizationId})");
|
||||
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||
.Received(0)
|
||||
.UpsertAsync(Arg.Any<InstallationDeviceEntity>());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData(ClientType.Browser)]
|
||||
[BitAutoData(ClientType.Desktop)]
|
||||
[BitAutoData(ClientType.Web)]
|
||||
[BitAutoData(ClientType.Mobile)]
|
||||
[NotificationCustomize(false)]
|
||||
public async Task
|
||||
PushNotificationStatusAsync_UserIdNullOrganizationIdProvidedClientTypeNotAll_SentToOrganization(
|
||||
ClientType clientType, SutProvider<NotificationHubPushNotificationService> sutProvider,
|
||||
Notification notification, NotificationStatus notificationStatus)
|
||||
{
|
||||
notification.UserId = null;
|
||||
notification.ClientType = clientType;
|
||||
var expectedNotification = ToNotificationPushNotification(notification, notificationStatus);
|
||||
|
||||
await sutProvider.Sut.PushNotificationStatusAsync(notification, notificationStatus);
|
||||
|
||||
await AssertSendTemplateNotificationAsync(sutProvider, PushType.SyncNotificationStatus,
|
||||
expectedNotification,
|
||||
$"(template:payload && organizationId:{notification.OrganizationId} && clientType:{clientType})");
|
||||
await sutProvider.GetDependency<IInstallationDeviceRepository>()
|
||||
.Received(0)
|
||||
@ -137,7 +294,7 @@ public class NotificationHubPushNotificationServiceTests
|
||||
[Theory]
|
||||
[BitAutoData([null])]
|
||||
[BitAutoData(ClientType.All)]
|
||||
public async void SendPayloadToUserAsync_ClientTypeNullOrAll_SentToUser(ClientType? clientType,
|
||||
public async Task SendPayloadToUserAsync_ClientTypeNullOrAll_SentToUser(ClientType? clientType,
|
||||
SutProvider<NotificationHubPushNotificationService> sutProvider, Guid userId, PushType pushType, string payload,
|
||||
string identifier)
|
||||
{
|
||||
@ -156,7 +313,7 @@ public class NotificationHubPushNotificationServiceTests
|
||||
[BitAutoData(ClientType.Desktop)]
|
||||
[BitAutoData(ClientType.Mobile)]
|
||||
[BitAutoData(ClientType.Web)]
|
||||
public async void SendPayloadToUserAsync_ClientTypeExplicit_SentToUserAndClientType(ClientType clientType,
|
||||
public async Task SendPayloadToUserAsync_ClientTypeExplicit_SentToUserAndClientType(ClientType clientType,
|
||||
SutProvider<NotificationHubPushNotificationService> sutProvider, Guid userId, PushType pushType, string payload,
|
||||
string identifier)
|
||||
{
|
||||
@ -173,7 +330,7 @@ public class NotificationHubPushNotificationServiceTests
|
||||
[Theory]
|
||||
[BitAutoData([null])]
|
||||
[BitAutoData(ClientType.All)]
|
||||
public async void SendPayloadToOrganizationAsync_ClientTypeNullOrAll_SentToOrganization(ClientType? clientType,
|
||||
public async Task SendPayloadToOrganizationAsync_ClientTypeNullOrAll_SentToOrganization(ClientType? clientType,
|
||||
SutProvider<NotificationHubPushNotificationService> sutProvider, Guid organizationId, PushType pushType,
|
||||
string payload, string identifier)
|
||||
{
|
||||
@ -192,7 +349,7 @@ public class NotificationHubPushNotificationServiceTests
|
||||
[BitAutoData(ClientType.Desktop)]
|
||||
[BitAutoData(ClientType.Mobile)]
|
||||
[BitAutoData(ClientType.Web)]
|
||||
public async void SendPayloadToOrganizationAsync_ClientTypeExplicit_SentToOrganizationAndClientType(
|
||||
public async Task SendPayloadToOrganizationAsync_ClientTypeExplicit_SentToOrganizationAndClientType(
|
||||
ClientType clientType, SutProvider<NotificationHubPushNotificationService> sutProvider, Guid organizationId,
|
||||
PushType pushType, string payload, string identifier)
|
||||
{
|
||||
@ -206,7 +363,8 @@ public class NotificationHubPushNotificationServiceTests
|
||||
.UpsertAsync(Arg.Any<InstallationDeviceEntity>());
|
||||
}
|
||||
|
||||
private static NotificationPushNotification ToSyncNotificationPushNotification(Notification notification) =>
|
||||
private static NotificationPushNotification ToNotificationPushNotification(Notification notification,
|
||||
NotificationStatus? notificationStatus) =>
|
||||
new()
|
||||
{
|
||||
Id = notification.Id,
|
||||
@ -218,7 +376,9 @@ public class NotificationHubPushNotificationServiceTests
|
||||
Title = notification.Title,
|
||||
Body = notification.Body,
|
||||
CreationDate = notification.CreationDate,
|
||||
RevisionDate = notification.RevisionDate
|
||||
RevisionDate = notification.RevisionDate,
|
||||
ReadDate = notificationStatus?.ReadDate,
|
||||
DeletedDate = notificationStatus?.DeletedDate
|
||||
};
|
||||
|
||||
private static async Task AssertSendTemplateNotificationAsync(
|
||||
|
@ -24,7 +24,7 @@ public class AzureQueuePushNotificationServiceTests
|
||||
[BitAutoData]
|
||||
[NotificationCustomize]
|
||||
[CurrentContextCustomize]
|
||||
public async void PushNotificationAsync_Notification_Sent(
|
||||
public async Task PushNotificationAsync_Notification_Sent(
|
||||
SutProvider<AzureQueuePushNotificationService> sutProvider, Notification notification, Guid deviceIdentifier,
|
||||
ICurrentContext currentContext)
|
||||
{
|
||||
@ -36,7 +36,30 @@ public class AzureQueuePushNotificationServiceTests
|
||||
|
||||
await sutProvider.GetDependency<QueueClient>().Received(1)
|
||||
.SendMessageAsync(Arg.Is<string>(message =>
|
||||
MatchMessage(PushType.SyncNotification, message, new SyncNotificationEquals(notification),
|
||||
MatchMessage(PushType.SyncNotification, message,
|
||||
new NotificationPushNotificationEquals(notification, null),
|
||||
deviceIdentifier.ToString())));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
[NotificationCustomize]
|
||||
[NotificationStatusCustomize]
|
||||
[CurrentContextCustomize]
|
||||
public async Task PushNotificationStatusAsync_Notification_Sent(
|
||||
SutProvider<AzureQueuePushNotificationService> sutProvider, Notification notification, Guid deviceIdentifier,
|
||||
ICurrentContext currentContext, NotificationStatus notificationStatus)
|
||||
{
|
||||
currentContext.DeviceIdentifier.Returns(deviceIdentifier.ToString());
|
||||
sutProvider.GetDependency<IHttpContextAccessor>().HttpContext!.RequestServices
|
||||
.GetService(Arg.Any<Type>()).Returns(currentContext);
|
||||
|
||||
await sutProvider.Sut.PushNotificationStatusAsync(notification, notificationStatus);
|
||||
|
||||
await sutProvider.GetDependency<QueueClient>().Received(1)
|
||||
.SendMessageAsync(Arg.Is<string>(message =>
|
||||
MatchMessage(PushType.SyncNotificationStatus, message,
|
||||
new NotificationPushNotificationEquals(notification, notificationStatus),
|
||||
deviceIdentifier.ToString())));
|
||||
}
|
||||
|
||||
@ -50,7 +73,8 @@ public class AzureQueuePushNotificationServiceTests
|
||||
pushNotificationData.ContextId == contextId;
|
||||
}
|
||||
|
||||
private class SyncNotificationEquals(Notification notification) : IEquatable<NotificationPushNotification>
|
||||
private class NotificationPushNotificationEquals(Notification notification, NotificationStatus? notificationStatus)
|
||||
: IEquatable<NotificationPushNotification>
|
||||
{
|
||||
public bool Equals(NotificationPushNotification? other)
|
||||
{
|
||||
@ -66,7 +90,9 @@ public class AzureQueuePushNotificationServiceTests
|
||||
other.Title == notification.Title &&
|
||||
other.Body == notification.Body &&
|
||||
other.CreationDate == notification.CreationDate &&
|
||||
other.RevisionDate == notification.RevisionDate;
|
||||
other.RevisionDate == notification.RevisionDate &&
|
||||
other.ReadDate == notificationStatus?.ReadDate &&
|
||||
other.DeletedDate == notificationStatus?.DeletedDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,22 @@ public class MultiServicePushNotificationServiceTests
|
||||
.PushNotificationAsync(notification);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
[NotificationCustomize]
|
||||
[NotificationStatusCustomize]
|
||||
public async Task PushNotificationStatusAsync_Notification_Sent(
|
||||
SutProvider<MultiServicePushNotificationService> sutProvider, Notification notification,
|
||||
NotificationStatus notificationStatus)
|
||||
{
|
||||
await sutProvider.Sut.PushNotificationStatusAsync(notification, notificationStatus);
|
||||
|
||||
await sutProvider.GetDependency<IEnumerable<IPushNotificationService>>()
|
||||
.First()
|
||||
.Received(1)
|
||||
.PushNotificationStatusAsync(notification, notificationStatus);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData([null, null])]
|
||||
[BitAutoData(ClientType.All, null)]
|
||||
|
Reference in New Issue
Block a user