mirror of https://github.com/abpframework/abp.git
12 changed files with 373 additions and 100 deletions
@ -0,0 +1,13 @@ |
|||
using Volo.Abp.Testing; |
|||
|
|||
namespace Volo.Abp.Auditing |
|||
{ |
|||
|
|||
public class AbpAuditingTestBase : AbpIntegratedTest<AbpAuditingTestModule> |
|||
{ |
|||
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) |
|||
{ |
|||
options.UseAutofac(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,64 @@ |
|||
using Microsoft.Data.Sqlite; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Infrastructure; |
|||
using Microsoft.EntityFrameworkCore.Storage; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Auditing.App.Entities; |
|||
using Volo.Abp.Auditing.App.EntityFrameworkCore; |
|||
using Volo.Abp.Autofac; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.Auditing |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpTestBaseModule), |
|||
typeof(AbpAutofacModule), |
|||
typeof(AbpEntityFrameworkCoreModule) |
|||
)] |
|||
public class AbpAuditingTestModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddAbpDbContext<AbpAuditingTestDbContext>(options => |
|||
{ |
|||
options.AddDefaultRepositories(true); |
|||
}); |
|||
|
|||
var sqliteConnection = CreateDatabaseAndGetConnection(); |
|||
|
|||
Configure<AbpDbContextOptions>(options => |
|||
{ |
|||
options.Configure(abpDbContextConfigurationContext => |
|||
{ |
|||
abpDbContextConfigurationContext.DbContextOptions.UseSqlite(sqliteConnection); |
|||
}); |
|||
}); |
|||
|
|||
Configure<AbpAuditingOptions>(options => |
|||
{ |
|||
options.EntityHistorySelectors.Add( |
|||
new NamedTypeSelector( |
|||
"AppEntityWithSelector", |
|||
type => type == typeof(AppEntityWithSelector)) |
|||
); |
|||
}); |
|||
|
|||
context.Services.AddType<Auditing_Tests.MyAuditedObject1>(); |
|||
} |
|||
|
|||
private static SqliteConnection CreateDatabaseAndGetConnection() |
|||
{ |
|||
var connection = new SqliteConnection("Data Source=:memory:"); |
|||
connection.Open(); |
|||
|
|||
using (var context = new AbpAuditingTestDbContext(new DbContextOptionsBuilder<AbpAuditingTestDbContext>() |
|||
.UseSqlite(connection).Options)) |
|||
{ |
|||
context.GetService<IRelationalDatabaseCreator>().CreateTables(); |
|||
} |
|||
|
|||
return connection; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using System; |
|||
using Volo.Abp.Domain.Entities; |
|||
|
|||
namespace Volo.Abp.Auditing.App.Entities |
|||
{ |
|||
[Audited] |
|||
public class AppEntityWithAudited : AggregateRoot<Guid> |
|||
{ |
|||
protected AppEntityWithAudited() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public AppEntityWithAudited(Guid id, string name) |
|||
: base(id) |
|||
{ |
|||
Name = name; |
|||
} |
|||
|
|||
public string Name { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using System; |
|||
using Volo.Abp.Domain.Entities; |
|||
|
|||
namespace Volo.Abp.Auditing.App.Entities |
|||
{ |
|||
[DisableAuditing] |
|||
public class AppEntityWithDisableAuditing : AggregateRoot<Guid> |
|||
{ |
|||
protected AppEntityWithDisableAuditing() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public AppEntityWithDisableAuditing(Guid id, string name) |
|||
: base(id) |
|||
{ |
|||
Name = name; |
|||
} |
|||
|
|||
public string Name { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using System; |
|||
using Volo.Abp.Domain.Entities; |
|||
|
|||
namespace Volo.Abp.Auditing.App.Entities |
|||
{ |
|||
[DisableAuditing] |
|||
public class AppEntityWithDisableAuditingAndPropertyHasAudited : AggregateRoot<Guid> |
|||
{ |
|||
protected AppEntityWithDisableAuditingAndPropertyHasAudited() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public AppEntityWithDisableAuditingAndPropertyHasAudited(Guid id, string name, string name2) |
|||
: base(id) |
|||
{ |
|||
Name = name; |
|||
Name2 = name2; |
|||
} |
|||
|
|||
[Audited] |
|||
public string Name { get; set; } |
|||
|
|||
public string Name2 { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using System; |
|||
using Volo.Abp.Domain.Entities; |
|||
|
|||
namespace Volo.Abp.Auditing.App.Entities |
|||
{ |
|||
public class AppEntityWithPropertyHasAudited : AggregateRoot<Guid> |
|||
{ |
|||
protected AppEntityWithPropertyHasAudited() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public AppEntityWithPropertyHasAudited(Guid id, string name) |
|||
: base(id) |
|||
{ |
|||
Name = name; |
|||
} |
|||
|
|||
[Audited] |
|||
public string Name { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using System; |
|||
using Volo.Abp.Domain.Entities; |
|||
|
|||
namespace Volo.Abp.Auditing.App.Entities |
|||
{ |
|||
public class AppEntityWithSelector : AggregateRoot<Guid> |
|||
{ |
|||
public AppEntityWithSelector(Guid id, string name) |
|||
: base(id) |
|||
{ |
|||
Name = name; |
|||
} |
|||
|
|||
public string Name { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Volo.Abp.Auditing.App.Entities; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
|
|||
namespace Volo.Abp.Auditing.App.EntityFrameworkCore |
|||
{ |
|||
public class AbpAuditingTestDbContext : AbpDbContext<AbpAuditingTestDbContext> |
|||
{ |
|||
public DbSet<AppEntityWithAudited> AppEntityWithAudited { get; set; } |
|||
|
|||
public DbSet<AppEntityWithDisableAuditing> AppEntityWithDisableAuditing { get; set; } |
|||
|
|||
public DbSet<AppEntityWithDisableAuditingAndPropertyHasAudited> AppEntityWithDisableAuditingAndPropertyHasAudited { get; set; } |
|||
|
|||
public DbSet<AppEntityWithPropertyHasAudited> AppEntityWithPropertyHasAudited { get; set; } |
|||
|
|||
public DbSet<AppEntityWithSelector> AppEntityWithSelector { get; set; } |
|||
|
|||
public AbpAuditingTestDbContext(DbContextOptions<AbpAuditingTestDbContext> options) |
|||
: base(options) |
|||
{ |
|||
|
|||
} |
|||
} |
|||
} |
|||
@ -1,93 +0,0 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using NSubstitute; |
|||
using Volo.Abp.Autofac; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Testing; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.Auditing |
|||
{ |
|||
public class AuditingInterceptor_Tests : AbpIntegratedTest<AuditingInterceptor_Tests.TestModule> |
|||
{ |
|||
private IAuditingStore _auditingStore; |
|||
private IAuditingManager _auditingManager; |
|||
|
|||
public AuditingInterceptor_Tests() |
|||
{ |
|||
_auditingManager = GetRequiredService<IAuditingManager>(); |
|||
} |
|||
|
|||
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) |
|||
{ |
|||
options.UseAutofac(); |
|||
} |
|||
|
|||
protected override void AfterAddApplication(IServiceCollection services) |
|||
{ |
|||
_auditingStore = Substitute.For<IAuditingStore>(); |
|||
services.Replace(ServiceDescriptor.Singleton(_auditingStore)); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Write_AuditLog_For_Classes_That_Implement_IAuditingEnabled() |
|||
{ |
|||
var myAuditedObject1 = GetRequiredService<MyAuditedObject1>(); |
|||
|
|||
using (var scope = _auditingManager.BeginScope()) |
|||
{ |
|||
await myAuditedObject1.DoItAsync(new InputObject { Value1 = "forty-two", Value2 = 42 }).ConfigureAwait(false); |
|||
await scope.SaveAsync().ConfigureAwait(false); |
|||
} |
|||
|
|||
#pragma warning disable 4014
|
|||
_auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>()); |
|||
#pragma warning restore 4014
|
|||
} |
|||
|
|||
[DependsOn( |
|||
typeof(AbpAuditingModule), |
|||
typeof(AbpAutofacModule) |
|||
)] |
|||
public class TestModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddType<MyAuditedObject1>(); |
|||
} |
|||
} |
|||
|
|||
public interface IMyAuditedObject : ITransientDependency, IAuditingEnabled |
|||
{ |
|||
|
|||
} |
|||
|
|||
public class MyAuditedObject1 : IMyAuditedObject |
|||
{ |
|||
public async virtual Task<ResultObject> DoItAsync(InputObject inputObject) |
|||
{ |
|||
return new ResultObject |
|||
{ |
|||
Value1 = inputObject.Value1 + "-result", |
|||
Value2 = inputObject.Value2 + 1 |
|||
}; |
|||
} |
|||
} |
|||
|
|||
public class ResultObject |
|||
{ |
|||
public string Value1 { get; set; } |
|||
|
|||
public int Value2 { get; set; } |
|||
} |
|||
|
|||
public class InputObject |
|||
{ |
|||
public string Value1 { get; set; } |
|||
|
|||
public int Value2 { get; set; } |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,154 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using NSubstitute; |
|||
using Volo.Abp.Auditing.App.Entities; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.Auditing |
|||
{ |
|||
public class Auditing_Tests : AbpAuditingTestBase |
|||
{ |
|||
private IAuditingStore _auditingStore; |
|||
private IAuditingManager _auditingManager; |
|||
|
|||
public Auditing_Tests() |
|||
{ |
|||
_auditingManager = GetRequiredService<IAuditingManager>(); |
|||
} |
|||
|
|||
protected override void AfterAddApplication(IServiceCollection services) |
|||
{ |
|||
_auditingStore = Substitute.For<IAuditingStore>(); |
|||
services.Replace(ServiceDescriptor.Singleton(_auditingStore)); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Write_AuditLog_For_Classes_That_Implement_IAuditingEnabled() |
|||
{ |
|||
var myAuditedObject1 = GetRequiredService<MyAuditedObject1>(); |
|||
|
|||
using (var scope = _auditingManager.BeginScope()) |
|||
{ |
|||
await myAuditedObject1.DoItAsync(new InputObject { Value1 = "forty-two", Value2 = 42 }).ConfigureAwait(false); |
|||
await scope.SaveAsync().ConfigureAwait(false); |
|||
} |
|||
|
|||
#pragma warning disable 4014
|
|||
_auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>()); |
|||
#pragma warning restore 4014
|
|||
} |
|||
|
|||
public interface IMyAuditedObject : ITransientDependency, IAuditingEnabled |
|||
{ |
|||
|
|||
} |
|||
|
|||
public class MyAuditedObject1 : IMyAuditedObject |
|||
{ |
|||
public async virtual Task<ResultObject> DoItAsync(InputObject inputObject) |
|||
{ |
|||
return new ResultObject |
|||
{ |
|||
Value1 = inputObject.Value1 + "-result", |
|||
Value2 = inputObject.Value2 + 1 |
|||
}; |
|||
} |
|||
} |
|||
|
|||
public class ResultObject |
|||
{ |
|||
public string Value1 { get; set; } |
|||
|
|||
public int Value2 { get; set; } |
|||
} |
|||
|
|||
public class InputObject |
|||
{ |
|||
public string Value1 { get; set; } |
|||
|
|||
public int Value2 { get; set; } |
|||
} |
|||
|
|||
[Fact] |
|||
public virtual async Task Should_Write_AuditLog_For_Entity_That_Has_Audited_Attribute() |
|||
{ |
|||
using (var scope = _auditingManager.BeginScope()) |
|||
{ |
|||
var repository = ServiceProvider.GetRequiredService<IBasicRepository<AppEntityWithAudited, Guid>>(); |
|||
await repository.InsertAsync(new AppEntityWithAudited(Guid.NewGuid(), "test name")).ConfigureAwait(false); |
|||
await scope.SaveAsync().ConfigureAwait(false); |
|||
} |
|||
|
|||
#pragma warning disable 4014
|
|||
_auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>()); |
|||
#pragma warning restore 4014
|
|||
} |
|||
|
|||
[Fact] |
|||
public virtual async Task Should_Not_Write_AuditLog_For_Entity_That_Has_DisableAuditing_Attribute() |
|||
{ |
|||
using (var scope = _auditingManager.BeginScope()) |
|||
{ |
|||
var repository = ServiceProvider.GetRequiredService<IBasicRepository<AppEntityWithDisableAuditing, Guid>>(); |
|||
await repository.InsertAsync(new AppEntityWithDisableAuditing(Guid.NewGuid(), "test name")).ConfigureAwait(false); |
|||
await scope.SaveAsync().ConfigureAwait(false); |
|||
} |
|||
|
|||
#pragma warning disable 4014
|
|||
_auditingStore.DidNotReceive().SaveAsync(Arg.Any<AuditLogInfo>()); |
|||
#pragma warning restore 4014
|
|||
} |
|||
|
|||
[Fact] |
|||
public virtual async Task Should_Write_AuditLog_For_Entity_That_Meet_Selectors() |
|||
{ |
|||
using (var scope = _auditingManager.BeginScope()) |
|||
{ |
|||
var repository = ServiceProvider.GetRequiredService<IBasicRepository<AppEntityWithSelector, Guid>>(); |
|||
await repository.InsertAsync(new AppEntityWithSelector(Guid.NewGuid(), "test name")).ConfigureAwait(false); |
|||
await scope.SaveAsync().ConfigureAwait(false); |
|||
} |
|||
|
|||
#pragma warning disable 4014
|
|||
_auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>()); |
|||
#pragma warning restore 4014
|
|||
} |
|||
|
|||
[Fact] |
|||
public virtual async Task Should_Write_AuditLog_For_Entity_That_Property_Has_Audited_Attribute() |
|||
{ |
|||
using (var scope = _auditingManager.BeginScope()) |
|||
{ |
|||
var repository = ServiceProvider.GetRequiredService<IBasicRepository<AppEntityWithPropertyHasAudited, Guid>>(); |
|||
await repository.InsertAsync(new AppEntityWithPropertyHasAudited(Guid.NewGuid(), "test name")).ConfigureAwait(false); |
|||
await scope.SaveAsync().ConfigureAwait(false); |
|||
} |
|||
|
|||
#pragma warning disable 4014
|
|||
_auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>()); |
|||
#pragma warning restore 4014
|
|||
} |
|||
|
|||
[Fact] |
|||
public virtual async Task Should_Write_AuditLog_For_Entity_That_Property_Has_Audited_Attribute_Even_Entity_Has_DisableAuditing_Attribute() |
|||
{ |
|||
using (var scope = _auditingManager.BeginScope()) |
|||
{ |
|||
var repository = ServiceProvider.GetRequiredService<IBasicRepository<AppEntityWithDisableAuditingAndPropertyHasAudited, Guid>>(); |
|||
await repository.InsertAsync(new AppEntityWithDisableAuditingAndPropertyHasAudited(Guid.NewGuid(), "test name", "test name2")).ConfigureAwait(false); |
|||
await scope.SaveAsync().ConfigureAwait(false); |
|||
} |
|||
|
|||
#pragma warning disable 4014
|
|||
_auditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x => |
|||
x.EntityChanges.Count == 1 && x.EntityChanges[0].PropertyChanges.Count == 1 && |
|||
x.EntityChanges[0].PropertyChanges[0].PropertyName == |
|||
nameof(AppEntityWithDisableAuditingAndPropertyHasAudited.Name))); |
|||
#pragma warning restore 4014
|
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue