1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-01 08:02:49 -05:00

[SM-151] Move EF Dapper tests to Infrastructure.EFIntegration.Test (#2204)

This commit is contained in:
Oscar Hinton
2022-08-29 15:40:59 +02:00
committed by GitHub
parent 2b2f9fafd2
commit 194c695cd0
104 changed files with 4098 additions and 1898 deletions

View File

@ -0,0 +1,120 @@
using System.Text.Json;
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Core.Models.Data;
using Bit.Core.Test.AutoFixture.UserFixtures;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture.Relays;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class CipherBuilder : ISpecimenBuilder
{
public bool OrganizationOwned { get; set; }
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || (type != typeof(Cipher) && type != typeof(List<Cipher>)))
{
return new NoSpecimen();
}
var fixture = new Fixture();
fixture.Customizations.Insert(0, new MaxLengthStringRelay());
if (!OrganizationOwned)
{
fixture.Customize<Cipher>(composer => composer
.Without(c => c.OrganizationId));
}
// Can't test valid Favorites and Folders without creating those values inide each test,
// since we won't have any UserIds until the test is running & creating data
fixture.Customize<Cipher>(c => c
.Without(e => e.Favorites)
.Without(e => e.Folders));
//
var serializerOptions = new JsonSerializerOptions()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
if (type == typeof(Cipher))
{
var obj = fixture.WithAutoNSubstitutions().Create<Cipher>();
var cipherData = fixture.WithAutoNSubstitutions().Create<CipherLoginData>();
var cipherAttachements = fixture.WithAutoNSubstitutions().Create<List<CipherAttachment>>();
obj.Data = JsonSerializer.Serialize(cipherData, serializerOptions);
obj.Attachments = JsonSerializer.Serialize(cipherAttachements, serializerOptions);
return obj;
}
if (type == typeof(List<Cipher>))
{
var ciphers = fixture.WithAutoNSubstitutions().CreateMany<Cipher>().ToArray();
for (var i = 0; i < ciphers.Count(); i++)
{
var cipherData = fixture.WithAutoNSubstitutions().Create<CipherLoginData>();
var cipherAttachements = fixture.WithAutoNSubstitutions().Create<List<CipherAttachment>>();
ciphers[i].Data = JsonSerializer.Serialize(cipherData, serializerOptions);
ciphers[i].Attachments = JsonSerializer.Serialize(cipherAttachements, serializerOptions);
}
return ciphers;
}
return new NoSpecimen();
}
}
internal class EfCipher : ICustomization
{
public bool OrganizationOwned { get; set; }
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new CipherBuilder()
{
OrganizationOwned = OrganizationOwned
});
fixture.Customizations.Add(new UserBuilder());
fixture.Customizations.Add(new OrganizationBuilder());
fixture.Customizations.Add(new OrganizationUserBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<CipherRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<OrganizationRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<OrganizationUserRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<UserRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<CollectionRepository>());
}
}
internal class EfUserCipherAutoDataAttribute : CustomAutoDataAttribute
{
public EfUserCipherAutoDataAttribute() : base(new SutProviderCustomization(), new EfCipher())
{ }
}
internal class EfOrganizationCipherAutoDataAttribute : CustomAutoDataAttribute
{
public EfOrganizationCipherAutoDataAttribute() : base(new SutProviderCustomization(), new EfCipher()
{
OrganizationOwned = true,
})
{ }
}
internal class InlineEfCipherAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfCipherAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfCipher) }, values)
{ }
}
}

View File

@ -0,0 +1,63 @@
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.UserFixtures;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture.Relays;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class CollectionCipherBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != typeof(CollectionCipher))
{
return new NoSpecimen();
}
var fixture = new Fixture();
fixture.Customizations.Insert(0, new MaxLengthStringRelay());
var obj = fixture.WithAutoNSubstitutions().Create<CollectionCipher>();
return obj;
}
}
internal class EfCollectionCipher : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new CollectionCipherBuilder());
fixture.Customizations.Add(new CollectionBuilder());
fixture.Customizations.Add(new CipherBuilder());
fixture.Customizations.Add(new UserBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<CollectionCipherRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<CollectionRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<CipherRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<UserRepository>());
}
}
internal class EfCollectionCipherAutoDataAttribute : CustomAutoDataAttribute
{
public EfCollectionCipherAutoDataAttribute() : base(new SutProviderCustomization(), new EfCollectionCipher())
{ }
}
internal class InlineEfCollectionCipherAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfCollectionCipherAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfCollectionCipher) }, values)
{ }
}
}

View File

@ -0,0 +1,58 @@
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture.Relays;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class CollectionBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != typeof(Collection))
{
return new NoSpecimen();
}
var fixture = new Fixture();
fixture.Customizations.Insert(0, new MaxLengthStringRelay());
var obj = fixture.WithAutoNSubstitutions().Create<Collection>();
return obj;
}
}
internal class EfCollection : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new CollectionBuilder());
fixture.Customizations.Add(new OrganizationBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<CollectionRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<OrganizationRepository>());
}
}
internal class EfCollectionAutoDataAttribute : CustomAutoDataAttribute
{
public EfCollectionAutoDataAttribute() : base(new SutProviderCustomization(), new EfCollection())
{ }
}
internal class InlineEfCollectionAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfCollectionAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfCollection) }, values)
{ }
}
}

View File

@ -0,0 +1,60 @@
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.UserFixtures;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture.Relays;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class DeviceBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != typeof(Device))
{
return new NoSpecimen();
}
var fixture = new Fixture();
fixture.Customizations.Insert(0, new MaxLengthStringRelay());
var obj = fixture.WithAutoNSubstitutions().Create<Device>();
return obj;
}
}
internal class EfDevice : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new DeviceBuilder());
fixture.Customizations.Add(new UserBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<DeviceRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<UserRepository>());
}
}
internal class EfDeviceAutoDataAttribute : CustomAutoDataAttribute
{
public EfDeviceAutoDataAttribute() : base(new SutProviderCustomization(), new EfDevice())
{ }
}
internal class InlineEfDeviceAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfDeviceAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfDevice) }, values)
{ }
}
}

View File

@ -0,0 +1,61 @@
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.UserFixtures;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture.Relays;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class EmergencyAccessBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != typeof(EmergencyAccess))
{
return new NoSpecimen();
}
var fixture = new Fixture();
fixture.Customizations.Insert(0, new MaxLengthStringRelay());
var obj = fixture.Create<EmergencyAccess>();
return obj;
}
}
internal class EfEmergencyAccess : ICustomization
{
public void Customize(IFixture fixture)
{
// TODO: Make a base EF Customization with IgnoreVirtualMembers/GlobalSettings/All repos and inherit
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new EmergencyAccessBuilder());
fixture.Customizations.Add(new UserBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<EmergencyAccessRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<UserRepository>());
}
}
internal class EfEmergencyAccessAutoDataAttribute : CustomAutoDataAttribute
{
public EfEmergencyAccessAutoDataAttribute() : base(new SutProviderCustomization(), new EfEmergencyAccess())
{ }
}
internal class InlineEfEmergencyAccessAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfEmergencyAccessAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfEmergencyAccess) }, values)
{ }
}
}

View File

@ -0,0 +1,122 @@
using System.Reflection;
using AutoFixture;
using AutoFixture.Kernel;
using AutoMapper;
using Bit.Core.Settings;
using Bit.Infrastructure.EFIntegration.Test.Helpers;
using Bit.Infrastructure.EntityFramework.Models;
using Bit.Infrastructure.EntityFramework.Repositories;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Moq;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class ServiceScopeFactoryBuilder : ISpecimenBuilder
{
private DbContextOptions<DatabaseContext> _options { get; set; }
public ServiceScopeFactoryBuilder(DbContextOptions<DatabaseContext> options)
{
_options = options;
}
public object Create(object request, ISpecimenContext context)
{
var fixture = new Fixture();
var serviceProvider = new Mock<IServiceProvider>();
var dbContext = new DatabaseContext(_options);
serviceProvider
.Setup(x => x.GetService(typeof(DatabaseContext)))
.Returns(dbContext);
var serviceScope = new Mock<IServiceScope>();
serviceScope.Setup(x => x.ServiceProvider).Returns(serviceProvider.Object);
var serviceScopeFactory = new Mock<IServiceScopeFactory>();
serviceScopeFactory
.Setup(x => x.CreateScope())
.Returns(serviceScope.Object);
return serviceScopeFactory.Object;
}
}
public class EfRepositoryListBuilder<T> : ISpecimenBuilder where T : BaseEntityFrameworkRepository
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var t = request as ParameterInfo;
if (t == null || t.ParameterType != typeof(List<T>))
{
return new NoSpecimen();
}
var list = new List<T>();
foreach (var option in DatabaseOptionsFactory.Options)
{
var fixture = new Fixture();
fixture.Customize<IServiceScopeFactory>(x => x.FromFactory(new ServiceScopeFactoryBuilder(option)));
fixture.Customize<IMapper>(x => x.FromFactory(() =>
new MapperConfiguration(cfg =>
{
cfg.AddProfile<CipherMapperProfile>();
cfg.AddProfile<CollectionCipherMapperProfile>();
cfg.AddProfile<CollectionMapperProfile>();
cfg.AddProfile<DeviceMapperProfile>();
cfg.AddProfile<EmergencyAccessMapperProfile>();
cfg.AddProfile<EventMapperProfile>();
cfg.AddProfile<FolderMapperProfile>();
cfg.AddProfile<GrantMapperProfile>();
cfg.AddProfile<GroupMapperProfile>();
cfg.AddProfile<GroupUserMapperProfile>();
cfg.AddProfile<InstallationMapperProfile>();
cfg.AddProfile<OrganizationMapperProfile>();
cfg.AddProfile<OrganizationSponsorshipMapperProfile>();
cfg.AddProfile<OrganizationUserMapperProfile>();
cfg.AddProfile<ProviderMapperProfile>();
cfg.AddProfile<ProviderUserMapperProfile>();
cfg.AddProfile<ProviderOrganizationMapperProfile>();
cfg.AddProfile<PolicyMapperProfile>();
cfg.AddProfile<SendMapperProfile>();
cfg.AddProfile<SsoConfigMapperProfile>();
cfg.AddProfile<SsoUserMapperProfile>();
cfg.AddProfile<TaxRateMapperProfile>();
cfg.AddProfile<TransactionMapperProfile>();
cfg.AddProfile<UserMapperProfile>();
})
.CreateMapper()));
var repo = fixture.Create<T>();
list.Add(repo);
}
return list;
}
}
public class IgnoreVirtualMembersCustomization : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
var pi = request as PropertyInfo;
if (pi == null)
{
return new NoSpecimen();
}
if (pi.GetGetMethod().IsVirtual && pi.DeclaringType != typeof(GlobalSettings))
{
return null;
}
return new NoSpecimen();
}
}
}

View File

@ -0,0 +1,57 @@
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture.Relays;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class EventBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != typeof(Event))
{
return new NoSpecimen();
}
var fixture = new Fixture();
fixture.Customizations.Insert(0, new MaxLengthStringRelay());
var obj = fixture.WithAutoNSubstitutions().Create<Event>();
return obj;
}
}
internal class EfEvent : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new EventBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<EventRepository>());
}
}
internal class EfEventAutoDataAttribute : CustomAutoDataAttribute
{
public EfEventAutoDataAttribute() : base(new SutProviderCustomization(), new EfEvent())
{ }
}
internal class InlineEfEventAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfEventAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfEvent) }, values)
{ }
}
}

View File

@ -0,0 +1,60 @@
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.UserFixtures;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture.Relays;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class FolderBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != typeof(Folder))
{
return new NoSpecimen();
}
var fixture = new Fixture();
fixture.Customizations.Insert(0, new MaxLengthStringRelay());
var obj = fixture.WithAutoNSubstitutions().Create<Folder>();
return obj;
}
}
internal class EfFolder : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new FolderBuilder());
fixture.Customizations.Add(new UserBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<FolderRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<UserRepository>());
}
}
internal class EfFolderAutoDataAttribute : CustomAutoDataAttribute
{
public EfFolderAutoDataAttribute() : base(new SutProviderCustomization(), new EfFolder())
{ }
}
internal class InlineEfFolderAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfFolderAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfFolder) }, values)
{ }
}
}

View File

@ -0,0 +1,56 @@
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture.Relays;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class GrantBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != typeof(Grant))
{
return new NoSpecimen();
}
var fixture = new Fixture();
fixture.Customizations.Insert(0, new MaxLengthStringRelay());
var obj = fixture.WithAutoNSubstitutions().Create<Grant>();
return obj;
}
}
internal class EfGrant : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new GrantBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<GrantRepository>());
}
}
internal class EfGrantAutoDataAttribute : CustomAutoDataAttribute
{
public EfGrantAutoDataAttribute() : base(new SutProviderCustomization(), new EfGrant())
{ }
}
internal class InlineEfGrantAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfGrantAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfGrant) }, values)
{ }
}
}

View File

@ -0,0 +1,58 @@
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture.Relays;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class GroupBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != typeof(Group))
{
return new NoSpecimen();
}
var fixture = new Fixture();
fixture.Customizations.Insert(0, new MaxLengthStringRelay());
var obj = fixture.WithAutoNSubstitutions().Create<Group>();
return obj;
}
}
internal class EfGroup : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new GroupBuilder());
fixture.Customizations.Add(new OrganizationBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<GroupRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<OrganizationRepository>());
}
}
internal class EfGroupAutoDataAttribute : CustomAutoDataAttribute
{
public EfGroupAutoDataAttribute() : base(new SutProviderCustomization(), new EfGroup())
{ }
}
internal class InlineEfGroupAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfGroupAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfGroup) }, values)
{ }
}
}

View File

@ -0,0 +1,55 @@
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class GroupUserBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != typeof(GroupUser))
{
return new NoSpecimen();
}
var fixture = new Fixture();
var obj = fixture.WithAutoNSubstitutions().Create<GroupUser>();
return obj;
}
}
internal class EfGroupUser : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new GroupUserBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<GroupRepository>());
}
}
internal class EfGroupUserAutoDataAttribute : CustomAutoDataAttribute
{
public EfGroupUserAutoDataAttribute() : base(new SutProviderCustomization(), new EfGroupUser())
{ }
}
internal class InlineEfGroupUserAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfGroupUserAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfGroupUser) }, values)
{ }
}
}

View File

