mirror of
https://github.com/bitwarden/server.git
synced 2025-07-08 19:34:09 -05:00
Introduce notification hub pool
This commit is contained in:
205
test/Core.Test/NotificationHub/NotificationHubConnectionTests.cs
Normal file
205
test/Core.Test/NotificationHub/NotificationHubConnectionTests.cs
Normal file
@ -0,0 +1,205 @@
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.NotificationHub;
|
||||
|
||||
public class NotificationHubConnectionTests
|
||||
{
|
||||
[Fact]
|
||||
public void IsValid_ConnectionStringIsNull_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var hub = new GlobalSettings.NotificationHubSettings()
|
||||
{
|
||||
ConnectionString = null,
|
||||
HubName = "hub",
|
||||
RegistrationStartDate = DateTime.UtcNow,
|
||||
RegistrationEndDate = DateTime.UtcNow.AddDays(1)
|
||||
};
|
||||
|
||||
// Act
|
||||
var connection = NotificationHubConnection.From(hub);
|
||||
|
||||
// Assert
|
||||
Assert.False(connection.IsValid);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsValid_HubNameIsNull_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var hub = new GlobalSettings.NotificationHubSettings()
|
||||
{
|
||||
ConnectionString = "Endpoint=sb://example.servicebus.windows.net/;",
|
||||
HubName = null,
|
||||
RegistrationStartDate = DateTime.UtcNow,
|
||||
RegistrationEndDate = DateTime.UtcNow.AddDays(1)
|
||||
};
|
||||
|
||||
// Act
|
||||
var connection = NotificationHubConnection.From(hub);
|
||||
|
||||
// Assert
|
||||
Assert.False(connection.IsValid);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsValid_ConnectionStringAndHubNameAreNotNull_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var hub = new GlobalSettings.NotificationHubSettings()
|
||||
{
|
||||
ConnectionString = "connection",
|
||||
HubName = "hub",
|
||||
RegistrationStartDate = DateTime.UtcNow,
|
||||
RegistrationEndDate = DateTime.UtcNow.AddDays(1)
|
||||
};
|
||||
|
||||
// Act
|
||||
var connection = NotificationHubConnection.From(hub);
|
||||
|
||||
// Assert
|
||||
Assert.True(connection.IsValid);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegistrationEnabled_QueryTimeIsBeforeStartDate_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var hub = new GlobalSettings.NotificationHubSettings()
|
||||
{
|
||||
ConnectionString = "connection",
|
||||
HubName = "hub",
|
||||
RegistrationStartDate = DateTime.UtcNow.AddDays(1),
|
||||
RegistrationEndDate = DateTime.UtcNow.AddDays(2)
|
||||
};
|
||||
var connection = NotificationHubConnection.From(hub);
|
||||
|
||||
// Act
|
||||
var result = connection.RegistrationEnabled(DateTime.UtcNow);
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegistrationEnabled_QueryTimeIsAfterEndDate_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var hub = new GlobalSettings.NotificationHubSettings()
|
||||
{
|
||||
ConnectionString = "connection",
|
||||
HubName = "hub",
|
||||
RegistrationStartDate = DateTime.UtcNow,
|
||||
RegistrationEndDate = DateTime.UtcNow.AddDays(1)
|
||||
};
|
||||
var connection = NotificationHubConnection.From(hub);
|
||||
|
||||
// Act
|
||||
var result = connection.RegistrationEnabled(DateTime.UtcNow.AddDays(2));
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegistrationEnabled_NullStartDate_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var hub = new GlobalSettings.NotificationHubSettings()
|
||||
{
|
||||
ConnectionString = "connection",
|
||||
HubName = "hub",
|
||||
RegistrationStartDate = null,
|
||||
RegistrationEndDate = DateTime.UtcNow.AddDays(1)
|
||||
};
|
||||
var connection = NotificationHubConnection.From(hub);
|
||||
|
||||
// Act
|
||||
var result = connection.RegistrationEnabled(DateTime.UtcNow);
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegistrationEnabled_QueryTimeIsBetweenStartDateAndEndDate_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var hub = new GlobalSettings.NotificationHubSettings()
|
||||
{
|
||||
ConnectionString = "connection",
|
||||
HubName = "hub",
|
||||
RegistrationStartDate = DateTime.UtcNow,
|
||||
RegistrationEndDate = DateTime.UtcNow.AddDays(1)
|
||||
};
|
||||
var connection = NotificationHubConnection.From(hub);
|
||||
|
||||
// Act
|
||||
var result = connection.RegistrationEnabled(DateTime.UtcNow.AddHours(1));
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegistrationEnabled_CombTimeIsBeforeStartDate_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var hub = new GlobalSettings.NotificationHubSettings()
|
||||
{
|
||||
ConnectionString = "connection",
|
||||
HubName = "hub",
|
||||
RegistrationStartDate = DateTime.UtcNow.AddDays(1),
|
||||
RegistrationEndDate = DateTime.UtcNow.AddDays(2)
|
||||
};
|
||||
var connection = NotificationHubConnection.From(hub);
|
||||
|
||||
// Act
|
||||
var result = connection.RegistrationEnabled(CoreHelpers.GenerateComb(Guid.NewGuid(), DateTime.UtcNow));
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegistrationEnabled_CombTimeIsAfterEndDate_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var hub = new GlobalSettings.NotificationHubSettings()
|
||||
{
|
||||
ConnectionString = "connection",
|
||||
HubName = "hub",
|
||||
RegistrationStartDate = DateTime.UtcNow,
|
||||
RegistrationEndDate = DateTime.UtcNow.AddDays(1)
|
||||
};
|
||||
var connection = NotificationHubConnection.From(hub);
|
||||
|
||||
// Act
|
||||
var result = connection.RegistrationEnabled(CoreHelpers.GenerateComb(Guid.NewGuid(), DateTime.UtcNow.AddDays(2)));
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegistrationEnabled_CombTimeIsBetweenStartDateAndEndDate_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var hub = new GlobalSettings.NotificationHubSettings()
|
||||
{
|
||||
ConnectionString = "connection",
|
||||
HubName = "hub",
|
||||
RegistrationStartDate = DateTime.UtcNow,
|
||||
RegistrationEndDate = DateTime.UtcNow.AddDays(1)
|
||||
};
|
||||
var connection = NotificationHubConnection.From(hub);
|
||||
|
||||
// Act
|
||||
var result = connection.RegistrationEnabled(CoreHelpers.GenerateComb(Guid.NewGuid(), DateTime.UtcNow.AddHours(1)));
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
}
|
||||
}
|
156
test/Core.Test/NotificationHub/NotificationHubPoolTests.cs
Normal file
156
test/Core.Test/NotificationHub/NotificationHubPoolTests.cs
Normal file
@ -0,0 +1,156 @@
|
||||
using Bit.Core.NotificationHub;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
using static Bit.Core.Settings.GlobalSettings;
|
||||
|
||||
namespace Bit.Core.Test.NotificationHub;
|
||||
|
||||
public class NotificationHubPoolTests
|
||||
{
|
||||
[Fact]
|
||||
public void NotificationHubPool_WarnsOnMissingConnectionString()
|
||||
{
|
||||
// Arrange
|
||||
var globalSettings = new GlobalSettings()
|
||||
{
|
||||
NotificationHubPool = new NotificationHubPoolSettings()
|
||||
{
|
||||
NotificationHubSettings = new() {
|
||||
new() {
|
||||
ConnectionString = null,
|
||||
HubName = "hub",
|
||||
RegistrationStartDate = DateTime.UtcNow,
|
||||
RegistrationEndDate = DateTime.UtcNow.AddDays(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var logger = Substitute.For<ILogger<NotificationHubPool>>();
|
||||
|
||||
// Act
|
||||
var sut = new NotificationHubPool(logger, globalSettings);
|
||||
|
||||
// Assert
|
||||
logger.Received().Log(LogLevel.Warning, Arg.Any<EventId>(),
|
||||
Arg.Is<object>(o => o.ToString() == "Invalid notification hub settings: hub"),
|
||||
null,
|
||||
Arg.Any<Func<object, Exception, string>>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NotificationHubPool_WarnsOnMissingHubName()
|
||||
{
|
||||
// Arrange
|
||||
var globalSettings = new GlobalSettings()
|
||||
{
|
||||
NotificationHubPool = new NotificationHubPoolSettings()
|
||||
{
|
||||
NotificationHubSettings = new() {
|
||||
new() {
|
||||
ConnectionString = "connection",
|
||||
HubName = null,
|
||||
RegistrationStartDate = DateTime.UtcNow,
|
||||
RegistrationEndDate = DateTime.UtcNow.AddDays(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var logger = Substitute.For<ILogger<NotificationHubPool>>();
|
||||
|
||||
// Act
|
||||
var sut = new NotificationHubPool(logger, globalSettings);
|
||||
|
||||
// Assert
|
||||
logger.Received().Log(LogLevel.Warning, Arg.Any<EventId>(),
|
||||
Arg.Is<object>(o => o.ToString() == "Invalid notification hub settings: hub name missing"),
|
||||
null,
|
||||
Arg.Any<Func<object, Exception, string>>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NotificationHubPool_ClientFor_ThrowsOnNoValidHubs()
|
||||
{
|
||||
// Arrange
|
||||
var globalSettings = new GlobalSettings()
|
||||
{
|
||||
NotificationHubPool = new NotificationHubPoolSettings()
|
||||
{
|
||||
NotificationHubSettings = new() {
|
||||
new() {
|
||||
ConnectionString = "connection",
|
||||
HubName = "hub",
|
||||
RegistrationStartDate = null,
|
||||
RegistrationEndDate = null,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var logger = Substitute.For<ILogger<NotificationHubPool>>();
|
||||
var sut = new NotificationHubPool(logger, globalSettings);
|
||||
|
||||
// Act
|
||||
Action act = () => sut.ClientFor(Guid.NewGuid());
|
||||
|
||||
// Assert
|
||||
Assert.Throws<InvalidOperationException>(act);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NotificationHubPool_ClientFor_ReturnsClient()
|
||||
{
|
||||
// Arrange
|
||||
var globalSettings = new GlobalSettings()
|
||||
{
|
||||
NotificationHubPool = new NotificationHubPoolSettings()
|
||||
{
|
||||
NotificationHubSettings = new() {
|
||||
new() {
|
||||
ConnectionString = "Endpoint=sb://example.servicebus.windows.net/;SharedAccessKey=example///example=",
|
||||
HubName = "hub",
|
||||
RegistrationStartDate = DateTime.UtcNow,
|
||||
RegistrationEndDate = DateTime.UtcNow.AddDays(1),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var logger = Substitute.For<ILogger<NotificationHubPool>>();
|
||||
var sut = new NotificationHubPool(logger, globalSettings);
|
||||
|
||||
// Act
|
||||
var client = sut.ClientFor(CoreHelpers.GenerateComb(Guid.NewGuid(), DateTime.UtcNow));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(client);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NotificationHubPool_AllClients_ReturnsProxy()
|
||||
{
|
||||
// Arrange
|
||||
var globalSettings = new GlobalSettings()
|
||||
{
|
||||
NotificationHubPool = new NotificationHubPoolSettings()
|
||||
{
|
||||
NotificationHubSettings = new() {
|
||||
new() {
|
||||
ConnectionString = "connection",
|
||||
HubName = "hub",
|
||||
RegistrationStartDate = DateTime.UtcNow,
|
||||
RegistrationEndDate = DateTime.UtcNow.AddDays(1),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var logger = Substitute.For<ILogger<NotificationHubPool>>();
|
||||
var sut = new NotificationHubPool(logger, globalSettings);
|
||||
|
||||
// Act
|
||||
var proxy = sut.AllClients;
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(proxy);
|
||||
}
|
||||
}
|
52
test/Core.Test/NotificationHub/NotificationHubProxyTests.cs
Normal file
52
test/Core.Test/NotificationHub/NotificationHubProxyTests.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using AutoFixture;
|
||||
using Bit.Core.NotificationHub;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Microsoft.Azure.NotificationHubs;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.NotificationHub;
|
||||
|
||||
public class NotificationHubProxyTests
|
||||
{
|
||||
private readonly IEnumerable<INotificationHubClient> _clients;
|
||||
public NotificationHubProxyTests()
|
||||
{
|
||||
_clients = new Fixture().WithAutoNSubstitutions().CreateMany<INotificationHubClient>();
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> ClientMethods =
|
||||
[
|
||||
[
|
||||
(NotificationHubClientProxy c) => c.DeleteInstallationAsync("test"),
|
||||
(INotificationHubClient c) => c.DeleteInstallationAsync("test"),
|
||||
],
|
||||
[
|
||||
(NotificationHubClientProxy c) => c.DeleteInstallationAsync("test", default),
|
||||
(INotificationHubClient c) => c.DeleteInstallationAsync("test", default),
|
||||
],
|
||||
[
|
||||
(NotificationHubClientProxy c) => c.PatchInstallationAsync("test", new List<PartialUpdateOperation>()),
|
||||
(INotificationHubClient c) => c.PatchInstallationAsync("test", Arg.Any<List<PartialUpdateOperation>>()),
|
||||
],
|
||||
[
|
||||
(NotificationHubClientProxy c) => c.PatchInstallationAsync("test", new List<PartialUpdateOperation>(), default),
|
||||
(INotificationHubClient c) => c.PatchInstallationAsync("test", Arg.Any<List<PartialUpdateOperation>>(), default)
|
||||
]
|
||||
];
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(ClientMethods))]
|
||||
public async void CallsAllClients(Func<NotificationHubClientProxy, Task> proxyMethod, Func<INotificationHubClient, Task> clientMethod)
|
||||
{
|
||||
var clients = _clients.ToArray();
|
||||
var proxy = new NotificationHubClientProxy(clients);
|
||||
|
||||
await proxyMethod(proxy);
|
||||
|
||||
foreach (var client in clients)
|
||||
{
|
||||
await clientMethod(client.Received());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.NotificationHub;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Settings;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
@ -6,7 +7,7 @@ using Microsoft.Extensions.Logging;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Services;
|
||||
namespace Bit.Core.Test.NotificationHub;
|
||||
|
||||
public class NotificationHubPushNotificationServiceTests
|
||||
{
|
@ -1,11 +1,11 @@
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.NotificationHub;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Settings;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Core.Test.Services;
|
||||
namespace Bit.Core.Test.NotificationHub;
|
||||
|
||||
public class NotificationHubPushRegistrationServiceTests
|
||||
{
|
||||
@ -15,6 +15,7 @@ public class NotificationHubPushRegistrationServiceTests
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly ILogger<NotificationHubPushRegistrationService> _logger;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly INotificationHubPool _notificationHubPool;
|
||||
|
||||
public NotificationHubPushRegistrationServiceTests()
|
||||
{
|
||||
@ -22,10 +23,12 @@ public class NotificationHubPushRegistrationServiceTests
|
||||
_serviceProvider = Substitute.For<IServiceProvider>();
|
||||
_logger = Substitute.For<ILogger<NotificationHubPushRegistrationService>>();
|
||||
_globalSettings = new GlobalSettings();
|
||||
_notificationHubPool = Substitute.For<INotificationHubPool>();
|
||||
|
||||
_sut = new NotificationHubPushRegistrationService(
|
||||
_installationDeviceRepository,
|
||||
_globalSettings,
|
||||
_notificationHubPool,
|
||||
_serviceProvider,
|
||||
_logger
|
||||
);
|
@ -34,33 +34,30 @@ public class CoreHelpersTests
|
||||
// the comb are working properly
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> GenerateCombCases = new[]
|
||||
{
|
||||
new object[]
|
||||
{
|
||||
public static IEnumerable<object[]> GuidSeedCases = [
|
||||
[
|
||||
Guid.Parse("a58db474-43d8-42f1-b4ee-0c17647cd0c0"), // Input Guid
|
||||
new DateTime(2022, 3, 12, 12, 12, 0, DateTimeKind.Utc), // Input Time
|
||||
Guid.Parse("a58db474-43d8-42f1-b4ee-ae5600c90cc1"), // Expected Comb
|
||||
},
|
||||
new object[]
|
||||
{
|
||||
],
|
||||
[
|
||||
Guid.Parse("f776e6ee-511f-4352-bb28-88513002bdeb"),
|
||||
new DateTime(2021, 5, 10, 10, 52, 0, DateTimeKind.Utc),
|
||||
Guid.Parse("f776e6ee-511f-4352-bb28-ad2400b313c1"),
|
||||
},
|
||||
new object[]
|
||||
{
|
||||
],
|
||||
[
|
||||
Guid.Parse("51a25fc7-3cad-497d-8e2f-8d77011648a1"),
|
||||
new DateTime(1999, 2, 26, 16, 53, 13, DateTimeKind.Utc),
|
||||
Guid.Parse("51a25fc7-3cad-497d-8e2f-8d77011649cd"),
|
||||
},
|
||||
new object[]
|
||||
{
|
||||
],
|
||||
[
|
||||
Guid.Parse("bfb8f353-3b32-4a9e-bef6-24fe0b54bfb0"),
|
||||
new DateTime(2024, 10, 20, 1, 32, 16, DateTimeKind.Utc),
|
||||
Guid.Parse("bfb8f353-3b32-4a9e-bef6-b20f00195780"),
|
||||
}
|
||||
};
|
||||
]
|
||||
];
|
||||
public static IEnumerable<object[]> GenerateCombCases = GuidSeedCases.Zip([
|
||||
Guid.Parse("a58db474-43d8-42f1-b4ee-ae5600c90cc1"), // Expected Comb for each Guid Seed case
|
||||
Guid.Parse("f776e6ee-511f-4352-bb28-ad2400b313c1"),
|
||||
Guid.Parse("51a25fc7-3cad-497d-8e2f-8d77011649cd"),
|
||||
Guid.Parse("bfb8f353-3b32-4a9e-bef6-b20f00195780"),
|
||||
]).Select((zip) => new object[] { zip.Item1[0], zip.Item1[1], zip.Item2 });
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateCombCases))]
|
||||
@ -72,7 +69,7 @@ public class CoreHelpersTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(GenerateCombCases))]
|
||||
[MemberData(nameof(GuidSeedCases))]
|
||||
public void DateFromComb_WithComb_Success(Guid inputGuid, DateTime inputTime)
|
||||
{
|
||||
var comb = CoreHelpers.GenerateComb(inputGuid, inputTime);
|
||||
|
Reference in New Issue
Block a user