Skip to content

Commit

Permalink
Merge pull request #65 from wemogy/56-soft-delete-gets-implicitly-ena…
Browse files Browse the repository at this point in the history
…bled-by-inheriting-from-entitybase

Fix Soft-Delete gets implicitly enabled by inheriting from EntityBase
  • Loading branch information
SebastianKuesters authored Mar 13, 2023
2 parents b334604 + 95cc630 commit 68eda5d
Show file tree
Hide file tree
Showing 14 changed files with 153 additions and 19 deletions.
2 changes: 1 addition & 1 deletion env/cosmos/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ services:
network_mode: host
image: robinmanuelthiel/cosmos-db-setup:2.0.0
command:
- "{\"databaseName\": \"infrastructuredbtests\", \"containers\": [{\"name\": \"users\", \"partitionKey\": \"/tenantId\"}]}"
- "{\"databaseName\": \"infrastructuredbtests\", \"containers\": [{\"name\": \"users\", \"partitionKey\": \"/tenantId\"}, {\"name\": \"datacenters\", \"partitionKey\": \"/partitionKey\"}]}"
depends_on:
- cosmosdb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Wemogy.Infrastructure.Database.Core.Abstractions;
using Wemogy.Infrastructure.Database.Core.UnitTests.Fakes.Entities;