@ -0,0 +1,55 @@
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class InstallationBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != typeof(Installation))
{
return new NoSpecimen();
}
var fixture = new Fixture();
var obj = fixture.WithAutoNSubstitutions().Create<Installation>();
return obj;
}
}
internal class EfInstallation : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new InstallationBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<InstallationRepository>());
}
}
internal class EfInstallationAutoDataAttribute : CustomAutoDataAttribute
{
public EfInstallationAutoDataAttribute() : base(new SutProviderCustomization(), new EfInstallation())
{ }
}
internal class InlineEfInstallationAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfInstallationAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfInstallation) }, values)
{ }
}
}

View File

@ -0,0 +1,58 @@
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Models;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class OrganizationBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != typeof(Organization))
{
return new NoSpecimen();
}
var fixture = new Fixture();
var providers = fixture.Create<Dictionary<TwoFactorProviderType, TwoFactorProvider>>();
var organization = new Fixture().WithAutoNSubstitutions().Create<Organization>();
organization.SetTwoFactorProviders(providers);
return organization;
}
}
internal class EfOrganization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new OrganizationBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<OrganizationRepository>());
}
}
internal class EfOrganizationAutoDataAttribute : CustomAutoDataAttribute
{
public EfOrganizationAutoDataAttribute() : base(new SutProviderCustomization(), new EfOrganization())
{ }
}
internal class InlineEfOrganizationAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfOrganizationAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfOrganization) }, values)
{ }
}
}

View File

@ -0,0 +1,56 @@
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class OrganizationSponsorshipBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != typeof(OrganizationSponsorship))
{
return new NoSpecimen();
}
var fixture = new Fixture();
var obj = fixture.WithAutoNSubstitutions().Create<OrganizationSponsorship>();
return obj;
}
}
internal class EfOrganizationSponsorship : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new OrganizationSponsorshipBuilder());
fixture.Customizations.Add(new OrganizationUserBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<OrganizationSponsorshipRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<OrganizationRepository>());
}
}
internal class EfOrganizationSponsorshipAutoDataAttribute : CustomAutoDataAttribute
{
public EfOrganizationSponsorshipAutoDataAttribute() : base(new SutProviderCustomization(), new EfOrganizationSponsorship(), new EfOrganization())
{ }
}
internal class InlineEfOrganizationSponsorshipAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfOrganizationSponsorshipAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfOrganizationSponsorship), typeof(EfOrganization) }, values)
{ }
}
}

View File

@ -0,0 +1,83 @@
using System.Text.Json;
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Models;
using Bit.Core.Models.Data;
using Bit.Core.Test.AutoFixture.OrganizationUserFixtures;
using Bit.Core.Test.AutoFixture.UserFixtures;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class OrganizationUserBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == typeof(OrganizationUserCustomization))
{
var fixture = new Fixture();
var orgUser = fixture.WithAutoNSubstitutions().Create<OrganizationUser>();
var orgUserPermissions = fixture.WithAutoNSubstitutions().Create<Permissions>();
orgUser.Permissions = JsonSerializer.Serialize(orgUserPermissions, new JsonSerializerOptions()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
});
return orgUser;
}
else if (type == typeof(List<OrganizationUserCustomization>))
{
var fixture = new Fixture();
var orgUsers = fixture.WithAutoNSubstitutions().CreateMany<OrganizationUser>(2);
foreach (var orgUser in orgUsers)
{
var providers = fixture.Create<Dictionary<TwoFactorProviderType, TwoFactorProvider>>();
var orgUserPermissions = fixture.WithAutoNSubstitutions().Create<Permissions>();
orgUser.Permissions = JsonSerializer.Serialize(orgUserPermissions, new JsonSerializerOptions()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
});
}
return orgUsers;
}
return new NoSpecimen();
}
}
internal class EfOrganizationUser : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new OrganizationUserBuilder());
fixture.Customizations.Add(new OrganizationBuilder());
fixture.Customizations.Add(new UserBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<OrganizationUserRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<UserRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<OrganizationRepository>());
}
}
internal class EfOrganizationUserAutoDataAttribute : CustomAutoDataAttribute
{
public EfOrganizationUserAutoDataAttribute() : base(new SutProviderCustomization(), new EfOrganizationUser())
{ }
}
internal class InlineEfOrganizationUserAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfOrganizationUserAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfOrganizationUser) }, values)
{ }
}
}

View File

@ -0,0 +1,80 @@
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class PolicyBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != typeof(Policy))
{
return new NoSpecimen();
}
var fixture = new Fixture();
var obj = fixture.WithAutoNSubstitutions().Create<Policy>();
return obj;
}
}
internal class EfPolicy : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new PolicyBuilder());
fixture.Customizations.Add(new OrganizationBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<PolicyRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<OrganizationRepository>());
}
}
internal class EfPolicyApplicableToUser : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new PolicyBuilder());
fixture.Customizations.Add(new OrganizationBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<PolicyRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<UserRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<OrganizationRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<OrganizationUserRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<ProviderRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<ProviderUserRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<ProviderOrganizationRepository>());
}
}
internal class EfPolicyAutoDataAttribute : CustomAutoDataAttribute
{
public EfPolicyAutoDataAttribute() : base(new SutProviderCustomization(), new EfPolicy())
{ }
}
internal class EfPolicyApplicableToUserInlineAutoDataAttribute : InlineCustomAutoDataAttribute
{
public EfPolicyApplicableToUserInlineAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization), typeof(EfPolicyApplicableToUser) }, values)
{ }
}
internal class InlineEfPolicyAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfPolicyAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfPolicy) }, values)
{ }
}
}

View File

@ -0,0 +1,41 @@
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using AutoFixture.Kernel;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture.Relays
{
// Creates a string the same length as any availible MaxLength data annotation
// Modified version of the StringLenfthRelay provided by AutoFixture
// https://github.com/AutoFixture/AutoFixture/blob/master/Src/AutoFixture/DataAnnotations/StringLengthAttributeRelay.cs
public class MaxLengthStringRelay : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (request == null)
{
return new NoSpecimen();
}
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var p = request as PropertyInfo;
if (p == null)
{
return new NoSpecimen();
}
var a = (MaxLengthAttribute)p.GetCustomAttributes(typeof(MaxLengthAttribute), false).SingleOrDefault();
if (a == null)
{
return new NoSpecimen();
}
return context.Resolve(new ConstrainedStringRequest(a.Length, a.Length));
}
}
}

View File

@ -0,0 +1,70 @@
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.UserFixtures;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture.Relays;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class SendBuilder : ISpecimenBuilder
{
public bool OrganizationOwned { get; set; }
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != typeof(Send))
{
return new NoSpecimen();
}
var fixture = new Fixture();
fixture.Customizations.Insert(0, new MaxLengthStringRelay());
if (!OrganizationOwned)
{
fixture.Customize<Send>(composer => composer
.Without(c => c.OrganizationId));
}
var obj = fixture.WithAutoNSubstitutions().Create<Send>();
return obj;
}
}
internal class EfSend : ICustomization
{
public bool OrganizationOwned { get; set; }
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new SendBuilder());
fixture.Customizations.Add(new UserBuilder());
fixture.Customizations.Add(new OrganizationBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<SendRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<UserRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<OrganizationRepository>());
}
}
internal class EfUserSendAutoDataAttribute : CustomAutoDataAttribute
{
public EfUserSendAutoDataAttribute() : base(new SutProviderCustomization(), new EfSend())
{ }
}
internal class EfOrganizationSendAutoDataAttribute : CustomAutoDataAttribute
{
public EfOrganizationSendAutoDataAttribute() : base(new SutProviderCustomization(), new EfSend()
{
OrganizationOwned = true,
})
{ }
}
}

View File

@ -0,0 +1,59 @@
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Core.Models.Data;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class SsoConfigBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != typeof(SsoConfig))
{
return new NoSpecimen();
}
var fixture = new Fixture();
var ssoConfig = fixture.WithAutoNSubstitutions().Create<SsoConfig>();
var ssoConfigData = fixture.WithAutoNSubstitutions().Create<SsoConfigurationData>();
ssoConfig.SetData(ssoConfigData);
return ssoConfig;
}
}
internal class EfSsoConfig : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new OrganizationBuilder());
fixture.Customizations.Add(new SsoConfigBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<SsoConfigRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<OrganizationRepository>());
}
}
internal class EfSsoConfigAutoDataAttribute : CustomAutoDataAttribute
{
public EfSsoConfigAutoDataAttribute() : base(new SutProviderCustomization(), new EfSsoConfig())
{ }
}
internal class InlineEfSsoConfigAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfSsoConfigAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfSsoConfig) }, values)
{ }
}
}

View File

@ -0,0 +1,37 @@
using AutoFixture;
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.UserFixtures;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class EfSsoUser : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new UserBuilder());
fixture.Customizations.Add(new OrganizationBuilder());
fixture.Customize<SsoUser>(composer => composer.Without(ou => ou.Id));
fixture.Customizations.Add(new EfRepositoryListBuilder<SsoUserRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<UserRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<OrganizationRepository>());
}
}
internal class EfSsoUserAutoDataAttribute : CustomAutoDataAttribute
{
public EfSsoUserAutoDataAttribute() : base(new SutProviderCustomization(), new EfSsoUser())
{ }
}
internal class InlineEfSsoUserAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfSsoUserAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfSsoUser) }, values)
{ }
}
}

View File

@ -0,0 +1,57 @@
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Entities;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture.Relays;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class TaxRateBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != typeof(TaxRate))
{
return new NoSpecimen();
}
var fixture = new Fixture();
fixture.Customizations.Insert(0, new MaxLengthStringRelay());
var obj = fixture.WithAutoNSubstitutions().Create<TaxRate>();
return obj;
}
}
internal class EfTaxRate : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new TaxRateBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<TaxRateRepository>());
}
}
internal class EfTaxRateAutoDataAttribute : CustomAutoDataAttribute
{
public EfTaxRateAutoDataAttribute() : base(new SutProviderCustomization(), new EfTaxRate())
{ }
}
internal class InlineEfTaxRateAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfTaxRateAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfTaxRate) }, values)
{ }
}
}

View File

@ -0,0 +1,70 @@
using AutoFixture;
using AutoFixture.Kernel;
using Bit.Core.Test.AutoFixture.UserFixtures;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture.Relays;
using Bit.Infrastructure.EntityFramework.Models;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class TransactionBuilder : ISpecimenBuilder
{
public bool OrganizationOwned { get; set; }
public object Create(object request, ISpecimenContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var type = request as Type;
if (type == null || type != typeof(Transaction))
{
return new NoSpecimen();
}
var fixture = new Fixture();
if (!OrganizationOwned)
{
fixture.Customize<Transaction>(composer => composer
.Without(c => c.OrganizationId));
}
fixture.Customizations.Add(new MaxLengthStringRelay());
var obj = fixture.WithAutoNSubstitutions().Create<Transaction>();
return obj;
}
}
internal class EfTransaction : ICustomization
{
public bool OrganizationOwned { get; set; }
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
fixture.Customizations.Add(new GlobalSettingsBuilder());
fixture.Customizations.Add(new TransactionBuilder());
fixture.Customizations.Add(new UserBuilder());
fixture.Customizations.Add(new OrganizationBuilder());
fixture.Customizations.Add(new EfRepositoryListBuilder<TransactionRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<UserRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<OrganizationRepository>());
}
}
internal class EfUserTransactionAutoDataAttribute : CustomAutoDataAttribute
{
public EfUserTransactionAutoDataAttribute() : base(new SutProviderCustomization(), new EfTransaction())
{ }
}
internal class EfOrganizationTransactionAutoDataAttribute : CustomAutoDataAttribute
{
public EfOrganizationTransactionAutoDataAttribute() : base(new SutProviderCustomization(), new EfTransaction()
{
OrganizationOwned = true,
})
{ }
}
}

View File

@ -0,0 +1,32 @@
using AutoFixture;
using Bit.Core.Test.AutoFixture.UserFixtures;
using Bit.Infrastructure.EntityFramework.Repositories;
using Bit.Test.Common.AutoFixture.Attributes;
namespace Bit.Infrastructure.EFIntegration.Test.AutoFixture
{
internal class EfUser : UserFixture
{
public override void Customize(IFixture fixture)
{
fixture.Customizations.Add(new IgnoreVirtualMembersCustomization());
base.Customize(fixture);
fixture.Customizations.Add(new EfRepositoryListBuilder<UserRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<SsoUserRepository>());
fixture.Customizations.Add(new EfRepositoryListBuilder<OrganizationRepository>());
}
}
internal class EfUserAutoDataAttribute : CustomAutoDataAttribute
{
public EfUserAutoDataAttribute() : base(new SutProviderCustomization(), new EfUser())
{ }
}
internal class InlineEfUserAutoDataAttribute : InlineCustomAutoDataAttribute
{
public InlineEfUserAutoDataAttribute(params object[] values) : base(new[] { typeof(SutProviderCustomization),
typeof(EfUser) }, values)
{ }
}
}

View File

@ -0,0 +1,26 @@
using Bit.Core.Test.Helpers.Factories;
using Bit.Infrastructure.EntityFramework.Repositories;
using Microsoft.EntityFrameworkCore;
namespace Bit.Infrastructure.EFIntegration.Test.Helpers
{
public static class DatabaseOptionsFactory
{
public static List<DbContextOptions<DatabaseContext>> Options { get; } = new();
static DatabaseOptionsFactory()
{
var globalSettings = GlobalSettingsFactory.GlobalSettings;
if (!string.IsNullOrWhiteSpace(GlobalSettingsFactory.GlobalSettings.PostgreSql?.ConnectionString))
{
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
Options.Add(new DbContextOptionsBuilder<DatabaseContext>().UseNpgsql(globalSettings.PostgreSql.ConnectionString).Options);
}
if (!string.IsNullOrWhiteSpace(GlobalSettingsFactory.GlobalSettings.MySql?.ConnectionString))
{
var mySqlConnectionString = globalSettings.MySql.ConnectionString;
Options.Add(new DbContextOptionsBuilder<DatabaseContext>().UseMySql(mySqlConnectionString, ServerVersion.AutoDetect(mySqlConnectionString)).Options);
}
}
}
}

View File

