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