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.
303 lines
15 KiB
303 lines
15 KiB
#nullable enable |
|
using Bit.Api.Platform.Push; |
|
using Bit.Core.Context; |
|
using Bit.Core.Enums; |
|
using Bit.Core.Exceptions; |
|
using Bit.Core.Models.Api; |
|
using Bit.Core.NotificationHub; |
|
using Bit.Core.Platform.Push; |
|
using Bit.Core.Settings; |
|
using Bit.Test.Common.AutoFixture; |
|
using Bit.Test.Common.AutoFixture.Attributes; |
|
using NSubstitute; |
|
using Xunit; |
|
|
|
namespace Bit.Api.Test.Platform.Push.Controllers; |
|
|
|
[ControllerCustomize(typeof(PushController))] |
|
[SutProviderCustomize] |
|
public class PushControllerTests |
|
{ |
|
[Theory] |
|
[BitAutoData(false, true)] |
|
[BitAutoData(false, false)] |
|
[BitAutoData(true, true)] |
|
public async Task SendAsync_InstallationIdNotSetOrSelfHosted_BadRequest(bool haveInstallationId, bool selfHosted, |
|
SutProvider<PushController> sutProvider, Guid installationId, Guid userId, Guid organizationId) |
|
{ |
|
sutProvider.GetDependency<IGlobalSettings>().SelfHosted = selfHosted; |
|
if (haveInstallationId) |
|
{ |
|
sutProvider.GetDependency<ICurrentContext>().InstallationId.Returns(installationId); |
|
} |
|
|
|
var exception = await Assert.ThrowsAsync<BadRequestException>(() => |
|
sutProvider.Sut.SendAsync(new PushSendRequestModel |
|
{ |
|
Type = PushType.Notification, |
|
UserId = userId.ToString(), |
|
OrganizationId = organizationId.ToString(), |
|
InstallationId = installationId.ToString(), |
|
Payload = "test-payload" |
|
})); |
|
|
|
Assert.Equal("Not correctly configured for push relays.", exception.Message); |
|
|
|
await sutProvider.GetDependency<IPushNotificationService>().Received(0) |
|
.SendPayloadToUserAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), Arg.Any<string>(), |
|
Arg.Any<string?>(), Arg.Any<ClientType?>()); |
|
await sutProvider.GetDependency<IPushNotificationService>().Received(0) |
|
.SendPayloadToOrganizationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), |
|
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>()); |
|
await sutProvider.GetDependency<IPushNotificationService>().Received(0) |
|
.SendPayloadToInstallationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), |
|
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>()); |
|
} |
|
|
|
[Theory] |
|
[BitAutoData] |
|
public async Task SendAsync_UserIdAndOrganizationIdAndInstallationIdEmpty_NoPushNotificationSent( |
|
SutProvider<PushController> sutProvider, Guid installationId) |
|
{ |
|
sutProvider.GetDependency<IGlobalSettings>().SelfHosted = false; |
|
sutProvider.GetDependency<ICurrentContext>().InstallationId.Returns(installationId); |
|
|
|
await sutProvider.Sut.SendAsync(new PushSendRequestModel |
|
{ |
|
Type = PushType.Notification, |
|
UserId = null, |
|
OrganizationId = null, |
|
InstallationId = null, |
|
Payload = "test-payload" |
|
}); |
|
|
|
await sutProvider.GetDependency<IPushNotificationService>().Received(0) |
|
.SendPayloadToUserAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), Arg.Any<string>(), |
|
Arg.Any<string?>(), Arg.Any<ClientType?>()); |
|
await sutProvider.GetDependency<IPushNotificationService>().Received(0) |
|
.SendPayloadToOrganizationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), |
|
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>()); |
|
await sutProvider.GetDependency<IPushNotificationService>().Received(0) |
|
.SendPayloadToInstallationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), |
|
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>()); |
|
} |
|
|
|
[Theory] |
|
[RepeatingPatternBitAutoData([false, true], [false, true], [false, true])] |
|
public async Task SendAsync_UserIdSet_SendPayloadToUserAsync(bool haveIdentifier, bool haveDeviceId, |
|
bool haveOrganizationId, SutProvider<PushController> sutProvider, Guid installationId, Guid userId, |
|
Guid identifier, Guid deviceId) |
|
{ |
|
sutProvider.GetDependency<IGlobalSettings>().SelfHosted = false; |
|
sutProvider.GetDependency<ICurrentContext>().InstallationId.Returns(installationId); |
|
|
|
var expectedUserId = $"{installationId}_{userId}"; |
|
var expectedIdentifier = haveIdentifier ? $"{installationId}_{identifier}" : null; |
|
var expectedDeviceId = haveDeviceId ? $"{installationId}_{deviceId}" : null; |
|
|
|
await sutProvider.Sut.SendAsync(new PushSendRequestModel |
|
{ |
|
Type = PushType.Notification, |
|
UserId = userId.ToString(), |
|
OrganizationId = haveOrganizationId ? Guid.NewGuid().ToString() : null, |
|
InstallationId = null, |
|
Payload = "test-payload", |
|
DeviceId = haveDeviceId ? deviceId.ToString() : null, |
|
Identifier = haveIdentifier ? identifier.ToString() : null, |
|
ClientType = ClientType.All, |
|
}); |
|
|
|
await sutProvider.GetDependency<IPushNotificationService>().Received(1) |
|
.SendPayloadToUserAsync(expectedUserId, PushType.Notification, "test-payload", expectedIdentifier, |
|
expectedDeviceId, ClientType.All); |
|
await sutProvider.GetDependency<IPushNotificationService>().Received(0) |
|
.SendPayloadToOrganizationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), |
|
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>()); |
|
await sutProvider.GetDependency<IPushNotificationService>().Received(0) |
|
.SendPayloadToInstallationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), |
|
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>()); |
|
} |
|
|
|
[Theory] |
|
[RepeatingPatternBitAutoData([false, true], [false, true])] |
|
public async Task SendAsync_OrganizationIdSet_SendPayloadToOrganizationAsync(bool haveIdentifier, bool haveDeviceId, |
|
SutProvider<PushController> sutProvider, Guid installationId, Guid organizationId, Guid identifier, |
|
Guid deviceId) |
|
{ |
|
sutProvider.GetDependency<IGlobalSettings>().SelfHosted = false; |
|
sutProvider.GetDependency<ICurrentContext>().InstallationId.Returns(installationId); |
|
|
|
var expectedOrganizationId = $"{installationId}_{organizationId}"; |
|
var expectedIdentifier = haveIdentifier ? $"{installationId}_{identifier}" : null; |
|
var expectedDeviceId = haveDeviceId ? $"{installationId}_{deviceId}" : null; |
|
|
|
await sutProvider.Sut.SendAsync(new PushSendRequestModel |
|
{ |
|
Type = PushType.Notification, |
|
UserId = null, |
|
OrganizationId = organizationId.ToString(), |
|
InstallationId = null, |
|
Payload = "test-payload", |
|
DeviceId = haveDeviceId ? deviceId.ToString() : null, |
|
Identifier = haveIdentifier ? identifier.ToString() : null, |
|
ClientType = ClientType.All, |
|
}); |
|
|
|
await sutProvider.GetDependency<IPushNotificationService>().Received(1) |
|
.SendPayloadToOrganizationAsync(expectedOrganizationId, PushType.Notification, "test-payload", |
|
expectedIdentifier, expectedDeviceId, ClientType.All); |
|
await sutProvider.GetDependency<IPushNotificationService>().Received(0) |
|
.SendPayloadToUserAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), Arg.Any<string>(), |
|
Arg.Any<string?>(), Arg.Any<ClientType?>()); |
|
await sutProvider.GetDependency<IPushNotificationService>().Received(0) |
|
.SendPayloadToInstallationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), |
|
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>()); |
|
} |
|
|
|
[Theory] |
|
[RepeatingPatternBitAutoData([false, true], [false, true])] |
|
public async Task SendAsync_InstallationIdSet_SendPayloadToInstallationAsync(bool haveIdentifier, bool haveDeviceId, |
|
SutProvider<PushController> sutProvider, Guid installationId, Guid identifier, Guid deviceId) |
|
{ |
|
sutProvider.GetDependency<IGlobalSettings>().SelfHosted = false; |
|
sutProvider.GetDependency<ICurrentContext>().InstallationId.Returns(installationId); |
|
|
|
var expectedIdentifier = haveIdentifier ? $"{installationId}_{identifier}" : null; |
|
var expectedDeviceId = haveDeviceId ? $"{installationId}_{deviceId}" : null; |
|
|
|
await sutProvider.Sut.SendAsync(new PushSendRequestModel |
|
{ |
|
Type = PushType.Notification, |
|
UserId = null, |
|
OrganizationId = null, |
|
InstallationId = installationId.ToString(), |
|
Payload = "test-payload", |
|
DeviceId = haveDeviceId ? deviceId.ToString() : null, |
|
Identifier = haveIdentifier ? identifier.ToString() : null, |
|
ClientType = ClientType.All, |
|
}); |
|
|
|
await sutProvider.GetDependency<IPushNotificationService>().Received(1) |
|
.SendPayloadToInstallationAsync(installationId.ToString(), PushType.Notification, "test-payload", |
|
expectedIdentifier, expectedDeviceId, ClientType.All); |
|
await sutProvider.GetDependency<IPushNotificationService>().Received(0) |
|
.SendPayloadToOrganizationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), |
|
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>()); |
|
await sutProvider.GetDependency<IPushNotificationService>().Received(0) |
|
.SendPayloadToUserAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), Arg.Any<string>(), |
|
Arg.Any<string?>(), Arg.Any<ClientType?>()); |
|
} |
|
|
|
[Theory] |
|
[BitAutoData] |
|
public async Task SendAsync_InstallationIdNotMatching_BadRequest(SutProvider<PushController> sutProvider, |
|
Guid installationId) |
|
{ |
|
sutProvider.GetDependency<IGlobalSettings>().SelfHosted = false; |
|
sutProvider.GetDependency<ICurrentContext>().InstallationId.Returns(installationId); |
|
|
|
var exception = await Assert.ThrowsAsync<BadRequestException>(() => |
|
sutProvider.Sut.SendAsync(new PushSendRequestModel |
|
{ |
|
Type = PushType.Notification, |
|
UserId = null, |
|
OrganizationId = null, |
|
InstallationId = Guid.NewGuid().ToString(), |
|
Payload = "test-payload", |
|
DeviceId = null, |
|
Identifier = null, |
|
ClientType = ClientType.All, |
|
})); |
|
|
|
Assert.Equal("InstallationId does not match current context.", exception.Message); |
|
|
|
await sutProvider.GetDependency<IPushNotificationService>().Received(0) |
|
.SendPayloadToInstallationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), |
|
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>()); |
|
await sutProvider.GetDependency<IPushNotificationService>().Received(0) |
|
.SendPayloadToOrganizationAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), |
|
Arg.Any<string>(), Arg.Any<string?>(), Arg.Any<ClientType?>()); |
|
await sutProvider.GetDependency<IPushNotificationService>().Received(0) |
|
.SendPayloadToUserAsync(Arg.Any<string>(), Arg.Any<PushType>(), Arg.Any<object>(), Arg.Any<string>(), |
|
Arg.Any<string?>(), Arg.Any<ClientType?>()); |
|
} |
|
|
|
[Theory] |
|
[BitAutoData(false, true)] |
|
[BitAutoData(false, false)] |
|
[BitAutoData(true, true)] |
|
public async Task RegisterAsync_InstallationIdNotSetOrSelfHosted_BadRequest(bool haveInstallationId, |
|
bool selfHosted, |
|
SutProvider<PushController> sutProvider, Guid installationId, Guid userId, Guid identifier, Guid deviceId) |
|
{ |
|
sutProvider.GetDependency<IGlobalSettings>().SelfHosted = selfHosted; |
|
if (haveInstallationId) |
|
{ |
|
sutProvider.GetDependency<ICurrentContext>().InstallationId.Returns(installationId); |
|
} |
|
|
|
var exception = await Assert.ThrowsAsync<BadRequestException>(() => |
|
sutProvider.Sut.RegisterAsync(new PushRegistrationRequestModel |
|
{ |
|
DeviceId = deviceId.ToString(), |
|
PushToken = "test-push-token", |
|
UserId = userId.ToString(), |
|
Type = DeviceType.Android, |
|
Identifier = identifier.ToString(), |
|
})); |
|
|
|
Assert.Equal("Not correctly configured for push relays.", exception.Message); |
|
|
|
await sutProvider.GetDependency<IPushRegistrationService>().Received(0) |
|
.CreateOrUpdateRegistrationAsync(Arg.Any<PushRegistrationData>(), Arg.Any<string>(), Arg.Any<string>(), |
|
Arg.Any<string>(), Arg.Any<DeviceType>(), Arg.Any<IEnumerable<string>>(), Arg.Any<Guid>()); |
|
} |
|
|
|
[Theory] |
|
[BitAutoData(false)] |
|
[BitAutoData(true)] |
|
public async Task RegisterAsync_ValidModel_CreatedOrUpdatedRegistration(bool haveOrganizationId, |
|
SutProvider<PushController> sutProvider, Guid installationId, Guid userId, Guid identifier, Guid deviceId, |
|
Guid organizationId) |
|
{ |
|
sutProvider.GetDependency<IGlobalSettings>().SelfHosted = false; |
|
sutProvider.GetDependency<ICurrentContext>().InstallationId.Returns(installationId); |
|
|
|
var expectedUserId = $"{installationId}_{userId}"; |
|
var expectedIdentifier = $"{installationId}_{identifier}"; |
|
var expectedDeviceId = $"{installationId}_{deviceId}"; |
|
var expectedOrganizationId = $"{installationId}_{organizationId}"; |
|
|
|
var model = new PushRegistrationRequestModel |
|
{ |
|
DeviceId = deviceId.ToString(), |
|
PushToken = "test-push-token", |
|
UserId = userId.ToString(), |
|
Type = DeviceType.Android, |
|
Identifier = identifier.ToString(), |
|
OrganizationIds = haveOrganizationId ? [organizationId.ToString()] : null, |
|
InstallationId = installationId |
|
}; |
|
|
|
await sutProvider.Sut.RegisterAsync(model); |
|
|
|
await sutProvider.GetDependency<IPushRegistrationService>().Received(1) |
|
.CreateOrUpdateRegistrationAsync( |
|
Arg.Is<PushRegistrationData>(data => data == new PushRegistrationData(model.PushToken)), |
|
expectedDeviceId, expectedUserId, |
|
expectedIdentifier, DeviceType.Android, Arg.Do<IEnumerable<string>>(organizationIds => |
|
{ |
|
Assert.NotNull(organizationIds); |
|
var organizationIdsList = organizationIds.ToList(); |
|
if (haveOrganizationId) |
|
{ |
|
Assert.Contains(expectedOrganizationId, organizationIdsList); |
|
Assert.Single(organizationIdsList); |
|
} |
|
else |
|
{ |
|
Assert.Empty(organizationIdsList); |
|
} |
|
}), installationId); |
|
} |
|
}
|
|
|