1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-29 13:25:17 +01:00

PM-10600: UTs coverage

This commit is contained in:
Maciej Zieniuk 2024-10-23 14:15:10 +01:00
parent cf8b91ebcc
commit f9477118d6
No known key found for this signature in database
GPG Key ID: 9CACE59F1272ACD9
4 changed files with 95 additions and 25 deletions

View File

@ -5,26 +5,24 @@ using Bit.Core.Context;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Models; using Bit.Core.Models;
using Bit.Core.NotificationCenter.Entities; using Bit.Core.NotificationCenter.Entities;
using Bit.Core.Settings;
using Bit.Core.Tools.Entities; using Bit.Core.Tools.Entities;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Bit.Core.Vault.Entities; using Bit.Core.Vault.Entities;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
namespace Bit.Core.Services; namespace Bit.Core.Services;
public class AzureQueuePushNotificationService : IPushNotificationService public class AzureQueuePushNotificationService : IPushNotificationService
{ {
private readonly QueueClient _queueClient; private readonly QueueClient _queueClient;
private readonly GlobalSettings _globalSettings;
private readonly IHttpContextAccessor _httpContextAccessor; private readonly IHttpContextAccessor _httpContextAccessor;
public AzureQueuePushNotificationService( public AzureQueuePushNotificationService(
GlobalSettings globalSettings, [FromKeyedServices("notifications")] QueueClient queueClient,
IHttpContextAccessor httpContextAccessor) IHttpContextAccessor httpContextAccessor)
{ {
_queueClient = new QueueClient(globalSettings.Notifications.ConnectionString, "notifications"); _queueClient = queueClient;
_globalSettings = globalSettings;
_httpContextAccessor = httpContextAccessor; _httpContextAccessor = httpContextAccessor;
} }

View File

@ -3,6 +3,7 @@ using System.Reflection;
using System.Security.Claims; using System.Security.Claims;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using AspNetCoreRateLimit; using AspNetCoreRateLimit;
using Azure.Storage.Queues;
using Bit.Core.AdminConsole.Models.Business.Tokenables; using Bit.Core.AdminConsole.Models.Business.Tokenables;
using Bit.Core.AdminConsole.OrganizationFeatures.Policies; using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
using Bit.Core.AdminConsole.Services; using Bit.Core.AdminConsole.Services;
@ -287,7 +288,10 @@ public static class ServiceCollectionExtensions
services.AddKeyedSingleton<IPushNotificationService, NotificationHubPushNotificationService>("implementation"); services.AddKeyedSingleton<IPushNotificationService, NotificationHubPushNotificationService>("implementation");
if (CoreHelpers.SettingHasValue(globalSettings.Notifications?.ConnectionString)) if (CoreHelpers.SettingHasValue(globalSettings.Notifications?.ConnectionString))
{ {
services.AddKeyedSingleton<IPushNotificationService, AzureQueuePushNotificationService>("implementation"); services.AddKeyedSingleton("notifications",
(_, _) => new QueueClient(globalSettings.Notifications.ConnectionString, "notifications"));
services.AddKeyedSingleton<IPushNotificationService, AzureQueuePushNotificationService>(
"implementation");
} }
} }
else else

View File

@ -0,0 +1,35 @@
#nullable enable
using AutoFixture;
using AutoFixture.Kernel;
using Azure.Storage.Queues;
using Bit.Test.Common.AutoFixture.Attributes;
using NSubstitute;
namespace Bit.Core.Test.AutoFixture;
public class QueueClientBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
var type = request as Type;
if (type == typeof(QueueClient))
{
return Substitute.For<QueueClient>();
}
return new NoSpecimen();
}
}
public class QueueClientCustomizeAttribute : BitCustomizeAttribute
{
public override ICustomization GetCustomization() => new QueueClientFixture();
}
public class QueueClientFixture : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new QueueClientBuilder());
}
}

View File

@ -1,34 +1,67 @@
using Bit.Core.Services; #nullable enable
using Bit.Core.Settings; using System.Text.Json;
using Azure.Storage.Queues;
using Bit.Core.Context;
using Bit.Core.Enums;
using Bit.Core.Models;
using Bit.Core.NotificationCenter.Entities;
using Bit.Core.Services;
using Bit.Core.Test.AutoFixture;
using Bit.Core.Test.AutoFixture.CurrentContextFixtures;
using Bit.Core.Test.NotificationCenter.AutoFixture;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using NSubstitute; using NSubstitute;
using Xunit; using Xunit;
namespace Bit.Core.Test.Services; namespace Bit.Core.Test.Services;
[QueueClientCustomize]
[SutProviderCustomize]
public class AzureQueuePushNotificationServiceTests public class AzureQueuePushNotificationServiceTests
{ {
private readonly AzureQueuePushNotificationService _sut; [Theory]
[BitAutoData]
private readonly GlobalSettings _globalSettings; [NotificationCustomize]
private readonly IHttpContextAccessor _httpContextAccessor; [CurrentContextCustomize]
public async void PushSyncNotificationAsync_Notification_Sent(
public AzureQueuePushNotificationServiceTests() SutProvider<AzureQueuePushNotificationService> sutProvider, Notification notification, Guid deviceIdentifier,
ICurrentContext currentContext)
{ {
_globalSettings = new GlobalSettings(); currentContext.DeviceIdentifier.Returns(deviceIdentifier.ToString());
_httpContextAccessor = Substitute.For<IHttpContextAccessor>(); sutProvider.GetDependency<IHttpContextAccessor>().HttpContext!.RequestServices
.GetService(Arg.Any<Type>()).Returns(currentContext);
_sut = new AzureQueuePushNotificationService( await sutProvider.Sut.PushSyncNotificationAsync(notification);
_globalSettings,
_httpContextAccessor await sutProvider.GetDependency<QueueClient>().Received(1)
); .SendMessageAsync(Arg.Is<string>(message =>
MatchMessage(PushType.SyncNotification, message, new SyncNotificationEquals(notification),
deviceIdentifier.ToString())));
} }
// Remove this test when we add actual tests. It only proves that private static bool MatchMessage<T>(PushType pushType, string message, IEquatable<T> expectedPayloadEquatable,
// we've properly constructed the system under test. string contextId)
[Fact(Skip = "Needs additional work")]
public void ServiceExists()
{ {
Assert.NotNull(_sut); var pushNotificationData =
JsonSerializer.Deserialize<PushNotificationData<T>>(message);
return pushNotificationData != null &&
pushNotificationData.Type == pushType &&
expectedPayloadEquatable.Equals(pushNotificationData.Payload) &&
pushNotificationData.ContextId == contextId;
}
private class SyncNotificationEquals(Notification notification) : IEquatable<SyncNotificationPushNotification>
{
public bool Equals(SyncNotificationPushNotification? other)
{
return other != null &&
other.Id == notification.Id &&
other.UserId == notification.UserId &&
other.OrganizationId == notification.OrganizationId &&
other.ClientType == notification.ClientType &&
other.RevisionDate == notification.RevisionDate;
}
} }
} }