1
0
mirror of https://github.com/bitwarden/server synced 2025-12-10 13:23:27 +00:00
Files
server/test/Core.Test/Services/Implementations/FeatureRoutedCacheServiceTests.cs

542 lines
19 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Bit.Core.AdminConsole.AbilitiesCache;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Entities.Provider;
using Bit.Core.AdminConsole.Models.Data.Provider;
using Bit.Core.AdminConsole.Repositories;
using Bit.Core.Models.Data.Organizations;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Services.Implementations;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
using NSubstitute;
using Xunit;
using GlobalSettings = Bit.Core.Settings.GlobalSettings;
namespace Bit.Core.Test.Services.Implementations;
[SutProviderCustomize]
public class FeatureRoutedCacheServiceTests
{
[Theory, BitAutoData]
public async Task GetOrganizationAbilitiesAsync_WhenFeatureIsEnabled_ReturnsFromVNextService(
SutProvider<FeatureRoutedCacheService> sutProvider,
IDictionary<Guid, OrganizationAbility> expectedResult)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(true);
sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.GetOrganizationAbilitiesAsync()
.Returns(expectedResult);
// Act
var result = await sutProvider.Sut.GetOrganizationAbilitiesAsync();
// Assert
Assert.Equal(expectedResult, result);
await sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.Received(1)
.GetOrganizationAbilitiesAsync();
await sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.DidNotReceive()
.GetOrganizationAbilitiesAsync();
}
[Theory, BitAutoData]
public async Task GetOrganizationAbilitiesAsync_WhenFeatureIsDisabled_ReturnsFromInMemoryService(
SutProvider<FeatureRoutedCacheService> sutProvider,
IDictionary<Guid, OrganizationAbility> expectedResult)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(false);
sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.GetOrganizationAbilitiesAsync()
.Returns(expectedResult);
// Act
var result = await sutProvider.Sut.GetOrganizationAbilitiesAsync();
// Assert
Assert.Equal(expectedResult, result);
await sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.Received(1)
.GetOrganizationAbilitiesAsync();
await sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.DidNotReceive()
.GetOrganizationAbilitiesAsync();
}
[Theory, BitAutoData]
public async Task GetOrganizationAbilityAsync_WhenFeatureIsEnabled_ReturnsFromVNextService(
SutProvider<FeatureRoutedCacheService> sutProvider,
Guid orgId,
OrganizationAbility expectedResult)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(true);
sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.GetOrganizationAbilityAsync(orgId)
.Returns(expectedResult);
// Act
var result = await sutProvider.Sut.GetOrganizationAbilityAsync(orgId);
// Assert
Assert.Equal(expectedResult, result);
await sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.Received(1)
.GetOrganizationAbilityAsync(orgId);
await sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.DidNotReceive()
.GetOrganizationAbilityAsync(orgId);
}
[Theory, BitAutoData]
public async Task GetOrganizationAbilityAsync_WhenFeatureIsDisabled_ReturnsFromInMemoryService(
SutProvider<FeatureRoutedCacheService> sutProvider,
Guid orgId,
OrganizationAbility expectedResult)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(false);
sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.GetOrganizationAbilityAsync(orgId)
.Returns(expectedResult);
// Act
var result = await sutProvider.Sut.GetOrganizationAbilityAsync(orgId);
// Assert
Assert.Equal(expectedResult, result);
await sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.Received(1)
.GetOrganizationAbilityAsync(orgId);
await sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.DidNotReceive()
.GetOrganizationAbilityAsync(orgId);
}
[Theory, BitAutoData]
public async Task GetProviderAbilitiesAsync_WhenFeatureIsEnabled_ReturnsFromVNextService(
SutProvider<FeatureRoutedCacheService> sutProvider,
IDictionary<Guid, ProviderAbility> expectedResult)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(true);
sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.GetProviderAbilitiesAsync()
.Returns(expectedResult);
// Act
var result = await sutProvider.Sut.GetProviderAbilitiesAsync();
// Assert
Assert.Equal(expectedResult, result);
await sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.Received(1)
.GetProviderAbilitiesAsync();
await sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.DidNotReceive()
.GetProviderAbilitiesAsync();
}
[Theory, BitAutoData]
public async Task GetProviderAbilitiesAsync_WhenFeatureIsDisabled_ReturnsFromInMemoryService(
SutProvider<FeatureRoutedCacheService> sutProvider,
IDictionary<Guid, ProviderAbility> expectedResult)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(false);
sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.GetProviderAbilitiesAsync()
.Returns(expectedResult);
// Act
var result = await sutProvider.Sut.GetProviderAbilitiesAsync();
// Assert
Assert.Equal(expectedResult, result);
await sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.Received(1)
.GetProviderAbilitiesAsync();
await sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.DidNotReceive()
.GetProviderAbilitiesAsync();
}
[Theory, BitAutoData]
public async Task UpsertOrganizationAbilityAsync_WhenFeatureIsEnabled_CallsVNextService(
SutProvider<FeatureRoutedCacheService> sutProvider,
Organization organization)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(true);
// Act
await sutProvider.Sut.UpsertOrganizationAbilityAsync(organization);
// Assert
await sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.Received(1)
.UpsertOrganizationAbilityAsync(organization);
await sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.DidNotReceive()
.GetProviderAbilitiesAsync();
}
[Theory, BitAutoData]
public async Task UpsertOrganizationAbilityAsync_WhenFeatureIsDisabled_CallsInMemoryService(
SutProvider<FeatureRoutedCacheService> sutProvider,
Organization organization)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(false);
// Act
await sutProvider.Sut.UpsertOrganizationAbilityAsync(organization);
// Assert
await sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.Received(1)
.UpsertOrganizationAbilityAsync(organization);
await sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.DidNotReceive()
.GetProviderAbilitiesAsync();
}
[Theory, BitAutoData]
public async Task UpsertProviderAbilityAsync_WhenFeatureIsEnabled_CallsVNextService(
SutProvider<FeatureRoutedCacheService> sutProvider,
Provider provider)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(true);
// Act
await sutProvider.Sut.UpsertProviderAbilityAsync(provider);
// Assert
await sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.Received(1)
.UpsertProviderAbilityAsync(provider);
await sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.DidNotReceive()
.UpsertProviderAbilityAsync(provider);
}
[Theory, BitAutoData]
public async Task UpsertProviderAbilityAsync_WhenFeatureIsDisabled_CallsInMemoryService(
SutProvider<FeatureRoutedCacheService> sutProvider,
Provider provider)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(false);
// Act
await sutProvider.Sut.UpsertProviderAbilityAsync(provider);
// Assert
await sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.Received(1)
.UpsertProviderAbilityAsync(provider);
await sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.DidNotReceive()
.UpsertProviderAbilityAsync(provider);
}
[Theory, BitAutoData]
public async Task DeleteOrganizationAbilityAsync_WhenFeatureIsEnabled_CallsVNextService(
SutProvider<FeatureRoutedCacheService> sutProvider,
Guid organizationId)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(true);
// Act
await sutProvider.Sut.DeleteOrganizationAbilityAsync(organizationId);
// Assert
await sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.Received(1)
.DeleteOrganizationAbilityAsync(organizationId);
await sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.DidNotReceive()
.DeleteOrganizationAbilityAsync(organizationId);
}
[Theory, BitAutoData]
public async Task DeleteOrganizationAbilityAsync_WhenFeatureIsDisabled_CallsInMemoryService(
SutProvider<FeatureRoutedCacheService> sutProvider,
Guid organizationId)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(false);
// Act
await sutProvider.Sut.DeleteOrganizationAbilityAsync(organizationId);
// Assert
await sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.Received(1)
.DeleteOrganizationAbilityAsync(organizationId);
await sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.DidNotReceive()
.DeleteOrganizationAbilityAsync(organizationId);
}
[Theory, BitAutoData]
public async Task DeleteProviderAbilityAsync_WhenFeatureIsEnabled_CallsVNextService(
SutProvider<FeatureRoutedCacheService> sutProvider,
Guid providerId)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(true);
// Act
await sutProvider.Sut.DeleteProviderAbilityAsync(providerId);
// Assert
await sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.Received(1)
.DeleteProviderAbilityAsync(providerId);
await sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.DidNotReceive()
.DeleteProviderAbilityAsync(providerId);
}
[Theory, BitAutoData]
public async Task DeleteProviderAbilityAsync_WhenFeatureIsDisabled_CallsInMemoryService(
SutProvider<FeatureRoutedCacheService> sutProvider,
Guid providerId)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(false);
// Act
await sutProvider.Sut.DeleteProviderAbilityAsync(providerId);
// Assert
await sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.Received(1)
.DeleteProviderAbilityAsync(providerId);
await sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.DidNotReceive()
.DeleteProviderAbilityAsync(providerId);
}
[Theory, BitAutoData]
public async Task BaseUpsertOrganizationAbilityAsync_WhenFeatureIsEnabled_CallsVNextService(
SutProvider<FeatureRoutedCacheService> sutProvider,
Organization organization)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(true);
// Act
await sutProvider.Sut.BaseUpsertOrganizationAbilityAsync(organization);
// Assert
await sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.Received(1)
.UpsertOrganizationAbilityAsync(organization);
await sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.DidNotReceive()
.UpsertOrganizationAbilityAsync(organization);
}
[Theory, BitAutoData]
public async Task BaseUpsertOrganizationAbilityAsync_WhenFeatureIsDisabled_CallsServiceBusCache(
Organization organization)
{
// Arrange
var featureService = Substitute.For<IFeatureService>();
var currentCacheService = CreateCurrentCacheMockService();
featureService
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(false);
var sutProvider = Substitute.For<FeatureRoutedCacheService>(
featureService,
Substitute.For<IVNextInMemoryApplicationCacheService>(),
currentCacheService,
Substitute.For<IApplicationCacheServiceBusMessaging>());
// Act
await sutProvider.BaseUpsertOrganizationAbilityAsync(organization);
// Assert
await currentCacheService
.Received(1)
.BaseUpsertOrganizationAbilityAsync(organization);
}
/// <summary>
/// Our SUT is using a method that is not part of the IVCurrentInMemoryApplicationCacheService,
/// so AutoFixtures auto-created mock wont work.
/// </summary>
/// <returns></returns>
private static InMemoryServiceBusApplicationCacheService CreateCurrentCacheMockService()
{
var currentCacheService = Substitute.For<InMemoryServiceBusApplicationCacheService>(
Substitute.For<IOrganizationRepository>(),
Substitute.For<IProviderRepository>(),
new GlobalSettings
{
ProjectName = "BitwardenTest",
ServiceBus = new GlobalSettings.ServiceBusSettings
{
ConnectionString = "Endpoint=sb://test.servicebus.windows.net/;SharedAccessKeyName=test;SharedAccessKey=test",
ApplicationCacheTopicName = "test-topic",
ApplicationCacheSubscriptionName = "test-subscription"
}
});
return currentCacheService;
}
[Theory, BitAutoData]
public async Task BaseUpsertOrganizationAbilityAsync_WhenFeatureIsDisabled_AndServiceIsNotServiceBusCache_ThrowsException(
SutProvider<FeatureRoutedCacheService> sutProvider,
Organization organization)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(false);
// Act
var ex = await Assert.ThrowsAsync<InvalidOperationException>(
() => sutProvider.Sut.BaseUpsertOrganizationAbilityAsync(organization));
// Assert
Assert.Equal(
ExpectedErrorMessage,
ex.Message);
}
private static string ExpectedErrorMessage
{
get => "Expected inMemoryApplicationCacheService to be of type InMemoryServiceBusApplicationCacheService";
}
[Theory, BitAutoData]
public async Task BaseDeleteOrganizationAbilityAsync_WhenFeatureIsEnabled_CallsVNextService(
SutProvider<FeatureRoutedCacheService> sutProvider,
Guid organizationId)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(true);
// Act
await sutProvider.Sut.BaseDeleteOrganizationAbilityAsync(organizationId);
// Assert
await sutProvider.GetDependency<IVNextInMemoryApplicationCacheService>()
.Received(1)
.DeleteOrganizationAbilityAsync(organizationId);
await sutProvider.GetDependency<IVCurrentInMemoryApplicationCacheService>()
.DidNotReceive()
.DeleteOrganizationAbilityAsync(organizationId);
}
[Theory, BitAutoData]
public async Task BaseDeleteOrganizationAbilityAsync_WhenFeatureIsDisabled_CallsServiceBusCache(
Guid organizationId)
{
// Arrange
var featureService = Substitute.For<IFeatureService>();
var currentCacheService = CreateCurrentCacheMockService();
featureService
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(false);
var sutProvider = Substitute.For<FeatureRoutedCacheService>(
featureService,
Substitute.For<IVNextInMemoryApplicationCacheService>(),
currentCacheService,
Substitute.For<IApplicationCacheServiceBusMessaging>());
// Act
await sutProvider.BaseDeleteOrganizationAbilityAsync(organizationId);
// Assert
await currentCacheService
.Received(1)
.BaseDeleteOrganizationAbilityAsync(organizationId);
}
[Theory, BitAutoData]
public async Task
BaseDeleteOrganizationAbilityAsync_WhenFeatureIsDisabled_AndServiceIsNotServiceBusCache_ThrowsException(
SutProvider<FeatureRoutedCacheService> sutProvider,
Guid organizationId)
{
// Arrange
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PM23845_VNextApplicationCache)
.Returns(false);
// Act
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() =>
sutProvider.Sut.BaseDeleteOrganizationAbilityAsync(organizationId));
// Assert
Assert.Equal(
ExpectedErrorMessage,
ex.Message);
}
}