@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="$(CoverletCollectorVersion)">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNetTestSdkVersion)" />
<PackageReference Include="Moq" Version="4.17.2" />
<PackageReference Include="NSubstitute" Version="$(NSubstitueVersion)" />
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(XUnitRunnerVisualStudioVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="AutoFixture.Xunit2" Version="$(AutoFixtureXUnit2Version)" />
<PackageReference Include="AutoFixture.AutoNSubstitute" Version="$(AutoFixtureAutoNSubstituteVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Infrastructure.Dapper\Infrastructure.Dapper.csproj" />
<ProjectReference Include="..\..\src\Infrastructure.EntityFramework\Infrastructure.EntityFramework.csproj" />
<ProjectReference Include="..\Common\Common.csproj" />
<ProjectReference Include="..\Core.Test\Core.Test.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="AutoFixture" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,192 @@
using Bit.Core.Entities;
using Bit.Core.Models.Data;
using Bit.Core.Test.AutoFixture.Attributes;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
using Bit.Infrastructure.EntityFramework.Repositories.Queries;
using LinqToDB;
using Xunit;
using EfRepo = Bit.Infrastructure.EntityFramework.Repositories;
using SqlRepo = Bit.Infrastructure.Dapper.Repositories;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories
{
public class CipherRepositoryTests
{
[Theory(Skip = "Run ad-hoc"), EfUserCipherAutoData]
public async void RefreshDb(List<EfRepo.CipherRepository> suts)
{
foreach (var sut in suts)
{
await sut.RefreshDb();
}
}
[CiSkippedTheory, EfUserCipherAutoData, EfOrganizationCipherAutoData]
public async void CreateAsync_Works_DataMatches(Cipher cipher, User user, Organization org,
CipherCompare equalityComparer, List<EfRepo.CipherRepository> suts, List<EfRepo.UserRepository> efUserRepos,
List<EfRepo.OrganizationRepository> efOrgRepos, SqlRepo.CipherRepository sqlCipherRepo,
SqlRepo.UserRepository sqlUserRepo, SqlRepo.OrganizationRepository sqlOrgRepo)
{
var savedCiphers = new List<Cipher>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var efUser = await efUserRepos[i].CreateAsync(user);
sut.ClearChangeTracking();
cipher.UserId = efUser.Id;
if (cipher.OrganizationId.HasValue)
{
var efOrg = await efOrgRepos[i].CreateAsync(org);
sut.ClearChangeTracking();
cipher.OrganizationId = efOrg.Id;
}
var postEfCipher = await sut.CreateAsync(cipher);
sut.ClearChangeTracking();
var savedCipher = await sut.GetByIdAsync(postEfCipher.Id);
savedCiphers.Add(savedCipher);
}
var sqlUser = await sqlUserRepo.CreateAsync(user);
cipher.UserId = sqlUser.Id;
if (cipher.OrganizationId.HasValue)
{
var sqlOrg = await sqlOrgRepo.CreateAsync(org);
cipher.OrganizationId = sqlOrg.Id;
}
var sqlCipher = await sqlCipherRepo.CreateAsync(cipher);
var savedSqlCipher = await sqlCipherRepo.GetByIdAsync(sqlCipher.Id);
savedCiphers.Add(savedSqlCipher);
var distinctItems = savedCiphers.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
[CiSkippedTheory, EfUserCipherAutoData]
public async void CreateAsync_BumpsUserAccountRevisionDate(Cipher cipher, User user, List<EfRepo.CipherRepository> suts, List<EfRepo.UserRepository> efUserRepos)
{
var bumpedUsers = new List<User>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var efUser = await efUserRepos[i].CreateAsync(user);
efUserRepos[i].ClearChangeTracking();
cipher.UserId = efUser.Id;
cipher.OrganizationId = null;
var postEfCipher = await sut.CreateAsync(cipher);
sut.ClearChangeTracking();
var bumpedUser = await efUserRepos[i].GetByIdAsync(efUser.Id);
bumpedUsers.Add(bumpedUser);
}
Assert.True(bumpedUsers.All(u => u.AccountRevisionDate.ToShortDateString() == DateTime.UtcNow.ToShortDateString()));
}
[CiSkippedTheory, EfOrganizationCipherAutoData]
public async void CreateAsync_BumpsOrgUserAccountRevisionDates(Cipher cipher, List<User> users,
List<OrganizationUser> orgUsers, Collection collection, Organization org, List<EfRepo.CipherRepository> suts, List<EfRepo.UserRepository> efUserRepos, List<EfRepo.OrganizationRepository> efOrgRepos,
List<EfRepo.OrganizationUserRepository> efOrgUserRepos, List<EfRepo.CollectionRepository> efCollectionRepos)
{
var savedCiphers = new List<Cipher>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var efUsers = await efUserRepos[i].CreateMany(users);
efUserRepos[i].ClearChangeTracking();
var efOrg = await efOrgRepos[i].CreateAsync(org);
efOrgRepos[i].ClearChangeTracking();
cipher.OrganizationId = efOrg.Id;
collection.OrganizationId = efOrg.Id;
var efCollection = await efCollectionRepos[i].CreateAsync(collection);
efCollectionRepos[i].ClearChangeTracking();
IEnumerable<object>[] lists = { efUsers, orgUsers };
var maxOrgUsers = lists.Min(l => l.Count());
orgUsers = orgUsers.Take(maxOrgUsers).ToList();
efUsers = efUsers.Take(maxOrgUsers).ToList();
for (var j = 0; j < maxOrgUsers; j++)
{
orgUsers[j].OrganizationId = efOrg.Id;
orgUsers[j].UserId = efUsers[j].Id;
}
orgUsers = await efOrgUserRepos[i].CreateMany(orgUsers);
var selectionReadOnlyList = new List<SelectionReadOnly>();
orgUsers.ForEach(ou => selectionReadOnlyList.Add(new SelectionReadOnly() { Id = ou.Id }));
await efCollectionRepos[i].UpdateUsersAsync(efCollection.Id, selectionReadOnlyList);
efCollectionRepos[i].ClearChangeTracking();
foreach (var ou in orgUsers)
{
var collectionUser = new CollectionUser()
{
CollectionId = efCollection.Id,
OrganizationUserId = ou.Id
};
}
cipher.UserId = null;
var postEfCipher = await sut.CreateAsync(cipher);
sut.ClearChangeTracking();
var query = new UserBumpAccountRevisionDateByCipherIdQuery(cipher);
var modifiedUsers = await sut.Run(query).ToListAsync();
Assert.True(modifiedUsers
.All(u => u.AccountRevisionDate.ToShortDateString() ==
DateTime.UtcNow.ToShortDateString()));
}
}
[CiSkippedTheory, EfUserCipherAutoData, EfOrganizationCipherAutoData]
public async void DeleteAsync_CipherIsDeleted(
Cipher cipher,
User user,
Organization org,
List<EfRepo.CipherRepository> suts,
List<EfRepo.UserRepository> efUserRepos,
List<EfRepo.OrganizationRepository> efOrgRepos
)
{
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var postEfOrg = await efOrgRepos[i].CreateAsync(org);
efOrgRepos[i].ClearChangeTracking();
var postEfUser = await efUserRepos[i].CreateAsync(user);
efUserRepos[i].ClearChangeTracking();
if (cipher.OrganizationId.HasValue)
{
cipher.OrganizationId = postEfOrg.Id;
}
cipher.UserId = postEfUser.Id;
await sut.CreateAsync(cipher);
sut.ClearChangeTracking();
await sut.DeleteAsync(cipher);
sut.ClearChangeTracking();
var savedCipher = await sut.GetByIdAsync(cipher.Id);
Assert.True(savedCipher == null);
}
}
}
}

View File

@ -0,0 +1,50 @@
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.Attributes;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
using Xunit;
using EfRepo = Bit.Infrastructure.EntityFramework.Repositories;
using SqlRepo = Bit.Infrastructure.Dapper.Repositories;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories
{
public class CollectionRepositoryTests
{
[CiSkippedTheory, EfCollectionAutoData]
public async void CreateAsync_Works_DataMatches(
Collection collection,
Organization organization,
CollectionCompare equalityComparer,
List<EfRepo.CollectionRepository> suts,
List<EfRepo.OrganizationRepository> efOrganizationRepos,
SqlRepo.CollectionRepository sqlCollectionRepo,
SqlRepo.OrganizationRepository sqlOrganizationRepo
)
{
var savedCollections = new List<Collection>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var efOrganization = await efOrganizationRepos[i].CreateAsync(organization);
sut.ClearChangeTracking();
collection.OrganizationId = efOrganization.Id;
var postEfCollection = await sut.CreateAsync(collection);
sut.ClearChangeTracking();
var savedCollection = await sut.GetByIdAsync(postEfCollection.Id);
savedCollections.Add(savedCollection);
}
var sqlOrganization = await sqlOrganizationRepo.CreateAsync(organization);
collection.OrganizationId = sqlOrganization.Id;
var sqlCollection = await sqlCollectionRepo.CreateAsync(collection);
var savedSqlCollection = await sqlCollectionRepo.GetByIdAsync(sqlCollection.Id);
savedCollections.Add(savedSqlCollection);
var distinctItems = savedCollections.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
}
}

View File

@ -0,0 +1,47 @@
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.Attributes;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
using Xunit;
using EfRepo = Bit.Infrastructure.EntityFramework.Repositories;
using SqlRepo = Bit.Infrastructure.Dapper.Repositories;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories
{
public class DeviceRepositoryTests
{
[CiSkippedTheory, EfDeviceAutoData]
public async void CreateAsync_Works_DataMatches(Device device, User user,
DeviceCompare equalityComparer, List<EfRepo.DeviceRepository> suts,
List<EfRepo.UserRepository> efUserRepos, SqlRepo.DeviceRepository sqlDeviceRepo,
SqlRepo.UserRepository sqlUserRepo)
{
var savedDevices = new List<Device>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var efUser = await efUserRepos[i].CreateAsync(user);
device.UserId = efUser.Id;
sut.ClearChangeTracking();
var postEfDevice = await sut.CreateAsync(device);
sut.ClearChangeTracking();
var savedDevice = await sut.GetByIdAsync(postEfDevice.Id);
savedDevices.Add(savedDevice);
}
var sqlUser = await sqlUserRepo.CreateAsync(user);
device.UserId = sqlUser.Id;
var sqlDevice = await sqlDeviceRepo.CreateAsync(device);
var savedSqlDevice = await sqlDeviceRepo.GetByIdAsync(sqlDevice.Id);
savedDevices.Add(savedSqlDevice);
var distinctItems = savedDevices.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
}
}

View File

@ -0,0 +1,59 @@
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.Attributes;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
using Xunit;
using EfRepo = Bit.Infrastructure.EntityFramework.Repositories;
using SqlRepo = Bit.Infrastructure.Dapper.Repositories;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories
{
public class EmergencyAccessRepositoryTests
{
[CiSkippedTheory, EfEmergencyAccessAutoData]
public async void CreateAsync_Works_DataMatches(
EmergencyAccess emergencyAccess,
List<User> users,
EmergencyAccessCompare equalityComparer,
List<EfRepo.EmergencyAccessRepository> suts,
List<EfRepo.UserRepository> efUserRepos,
SqlRepo.EmergencyAccessRepository sqlEmergencyAccessRepo,
SqlRepo.UserRepository sqlUserRepo
)
{
var savedEmergencyAccesss = new List<EmergencyAccess>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
for (int j = 0; j < users.Count; j++)
{
users[j] = await efUserRepos[i].CreateAsync(users[j]);
}
sut.ClearChangeTracking();
emergencyAccess.GrantorId = users[0].Id;
emergencyAccess.GranteeId = users[0].Id;
var postEfEmergencyAccess = await sut.CreateAsync(emergencyAccess);
sut.ClearChangeTracking();
var savedEmergencyAccess = await sut.GetByIdAsync(postEfEmergencyAccess.Id);
savedEmergencyAccesss.Add(savedEmergencyAccess);
}
for (int j = 0; j < users.Count; j++)
{
users[j] = await sqlUserRepo.CreateAsync(users[j]);
}
emergencyAccess.GrantorId = users[0].Id;
emergencyAccess.GranteeId = users[0].Id;
var sqlEmergencyAccess = await sqlEmergencyAccessRepo.CreateAsync(emergencyAccess);
var savedSqlEmergencyAccess = await sqlEmergencyAccessRepo.GetByIdAsync(sqlEmergencyAccess.Id);
savedEmergencyAccesss.Add(savedSqlEmergencyAccess);
var distinctItems = savedEmergencyAccesss.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
}
}

View File