namespace Wemogy.Infrastructure.Database.Core.UnitTests.DatabaseRepositories
{
public interface IDataCenterRepository : IDatabaseRepository<DataCenter>
{
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using FluentAssertions;
using Wemogy.Core.Errors.Exceptions;
using Wemogy.Infrastructure.Database.Core.Attributes;
using Wemogy.Infrastructure.Database.Core.Extensions;
using Xunit;
Expand All @@ -18,13 +19,21 @@ public class TypeExtensionsTests
[InlineData(
typeof(SoftDeletableClassSubClass),
true)]
public void IsSoftDeletableShouldWork(Type type, bool expectedToBeSoftDeletable)
public void ThrowIfNotSoftDeletableShouldWork(Type type, bool expectedToBeSoftDeletable)
{
// Act
var isSoftDeletable = type.IsSoftDeletable();
var exception = Record.Exception(() => type.ThrowIfNotSoftDeletable());

// Assert
isSoftDeletable.Should().Be(expectedToBeSoftDeletable);
if (expectedToBeSoftDeletable)
{
exception.Should().BeNull();
}
else
{
exception.Should().NotBeNull();
exception.Should().BeOfType<UnexpectedErrorException>();
}
}

private class NotSoftDeletableClass
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using Bogus;
using Wemogy.Infrastructure.Database.Core.Abstractions;
using Wemogy.Infrastructure.Database.Core.Attributes;

namespace Wemogy.Infrastructure.Database.Core.UnitTests.Fakes.Entities
{
public class DataCenter : EntityBase
{
public string Location { get; set; }

[PartitionKey]
public string PartitionKey { get; set; }

public DataCenter()
: base(Guid.NewGuid().ToString())
{
Location = string.Empty;
PartitionKey = string.Empty;
}

public static Faker<DataCenter> Faker
{
get
{
return new Faker<DataCenter>()
.RuleFor(
x => x.PartitionKey,
f => f.Random.Guid().ToString())
.RuleFor(
x => x.Location,
f => f.Address.Country())
.RuleFor(
x => x.IsDeleted,
f => false);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ public abstract partial class MultiTenantDatabaseRepositoryTestsBase : Repositor
{
protected MultiTenantDatabaseRepositoryTestsBase(
Func<IDatabaseRepository<User>> multiTenantUserRepositoryFactory1,
Func<IDatabaseRepository<User>> multiTenantUserRepositoryFactory2)
: base(multiTenantUserRepositoryFactory1)
Func<IDatabaseRepository<User>> multiTenantUserRepositoryFactory2,
Func<IDatabaseRepository<DataCenter>> dataCenterRepositoryFactory)
: base(multiTenantUserRepositoryFactory1, dataCenterRepositoryFactory)
{
AppleUserRepository = multiTenantUserRepositoryFactory2();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Wemogy.Infrastructure.Database.Core.Plugins.MultiTenantDatabase.Abstractions;

namespace Wemogy.Infrastructure.Database.Core.UnitTests.Providers;

public class DataCenterTenantProvider : IDatabaseTenantProvider
{
public string GetTenantId() => "datacenter-staging";
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,27 @@ public async Task GetAllAsync_ShouldRespectSoftDeleteReturnAllItems()
// Assert
usersFromDb.Should().HaveCount(10);
}

[Fact]
public async Task GetAllAsync_SoftDeleteShouldNotEnableByDefault()
{
// Arrange
await ResetAsync();
var dataCenters = DataCenter.Faker.Generate(20);
foreach (var dataCenter in dataCenters)
{
if (dataCenters.IndexOf(dataCenter) % 2 == 0)
{
dataCenter.IsDeleted = true;
}

await DataCenterRepository.CreateAsync(dataCenter);
}

// Act
var result = await DataCenterRepository.GetAllAsync();

// Assert
result.Should().HaveCount(20);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,27 @@
using System.Threading.Tasks;
using Wemogy.Infrastructure.Database.Core.Abstractions;
using Wemogy.Infrastructure.Database.Core.Factories;
using Wemogy.Infrastructure.Database.Core.UnitTests.DatabaseRepositories;
using Wemogy.Infrastructure.Database.Core.UnitTests.Fakes.Entities;

namespace Wemogy.Infrastructure.Database.Core.UnitTests.Repositories;

public abstract partial class RepositoryTestBase
{
protected RepositoryTestBase(Func<IDatabaseRepository<User>> userRepositoryFactory)
protected RepositoryTestBase(Func<IDatabaseRepository<User>> userRepositoryFactory, Func<IDatabaseRepository<DataCenter>> dataCenterRepositoryFactory)
{
MicrosoftUserRepository = userRepositoryFactory();
UserRepositoryFactory = userRepositoryFactory;
DataCenterRepository = dataCenterRepositoryFactory();
DatabaseRepositoryFactoryFactory.DatabaseClientProxy = null;
}

protected IDatabaseRepository<User> MicrosoftUserRepository { get; set; }
protected IDatabaseRepository<DataCenter> DataCenterRepository { get; set; }
private Func<IDatabaseRepository<User>> UserRepositoryFactory { get; }

protected virtual async Task ResetAsync()
{
await MicrosoftUserRepository.DeleteAsync(x => true);
await DataCenterRepository.DeleteAsync(x => true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public static void ThrowIfNotSoftDeletable(this Type entityType)
}
}

public static bool IsSoftDeletable(this Type entityType)
private static bool IsSoftDeletable(this Type entityType)
{
var softDeleteFlagAttributeType = typeof(SoftDeleteFlagAttribute);
return entityType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using Wemogy.Infrastructure.Database.Core.Abstractions;
using Wemogy.Infrastructure.Database.Core.Attributes;
using Wemogy.Infrastructure.Database.Core.Delegates;
using Wemogy.Infrastructure.Database.Core.Extensions;
using Wemogy.Infrastructure.Database.Core.Models;
using Wemogy.Infrastructure.Database.Core.Setup;

Expand Down Expand Up @@ -56,7 +55,7 @@ private DatabaseRepositoryOptions ResolveDatabaseRepositoryOptions(DatabaseRepos
typeMetadata.DatabaseRepositoryType.GetCustomAttribute<RepositoryOptionsAttribute>();
var databaseRepositoryOptions = new DatabaseRepositoryOptions(
repositoryOptionsAttribute?.CollectionName ?? $"{typeMetadata.EntityType.Name.ToLower()}s",
repositoryOptionsAttribute?.EnableSoftDelete ?? typeMetadata.EntityType.IsSoftDeletable());
repositoryOptionsAttribute?.EnableSoftDelete ?? false);
return databaseRepositoryOptions;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ public class CosmosMultiTenantDatabaseRepositoryTests : MultiTenantDatabaseRepos
{
public CosmosMultiTenantDatabaseRepositoryTests()
: base(
GetFactory(new MicrosoftTenantProvider()),
GetFactory(new AppleTenantProvider()))
GetFactoryUser(new MicrosoftTenantProvider()),
GetFactoryUser(new AppleTenantProvider()),
GetFactoryDataCenter(new DataCenterTenantProvider()))
{
}

private static Func<IDatabaseRepository<User>> GetFactory(IDatabaseTenantProvider provider)
private static Func<IDatabaseRepository<User>> GetFactoryUser(IDatabaseTenantProvider provider)
{
return () =>
{
Expand All @@ -38,4 +39,21 @@ private static Func<IDatabaseRepository<User>> GetFactory(IDatabaseTenantProvide
return multiTenantRepository;
};
}

private static Func<IDatabaseRepository<DataCenter>> GetFactoryDataCenter(IDatabaseTenantProvider provider)
{
return () =>
{
var cosmosDatabaseClientFactory = new CosmosDatabaseClientFactory(
TestingConstants.ConnectionString,
TestingConstants.DatabaseName,
true);
var multiTenantRepository = new MultiTenantDatabaseRepositoryFactory(
cosmosDatabaseClientFactory,
provider).CreateInstance<IDataCenterRepository>();
return multiTenantRepository;
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ namespace Wemogy.Infrastructure.Database.Cosmos.UnitTests.Repositories;
public class CosmosDatabaseRepositoryTests : RepositoryTestBase
{
public CosmosDatabaseRepositoryTests()
: base(() => CosmosDatabaseRepositoryFactory.CreateInstance<IUserRepository>(
: base(
() => CosmosDatabaseRepositoryFactory.CreateInstance<IUserRepository>(
TestingConstants.ConnectionString,
TestingConstants.DatabaseName,
true,
true),
() => CosmosDatabaseRepositoryFactory.CreateInstance<IDataCenterRepository>(
TestingConstants.ConnectionString,
TestingConstants.DatabaseName,
true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ public class InMemoryMultiTenantDatabaseRepositoryTests : MultiTenantDatabaseRep
{
public InMemoryMultiTenantDatabaseRepositoryTests()
: base(
GetFactory(new MicrosoftTenantProvider()),
GetFactory(new AppleTenantProvider()))
GetFactoryUser(new MicrosoftTenantProvider()),
GetFactoryUser(new AppleTenantProvider()),
GetFactoryDataCenter(new DataCenterTenantProvider()))
{
}

private static Func<IDatabaseRepository<User>> GetFactory(IDatabaseTenantProvider provider)
private static Func<IDatabaseRepository<User>> GetFactoryUser(IDatabaseTenantProvider provider)
{
return () =>
{
Expand All @@ -34,4 +35,18 @@ private static Func<IDatabaseRepository<User>> GetFactory(IDatabaseTenantProvide
return multiTenantRepository;
};
}

private static Func<IDatabaseRepository<DataCenter>> GetFactoryDataCenter(IDatabaseTenantProvider provider)
{
return () =>
{
var databaseRepository = InMemoryDatabaseRepositoryFactory.CreateInstance<IDataCenterRepository>();
var multiTenantRepository = new MultiTenantDatabaseRepository<DataCenter>(
databaseRepository,
provider);
return multiTenantRepository;
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Wemogy.Infrastructure.Database.InMemory.UnitTests.Repositories;
public class InMemoryDatabaseRepositoryTests : RepositoryTestBase
{
public InMemoryDatabaseRepositoryTests()
: base(InMemoryDatabaseRepositoryFactory.CreateInstance<IUserRepository>)
: base(InMemoryDatabaseRepositoryFactory.CreateInstance<IUserRepository>, InMemoryDatabaseRepositoryFactory.CreateInstance<IDataCenterRepository>)
{
}
}

0 comments on commit 68eda5d

Please sign in to comment.