You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
298 lines
16 KiB
298 lines
16 KiB
#nullable enable |
|
using Bit.Core.Enums; |
|
using Bit.Core.NotificationHub; |
|
using Bit.Core.Utilities; |
|
using Bit.Test.Common.AutoFixture; |
|
using Bit.Test.Common.AutoFixture.Attributes; |
|
using Microsoft.Azure.NotificationHubs; |
|
using NSubstitute; |
|
using Xunit; |
|
|
|
namespace Bit.Core.Test.NotificationHub; |
|
|
|
[SutProviderCustomize] |
|
public class NotificationHubPushRegistrationServiceTests |
|
{ |
|
[Theory] |
|
[RepeatingPatternBitAutoData([null, "", " "])] |
|
public async Task CreateOrUpdateRegistrationAsync_PushTokenNullOrEmpty_InstallationNotCreated(string? pushToken, |
|
SutProvider<NotificationHubPushRegistrationService> sutProvider, Guid deviceId, Guid userId, Guid identifier, |
|
Guid organizationId, Guid installationId) |
|
{ |
|
await sutProvider.Sut.CreateOrUpdateRegistrationAsync(new PushRegistrationData(pushToken), deviceId.ToString(), userId.ToString(), |
|
identifier.ToString(), DeviceType.Android, [organizationId.ToString()], installationId); |
|
|
|
sutProvider.GetDependency<INotificationHubPool>() |
|
.Received(0) |
|
.ClientFor(deviceId); |
|
} |
|
|
|
[Theory] |
|
[RepeatingPatternBitAutoData([false, true], [false, true], [false, true])] |
|
public async Task CreateOrUpdateRegistrationAsync_DeviceTypeAndroid_InstallationCreated(bool identifierNull, |
|
bool partOfOrganizationId, bool installationIdNull, |
|
SutProvider<NotificationHubPushRegistrationService> sutProvider, Guid deviceId, Guid userId, Guid? identifier, |
|
Guid organizationId, Guid installationId) |
|
{ |
|
var notificationHubClient = Substitute.For<INotificationHubClient>(); |
|
sutProvider.GetDependency<INotificationHubPool>().ClientFor(Arg.Any<Guid>()).Returns(notificationHubClient); |
|
|
|
var pushToken = "test push token"; |
|
|
|
await sutProvider.Sut.CreateOrUpdateRegistrationAsync(new PushRegistrationData(pushToken), deviceId.ToString(), userId.ToString(), |
|
identifierNull ? null : identifier.ToString(), DeviceType.Android, |
|
partOfOrganizationId ? [organizationId.ToString()] : [], |
|
installationIdNull ? Guid.Empty : installationId); |
|
|
|
sutProvider.GetDependency<INotificationHubPool>() |
|
.Received(1) |
|
.ClientFor(deviceId); |
|
await notificationHubClient |
|
.Received(1) |
|
.CreateOrUpdateInstallationAsync(Arg.Is<Installation>(installation => |
|
installation.InstallationId == deviceId.ToString() && |
|
installation.PushChannel == pushToken && |
|
installation.Platform == NotificationPlatform.FcmV1 && |
|
installation.Tags.Contains($"userId:{userId}") && |
|
installation.Tags.Contains("clientType:Mobile") && |
|
(identifierNull || installation.Tags.Contains($"deviceIdentifier:{identifier}")) && |
|
(!partOfOrganizationId || installation.Tags.Contains($"organizationId:{organizationId}")) && |
|
(installationIdNull || installation.Tags.Contains($"installationId:{installationId}")) && |
|
installation.Templates.Count == 3)); |
|
await notificationHubClient |
|
.Received(1) |
|
.CreateOrUpdateInstallationAsync(Arg.Is<Installation>(installation => MatchingInstallationTemplate( |
|
installation.Templates, "template:payload", |
|
"{\"message\":{\"data\":{\"type\":\"$(type)\",\"payload\":\"$(payload)\"}}}", |
|
new List<string?> |
|
{ |
|
"template:payload", |
|
$"template:payload_userId:{userId}", |
|
"clientType:Mobile", |
|
identifierNull ? null : $"template:payload_deviceIdentifier:{identifier}", |
|
partOfOrganizationId ? $"organizationId:{organizationId}" : null, |
|
installationIdNull ? null : $"installationId:{installationId}", |
|
}))); |
|
await notificationHubClient |
|
.Received(1) |
|
.CreateOrUpdateInstallationAsync(Arg.Is<Installation>(installation => MatchingInstallationTemplate( |
|
installation.Templates, "template:message", |
|
"{\"message\":{\"data\":{\"type\":\"$(type)\"},\"notification\":{\"title\":\"$(title)\",\"body\":\"$(message)\"}}}", |
|
new List<string?> |
|
{ |
|
"template:message", |
|
$"template:message_userId:{userId}", |
|
"clientType:Mobile", |
|
identifierNull ? null : $"template:message_deviceIdentifier:{identifier}", |
|
partOfOrganizationId ? $"organizationId:{organizationId}" : null, |
|
installationIdNull ? null : $"installationId:{installationId}", |
|
}))); |
|
await notificationHubClient |
|
.Received(1) |
|
.CreateOrUpdateInstallationAsync(Arg.Is<Installation>(installation => MatchingInstallationTemplate( |
|
installation.Templates, "template:badgeMessage", |
|
"{\"message\":{\"data\":{\"type\":\"$(type)\"},\"notification\":{\"title\":\"$(title)\",\"body\":\"$(message)\"}}}", |
|
new List<string?> |
|
{ |
|
"template:badgeMessage", |
|
$"template:badgeMessage_userId:{userId}", |
|
"clientType:Mobile", |
|
identifierNull ? null : $"template:badgeMessage_deviceIdentifier:{identifier}", |
|
partOfOrganizationId ? $"organizationId:{organizationId}" : null, |
|
installationIdNull ? null : $"installationId:{installationId}", |
|
}))); |
|
} |
|
|
|
[Theory] |
|
[RepeatingPatternBitAutoData([false, true], [false, true], [false, true])] |
|
public async Task CreateOrUpdateRegistrationAsync_DeviceTypeIOS_InstallationCreated(bool identifierNull, |
|
bool partOfOrganizationId, bool installationIdNull, |
|
SutProvider<NotificationHubPushRegistrationService> sutProvider, Guid deviceId, Guid userId, Guid identifier, |
|
Guid organizationId, Guid installationId) |
|
{ |
|
var notificationHubClient = Substitute.For<INotificationHubClient>(); |
|
sutProvider.GetDependency<INotificationHubPool>().ClientFor(Arg.Any<Guid>()).Returns(notificationHubClient); |
|
|
|
var pushToken = "test push token"; |
|
|
|
await sutProvider.Sut.CreateOrUpdateRegistrationAsync(new PushRegistrationData(pushToken), deviceId.ToString(), userId.ToString(), |
|
identifierNull ? null : identifier.ToString(), DeviceType.iOS, |
|
partOfOrganizationId ? [organizationId.ToString()] : [], |
|
installationIdNull ? Guid.Empty : installationId); |
|
|
|
sutProvider.GetDependency<INotificationHubPool>() |
|
.Received(1) |
|
.ClientFor(deviceId); |
|
await notificationHubClient |
|
.Received(1) |
|
.CreateOrUpdateInstallationAsync(Arg.Is<Installation>(installation => |
|
installation.InstallationId == deviceId.ToString() && |
|
installation.PushChannel == pushToken && |
|
installation.Platform == NotificationPlatform.Apns && |
|
installation.Tags.Contains($"userId:{userId}") && |
|
installation.Tags.Contains("clientType:Mobile") && |
|
(identifierNull || installation.Tags.Contains($"deviceIdentifier:{identifier}")) && |
|
(!partOfOrganizationId || installation.Tags.Contains($"organizationId:{organizationId}")) && |
|
(installationIdNull || installation.Tags.Contains($"installationId:{installationId}")) && |
|
installation.Templates.Count == 3)); |
|
await notificationHubClient |
|
.Received(1) |
|
.CreateOrUpdateInstallationAsync(Arg.Is<Installation>(installation => MatchingInstallationTemplate( |
|
installation.Templates, "template:payload", |
|
"{\"data\":{\"type\":\"#(type)\",\"payload\":\"$(payload)\"},\"aps\":{\"content-available\":1}}", |
|
new List<string?> |
|
{ |
|
"template:payload", |
|
$"template:payload_userId:{userId}", |
|
"clientType:Mobile", |
|
identifierNull ? null : $"template:payload_deviceIdentifier:{identifier}", |
|
partOfOrganizationId ? $"organizationId:{organizationId}" : null, |
|
installationIdNull ? null : $"installationId:{installationId}", |
|
}))); |
|
await notificationHubClient |
|
.Received(1) |
|
.CreateOrUpdateInstallationAsync(Arg.Is<Installation>(installation => MatchingInstallationTemplate( |
|
installation.Templates, "template:message", |
|
"{\"data\":{\"type\":\"#(type)\"},\"aps\":{\"alert\":\"$(message)\",\"badge\":null,\"content-available\":1}}", |
|
new List<string?> |
|
{ |
|
"template:message", |
|
$"template:message_userId:{userId}", |
|
"clientType:Mobile", |
|
identifierNull ? null : $"template:message_deviceIdentifier:{identifier}", |
|
partOfOrganizationId ? $"organizationId:{organizationId}" : null, |
|
installationIdNull ? null : $"installationId:{installationId}", |
|
}))); |
|
await notificationHubClient |
|
.Received(1) |
|
.CreateOrUpdateInstallationAsync(Arg.Is<Installation>(installation => MatchingInstallationTemplate( |
|
installation.Templates, "template:badgeMessage", |
|
"{\"data\":{\"type\":\"#(type)\"},\"aps\":{\"alert\":\"$(message)\",\"badge\":\"#(badge)\",\"content-available\":1}}", |
|
new List<string?> |
|
{ |
|
"template:badgeMessage", |
|
$"template:badgeMessage_userId:{userId}", |
|
"clientType:Mobile", |
|
identifierNull ? null : $"template:badgeMessage_deviceIdentifier:{identifier}", |
|
partOfOrganizationId ? $"organizationId:{organizationId}" : null, |
|
installationIdNull ? null : $"installationId:{installationId}", |
|
}))); |
|
} |
|
|
|
[Theory] |
|
[RepeatingPatternBitAutoData([false, true], [false, true], [false, true])] |
|
public async Task CreateOrUpdateRegistrationAsync_DeviceTypeAndroidAmazon_InstallationCreated(bool identifierNull, |
|
bool partOfOrganizationId, bool installationIdNull, |
|
SutProvider<NotificationHubPushRegistrationService> sutProvider, Guid deviceId, |
|
Guid userId, Guid identifier, Guid organizationId, Guid installationId) |
|
{ |
|
var notificationHubClient = Substitute.For<INotificationHubClient>(); |
|
sutProvider.GetDependency<INotificationHubPool>().ClientFor(Arg.Any<Guid>()).Returns(notificationHubClient); |
|
|
|
var pushToken = "test push token"; |
|
|
|
await sutProvider.Sut.CreateOrUpdateRegistrationAsync(new PushRegistrationData(pushToken), deviceId.ToString(), userId.ToString(), |
|
identifierNull ? null : identifier.ToString(), DeviceType.AndroidAmazon, |
|
partOfOrganizationId ? [organizationId.ToString()] : [], |
|
installationIdNull ? Guid.Empty : installationId); |
|
|
|
sutProvider.GetDependency<INotificationHubPool>() |
|
.Received(1) |
|
.ClientFor(deviceId); |
|
await notificationHubClient |
|
.Received(1) |
|
.CreateOrUpdateInstallationAsync(Arg.Is<Installation>(installation => |
|
installation.InstallationId == deviceId.ToString() && |
|
installation.PushChannel == pushToken && |
|
installation.Platform == NotificationPlatform.Adm && |
|
installation.Tags.Contains($"userId:{userId}") && |
|
installation.Tags.Contains("clientType:Mobile") && |
|
(identifierNull || installation.Tags.Contains($"deviceIdentifier:{identifier}")) && |
|
(!partOfOrganizationId || installation.Tags.Contains($"organizationId:{organizationId}")) && |
|
(installationIdNull || installation.Tags.Contains($"installationId:{installationId}")) && |
|
installation.Templates.Count == 3)); |
|
await notificationHubClient |
|
.Received(1) |
|
.CreateOrUpdateInstallationAsync(Arg.Is<Installation>(installation => MatchingInstallationTemplate( |
|
installation.Templates, "template:payload", |
|
"{\"data\":{\"type\":\"#(type)\",\"payload\":\"$(payload)\"}}", |
|
new List<string?> |
|
{ |
|
"template:payload", |
|
$"template:payload_userId:{userId}", |
|
"clientType:Mobile", |
|
identifierNull ? null : $"template:payload_deviceIdentifier:{identifier}", |
|
partOfOrganizationId ? $"organizationId:{organizationId}" : null, |
|
installationIdNull ? null : $"installationId:{installationId}", |
|
}))); |
|
await notificationHubClient |
|
.Received(1) |
|
.CreateOrUpdateInstallationAsync(Arg.Is<Installation>(installation => MatchingInstallationTemplate( |
|
installation.Templates, "template:message", |
|
"{\"data\":{\"type\":\"#(type)\",\"message\":\"$(message)\"}}", |
|
new List<string?> |
|
{ |
|
"template:message", |
|
$"template:message_userId:{userId}", |
|
"clientType:Mobile", |
|
identifierNull ? null : $"template:message_deviceIdentifier:{identifier}", |
|
partOfOrganizationId ? $"organizationId:{organizationId}" : null, |
|
installationIdNull ? null : $"installationId:{installationId}", |
|
}))); |
|
await notificationHubClient |
|
.Received(1) |
|
.CreateOrUpdateInstallationAsync(Arg.Is<Installation>(installation => MatchingInstallationTemplate( |
|
installation.Templates, "template:badgeMessage", |
|
"{\"data\":{\"type\":\"#(type)\",\"message\":\"$(message)\"}}", |
|
new List<string?> |
|
{ |
|
"template:badgeMessage", |
|
$"template:badgeMessage_userId:{userId}", |
|
"clientType:Mobile", |
|
identifierNull ? null : $"template:badgeMessage_deviceIdentifier:{identifier}", |
|
partOfOrganizationId ? $"organizationId:{organizationId}" : null, |
|
installationIdNull ? null : $"installationId:{installationId}", |
|
}))); |
|
} |
|
|
|
[Theory] |
|
[BitAutoData(DeviceType.ChromeBrowser)] |
|
[BitAutoData(DeviceType.ChromeExtension)] |
|
[BitAutoData(DeviceType.MacOsDesktop)] |
|
public async Task CreateOrUpdateRegistrationAsync_DeviceTypeNotMobile_InstallationCreated(DeviceType deviceType, |
|
SutProvider<NotificationHubPushRegistrationService> sutProvider, Guid deviceId, Guid userId, Guid identifier, |
|
Guid organizationId, Guid installationId) |
|
{ |
|
var notificationHubClient = Substitute.For<INotificationHubClient>(); |
|
sutProvider.GetDependency<INotificationHubPool>().ClientFor(Arg.Any<Guid>()).Returns(notificationHubClient); |
|
|
|
var pushToken = "test push token"; |
|
|
|
await sutProvider.Sut.CreateOrUpdateRegistrationAsync(new PushRegistrationData(pushToken), deviceId.ToString(), userId.ToString(), |
|
identifier.ToString(), deviceType, [organizationId.ToString()], installationId); |
|
|
|
sutProvider.GetDependency<INotificationHubPool>() |
|
.Received(1) |
|
.ClientFor(deviceId); |
|
await notificationHubClient |
|
.Received(1) |
|
.CreateOrUpdateInstallationAsync(Arg.Is<Installation>(installation => |
|
installation.InstallationId == deviceId.ToString() && |
|
installation.PushChannel == pushToken && |
|
installation.Tags.Contains($"userId:{userId}") && |
|
installation.Tags.Contains($"clientType:{DeviceTypes.ToClientType(deviceType)}") && |
|
installation.Tags.Contains($"deviceIdentifier:{identifier}") && |
|
installation.Tags.Contains($"organizationId:{organizationId}") && |
|
installation.Tags.Contains($"installationId:{installationId}") && |
|
installation.Templates.Count == 0)); |
|
} |
|
|
|
private static bool MatchingInstallationTemplate(IDictionary<string, InstallationTemplate> templates, string key, |
|
string body, List<string?> tags) |
|
{ |
|
var tagsNoNulls = tags.FindAll(tag => tag != null); |
|
return templates.ContainsKey(key) && templates[key].Body == body && |
|
templates[key].Tags.Count == tagsNoNulls.Count && |
|
templates[key].Tags.All(tagsNoNulls.Contains); |
|
} |
|
}
|
|
|