@ -0,0 +1,21 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class CipherCompare : IEqualityComparer<Cipher>
{
public bool Equals(Cipher x, Cipher y)
{
return x.Type == y.Type &&
x.Data == y.Data &&
x.Favorites == y.Favorites &&
x.Attachments == y.Attachments;
}
public int GetHashCode([DisallowNull] Cipher obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,19 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class CollectionCompare : IEqualityComparer<Collection>
{
public bool Equals(Collection x, Collection y)
{
return x.Name == y.Name &&
x.ExternalId == y.ExternalId;
}
public int GetHashCode([DisallowNull] Collection obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,21 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class DeviceCompare : IEqualityComparer<Device>
{
public bool Equals(Device x, Device y)
{
return x.Name == y.Name &&
x.Type == y.Type &&
x.Identifier == y.Identifier &&
x.PushToken == y.PushToken;
}
public int GetHashCode([DisallowNull] Device obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,24 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class EmergencyAccessCompare : IEqualityComparer<EmergencyAccess>
{
public bool Equals(EmergencyAccess x, EmergencyAccess y)
{
return x.Email == y.Email &&
x.KeyEncrypted == y.KeyEncrypted &&
x.Type == y.Type &&
x.Status == y.Status &&
x.WaitTimeDays == y.WaitTimeDays &&
x.RecoveryInitiatedDate == y.RecoveryInitiatedDate &&
x.LastNotificationDate == y.LastNotificationDate;
}
public int GetHashCode([DisallowNull] EmergencyAccess obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,20 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class EventCompare : IEqualityComparer<Event>
{
public bool Equals(Event x, Event y)
{
return x.Date.ToShortDateString() == y.Date.ToShortDateString() &&
x.Type == y.Type &&
x.IpAddress == y.IpAddress;
}
public int GetHashCode([DisallowNull] Event obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,18 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class FolderCompare : IEqualityComparer<Folder>
{
public bool Equals(Folder x, Folder y)
{
return x.Name == y.Name;
}
public int GetHashCode([DisallowNull] Folder obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,25 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class GrantCompare : IEqualityComparer<Grant>
{
public bool Equals(Grant x, Grant y)
{
return x.Key == y.Key &&
x.Type == y.Type &&
x.SubjectId == y.SubjectId &&
x.ClientId == y.ClientId &&
x.Description == y.Description &&
x.ExpirationDate == y.ExpirationDate &&
x.ConsumedDate == y.ConsumedDate &&
x.Data == y.Data;
}
public int GetHashCode([DisallowNull] Grant obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,20 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class GroupCompare : IEqualityComparer<Group>
{
public bool Equals(Group x, Group y)
{
return x.Name == y.Name &&
x.AccessAll == y.AccessAll &&
x.ExternalId == y.ExternalId;
}
public int GetHashCode([DisallowNull] Group obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,20 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class InstallationCompare : IEqualityComparer<Installation>
{
public bool Equals(Installation x, Installation y)
{
return x.Email == y.Email &&
x.Key == y.Key &&
x.Enabled == y.Enabled;
}
public int GetHashCode([DisallowNull] Installation obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,54 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class OrganizationCompare : IEqualityComparer<Organization>
{
public bool Equals(Organization x, Organization y)
{
var a = x.ExpirationDate.ToString();
var b = y.ExpirationDate.ToString();
return x.Identifier.Equals(y.Identifier) &&
x.Name.Equals(y.Name) &&
x.BusinessName.Equals(y.BusinessName) &&
x.BusinessAddress1.Equals(y.BusinessAddress1) &&
x.BusinessAddress2.Equals(y.BusinessAddress2) &&
x.BusinessAddress3.Equals(y.BusinessAddress3) &&
x.BusinessCountry.Equals(y.BusinessCountry) &&
x.BusinessTaxNumber.Equals(y.BusinessTaxNumber) &&
x.BillingEmail.Equals(y.BillingEmail) &&
x.Plan.Equals(y.Plan) &&
x.PlanType.Equals(y.PlanType) &&
x.Seats.Equals(y.Seats) &&
x.MaxCollections.Equals(y.MaxCollections) &&
x.UsePolicies.Equals(y.UsePolicies) &&
x.UseSso.Equals(y.UseSso) &&
x.UseKeyConnector.Equals(y.UseKeyConnector) &&
x.UseScim.Equals(y.UseScim) &&
x.UseGroups.Equals(y.UseGroups) &&
x.UseDirectory.Equals(y.UseDirectory) &&
x.UseEvents.Equals(y.UseEvents) &&
x.UseTotp.Equals(y.UseTotp) &&
x.Use2fa.Equals(y.Use2fa) &&
x.UseApi.Equals(y.UseApi) &&
x.SelfHost.Equals(y.SelfHost) &&
x.UsersGetPremium.Equals(y.UsersGetPremium) &&
x.Storage.Equals(y.Storage) &&
x.MaxStorageGb.Equals(y.MaxStorageGb) &&
x.Gateway.Equals(y.Gateway) &&
x.GatewayCustomerId.Equals(y.GatewayCustomerId) &&
x.GatewaySubscriptionId.Equals(y.GatewaySubscriptionId) &&
x.ReferenceData.Equals(y.ReferenceData) &&
x.Enabled.Equals(y.Enabled) &&
x.LicenseKey.Equals(y.LicenseKey) &&
x.TwoFactorProviders.Equals(y.TwoFactorProviders) &&
x.ExpirationDate.ToString().Equals(y.ExpirationDate.ToString());
}
public int GetHashCode([DisallowNull] Organization obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,23 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class OrganizationSponsorshipCompare : IEqualityComparer<OrganizationSponsorship>
{
public bool Equals(OrganizationSponsorship x, OrganizationSponsorship y)
{
return x.SponsoringOrganizationId.Equals(y.SponsoringOrganizationId) &&
x.SponsoringOrganizationUserId.Equals(y.SponsoringOrganizationUserId) &&
x.SponsoredOrganizationId.Equals(y.SponsoredOrganizationId) &&
x.OfferedToEmail.Equals(y.OfferedToEmail) &&
x.ToDelete.Equals(y.ToDelete) &&
x.ValidUntil.ToString().Equals(y.ValidUntil.ToString());
}
public int GetHashCode([DisallowNull] OrganizationSponsorship obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,23 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class OrganizationUserCompare : IEqualityComparer<OrganizationUser>
{
public bool Equals(OrganizationUser x, OrganizationUser y)
{
return x.Email == y.Email &&
x.Status == y.Status &&
x.Type == y.Type &&
x.AccessAll == y.AccessAll &&
x.ExternalId == y.ExternalId &&
x.Permissions == y.Permissions;
}
public int GetHashCode([DisallowNull] OrganizationUser obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,29 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class PolicyCompare : IEqualityComparer<Policy>
{
public bool Equals(Policy x, Policy y)
{
return x.Type == y.Type &&
x.Data == y.Data &&
x.Enabled == y.Enabled;
}
public int GetHashCode([DisallowNull] Policy obj)
{
return base.GetHashCode();
}
}
public class PolicyCompareIncludingOrganization : PolicyCompare
{
public new bool Equals(Policy x, Policy y)
{
return base.Equals(x, y) &&
x.OrganizationId == y.OrganizationId;
}
}
}

View File

@ -0,0 +1,27 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class SendCompare : IEqualityComparer<Send>
{
public bool Equals(Send x, Send y)
{
return x.Type == y.Type &&
x.Data == y.Data &&
x.Key == y.Key &&
x.Password == y.Password &&
x.MaxAccessCount == y.MaxAccessCount &&
x.AccessCount == y.AccessCount &&
x.ExpirationDate?.ToShortDateString() == y.ExpirationDate?.ToShortDateString() &&
x.DeletionDate.ToShortDateString() == y.DeletionDate.ToShortDateString() &&
x.Disabled == y.Disabled &&
x.HideEmail == y.HideEmail;
}
public int GetHashCode([DisallowNull] Send obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,20 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class SsoConfigCompare : IEqualityComparer<SsoConfig>
{
public bool Equals(SsoConfig x, SsoConfig y)
{
return x.Enabled == y.Enabled &&
x.OrganizationId == y.OrganizationId &&
x.Data == y.Data;
}
public int GetHashCode([DisallowNull] SsoConfig obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,18 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class SsoUserCompare : IEqualityComparer<SsoUser>
{
public bool Equals(SsoUser x, SsoUser y)
{
return x.ExternalId == y.ExternalId;
}
public int GetHashCode([DisallowNull] SsoUser obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,22 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class TaxRateCompare : IEqualityComparer<TaxRate>
{
public bool Equals(TaxRate x, TaxRate y)
{
return x.Country == y.Country &&
x.State == y.State &&
x.PostalCode == y.PostalCode &&
x.Rate == y.Rate &&
x.Active == y.Active;
}
public int GetHashCode([DisallowNull] TaxRate obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,24 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class TransactionCompare : IEqualityComparer<Transaction>
{
public bool Equals(Transaction x, Transaction y)
{
return x.Type == y.Type &&
x.Amount == y.Amount &&
x.Refunded == y.Refunded &&
x.Details == y.Details &&
x.PaymentMethodType == y.PaymentMethodType &&
x.Gateway == y.Gateway &&
x.GatewayId == y.GatewayId;
}
public int GetHashCode([DisallowNull] Transaction obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,40 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Entities;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class UserCompare : IEqualityComparer<User>
{
public bool Equals(User x, User y)
{
return x.Name == y.Name &&
x.Email == y.Email &&
x.EmailVerified == y.EmailVerified &&
x.MasterPassword == y.MasterPassword &&
x.MasterPasswordHint == y.MasterPasswordHint &&
x.Culture == y.Culture &&
x.SecurityStamp == y.SecurityStamp &&
x.TwoFactorProviders == y.TwoFactorProviders &&
x.TwoFactorRecoveryCode == y.TwoFactorRecoveryCode &&
x.EquivalentDomains == y.EquivalentDomains &&
x.Key == y.Key &&
x.PublicKey == y.PublicKey &&
x.PrivateKey == y.PrivateKey &&
x.Premium == y.Premium &&
x.Storage == y.Storage &&
x.MaxStorageGb == y.MaxStorageGb &&
x.Gateway == y.Gateway &&
x.GatewayCustomerId == y.GatewayCustomerId &&
x.ReferenceData == y.ReferenceData &&
x.LicenseKey == y.LicenseKey &&
x.ApiKey == y.ApiKey &&
x.Kdf == y.Kdf &&
x.KdfIterations == y.KdfIterations;
}
public int GetHashCode([DisallowNull] User obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,19 @@
using System.Diagnostics.CodeAnalysis;
using Bit.Core.Models.Data;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers
{
public class UserKdfInformationCompare : IEqualityComparer<UserKdfInformation>
{
public bool Equals(UserKdfInformation x, UserKdfInformation y)
{
return x.Kdf == y.Kdf &&
x.KdfIterations == y.KdfIterations;
}
public int GetHashCode([DisallowNull] UserKdfInformation obj)
{
return base.GetHashCode();
}
}
}

View File

@ -0,0 +1,49 @@
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.Attributes;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
using Xunit;
using EfRepo = Bit.Infrastructure.EntityFramework.Repositories;
using SqlRepo = Bit.Infrastructure.Dapper.Repositories;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories
{
public class FolderRepositoryTests
{
[CiSkippedTheory, EfFolderAutoData]
public async void CreateAsync_Works_DataMatches(
Folder folder,
User user,
FolderCompare equalityComparer,
List<EfRepo.FolderRepository> suts,
List<EfRepo.UserRepository> efUserRepos,
SqlRepo.FolderRepository sqlFolderRepo,
SqlRepo.UserRepository sqlUserRepo)
{
var savedFolders = new List<Folder>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var efUser = await efUserRepos[i].CreateAsync(user);
sut.ClearChangeTracking();
folder.UserId = efUser.Id;
var postEfFolder = await sut.CreateAsync(folder);
sut.ClearChangeTracking();
var savedFolder = await sut.GetByIdAsync(folder.Id);
savedFolders.Add(savedFolder);
}
var sqlUser = await sqlUserRepo.CreateAsync(user);
folder.UserId = sqlUser.Id;
var sqlFolder = await sqlFolderRepo.CreateAsync(folder);
savedFolders.Add(await sqlFolderRepo.GetByIdAsync(sqlFolder.Id));
var distinctItems = savedFolders.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
}
}

View File

@ -0,0 +1,39 @@
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.Attributes;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
using Xunit;
using EfRepo = Bit.Infrastructure.EntityFramework.Repositories;
using SqlRepo = Bit.Infrastructure.Dapper.Repositories;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories
{
public class InstallationRepositoryTests
{
[CiSkippedTheory, EfInstallationAutoData]
public async void CreateAsync_Works_DataMatches(
Installation installation,
InstallationCompare equalityComparer,
List<EfRepo.InstallationRepository> suts,
SqlRepo.InstallationRepository sqlInstallationRepo
)
{
var savedInstallations = new List<Installation>();
foreach (var sut in suts)
{
var postEfInstallation = await sut.CreateAsync(installation);
sut.ClearChangeTracking();
var savedInstallation = await sut.GetByIdAsync(postEfInstallation.Id);
savedInstallations.Add(savedInstallation);
}
var sqlInstallation = await sqlInstallationRepo.CreateAsync(installation);
var savedSqlInstallation = await sqlInstallationRepo.GetByIdAsync(sqlInstallation.Id);
savedInstallations.Add(savedSqlInstallation);
var distinctItems = savedInstallations.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
}
}

View File

@ -0,0 +1,150 @@
using Bit.Core.Models.Data.Organizations;
using Bit.Core.Test.AutoFixture.Attributes;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
using Xunit;
using EfRepo = Bit.Infrastructure.EntityFramework.Repositories;
using Organization = Bit.Core.Entities.Organization;
using SqlRepo = Bit.Infrastructure.Dapper.Repositories;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories
{
public class OrganizationRepositoryTests
{
[CiSkippedTheory, EfOrganizationAutoData]
public async void CreateAsync_Works_DataMatches(
Organization organization,
SqlRepo.OrganizationRepository sqlOrganizationRepo, OrganizationCompare equalityComparer,
List<EfRepo.OrganizationRepository> suts)
{
var savedOrganizations = new List<Organization>();
foreach (var sut in suts)
{
var postEfOrganization = await sut.CreateAsync(organization);
sut.ClearChangeTracking();
var savedOrganization = await sut.GetByIdAsync(organization.Id);
savedOrganizations.Add(savedOrganization);
}
var sqlOrganization = await sqlOrganizationRepo.CreateAsync(organization);
savedOrganizations.Add(await sqlOrganizationRepo.GetByIdAsync(sqlOrganization.Id));
var distinctItems = savedOrganizations.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
[CiSkippedTheory, EfOrganizationAutoData]
public async void ReplaceAsync_Works_DataMatches(Organization postOrganization,
Organization replaceOrganization, SqlRepo.OrganizationRepository sqlOrganizationRepo,
OrganizationCompare equalityComparer, List<EfRepo.OrganizationRepository> suts)
{
var savedOrganizations = new List<Organization>();
foreach (var sut in suts)
{
var postEfOrganization = await sut.CreateAsync(postOrganization);
sut.ClearChangeTracking();
replaceOrganization.Id = postEfOrganization.Id;
await sut.ReplaceAsync(replaceOrganization);
sut.ClearChangeTracking();
var replacedOrganization = await sut.GetByIdAsync(replaceOrganization.Id);
savedOrganizations.Add(replacedOrganization);
}
var postSqlOrganization = await sqlOrganizationRepo.CreateAsync(postOrganization);
replaceOrganization.Id = postSqlOrganization.Id;
await sqlOrganizationRepo.ReplaceAsync(replaceOrganization);
savedOrganizations.Add(await sqlOrganizationRepo.GetByIdAsync(replaceOrganization.Id));
var distinctItems = savedOrganizations.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
[CiSkippedTheory, EfOrganizationAutoData]
public async void DeleteAsync_Works_DataMatches(Organization organization,
SqlRepo.OrganizationRepository sqlOrganizationRepo, List<EfRepo.OrganizationRepository> suts)
{
foreach (var sut in suts)
{
var postEfOrganization = await sut.CreateAsync(organization);
sut.ClearChangeTracking();
var savedEfOrganization = await sut.GetByIdAsync(postEfOrganization.Id);
sut.ClearChangeTracking();
Assert.True(savedEfOrganization != null);
await sut.DeleteAsync(savedEfOrganization);
sut.ClearChangeTracking();
savedEfOrganization = await sut.GetByIdAsync(savedEfOrganization.Id);
Assert.True(savedEfOrganization == null);
}
var postSqlOrganization = await sqlOrganizationRepo.CreateAsync(organization);
var savedSqlOrganization = await sqlOrganizationRepo.GetByIdAsync(postSqlOrganization.Id);
Assert.True(savedSqlOrganization != null);
await sqlOrganizationRepo.DeleteAsync(postSqlOrganization);
savedSqlOrganization = await sqlOrganizationRepo.GetByIdAsync(postSqlOrganization.Id);
Assert.True(savedSqlOrganization == null);
}
[CiSkippedTheory, EfOrganizationAutoData]
public async void GetByIdentifierAsync_Works_DataMatches(Organization organization,
SqlRepo.OrganizationRepository sqlOrganizationRepo, OrganizationCompare equalityComparer,
List<EfRepo.OrganizationRepository> suts)
{
var returnedOrgs = new List<Organization>();
foreach (var sut in suts)
{
var postEfOrg = await sut.CreateAsync(organization);
sut.ClearChangeTracking();
var returnedOrg = await sut.GetByIdentifierAsync(postEfOrg.Identifier.ToUpperInvariant());
returnedOrgs.Add(returnedOrg);
}
var postSqlOrg = await sqlOrganizationRepo.CreateAsync(organization);
returnedOrgs.Add(await sqlOrganizationRepo.GetByIdentifierAsync(postSqlOrg.Identifier.ToUpperInvariant()));
var distinctItems = returnedOrgs.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
[CiSkippedTheory, EfOrganizationAutoData]
public async void GetManyByEnabledAsync_Works_DataMatches(Organization organization,
SqlRepo.OrganizationRepository sqlOrganizationRepo, List<EfRepo.OrganizationRepository> suts)
{
var returnedOrgs = new List<Organization>();
foreach (var sut in suts)
{
var postEfOrg = await sut.CreateAsync(organization);
sut.ClearChangeTracking();
var efReturnedOrgs = await sut.GetManyByEnabledAsync();
returnedOrgs.Concat(efReturnedOrgs);
}
var postSqlOrg = await sqlOrganizationRepo.CreateAsync(organization);
returnedOrgs.Concat(await sqlOrganizationRepo.GetManyByEnabledAsync());
Assert.True(returnedOrgs.All(o => o.Enabled));
}
// testing data matches here would require manipulating all organization abilities in the db
[CiSkippedTheory, EfOrganizationAutoData]
public async void GetManyAbilitiesAsync_Works(SqlRepo.OrganizationRepository sqlOrganizationRepo, List<EfRepo.OrganizationRepository> suts)
{
var list = new List<OrganizationAbility>();
foreach (var sut in suts)
{
list.Concat(await sut.GetManyAbilitiesAsync());
}
list.Concat(await sqlOrganizationRepo.GetManyAbilitiesAsync());
Assert.True(list.All(x => x.GetType() == typeof(OrganizationAbility)));
}
}
}

View File

@ -0,0 +1,132 @@
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.Attributes;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
using Xunit;
using EfRepo = Bit.Infrastructure.EntityFramework.Repositories;
using SqlRepo = Bit.Infrastructure.Dapper.Repositories;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories
{
public class OrganizationSponsorshipRepositoryTests
{
[CiSkippedTheory, EfOrganizationSponsorshipAutoData]
public async void CreateAsync_Works_DataMatches(
OrganizationSponsorship organizationSponsorship, Organization sponsoringOrg,
List<EfRepo.OrganizationRepository> efOrgRepos,
SqlRepo.OrganizationRepository sqlOrganizationRepo,
SqlRepo.OrganizationSponsorshipRepository sqlOrganizationSponsorshipRepo,
OrganizationSponsorshipCompare equalityComparer,
List<EfRepo.OrganizationSponsorshipRepository> suts)
{
organizationSponsorship.SponsoredOrganizationId = null;
var savedOrganizationSponsorships = new List<OrganizationSponsorship>();
foreach (var (sut, orgRepo) in suts.Zip(efOrgRepos))
{
var efSponsoringOrg = await orgRepo.CreateAsync(sponsoringOrg);
sut.ClearChangeTracking();
organizationSponsorship.SponsoringOrganizationId = efSponsoringOrg.Id;
await sut.CreateAsync(organizationSponsorship);
sut.ClearChangeTracking();
var savedOrganizationSponsorship = await sut.GetByIdAsync(organizationSponsorship.Id);
savedOrganizationSponsorships.Add(savedOrganizationSponsorship);
}
var sqlSponsoringOrg = await sqlOrganizationRepo.CreateAsync(sponsoringOrg);
organizationSponsorship.SponsoringOrganizationId = sqlSponsoringOrg.Id;
var sqlOrganizationSponsorship = await sqlOrganizationSponsorshipRepo.CreateAsync(organizationSponsorship);
savedOrganizationSponsorships.Add(await sqlOrganizationSponsorshipRepo.GetByIdAsync(sqlOrganizationSponsorship.Id));
var distinctItems = savedOrganizationSponsorships.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
[CiSkippedTheory, EfOrganizationSponsorshipAutoData]
public async void ReplaceAsync_Works_DataMatches(OrganizationSponsorship postOrganizationSponsorship,
OrganizationSponsorship replaceOrganizationSponsorship, Organization sponsoringOrg,
List<EfRepo.OrganizationRepository> efOrgRepos,
SqlRepo.OrganizationRepository sqlOrganizationRepo,
SqlRepo.OrganizationSponsorshipRepository sqlOrganizationSponsorshipRepo,
OrganizationSponsorshipCompare equalityComparer, List<EfRepo.OrganizationSponsorshipRepository> suts)
{
postOrganizationSponsorship.SponsoredOrganizationId = null;
replaceOrganizationSponsorship.SponsoredOrganizationId = null;
var savedOrganizationSponsorships = new List<OrganizationSponsorship>();
foreach (var (sut, orgRepo) in suts.Zip(efOrgRepos))
{
var efSponsoringOrg = await orgRepo.CreateAsync(sponsoringOrg);
sut.ClearChangeTracking();
postOrganizationSponsorship.SponsoringOrganizationId = efSponsoringOrg.Id;
replaceOrganizationSponsorship.SponsoringOrganizationId = efSponsoringOrg.Id;
var postEfOrganizationSponsorship = await sut.CreateAsync(postOrganizationSponsorship);
sut.ClearChangeTracking();
replaceOrganizationSponsorship.Id = postEfOrganizationSponsorship.Id;
await sut.ReplaceAsync(replaceOrganizationSponsorship);
sut.ClearChangeTracking();
var replacedOrganizationSponsorship = await sut.GetByIdAsync(replaceOrganizationSponsorship.Id);
savedOrganizationSponsorships.Add(replacedOrganizationSponsorship);
}
var sqlSponsoringOrg = await sqlOrganizationRepo.CreateAsync(sponsoringOrg);
postOrganizationSponsorship.SponsoringOrganizationId = sqlSponsoringOrg.Id;
var postSqlOrganization = await sqlOrganizationSponsorshipRepo.CreateAsync(postOrganizationSponsorship);
replaceOrganizationSponsorship.Id = postSqlOrganization.Id;
await sqlOrganizationSponsorshipRepo.ReplaceAsync(replaceOrganizationSponsorship);
savedOrganizationSponsorships.Add(await sqlOrganizationSponsorshipRepo.GetByIdAsync(replaceOrganizationSponsorship.Id));
var distinctItems = savedOrganizationSponsorships.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
[CiSkippedTheory, EfOrganizationSponsorshipAutoData]
public async void DeleteAsync_Works_DataMatches(OrganizationSponsorship organizationSponsorship,
Organization sponsoringOrg,
List<EfRepo.OrganizationRepository> efOrgRepos,
SqlRepo.OrganizationRepository sqlOrganizationRepo,
SqlRepo.OrganizationSponsorshipRepository sqlOrganizationSponsorshipRepo,
List<EfRepo.OrganizationSponsorshipRepository> suts)
{
organizationSponsorship.SponsoredOrganizationId = null;
foreach (var (sut, orgRepo) in suts.Zip(efOrgRepos))
{
var efSponsoringOrg = await orgRepo.CreateAsync(sponsoringOrg);
sut.ClearChangeTracking();
organizationSponsorship.SponsoringOrganizationId = efSponsoringOrg.Id;
var postEfOrganizationSponsorship = await sut.CreateAsync(organizationSponsorship);
sut.ClearChangeTracking();
var savedEfOrganizationSponsorship = await sut.GetByIdAsync(postEfOrganizationSponsorship.Id);
sut.ClearChangeTracking();
Assert.True(savedEfOrganizationSponsorship != null);
await sut.DeleteAsync(savedEfOrganizationSponsorship);
sut.ClearChangeTracking();
savedEfOrganizationSponsorship = await sut.GetByIdAsync(savedEfOrganizationSponsorship.Id);
Assert.True(savedEfOrganizationSponsorship == null);
}
var sqlSponsoringOrg = await sqlOrganizationRepo.CreateAsync(sponsoringOrg);
organizationSponsorship.SponsoringOrganizationId = sqlSponsoringOrg.Id;
var postSqlOrganizationSponsorship = await sqlOrganizationSponsorshipRepo.CreateAsync(organizationSponsorship);
var savedSqlOrganizationSponsorship = await sqlOrganizationSponsorshipRepo.GetByIdAsync(postSqlOrganizationSponsorship.Id);
Assert.True(savedSqlOrganizationSponsorship != null);
await sqlOrganizationSponsorshipRepo.DeleteAsync(postSqlOrganizationSponsorship);
savedSqlOrganizationSponsorship = await sqlOrganizationSponsorshipRepo.GetByIdAsync(postSqlOrganizationSponsorship.Id);
Assert.True(savedSqlOrganizationSponsorship == null);
}
}
}

View File

@ -0,0 +1,148 @@
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.Attributes;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
using Xunit;
using EfRepo = Bit.Infrastructure.EntityFramework.Repositories;
using OrganizationUser = Bit.Core.Entities.OrganizationUser;
using SqlRepo = Bit.Infrastructure.Dapper.Repositories;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories
{
public class OrganizationUserRepositoryTests
{
[CiSkippedTheory, EfOrganizationUserAutoData]
public async void CreateAsync_Works_DataMatches(OrganizationUser orgUser, User user, Organization org,
OrganizationUserCompare equalityComparer, List<EfRepo.OrganizationUserRepository> suts,
List<EfRepo.OrganizationRepository> efOrgRepos, List<EfRepo.UserRepository> efUserRepos,
SqlRepo.OrganizationUserRepository sqlOrgUserRepo, SqlRepo.UserRepository sqlUserRepo,
SqlRepo.OrganizationRepository sqlOrgRepo)
{
var savedOrgUsers = new List<OrganizationUser>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var postEfUser = await efUserRepos[i].CreateAsync(user);
var postEfOrg = await efOrgRepos[i].CreateAsync(org);
sut.ClearChangeTracking();
orgUser.UserId = postEfUser.Id;
orgUser.OrganizationId = postEfOrg.Id;
var postEfOrgUser = await sut.CreateAsync(orgUser);
sut.ClearChangeTracking();
var savedOrgUser = await sut.GetByIdAsync(postEfOrgUser.Id);
savedOrgUsers.Add(savedOrgUser);
}
var postSqlUser = await sqlUserRepo.CreateAsync(user);
var postSqlOrg = await sqlOrgRepo.CreateAsync(org);
orgUser.UserId = postSqlUser.Id;
orgUser.OrganizationId = postSqlOrg.Id;
var sqlOrgUser = await sqlOrgUserRepo.CreateAsync(orgUser);
var savedSqlOrgUser = await sqlOrgUserRepo.GetByIdAsync(sqlOrgUser.Id);
savedOrgUsers.Add(savedSqlOrgUser);
var distinctItems = savedOrgUsers.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
[CiSkippedTheory, EfOrganizationUserAutoData]
public async void ReplaceAsync_Works_DataMatches(
OrganizationUser postOrgUser,
OrganizationUser replaceOrgUser,
User user,
Organization org,
OrganizationUserCompare equalityComparer,
List<EfRepo.OrganizationUserRepository> suts,
List<EfRepo.UserRepository> efUserRepos,
List<EfRepo.OrganizationRepository> efOrgRepos,
SqlRepo.OrganizationUserRepository sqlOrgUserRepo,
SqlRepo.UserRepository sqlUserRepo,
SqlRepo.OrganizationRepository sqlOrgRepo
)
{
var savedOrgUsers = new List<OrganizationUser>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var postEfUser = await efUserRepos[i].CreateAsync(user);
var postEfOrg = await efOrgRepos[i].CreateAsync(org);
sut.ClearChangeTracking();
postOrgUser.UserId = replaceOrgUser.UserId = postEfUser.Id;
postOrgUser.OrganizationId = replaceOrgUser.OrganizationId = postEfOrg.Id;
var postEfOrgUser = await sut.CreateAsync(postOrgUser);
sut.ClearChangeTracking();
replaceOrgUser.Id = postOrgUser.Id;
await sut.ReplaceAsync(replaceOrgUser);
sut.ClearChangeTracking();
var replacedOrganizationUser = await sut.GetByIdAsync(replaceOrgUser.Id);
savedOrgUsers.Add(replacedOrganizationUser);
}
var postSqlUser = await sqlUserRepo.CreateAsync(user);
var postSqlOrg = await sqlOrgRepo.CreateAsync(org);
postOrgUser.UserId = replaceOrgUser.UserId = postSqlUser.Id;
postOrgUser.OrganizationId = replaceOrgUser.OrganizationId = postSqlOrg.Id;
var postSqlOrgUser = await sqlOrgUserRepo.CreateAsync(postOrgUser);
replaceOrgUser.Id = postSqlOrgUser.Id;
await sqlOrgUserRepo.ReplaceAsync(replaceOrgUser);
var replacedSqlUser = await sqlOrgUserRepo.GetByIdAsync(replaceOrgUser.Id);
var distinctItems = savedOrgUsers.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
[CiSkippedTheory, EfOrganizationUserAutoData]
public async void DeleteAsync_Works_DataMatches(OrganizationUser orgUser, User user, Organization org, List<EfRepo.OrganizationUserRepository> suts,
List<EfRepo.UserRepository> efUserRepos, List<EfRepo.OrganizationRepository> efOrgRepos,
SqlRepo.OrganizationUserRepository sqlOrgUserRepo, SqlRepo.UserRepository sqlUserRepo,
SqlRepo.OrganizationRepository sqlOrgRepo)
{
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var postEfUser = await efUserRepos[i].CreateAsync(user);
var postEfOrg = await efOrgRepos[i].CreateAsync(org);
sut.ClearChangeTracking();
orgUser.UserId = postEfUser.Id;
orgUser.OrganizationId = postEfOrg.Id;
var postEfOrgUser = await sut.CreateAsync(orgUser);
sut.ClearChangeTracking();
var savedEfOrgUser = await sut.GetByIdAsync(postEfOrgUser.Id);
Assert.True(savedEfOrgUser != null);
sut.ClearChangeTracking();
await sut.DeleteAsync(savedEfOrgUser);
sut.ClearChangeTracking();
savedEfOrgUser = await sut.GetByIdAsync(savedEfOrgUser.Id);
Assert.True(savedEfOrgUser == null);
}
var postSqlUser = await sqlUserRepo.CreateAsync(user);
var postSqlOrg = await sqlOrgRepo.CreateAsync(org);
orgUser.UserId = postSqlUser.Id;
orgUser.OrganizationId = postSqlOrg.Id;
var postSqlOrgUser = await sqlOrgUserRepo.CreateAsync(orgUser);
var savedSqlOrgUser = await sqlOrgUserRepo.GetByIdAsync(postSqlOrgUser.Id);
Assert.True(savedSqlOrgUser != null);
await sqlOrgUserRepo.DeleteAsync(postSqlOrgUser);
savedSqlOrgUser = await sqlOrgUserRepo.GetByIdAsync(postSqlOrgUser.Id);
Assert.True(savedSqlOrgUser == null);
}
}
}

View File

@ -0,0 +1,196 @@
using System.Text.Json;
using Bit.Core.Entities;
using Bit.Core.Entities.Provider;
using Bit.Core.Enums;
using Bit.Core.Models.Data;
using Bit.Core.Repositories;
using Bit.Core.Test.AutoFixture.Attributes;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
using Xunit;
using EfRepo = Bit.Infrastructure.EntityFramework.Repositories;
using Policy = Bit.Core.Entities.Policy;
using SqlRepo = Bit.Infrastructure.Dapper.Repositories;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories
{
public class PolicyRepositoryTests
{
[CiSkippedTheory, EfPolicyAutoData]
public async void CreateAsync_Works_DataMatches(
Policy policy,
Organization organization,
PolicyCompare equalityComparer,
List<EfRepo.PolicyRepository> suts,
List<EfRepo.OrganizationRepository> efOrganizationRepos,
SqlRepo.PolicyRepository sqlPolicyRepo,
SqlRepo.OrganizationRepository sqlOrganizationRepo
)
{
var savedPolicys = new List<Policy>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var efOrganization = await efOrganizationRepos[i].CreateAsync(organization);
sut.ClearChangeTracking();
policy.OrganizationId = efOrganization.Id;
var postEfPolicy = await sut.CreateAsync(policy);
sut.ClearChangeTracking();
var savedPolicy = await sut.GetByIdAsync(postEfPolicy.Id);
savedPolicys.Add(savedPolicy);
}
var sqlOrganization = await sqlOrganizationRepo.CreateAsync(organization);
policy.OrganizationId = sqlOrganization.Id;
var sqlPolicy = await sqlPolicyRepo.CreateAsync(policy);
var savedSqlPolicy = await sqlPolicyRepo.GetByIdAsync(sqlPolicy.Id);
savedPolicys.Add(savedSqlPolicy);
var distinctItems = savedPolicys.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
[CiSkippedTheory]
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Confirmed, false, true, true, false)] // Ordinary user
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Invited, true, true, true, false)] // Invited user
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.Owner, false, OrganizationUserStatusType.Confirmed, false, true, true, false)] // Owner
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.Admin, false, OrganizationUserStatusType.Confirmed, false, true, true, false)] // Admin
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, true, OrganizationUserStatusType.Confirmed, false, true, true, false)] // canManagePolicies
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Confirmed, false, true, true, true)] // Provider
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Confirmed, false, false, true, false)] // Policy disabled
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Confirmed, false, true, false, false)] // No policy of Type
[EfPolicyApplicableToUserInlineAutoData(OrganizationUserType.User, false, OrganizationUserStatusType.Invited, false, true, true, false)] // User not minStatus
public async void GetManyByTypeApplicableToUser_Works_DataMatches(
// Inline data
OrganizationUserType userType,
bool canManagePolicies,
OrganizationUserStatusType orgUserStatus,
bool includeInvited,
bool policyEnabled,
bool policySameType,
bool isProvider,
// Auto data - models
Policy policy,
User user,
Organization organization,
OrganizationUser orgUser,
Provider provider,
ProviderOrganization providerOrganization,
ProviderUser providerUser,
PolicyCompareIncludingOrganization equalityComparer,
// Auto data - EF repos
List<EfRepo.PolicyRepository> suts,
List<EfRepo.UserRepository> efUserRepository,
List<EfRepo.OrganizationRepository> efOrganizationRepository,
List<EfRepo.OrganizationUserRepository> efOrganizationUserRepository,
List<EfRepo.ProviderRepository> efProviderRepository,
List<EfRepo.ProviderOrganizationRepository> efProviderOrganizationRepository,
List<EfRepo.ProviderUserRepository> efProviderUserRepository,
// Auto data - SQL repos
SqlRepo.PolicyRepository sqlPolicyRepo,
SqlRepo.UserRepository sqlUserRepo,
SqlRepo.OrganizationRepository sqlOrganizationRepo,
SqlRepo.ProviderRepository sqlProviderRepo,
SqlRepo.OrganizationUserRepository sqlOrganizationUserRepo,
SqlRepo.ProviderOrganizationRepository sqlProviderOrganizationRepo,
SqlRepo.ProviderUserRepository sqlProviderUserRepo
)
{
// Combine EF and SQL repos into one list per type
var policyRepos = suts.ToList<IPolicyRepository>();
policyRepos.Add(sqlPolicyRepo);
var userRepos = efUserRepository.ToList<IUserRepository>();
userRepos.Add(sqlUserRepo);
var orgRepos = efOrganizationRepository.ToList<IOrganizationRepository>();
orgRepos.Add(sqlOrganizationRepo);
var orgUserRepos = efOrganizationUserRepository.ToList<IOrganizationUserRepository>();
orgUserRepos.Add(sqlOrganizationUserRepo);
var providerRepos = efProviderRepository.ToList<IProviderRepository>();
providerRepos.Add(sqlProviderRepo);
var providerOrgRepos = efProviderOrganizationRepository.ToList<IProviderOrganizationRepository>();
providerOrgRepos.Add(sqlProviderOrganizationRepo);
var providerUserRepos = efProviderUserRepository.ToList<IProviderUserRepository>();
providerUserRepos.Add(sqlProviderUserRepo);
// Arrange data
var savedPolicyType = PolicyType.SingleOrg;
var queriedPolicyType = policySameType ? savedPolicyType : PolicyType.DisableSend;
orgUser.Type = userType;
orgUser.Status = orgUserStatus;
var permissionsData = new Permissions { ManagePolicies = canManagePolicies };
orgUser.Permissions = JsonSerializer.Serialize(permissionsData, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
});
policy.Enabled = policyEnabled;
policy.Type = savedPolicyType;
var results = new List<Policy>();
foreach (var policyRepo in policyRepos)
{
var i = policyRepos.IndexOf(policyRepo);
// Seed database
var savedUser = await userRepos[i].CreateAsync(user);
var savedOrg = await orgRepos[i].CreateAsync(organization);
// Invited orgUsers are not associated with an account yet, so they are identified by Email not UserId
if (orgUserStatus == OrganizationUserStatusType.Invited)
{
orgUser.Email = savedUser.Email;
orgUser.UserId = null;
}
else
{
orgUser.UserId = savedUser.Id;
}
orgUser.OrganizationId = savedOrg.Id;
await orgUserRepos[i].CreateAsync(orgUser);
if (isProvider)
{
var savedProvider = await providerRepos[i].CreateAsync(provider);
providerOrganization.OrganizationId = savedOrg.Id;
providerOrganization.ProviderId = savedProvider.Id;
await providerOrgRepos[i].CreateAsync(providerOrganization);
providerUser.UserId = savedUser.Id;
providerUser.ProviderId = savedProvider.Id;
await providerUserRepos[i].CreateAsync(providerUser);
}
policy.OrganizationId = savedOrg.Id;
await policyRepo.CreateAsync(policy);
if (suts.Contains(policyRepo))
{
(policyRepo as EfRepo.BaseEntityFrameworkRepository).ClearChangeTracking();
}
var minStatus = includeInvited ? OrganizationUserStatusType.Invited : OrganizationUserStatusType.Accepted;
// Act
var result = await policyRepo.GetManyByTypeApplicableToUserIdAsync(savedUser.Id, queriedPolicyType, minStatus);
results.Add(result.FirstOrDefault());
}
// Assert
var distinctItems = results.Distinct(equalityComparer);
Assert.True(results.All(r => r == null) ||
!distinctItems.Skip(1).Any());
}
}
}

View File

@ -0,0 +1,65 @@
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.Attributes;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
using Xunit;
using EfRepo = Bit.Infrastructure.EntityFramework.Repositories;
using SqlRepo = Bit.Infrastructure.Dapper.Repositories;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories
{
public class SendRepositoryTests
{
[CiSkippedTheory, EfUserSendAutoData, EfOrganizationSendAutoData]
public async void CreateAsync_Works_DataMatches(
Send send,
User user,
Organization org,
SendCompare equalityComparer,
List<EfRepo.SendRepository> suts,
List<EfRepo.UserRepository> efUserRepos,
List<EfRepo.OrganizationRepository> efOrgRepos,
SqlRepo.SendRepository sqlSendRepo,
SqlRepo.UserRepository sqlUserRepo,
SqlRepo.OrganizationRepository sqlOrgRepo
)
{
var savedSends = new List<Send>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
if (send.OrganizationId.HasValue)
{
var efOrg = await efOrgRepos[i].CreateAsync(org);
sut.ClearChangeTracking();
send.OrganizationId = efOrg.Id;
}
var efUser = await efUserRepos[i].CreateAsync(user);
sut.ClearChangeTracking();
send.UserId = efUser.Id;
var postEfSend = await sut.CreateAsync(send);
sut.ClearChangeTracking();
var savedSend = await sut.GetByIdAsync(postEfSend.Id);
savedSends.Add(savedSend);
}
var sqlUser = await sqlUserRepo.CreateAsync(user);
if (send.OrganizationId.HasValue)
{
var sqlOrg = await sqlOrgRepo.CreateAsync(org);
send.OrganizationId = sqlOrg.Id;
}
send.UserId = sqlUser.Id;
var sqlSend = await sqlSendRepo.CreateAsync(send);
var savedSqlSend = await sqlSendRepo.GetByIdAsync(sqlSend.Id);
savedSends.Add(savedSqlSend);
var distinctItems = savedSends.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
}
}

View File

@ -0,0 +1,227 @@
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.Attributes;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
using Xunit;
using EfRepo = Bit.Infrastructure.EntityFramework.Repositories;
using SqlRepo = Bit.Infrastructure.Dapper.Repositories;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories
{
public class SsoConfigRepositoryTests
{
[CiSkippedTheory, EfSsoConfigAutoData]
public async void CreateAsync_Works_DataMatches(SsoConfig ssoConfig, Organization org,
SsoConfigCompare equalityComparer, List<EfRepo.SsoConfigRepository> suts,
List<EfRepo.OrganizationRepository> efOrgRepos, SqlRepo.SsoConfigRepository sqlSsoConfigRepo,
SqlRepo.OrganizationRepository sqlOrganizationRepo)
{
var savedSsoConfigs = new List<SsoConfig>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var savedEfOrg = await efOrgRepos[i].CreateAsync(org);
sut.ClearChangeTracking();
ssoConfig.OrganizationId = savedEfOrg.Id;
var postEfSsoConfig = await sut.CreateAsync(ssoConfig);
sut.ClearChangeTracking();
var savedEfSsoConfig = await sut.GetByIdAsync(ssoConfig.Id);
Assert.True(savedEfSsoConfig != null);
savedSsoConfigs.Add(savedEfSsoConfig);
}
var sqlOrganization = await sqlOrganizationRepo.CreateAsync(org);
ssoConfig.OrganizationId = sqlOrganization.Id;
var sqlSsoConfig = await sqlSsoConfigRepo.CreateAsync(ssoConfig);
var savedSqlSsoConfig = await sqlSsoConfigRepo.GetByIdAsync(sqlSsoConfig.Id);
Assert.True(savedSqlSsoConfig != null);
savedSsoConfigs.Add(savedSqlSsoConfig);
var distinctItems = savedSsoConfigs.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
[CiSkippedTheory, EfSsoConfigAutoData]
public async void ReplaceAsync_Works_DataMatches(SsoConfig postSsoConfig, SsoConfig replaceSsoConfig,
Organization org, SsoConfigCompare equalityComparer, List<EfRepo.SsoConfigRepository> suts,
List<EfRepo.OrganizationRepository> efOrgRepos, SqlRepo.SsoConfigRepository sqlSsoConfigRepo,
SqlRepo.OrganizationRepository sqlOrganizationRepo)
{
var savedSsoConfigs = new List<SsoConfig>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var savedEfOrg = await efOrgRepos[i].CreateAsync(org);
sut.ClearChangeTracking();
postSsoConfig.OrganizationId = replaceSsoConfig.OrganizationId = savedEfOrg.Id;
var postEfSsoConfig = await sut.CreateAsync(postSsoConfig);
sut.ClearChangeTracking();
replaceSsoConfig.Id = postEfSsoConfig.Id;
savedSsoConfigs.Add(postEfSsoConfig);
await sut.ReplaceAsync(replaceSsoConfig);
sut.ClearChangeTracking();
var replacedSsoConfig = await sut.GetByIdAsync(replaceSsoConfig.Id);
Assert.True(replacedSsoConfig != null);
savedSsoConfigs.Add(replacedSsoConfig);
}
var sqlOrganization = await sqlOrganizationRepo.CreateAsync(org);
postSsoConfig.OrganizationId = sqlOrganization.Id;
var postSqlSsoConfig = await sqlSsoConfigRepo.CreateAsync(postSsoConfig);
replaceSsoConfig.Id = postSqlSsoConfig.Id;
savedSsoConfigs.Add(postSqlSsoConfig);
await sqlSsoConfigRepo.ReplaceAsync(replaceSsoConfig);
var replacedSqlSsoConfig = await sqlSsoConfigRepo.GetByIdAsync(replaceSsoConfig.Id);
Assert.True(replacedSqlSsoConfig != null);
savedSsoConfigs.Add(replacedSqlSsoConfig);
var distinctItems = savedSsoConfigs.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(2).Any());
}
[CiSkippedTheory, EfSsoConfigAutoData]
public async void DeleteAsync_Works_DataMatches(SsoConfig ssoConfig, Organization org, List<EfRepo.SsoConfigRepository> suts,
List<EfRepo.OrganizationRepository> efOrgRepos, SqlRepo.SsoConfigRepository sqlSsoConfigRepo,
SqlRepo.OrganizationRepository sqlOrganizationRepo)
{
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var savedEfOrg = await efOrgRepos[i].CreateAsync(org);
sut.ClearChangeTracking();
ssoConfig.OrganizationId = savedEfOrg.Id;
var postEfSsoConfig = await sut.CreateAsync(ssoConfig);
sut.ClearChangeTracking();
var savedEfSsoConfig = await sut.GetByIdAsync(postEfSsoConfig.Id);
Assert.True(savedEfSsoConfig != null);
sut.ClearChangeTracking();
await sut.DeleteAsync(savedEfSsoConfig);
var deletedEfSsoConfig = await sut.GetByIdAsync(savedEfSsoConfig.Id);
Assert.True(deletedEfSsoConfig == null);
}
var sqlOrganization = await sqlOrganizationRepo.CreateAsync(org);
ssoConfig.OrganizationId = sqlOrganization.Id;
var postSqlSsoConfig = await sqlSsoConfigRepo.CreateAsync(ssoConfig);
var savedSqlSsoConfig = await sqlSsoConfigRepo.GetByIdAsync(postSqlSsoConfig.Id);
Assert.True(savedSqlSsoConfig != null);
await sqlSsoConfigRepo.DeleteAsync(savedSqlSsoConfig);
savedSqlSsoConfig = await sqlSsoConfigRepo.GetByIdAsync(postSqlSsoConfig.Id);
Assert.True(savedSqlSsoConfig == null);
}
[CiSkippedTheory, EfSsoConfigAutoData]
public async void GetByOrganizationIdAsync_Works_DataMatches(SsoConfig ssoConfig, Organization org,
SsoConfigCompare equalityComparer, List<EfRepo.SsoConfigRepository> suts,
List<EfRepo.OrganizationRepository> efOrgRepos, SqlRepo.SsoConfigRepository sqlSsoConfigRepo,
SqlRepo.OrganizationRepository sqlOrgRepo)
{
var returnedList = new List<SsoConfig>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var savedEfOrg = await efOrgRepos[i].CreateAsync(org);
sut.ClearChangeTracking();
ssoConfig.OrganizationId = savedEfOrg.Id;
await sut.CreateAsync(ssoConfig);
sut.ClearChangeTracking();
var savedEfUser = await sut.GetByOrganizationIdAsync(savedEfOrg.Id);
Assert.True(savedEfUser != null);
returnedList.Add(savedEfUser);
}
var savedSqlOrg = await sqlOrgRepo.CreateAsync(org);
ssoConfig.OrganizationId = savedSqlOrg.Id;
var postSqlSsoConfig = await sqlSsoConfigRepo.CreateAsync(ssoConfig);
var savedSqlSsoConfig = await sqlSsoConfigRepo.GetByOrganizationIdAsync(ssoConfig.OrganizationId);
Assert.True(savedSqlSsoConfig != null);
returnedList.Add(savedSqlSsoConfig);
var distinctItems = returnedList.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
[CiSkippedTheory, EfSsoConfigAutoData]
public async void GetByIdentifierAsync_Works_DataMatches(SsoConfig ssoConfig, Organization org,
SsoConfigCompare equalityComparer, List<EfRepo.SsoConfigRepository> suts,
List<EfRepo.OrganizationRepository> efOrgRepos, SqlRepo.SsoConfigRepository sqlSsoConfigRepo,
SqlRepo.OrganizationRepository sqlOrgRepo)
{
var returnedList = new List<SsoConfig>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var savedEfOrg = await efOrgRepos[i].CreateAsync(org);
sut.ClearChangeTracking();
ssoConfig.OrganizationId = savedEfOrg.Id;
await sut.CreateAsync(ssoConfig);
sut.ClearChangeTracking();
var savedEfSsoConfig = await sut.GetByIdentifierAsync(org.Identifier);
Assert.True(savedEfSsoConfig != null);
returnedList.Add(savedEfSsoConfig);
}
var savedSqlOrg = await sqlOrgRepo.CreateAsync(org);
ssoConfig.OrganizationId = savedSqlOrg.Id;
var postSqlSsoConfig = await sqlSsoConfigRepo.CreateAsync(ssoConfig);
var savedSqlSsoConfig = await sqlSsoConfigRepo.GetByIdentifierAsync(org.Identifier);
Assert.True(savedSqlSsoConfig != null);
returnedList.Add(savedSqlSsoConfig);
var distinctItems = returnedList.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
// Testing that data matches here would involve manipulating all SsoConfig records in the db
[CiSkippedTheory, EfSsoConfigAutoData]
public async void GetManyByRevisionNotBeforeDate_Works(SsoConfig ssoConfig, DateTime notBeforeDate,
Organization org, List<EfRepo.SsoConfigRepository> suts,
List<EfRepo.OrganizationRepository> efOrgRepos)
{
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var savedEfOrg = await efOrgRepos[i].CreateAsync(org);
sut.ClearChangeTracking();
ssoConfig.OrganizationId = savedEfOrg.Id;
await sut.CreateAsync(ssoConfig);
sut.ClearChangeTracking();
var returnedEfSsoConfigs = await sut.GetManyByRevisionNotBeforeDate(notBeforeDate);
Assert.True(returnedEfSsoConfigs.All(sc => sc.RevisionDate >= notBeforeDate));
}
}
}
}

View File

@ -0,0 +1,187 @@
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.Attributes;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
using Xunit;
using EfRepo = Bit.Infrastructure.EntityFramework.Repositories;
using SqlRepo = Bit.Infrastructure.Dapper.Repositories;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories
{
public class SsoUserRepositoryTests
{
[CiSkippedTheory, EfSsoUserAutoData]
public async void CreateAsync_Works_DataMatches(SsoUser ssoUser, User user, Organization org,
SsoUserCompare equalityComparer, List<EfRepo.SsoUserRepository> suts,
List<EfRepo.OrganizationRepository> efOrgRepos, List<EfRepo.UserRepository> efUserRepos,
SqlRepo.SsoUserRepository sqlSsoUserRepo, SqlRepo.OrganizationRepository sqlOrgRepo,
SqlRepo.UserRepository sqlUserRepo)
{
var createdSsoUsers = new List<SsoUser>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var efUser = await efUserRepos[i].CreateAsync(user);
var efOrg = await efOrgRepos[i].CreateAsync(org);
sut.ClearChangeTracking();
ssoUser.UserId = efUser.Id;
ssoUser.OrganizationId = efOrg.Id;
var postEfSsoUser = await sut.CreateAsync(ssoUser);
sut.ClearChangeTracking();
var savedSsoUser = await sut.GetByIdAsync(ssoUser.Id);
createdSsoUsers.Add(savedSsoUser);
}
var sqlUser = await sqlUserRepo.CreateAsync(user);
var sqlOrganization = await sqlOrgRepo.CreateAsync(org);
ssoUser.UserId = sqlUser.Id;
ssoUser.OrganizationId = sqlOrganization.Id;
var sqlSsoUser = await sqlSsoUserRepo.CreateAsync(ssoUser);
createdSsoUsers.Add(await sqlSsoUserRepo.GetByIdAsync(sqlSsoUser.Id));
var distinctSsoUsers = createdSsoUsers.Distinct(equalityComparer);
Assert.True(!distinctSsoUsers.Skip(1).Any());
}
[CiSkippedTheory, EfSsoUserAutoData]
public async void ReplaceAsync_Works_DataMatches(SsoUser postSsoUser, SsoUser replaceSsoUser,
Organization org, User user, SsoUserCompare equalityComparer,
List<EfRepo.SsoUserRepository> suts, List<EfRepo.UserRepository> efUserRepos,
List<EfRepo.OrganizationRepository> efOrgRepos, SqlRepo.SsoUserRepository sqlSsoUserRepo,
SqlRepo.OrganizationRepository sqlOrgRepo, SqlRepo.UserRepository sqlUserRepo)
{
var savedSsoUsers = new List<SsoUser>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var efUser = await efUserRepos[i].CreateAsync(user);
var efOrg = await efOrgRepos[i].CreateAsync(org);
sut.ClearChangeTracking();
postSsoUser.UserId = efUser.Id;
postSsoUser.OrganizationId = efOrg.Id;
var postEfSsoUser = await sut.CreateAsync(postSsoUser);
sut.ClearChangeTracking();
replaceSsoUser.Id = postEfSsoUser.Id;
replaceSsoUser.UserId = postEfSsoUser.UserId;
replaceSsoUser.OrganizationId = postEfSsoUser.OrganizationId;
await sut.ReplaceAsync(replaceSsoUser);
sut.ClearChangeTracking();
var replacedSsoUser = await sut.GetByIdAsync(replaceSsoUser.Id);
savedSsoUsers.Add(replacedSsoUser);
}
var sqlUser = await sqlUserRepo.CreateAsync(user);
var sqlOrganization = await sqlOrgRepo.CreateAsync(org);
postSsoUser.UserId = sqlUser.Id;
postSsoUser.OrganizationId = sqlOrganization.Id;
var postSqlSsoUser = await sqlSsoUserRepo.CreateAsync(postSsoUser);
replaceSsoUser.Id = postSqlSsoUser.Id;
replaceSsoUser.UserId = postSqlSsoUser.UserId;
replaceSsoUser.OrganizationId = postSqlSsoUser.OrganizationId;
await sqlSsoUserRepo.ReplaceAsync(replaceSsoUser);
savedSsoUsers.Add(await sqlSsoUserRepo.GetByIdAsync(replaceSsoUser.Id));
var distinctItems = savedSsoUsers.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
[CiSkippedTheory, EfSsoUserAutoData]
public async void DeleteAsync_Works_DataMatches(SsoUser ssoUser, Organization org, User user, List<EfRepo.SsoUserRepository> suts,
List<EfRepo.UserRepository> efUserRepos, List<EfRepo.OrganizationRepository> efOrgRepos,
SqlRepo.SsoUserRepository sqlSsoUserRepo, SqlRepo.UserRepository sqlUserRepo,
SqlRepo.OrganizationRepository sqlOrganizationRepo)
{
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var savedEfUser = await efUserRepos[i].CreateAsync(user);
var savedEfOrg = await efOrgRepos[i].CreateAsync(org);
sut.ClearChangeTracking();
ssoUser.UserId = savedEfUser.Id;
ssoUser.OrganizationId = savedEfOrg.Id;
var postEfSsoUser = await sut.CreateAsync(ssoUser);
sut.ClearChangeTracking();
var savedEfSsoUser = await sut.GetByIdAsync(postEfSsoUser.Id);
Assert.True(savedEfSsoUser != null);
sut.ClearChangeTracking();
await sut.DeleteAsync(savedEfSsoUser);
savedEfSsoUser = await sut.GetByIdAsync(savedEfSsoUser.Id);
Assert.True(savedEfSsoUser == null);
}
var sqlUser = await sqlUserRepo.CreateAsync(user);
var sqlOrganization = await sqlOrganizationRepo.CreateAsync(org);
ssoUser.UserId = sqlUser.Id;
ssoUser.OrganizationId = sqlOrganization.Id;
var postSqlSsoUser = await sqlSsoUserRepo.CreateAsync(ssoUser);
var savedSqlSsoUser = await sqlSsoUserRepo.GetByIdAsync(postSqlSsoUser.Id);
Assert.True(savedSqlSsoUser != null);
await sqlSsoUserRepo.DeleteAsync(savedSqlSsoUser);
savedSqlSsoUser = await sqlSsoUserRepo.GetByIdAsync(postSqlSsoUser.Id);
Assert.True(savedSqlSsoUser == null);
}
[CiSkippedTheory, EfSsoUserAutoData]
public async void DeleteAsync_UserIdOrganizationId_Works_DataMatches(SsoUser ssoUser,
User user, Organization org, List<EfRepo.SsoUserRepository> suts,
List<EfRepo.UserRepository> efUserRepos, List<EfRepo.OrganizationRepository> efOrgRepos,
SqlRepo.SsoUserRepository sqlSsoUserRepo, SqlRepo.UserRepository sqlUserRepo, SqlRepo.OrganizationRepository sqlOrgRepo
)
{
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var savedEfUser = await efUserRepos[i].CreateAsync(user);
var savedEfOrg = await efOrgRepos[i].CreateAsync(org);
sut.ClearChangeTracking();
ssoUser.UserId = savedEfUser.Id;
ssoUser.OrganizationId = savedEfOrg.Id;
var postEfSsoUser = await sut.CreateAsync(ssoUser);
sut.ClearChangeTracking();
var savedEfSsoUser = await sut.GetByIdAsync(postEfSsoUser.Id);
Assert.True(savedEfSsoUser != null);
sut.ClearChangeTracking();
await sut.DeleteAsync(savedEfSsoUser.UserId, savedEfSsoUser.OrganizationId);
sut.ClearChangeTracking();
savedEfSsoUser = await sut.GetByIdAsync(savedEfSsoUser.Id);
Assert.True(savedEfSsoUser == null);
}
var sqlUser = await sqlUserRepo.CreateAsync(user);
var sqlOrganization = await sqlOrgRepo.CreateAsync(org);
ssoUser.UserId = sqlUser.Id;
ssoUser.OrganizationId = sqlOrganization.Id;
var postSqlSsoUser = await sqlSsoUserRepo.CreateAsync(ssoUser);
var savedSqlSsoUser = await sqlSsoUserRepo.GetByIdAsync(postSqlSsoUser.Id);
Assert.True(savedSqlSsoUser != null);
await sqlSsoUserRepo.DeleteAsync(savedSqlSsoUser.UserId, savedSqlSsoUser.OrganizationId);
savedSqlSsoUser = await sqlSsoUserRepo.GetByIdAsync(postSqlSsoUser.Id);
Assert.True(savedSqlSsoUser == null);
}
}
}

View File

@ -0,0 +1,40 @@
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.Attributes;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
using Xunit;
using EfRepo = Bit.Infrastructure.EntityFramework.Repositories;
using SqlRepo = Bit.Infrastructure.Dapper.Repositories;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories
{
public class TaxRateRepositoryTests
{
[CiSkippedTheory, EfTaxRateAutoData]
public async void CreateAsync_Works_DataMatches(
TaxRate taxRate,
TaxRateCompare equalityComparer,
List<EfRepo.TaxRateRepository> suts,
SqlRepo.TaxRateRepository sqlTaxRateRepo
)
{
var savedTaxRates = new List<TaxRate>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var postEfTaxRate = await sut.CreateAsync(taxRate);
sut.ClearChangeTracking();
var savedTaxRate = await sut.GetByIdAsync(postEfTaxRate.Id);
savedTaxRates.Add(savedTaxRate);
}
var sqlTaxRate = await sqlTaxRateRepo.CreateAsync(taxRate);
var savedSqlTaxRate = await sqlTaxRateRepo.GetByIdAsync(sqlTaxRate.Id);
savedTaxRates.Add(savedSqlTaxRate);
var distinctItems = savedTaxRates.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
}
}

View File

@ -0,0 +1,64 @@
using Bit.Core.Entities;
using Bit.Core.Test.AutoFixture.Attributes;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
using Xunit;
using EfRepo = Bit.Infrastructure.EntityFramework.Repositories;
using SqlRepo = Bit.Infrastructure.Dapper.Repositories;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories
{
public class TransactionRepositoryTests
{
[CiSkippedTheory, EfUserTransactionAutoData, EfOrganizationTransactionAutoData]
public async void CreateAsync_Works_DataMatches(
Transaction transaction,
User user,
Organization org,
TransactionCompare equalityComparer,
List<EfRepo.TransactionRepository> suts,
List<EfRepo.UserRepository> efUserRepos,
List<EfRepo.OrganizationRepository> efOrgRepos,
SqlRepo.TransactionRepository sqlTransactionRepo,
SqlRepo.UserRepository sqlUserRepo,
SqlRepo.OrganizationRepository sqlOrgRepo
)
{
var savedTransactions = new List<Transaction>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var efUser = await efUserRepos[i].CreateAsync(user);
if (transaction.OrganizationId.HasValue)
{
var efOrg = await efOrgRepos[i].CreateAsync(org);
transaction.OrganizationId = efOrg.Id;
}
sut.ClearChangeTracking();
transaction.UserId = efUser.Id;
var postEfTransaction = await sut.CreateAsync(transaction);
sut.ClearChangeTracking();
var savedTransaction = await sut.GetByIdAsync(postEfTransaction.Id);
savedTransactions.Add(savedTransaction);
}
var sqlUser = await sqlUserRepo.CreateAsync(user);
if (transaction.OrganizationId.HasValue)
{
var sqlOrg = await sqlOrgRepo.CreateAsync(org);
transaction.OrganizationId = sqlOrg.Id;
}
transaction.UserId = sqlUser.Id;
var sqlTransaction = await sqlTransactionRepo.CreateAsync(transaction);
var savedSqlTransaction = await sqlTransactionRepo.GetByIdAsync(sqlTransaction.Id);
savedTransactions.Add(savedSqlTransaction);
var distinctItems = savedTransactions.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
}
}

View File

@ -0,0 +1,290 @@
using Bit.Core.Entities;
using Bit.Core.Models.Data;
using Bit.Core.Test.AutoFixture.Attributes;
using Bit.Infrastructure.EFIntegration.Test.AutoFixture;
using Bit.Infrastructure.EFIntegration.Test.Repositories.EqualityComparers;
using Xunit;
using EfRepo = Bit.Infrastructure.EntityFramework.Repositories;
using SqlRepo = Bit.Infrastructure.Dapper.Repositories;
namespace Bit.Infrastructure.EFIntegration.Test.Repositories
{
public class UserRepositoryTests
{
[CiSkippedTheory, EfUserAutoData]
public async void CreateAsync_Works_DataMatches(
User user, UserCompare equalityComparer,
List<EfRepo.UserRepository> suts,
SqlRepo.UserRepository sqlUserRepo
)
{
var savedUsers = new List<User>();
foreach (var sut in suts)
{
var postEfUser = await sut.CreateAsync(user);
sut.ClearChangeTracking();
var savedUser = await sut.GetByIdAsync(postEfUser.Id);
savedUsers.Add(savedUser);
}
var sqlUser = await sqlUserRepo.CreateAsync(user);
savedUsers.Add(await sqlUserRepo.GetByIdAsync(sqlUser.Id));
var distinctItems = savedUsers.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
[CiSkippedTheory, EfUserAutoData]
public async void ReplaceAsync_Works_DataMatches(User postUser, User replaceUser,
UserCompare equalityComparer, List<EfRepo.UserRepository> suts,
SqlRepo.UserRepository sqlUserRepo)
{
var savedUsers = new List<User>();
foreach (var sut in suts)
{
var postEfUser = await sut.CreateAsync(postUser);
replaceUser.Id = postEfUser.Id;
await sut.ReplaceAsync(replaceUser);
var replacedUser = await sut.GetByIdAsync(replaceUser.Id);
savedUsers.Add(replacedUser);
}
var postSqlUser = await sqlUserRepo.CreateAsync(postUser);
replaceUser.Id = postSqlUser.Id;
await sqlUserRepo.ReplaceAsync(replaceUser);
savedUsers.Add(await sqlUserRepo.GetByIdAsync(replaceUser.Id));
var distinctItems = savedUsers.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
[CiSkippedTheory, EfUserAutoData]
public async void DeleteAsync_Works_DataMatches(User user, List<EfRepo.UserRepository> suts, SqlRepo.UserRepository sqlUserRepo)
{
foreach (var sut in suts)
{
var postEfUser = await sut.CreateAsync(user);
sut.ClearChangeTracking();
var savedEfUser = await sut.GetByIdAsync(postEfUser.Id);
Assert.True(savedEfUser != null);
sut.ClearChangeTracking();
await sut.DeleteAsync(savedEfUser);
sut.ClearChangeTracking();
savedEfUser = await sut.GetByIdAsync(savedEfUser.Id);
Assert.True(savedEfUser == null);
}
var postSqlUser = await sqlUserRepo.CreateAsync(user);
var savedSqlUser = await sqlUserRepo.GetByIdAsync(postSqlUser.Id);
Assert.True(savedSqlUser != null);
await sqlUserRepo.DeleteAsync(postSqlUser);
savedSqlUser = await sqlUserRepo.GetByIdAsync(postSqlUser.Id);
Assert.True(savedSqlUser == null);
}
[CiSkippedTheory, EfUserAutoData]
public async void GetByEmailAsync_Works_DataMatches(User user, UserCompare equalityComparer,
List<EfRepo.UserRepository> suts, SqlRepo.UserRepository sqlUserRepo)
{
var savedUsers = new List<User>();
foreach (var sut in suts)
{
var postEfUser = await sut.CreateAsync(user);
sut.ClearChangeTracking();
var savedUser = await sut.GetByEmailAsync(postEfUser.Email.ToUpperInvariant());
savedUsers.Add(savedUser);
}
var postSqlUser = await sqlUserRepo.CreateAsync(user);
savedUsers.Add(await sqlUserRepo.GetByEmailAsync(postSqlUser.Email.ToUpperInvariant()));
var distinctItems = savedUsers.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
[CiSkippedTheory, EfUserAutoData]
public async void GetKdfInformationByEmailAsync_Works_DataMatches(User user,
UserKdfInformationCompare equalityComparer, List<EfRepo.UserRepository> suts,
SqlRepo.UserRepository sqlUserRepo)
{
var savedKdfInformation = new List<UserKdfInformation>();
foreach (var sut in suts)
{
var postEfUser = await sut.CreateAsync(user);
sut.ClearChangeTracking();
var kdfInformation = await sut.GetKdfInformationByEmailAsync(postEfUser.Email.ToUpperInvariant());
savedKdfInformation.Add(kdfInformation);
}
var postSqlUser = await sqlUserRepo.CreateAsync(user);
var sqlKdfInformation = await sqlUserRepo.GetKdfInformationByEmailAsync(postSqlUser.Email);
savedKdfInformation.Add(sqlKdfInformation);
var distinctItems = savedKdfInformation.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
[CiSkippedTheory, EfUserAutoData]
public async void SearchAsync_Works_DataMatches(User user, int skip, int take,
UserCompare equalityCompare, List<EfRepo.UserRepository> suts,
SqlRepo.UserRepository sqlUserRepo)
{
var searchedEfUsers = new List<User>();
foreach (var sut in suts)
{
var postEfUser = await sut.CreateAsync(user);
sut.ClearChangeTracking();
var searchedEfUsersCollection = await sut.SearchAsync(postEfUser.Email.ToUpperInvariant(), skip, take);
searchedEfUsers.Concat(searchedEfUsersCollection.ToList());
}
var postSqlUser = await sqlUserRepo.CreateAsync(user);
var searchedSqlUsers = await sqlUserRepo.SearchAsync(postSqlUser.Email.ToUpperInvariant(), skip, take);
var distinctItems = searchedEfUsers.Concat(searchedSqlUsers).Distinct(equalityCompare);
Assert.True(!distinctItems.Skip(1).Any());
}
[CiSkippedTheory, EfUserAutoData]
public async void GetManyByPremiumAsync_Works_DataMatches(User user,
List<EfRepo.UserRepository> suts, SqlRepo.UserRepository sqlUserRepo)
{
var returnedUsers = new List<User>();
foreach (var sut in suts)
{
var postEfUser = await sut.CreateAsync(user);
sut.ClearChangeTracking();
var searchedEfUsers = await sut.GetManyByPremiumAsync(user.Premium);
returnedUsers.Concat(searchedEfUsers.ToList());
}
var postSqlUser = await sqlUserRepo.CreateAsync(user);
var searchedSqlUsers = await sqlUserRepo.GetManyByPremiumAsync(user.Premium);
returnedUsers.Concat(searchedSqlUsers.ToList());
Assert.True(returnedUsers.All(x => x.Premium == user.Premium));
}
[CiSkippedTheory, EfUserAutoData]
public async void GetPublicKeyAsync_Works_DataMatches(User user, List<EfRepo.UserRepository> suts,
SqlRepo.UserRepository sqlUserRepo)
{
var returnedKeys = new List<string>();
foreach (var sut in suts)
{
var postEfUser = await sut.CreateAsync(user);
sut.ClearChangeTracking();
var efKey = await sut.GetPublicKeyAsync(postEfUser.Id);
returnedKeys.Add(efKey);
}
var postSqlUser = await sqlUserRepo.CreateAsync(user);
var sqlKey = await sqlUserRepo.GetPublicKeyAsync(postSqlUser.Id);
returnedKeys.Add(sqlKey);
Assert.True(!returnedKeys.Distinct().Skip(1).Any());
}
[CiSkippedTheory, EfUserAutoData]
public async void GetAccountRevisionDateAsync(User user, List<EfRepo.UserRepository> suts,
SqlRepo.UserRepository sqlUserRepo)
{
var returnedKeys = new List<string>();
foreach (var sut in suts)
{
var postEfUser = await sut.CreateAsync(user);
sut.ClearChangeTracking();
var efKey = await sut.GetPublicKeyAsync(postEfUser.Id);
returnedKeys.Add(efKey);
}
var postSqlUser = await sqlUserRepo.CreateAsync(user);
var sqlKey = await sqlUserRepo.GetPublicKeyAsync(postSqlUser.Id);
returnedKeys.Add(sqlKey);
Assert.True(!returnedKeys.Distinct().Skip(1).Any());
}
[CiSkippedTheory, EfUserAutoData]
public async void UpdateRenewalReminderDateAsync_Works_DataMatches(User user,
DateTime updatedReminderDate, List<EfRepo.UserRepository> suts,
SqlRepo.UserRepository sqlUserRepo)
{
var savedDates = new List<DateTime?>();
foreach (var sut in suts)
{
var postEfUser = user;
postEfUser = await sut.CreateAsync(user);
sut.ClearChangeTracking();
await sut.UpdateRenewalReminderDateAsync(postEfUser.Id, updatedReminderDate);
sut.ClearChangeTracking();
var replacedUser = await sut.GetByIdAsync(postEfUser.Id);
savedDates.Add(replacedUser.RenewalReminderDate);
}
var postSqlUser = await sqlUserRepo.CreateAsync(user);
await sqlUserRepo.UpdateRenewalReminderDateAsync(postSqlUser.Id, updatedReminderDate);
var replacedSqlUser = await sqlUserRepo.GetByIdAsync(postSqlUser.Id);
savedDates.Add(replacedSqlUser.RenewalReminderDate);
var distinctItems = savedDates.GroupBy(e => e.ToString());
Assert.True(!distinctItems.Skip(1).Any() &&
savedDates.All(e => e.ToString() == updatedReminderDate.ToString()));
}
[CiSkippedTheory, EfUserAutoData]
public async void GetBySsoUserAsync_Works_DataMatches(User user, Organization org,
SsoUser ssoUser, UserCompare equalityComparer, List<EfRepo.UserRepository> suts,
List<EfRepo.SsoUserRepository> ssoUserRepos, List<EfRepo.OrganizationRepository> orgRepos,
SqlRepo.UserRepository sqlUserRepo, SqlRepo.SsoUserRepository sqlSsoUserRepo,
SqlRepo.OrganizationRepository sqlOrgRepo)
{
var returnedList = new List<User>();
foreach (var sut in suts)
{
var i = suts.IndexOf(sut);
var postEfUser = await sut.CreateAsync(user);
sut.ClearChangeTracking();
var efOrg = await orgRepos[i].CreateAsync(org);
sut.ClearChangeTracking();
ssoUser.UserId = postEfUser.Id;
ssoUser.OrganizationId = efOrg.Id;
var postEfSsoUser = await ssoUserRepos[i].CreateAsync(ssoUser);
sut.ClearChangeTracking();
var returnedUser = await sut.GetBySsoUserAsync(postEfSsoUser.ExternalId.ToUpperInvariant(), efOrg.Id);
returnedList.Add(returnedUser);
}
var sqlUser = await sqlUserRepo.CreateAsync(user);
var sqlOrganization = await sqlOrgRepo.CreateAsync(org);
ssoUser.UserId = sqlUser.Id;
ssoUser.OrganizationId = sqlOrganization.Id;
var postSqlSsoUser = await sqlSsoUserRepo.CreateAsync(ssoUser);
var returnedSqlUser = await sqlUserRepo
.GetBySsoUserAsync(postSqlSsoUser.ExternalId, sqlOrganization.Id);
returnedList.Add(returnedSqlUser);
var distinctItems = returnedList.Distinct(equalityComparer);
Assert.True(!distinctItems.Skip(1).Any());
}
}
}

File diff suppressed because it is too large Load Diff