Skip to content

Commit 1f9875d

Browse files
committed
Added additional tests
1 parent 02749da commit 1f9875d

12 files changed

Lines changed: 206 additions & 7 deletions

File tree

src/EntityFrameworkCore.Triggered.Abstractions/ITriggerContext.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace EntityFrameworkCore.Triggered
1+
using System.Collections.Generic;
2+
3+
namespace EntityFrameworkCore.Triggered
24
{
35
public interface ITriggerContext<out TEntity>
46
where TEntity : class
@@ -8,5 +10,10 @@ public interface ITriggerContext<out TEntity>
810
TEntity Entity { get; }
911

1012
TEntity? UnmodifiedEntity { get; }
13+
14+
/// <summary>
15+
/// Gets or sets a key/value collection that can be used to share data within the scope of this Entity
16+
/// </summary>
17+
IDictionary<object, object> EntityBag { get; }
1118
}
1219
}

src/EntityFrameworkCore.Triggered/Internal/EntityStateBagManager.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ namespace EntityFrameworkCore.Triggered.Internal
66
{
77
public sealed class EntityBagStateManager
88
{
9-
private readonly Dictionary<object, IDictionary<string, object>> _resolvedBags = new();
9+
private readonly Dictionary<object, IDictionary<object, object>> _resolvedBags = new();
1010

11-
public IDictionary<string, object> GetForEntity(object entity)
11+
public IDictionary<object, object> GetForEntity(object entity)
1212
{
1313
if (!_resolvedBags.TryGetValue(entity, out var bag))
1414
{
15-
bag = new Dictionary<string, object>();
15+
bag = new Dictionary<object, object>();
1616
_resolvedBags.Add(entity, bag);
1717
}
1818

src/EntityFrameworkCore.Triggered/TriggerContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,6 @@ public TEntity? UnmodifiedEntity
4444
}
4545
}
4646

47-
public IDictionary<string, object> Bag => _entityBagStateManager.GetForEntity(_entity);
47+
public IDictionary<object, object> EntityBag => _entityBagStateManager.GetForEntity(_entity);
4848
}
4949
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using Microsoft.EntityFrameworkCore;
2+
3+
namespace EntityFrameworkCore.Triggered.IntegrationTests.EntityBags
4+
{
5+
public class ApplicationDbContext
6+
#if EFCORETRIGGERED1
7+
: TriggeredDbContext
8+
#else
9+
: DbContext
10+
#endif
11+
{
12+
public ApplicationDbContext(DbContextOptions options) : base(options)
13+
{
14+
}
15+
16+
public DbSet<User> Users { get; set; }
17+
}
18+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using Microsoft.EntityFrameworkCore;
7+
using Microsoft.Extensions.DependencyInjection;
8+
using ScenarioTests;
9+
using Xunit;
10+
11+
namespace EntityFrameworkCore.Triggered.IntegrationTests.EntityBags
12+
{
13+
public partial class EntityBagsTestScenario
14+
{
15+
[Scenario(NamingPolicy = ScenarioTestMethodNamingPolicy.Test)]
16+
public void PlayScenario(ScenarioContext scenario)
17+
{
18+
using var dbcontext = new ApplicationDbContext(
19+
new DbContextOptionsBuilder()
20+
.UseInMemoryDatabase(scenario.TargetName)
21+
.UseTriggers(triggerOptions => {
22+
triggerOptions.AddTrigger<Triggers.StampModifiedOnTrigger>();
23+
triggerOptions.AddTrigger<Triggers.SoftDeleteTrigger>();
24+
})
25+
.Options
26+
);
27+
28+
var user = new User();
29+
dbcontext.Users.Add(user);
30+
dbcontext.SaveChanges();
31+
32+
scenario.Fact("ModifiedOn is null", () => Assert.Null(user.ModifiedOn));
33+
scenario.Fact("DeletedOn is null", () => Assert.Null(user.DeletedOn));
34+
35+
dbcontext.Remove(user);
36+
dbcontext.SaveChanges();
37+
38+
scenario.Fact("ModifiedOn is null after removal", () => Assert.Null(user.ModifiedOn));
39+
scenario.Fact("DeletedOn is not null after removal", () => Assert.NotNull(user.DeletedOn));
40+
41+
user.Name = "Jon";
42+
dbcontext.SaveChanges();
43+
44+
scenario.Fact("ModifiedOn is not null after update", () => Assert.NotNull(user.ModifiedOn));
45+
}
46+
}
47+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
8+
namespace EntityFrameworkCore.Triggered.IntegrationTests.EntityBags.Triggers
9+
{
10+
public class SoftDeleteTrigger : IBeforeSaveTrigger<User>
11+
{
12+
public const string IsSoftDeleted = "SoftDeleteTrigger_IsSoftDeleted";
13+
14+
readonly ApplicationDbContext _dbContext;
15+
16+
public SoftDeleteTrigger(ApplicationDbContext dbContext)
17+
{
18+
_dbContext = dbContext;
19+
}
20+
21+
public Task BeforeSave(ITriggerContext<User> context, CancellationToken cancellationToken)
22+
{
23+
if (context.ChangeType is ChangeType.Deleted)
24+
{
25+
context.EntityBag[IsSoftDeleted] = true;
26+
context.Entity.DeletedOn = DateTime.UtcNow;
27+
28+
_dbContext.Entry(context.Entity).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
29+
}
30+
31+
return Task.CompletedTask;
32+
}
33+
}
34+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
8+
namespace EntityFrameworkCore.Triggered.IntegrationTests.EntityBags.Triggers
9+
{
10+
public class StampModifiedOnTrigger : IBeforeSaveTrigger<User>
11+
{
12+
public Task BeforeSave(ITriggerContext<User> context, CancellationToken cancellationToken)
13+
{
14+
if (context.ChangeType is ChangeType.Modified)
15+
{
16+
if (!context.EntityBag.ContainsKey(SoftDeleteTrigger.IsSoftDeleted))
17+
{
18+
context.Entity.ModifiedOn = DateTime.UtcNow;
19+
}
20+
}
21+
22+
return Task.CompletedTask;
23+
}
24+
}
25+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System;
2+
3+
namespace EntityFrameworkCore.Triggered.IntegrationTests.EntityBags
4+
{
5+
public class User
6+
{
7+
public int Id { get; set; }
8+
public string Name { get; set; }
9+
10+
public DateTime? ModifiedOn { get; set; }
11+
public DateTime? DeletedOn { get; set; }
12+
}
13+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using EntityFrameworkCore.Triggered.Internal;
7+
using Xunit;
8+
9+
namespace EntityFrameworkCore.Triggered.Tests.Internal
10+
{
11+
public class EntityBagStateManagerTests
12+
{
13+
[Fact]
14+
public void GetForEntity_MultipleCallsForSameEntity_ReturnsSameInstance()
15+
{
16+
var subject = new EntityBagStateManager();
17+
var entity = new object();
18+
var expectedBag = subject.GetForEntity(entity);
19+
20+
var bag = subject.GetForEntity(entity);
21+
22+
Assert.Same(expectedBag, bag);
23+
}
24+
25+
[Fact]
26+
public void GetForEntity_MultipleCallsForDifferentEntities_ReturnsDifferentInstances()
27+
{
28+
var subject = new EntityBagStateManager();
29+
var entity1 = new object();
30+
var entity2 = new object();
31+
32+
var entity1Bag = subject.GetForEntity(entity1);
33+
var entity2Bag = subject.GetForEntity(entity2);
34+
35+
Assert.NotSame(entity1Bag, entity2Bag);
36+
}
37+
}
38+
}
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace EntityFrameworkCore.Triggered.Tests.Stubs
1+
using System.Collections.Generic;
2+
3+
namespace EntityFrameworkCore.Triggered.Tests.Stubs
24
{
35
public class TriggerContextStub<TEntity> : ITriggerContext<TEntity>
46
where TEntity : class
@@ -7,5 +9,6 @@ public class TriggerContextStub<TEntity> : ITriggerContext<TEntity>
79
public ChangeType ChangeType { get; set; }
810
public TEntity Entity { get; set; }
911
public TEntity UnmodifiedEntity { get; set; }
12+
public IDictionary<object, object> EntityBag { get; set; }
1013
}
1114
}

0 commit comments

Comments
 (0)