Skip to content

Commit 8be7afe

Browse files
committed
update and fix bugs
1 parent 8a8e3d7 commit 8be7afe

File tree

13 files changed

+149
-103
lines changed

13 files changed

+149
-103
lines changed

src/Core/DKNet.Fw.Extensions/PropertyExtensions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ public void SetPropertyValue(string propertyName, object value)
152152
/// </exception>
153153
public void TrySetPropertyValue(string propertyName, object value)
154154
{
155-
if (string.IsNullOrEmpty(propertyName))
156-
throw new ArgumentNullException(nameof(propertyName), "The property name cannot be null or empty.");
155+
ArgumentException.ThrowIfNullOrEmpty(propertyName);
156+
ArgumentNullException.ThrowIfNull(obj);
157157

158158
try
159159
{
@@ -179,8 +179,8 @@ public void TrySetPropertyValue(string propertyName, object value)
179179
/// </exception>
180180
public void TrySetPropertyValue(PropertyInfo property, object? value)
181181
{
182-
if (property == null)
183-
throw new ArgumentNullException(nameof(property), "The property info cannot be null.");
182+
ArgumentNullException.ThrowIfNull(property);
183+
ArgumentNullException.ThrowIfNull(obj);
184184

185185
try
186186
{

src/DKNet.FW.sln.DotSettings.user

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -573,14 +573,14 @@
573573
&lt;/AssemblyExplorer&gt;</s:String>
574574
<s:Boolean x:Key="/Default/Environment/Filtering/ExcludeCoverageFilters/=_002ATests_002A_003B_002A_003B_002A_003B_002A/@EntryIndexedValue">True</s:Boolean>
575575
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002EMemberReordering_002EMigrations_002ECSharpFileLayoutPatternRemoveIsAttributeUpgrade/@EntryIndexedValue">True</s:Boolean>
576-
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=1dff25f3_002Dfbaa_002D485f_002Daa89_002D134e33eadc1a/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from &amp;lt;SlimBus&amp;gt;\&amp;lt;SlimBus.Extensions.Tests&amp;gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
577-
&lt;Project Location="/Users/steven/_CODE/DRUNK/DKNet/src/SlimBus/SlimBus.Extensions.Tests" Presentation="&amp;lt;SlimBus&amp;gt;\&amp;lt;SlimBus.Extensions.Tests&amp;gt;" /&gt;
578-
&lt;/SessionState&gt;</s:String>
579-
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=8275c8a4_002D4ae3_002D406a_002D9cd0_002D6dc520603cf1/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="All tests from &amp;lt;EfCore&amp;gt;\&amp;lt;EfCore.Specifications.Tests&amp;gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
580-
&lt;Project Location="/Users/steven/_CODE/DRUNK/DKNet/src/EfCore/EfCore.Specifications.Tests" Presentation="&amp;lt;EfCore&amp;gt;\&amp;lt;EfCore.Specifications.Tests&amp;gt;" /&gt;
581-
&lt;/SessionState&gt;</s:String>
582-
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=bd8ac265_002D8b5d_002D4892_002D9e95_002Dccb01cb363e1/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="All tests from &amp;lt;EfCore&amp;gt;\&amp;lt;EfCore.Specifications.Tests&amp;gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
583-
&lt;Project Location="/Users/steven/_CODE/DRUNK/DKNet/src" Presentation="&amp;lt;EfCore&amp;gt;" /&gt;
576+
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=6d0fd073_002Df64d_002D4a61_002D9bee_002Dfcf35c41daf3/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="Session" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
577+
&lt;Or&gt;
578+
&lt;Project Location="/Users/steven/_CODE/DRUNK/DKNet/src" Presentation="&amp;lt;AspNet&amp;gt;" /&gt;
579+
&lt;Project Location="/Users/steven/_CODE/DRUNK/DKNet/src" Presentation="&amp;lt;Core&amp;gt;" /&gt;
580+
&lt;Project Location="/Users/steven/_CODE/DRUNK/DKNet/src" Presentation="&amp;lt;EfCore&amp;gt;" /&gt;
581+
&lt;Project Location="/Users/steven/_CODE/DRUNK/DKNet/src" Presentation="&amp;lt;Services&amp;gt;" /&gt;
582+
&lt;Project Location="/Users/steven/_CODE/DRUNK/DKNet/src" Presentation="&amp;lt;SlimBus&amp;gt;" /&gt;
583+
&lt;/Or&gt;
584584
&lt;/SessionState&gt;</s:String>
585585

586586

@@ -787,6 +787,9 @@
787787

788788

789789

790+
791+
792+
790793

791794

792795

src/EfCore/DKNet.EfCore.Abstractions/Entities/AuditedEntity.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,10 @@ protected AuditedEntity(TKey id)
8989
/// <param name="userName">The username of the creator.</param>
9090
/// <param name="createdOn">Optional creation timestamp. Defaults to UTC now if not specified.</param>
9191
/// <exception cref="ArgumentNullException">Thrown when userName is null.</exception>
92-
public void SetCreatedBy(string userName, DateTimeOffset? createdOn = null)
92+
protected void SetCreatedBy(string userName, DateTimeOffset? createdOn = null)
9393
{
9494
if (!string.IsNullOrEmpty(CreatedBy)) return;
95+
ArgumentException.ThrowIfNullOrWhiteSpace(userName);
9596

9697
CreatedBy = userName;
9798
CreatedOn = createdOn ?? DateTimeOffset.UtcNow;
@@ -103,9 +104,10 @@ public void SetCreatedBy(string userName, DateTimeOffset? createdOn = null)
103104
/// <param name="userName">The username of the modifier.</param>
104105
/// <param name="updatedOn">Optional modification timestamp. Defaults to UTC now if not specified.</param>
105106
/// <exception cref="ArgumentNullException">Thrown when userName is null or empty.</exception>
106-
public void SetUpdatedBy(string userName, DateTimeOffset? updatedOn = null)
107+
protected void SetUpdatedBy(string userName, DateTimeOffset? updatedOn = null)
107108
{
108109
if (updatedOn < UpdatedOn) return;
110+
ArgumentException.ThrowIfNullOrWhiteSpace(userName);
109111

110112
UpdatedBy = userName;
111113
UpdatedOn = updatedOn ?? DateTimeOffset.UtcNow;

src/EfCore/DKNet.EfCore.Abstractions/Entities/IAuditedEntity.cs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,21 @@ namespace DKNet.EfCore.Abstractions.Entities;
1313
/// </remarks>
1414
public interface IAuditedEntity<out TKey> : IEntity<TKey>, IAuditedProperties
1515
{
16-
#region Methods
17-
18-
/// <summary>
19-
/// Sets the creation audit information for the entity.
20-
/// </summary>
21-
/// <param name="userName">The identifier of the creating user.</param>
22-
/// <param name="createdOn">Optional creation timestamp.</param>
23-
void SetCreatedBy(string userName, DateTimeOffset? createdOn = null);
24-
25-
/// <summary>
26-
/// Sets the update audit information for the entity.
27-
/// </summary>
28-
/// <param name="userName">The identifier of the updating user.</param>
29-
/// <param name="updatedOn">Optional update timestamp.</param>
30-
void SetUpdatedBy(string userName, DateTimeOffset? updatedOn = null);
31-
32-
#endregion
16+
// #region Methods
17+
//
18+
// /// <summary>
19+
// /// Sets the creation audit information for the entity.
20+
// /// </summary>
21+
// /// <param name="userName">The identifier of the creating user.</param>
22+
// /// <param name="createdOn">Optional creation timestamp.</param>
23+
// protected void SetCreatedBy(string userName, DateTimeOffset? createdOn = null);
24+
//
25+
// /// <summary>
26+
// /// Sets the update audit information for the entity.
27+
// /// </summary>
28+
// /// <param name="userName">The identifier of the updating user.</param>
29+
// /// <param name="updatedOn">Optional update timestamp.</param>
30+
// protected void SetUpdatedBy(string userName, DateTimeOffset? updatedOn = null);
31+
//
32+
// #endregion
3333
}

src/EfCore/EfCore.Abstractions.Tests/AuditedEntityTests.cs

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public TestAuditedEntity(int id) : base(id)
1515

1616
public TestAuditedEntity(int id, string createdBy, DateTimeOffset? createdOn = null) : base(id)
1717
{
18-
SetCreatedBy(createdBy, createdOn);
18+
SetCreatedOn(createdBy, createdOn);
1919
}
2020

2121
#endregion
@@ -25,6 +25,13 @@ public TestAuditedEntity(int id, string createdBy, DateTimeOffset? createdOn = n
2525
public string Name { get; set; } = string.Empty;
2626

2727
#endregion
28+
29+
#region Methods
30+
31+
public void SetCreatedOn(string byUser, DateTimeOffset? on = null) => SetCreatedBy(byUser, on);
32+
public void SetUpdatedOn(string byUser, DateTimeOffset? on = null) => SetUpdatedBy(byUser, on);
33+
34+
#endregion
2835
}
2936

3037
public class TestAuditedGuidEntity : AuditedEntity
@@ -172,7 +179,7 @@ public void LastModifiedBy_WhenNotUpdated_ShouldReturnCreatedBy()
172179
// Arrange
173180
var entity = new TestAuditedEntity();
174181
const string createdBy = "creator";
175-
entity.SetCreatedBy(createdBy);
182+
entity.SetCreatedOn(createdBy);
176183

177184
// Act & Assert
178185
entity.LastModifiedBy.ShouldBe(createdBy);
@@ -186,8 +193,8 @@ public void LastModifiedBy_WhenUpdated_ShouldReturnUpdatedBy()
186193
const string createdBy = "creator";
187194
const string updatedBy = "updater";
188195

189-
entity.SetCreatedBy(createdBy);
190-
entity.SetUpdatedBy(updatedBy);
196+
entity.SetCreatedOn(createdBy);
197+
entity.SetUpdatedOn(updatedBy);
191198

192199
// Act & Assert
193200
entity.LastModifiedBy.ShouldBe(updatedBy);
@@ -199,7 +206,7 @@ public void LastModifiedOn_WhenNotUpdated_ShouldReturnCreatedOn()
199206
// Arrange
200207
var entity = new TestAuditedEntity();
201208
var createdOn = DateTimeOffset.UtcNow.AddMinutes(-10);
202-
entity.SetCreatedBy("creator", createdOn);
209+
entity.SetCreatedOn("creator", createdOn);
203210

204211
// Act & Assert
205212
entity.LastModifiedOn.ShouldBe(createdOn);
@@ -213,52 +220,52 @@ public void LastModifiedOn_WhenUpdated_ShouldReturnUpdatedOn()
213220
var createdOn = DateTimeOffset.UtcNow.AddMinutes(-10);
214221
var updatedOn = DateTimeOffset.UtcNow.AddMinutes(-5);
215222

216-
entity.SetCreatedBy("creator", createdOn);
217-
entity.SetUpdatedBy("updater", updatedOn);
223+
entity.SetCreatedOn("creator", createdOn);
224+
entity.SetUpdatedOn("updater", updatedOn);
218225

219226
// Act & Assert
220227
entity.LastModifiedOn.ShouldBe(updatedOn);
221228
}
222229

223230
[Fact]
224-
public void SetCreatedBy_WhenAlreadySet_ShouldNotChange()
231+
public void SetCreatedOn_WhenAlreadySet_ShouldNotChange()
225232
{
226233
// Arrange
227234
var entity = new TestAuditedEntity();
228235
const string originalUser = "originaluser";
229236
const string newUser = "newuser";
230237
var originalTimestamp = DateTimeOffset.UtcNow.AddMinutes(-10);
231238

232-
entity.SetCreatedBy(originalUser, originalTimestamp);
239+
entity.SetCreatedOn(originalUser, originalTimestamp);
233240

234241
// Act
235-
entity.SetCreatedBy(newUser);
242+
entity.SetCreatedOn(newUser);
236243

237244
// Assert
238245
entity.CreatedBy.ShouldBe(originalUser);
239246
entity.CreatedOn.ShouldBe(originalTimestamp);
240247
}
241248

242249
[Fact]
243-
public void SetCreatedBy_WithNullUserName_ShouldThrowArgumentNullException()
250+
public void SetCreatedOn_WithNullUserName_ShouldThrowArgumentNullException()
244251
{
245252
// Arrange
246253
var entity = new TestAuditedEntity();
247254

248255
// Act & Assert
249-
Should.Throw<ArgumentNullException>(() => entity.SetCreatedBy(null!));
256+
Should.Throw<ArgumentNullException>(() => entity.SetCreatedOn(null!));
250257
}
251258

252259
[Fact]
253-
public void SetCreatedBy_WithUserName_ShouldSetCreatedByAndCreatedOn()
260+
public void SetCreatedOn_WithUserName_ShouldSetCreatedOnAndCreatedOn()
254261
{
255262
// Arrange
256263
var entity = new TestAuditedEntity();
257264
const string userName = "testuser";
258265
var beforeCall = DateTimeOffset.UtcNow;
259266

260267
// Act
261-
entity.SetCreatedBy(userName);
268+
entity.SetCreatedOn(userName);
262269
var afterCall = DateTimeOffset.UtcNow;
263270

264271
// Assert
@@ -268,15 +275,15 @@ public void SetCreatedBy_WithUserName_ShouldSetCreatedByAndCreatedOn()
268275
}
269276

270277
[Fact]
271-
public void SetCreatedBy_WithUserNameAndTimestamp_ShouldSetBoth()
278+
public void SetCreatedOn_WithUserNameAndTimestamp_ShouldSetBoth()
272279
{
273280
// Arrange
274281
var entity = new TestAuditedEntity();
275282
const string userName = "testuser";
276283
var timestamp = DateTimeOffset.UtcNow.AddMinutes(-10);
277284

278285
// Act
279-
entity.SetCreatedBy(userName, timestamp);
286+
entity.SetCreatedOn(userName, timestamp);
280287

281288
// Assert
282289
entity.CreatedBy.ShouldBe(userName);
@@ -290,8 +297,8 @@ public void SetUpdatedBy_WithNullOrEmptyUserName_ShouldThrowArgumentNullExceptio
290297
var entity = new TestAuditedEntity();
291298

292299
// Act & Assert
293-
Should.Throw<ArgumentNullException>(() => entity.SetUpdatedBy(null!));
294-
Should.Throw<ArgumentNullException>(() => entity.SetUpdatedBy(string.Empty));
300+
Should.Throw<ArgumentNullException>(() => entity.SetUpdatedOn(null!));
301+
Should.Throw<ArgumentException>(() => entity.SetUpdatedOn(string.Empty));
295302
}
296303

297304
[Fact]
@@ -303,7 +310,7 @@ public void SetUpdatedBy_WithUserName_ShouldSetUpdatedByAndUpdatedOn()
303310
var beforeCall = DateTimeOffset.UtcNow;
304311

305312
// Act
306-
entity.SetUpdatedBy(userName);
313+
entity.SetUpdatedOn(userName);
307314
var afterCall = DateTimeOffset.UtcNow;
308315

309316
// Assert
@@ -322,7 +329,7 @@ public void SetUpdatedBy_WithUserNameAndTimestamp_ShouldSetBoth()
322329
var timestamp = DateTimeOffset.UtcNow.AddMinutes(-5);
323330

324331
// Act
325-
entity.SetUpdatedBy(userName, timestamp);
332+
entity.SetUpdatedOn(userName, timestamp);
326333

327334
// Assert
328335
entity.UpdatedBy.ShouldBe(userName);

src/EfCore/EfCore.AuditLogs.Tests/AdditionalAuditLogEdgeCasesTests.cs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ public async Task BuildAuditLog_Deletions_Include_All_Scalar_Properties()
1313
{
1414
await using var ctx = await InitAsync();
1515
var e = new TestAuditEntity { Name = "DelUser", Age = 5, IsActive = true, Balance = 10m };
16-
e.SetCreatedBy("creator");
16+
e.SetCreatedOn("creator");
17+
1718
await ctx.AddAsync(e);
1819
await ctx.SaveChangesAsync();
20+
1921
ctx.Remove(e);
2022
ctx.ChangeTracker.DetectChanges();
2123
var entry = ctx.Entry(e);
@@ -29,7 +31,7 @@ public async Task BuildAuditLog_EmptyChanges_WhenForcedModified_NoDiff()
2931
{
3032
await using var ctx = await InitAsync();
3133
var e = new TestAuditEntity { Name = "NoDiff", Age = 8, IsActive = true, Balance = 5m };
32-
e.SetCreatedBy("creator");
34+
e.SetCreatedOn("creator");
3335
await ctx.AddAsync(e);
3436
await ctx.SaveChangesAsync();
3537
var entry = ctx.Entry(e);
@@ -38,10 +40,7 @@ public async Task BuildAuditLog_EmptyChanges_WhenForcedModified_NoDiff()
3840
entry.State = EntityState.Modified;
3941

4042
// Ensure none of the properties marked modified
41-
foreach (var p in entry.Properties)
42-
{
43-
p.IsModified = false;
44-
}
43+
foreach (var p in entry.Properties) p.IsModified = false;
4544

4645
var log = entry.BuildAuditLog(EntityState.Modified, AuditLogBehaviour.IncludeAllAuditedEntities)!;
4746
log.Changes.ShouldBeEmpty();
@@ -52,7 +51,7 @@ public async Task BuildAuditLog_Ignores_Unchanged_Null_Property()
5251
{
5352
await using var ctx = await InitAsync();
5453
var e = new TestAuditEntity { Name = "NullSkip", Age = 4, IsActive = true, Balance = 2m, Notes = null };
55-
e.SetCreatedBy("creator");
54+
e.SetCreatedOn("creator");
5655
await ctx.AddAsync(e);
5756
await ctx.SaveChangesAsync();
5857

@@ -69,7 +68,7 @@ public async Task BuildAuditLog_ModifiedEqualValue_StillIncluded_When_IsModified
6968
{
7069
await using var ctx = await InitAsync();
7170
var e = new TestAuditEntity { Name = "EqualUser", Age = 7, IsActive = true, Balance = 9m };
72-
e.SetCreatedBy("creator");
71+
e.SetCreatedOn("creator");
7372
await ctx.AddAsync(e);
7473
await ctx.SaveChangesAsync();
7574

@@ -86,7 +85,7 @@ public async Task BuildAuditLog_Skips_Unchanged_Properties()
8685
{
8786
await using var ctx = await InitAsync();
8887
var e = new TestAuditEntity { Name = "SkipUser", Age = 2, IsActive = false, Balance = 3.3m };
89-
e.SetCreatedBy("creator");
88+
e.SetCreatedOn("creator");
9089
await ctx.AddAsync(e);
9190
await ctx.SaveChangesAsync();
9291

@@ -110,7 +109,7 @@ public async Task BuildAuditLog_ValueCleared_To_Null_Registers_Change()
110109
{
111110
await using var ctx = await InitAsync();
112111
var e = new TestAuditEntity { Name = "ClearUser", Age = 3, IsActive = true, Balance = 1m, Notes = "original" };
113-
e.SetCreatedBy("creator");
112+
e.SetCreatedOn("creator");
114113
await ctx.AddAsync(e);
115114
await ctx.SaveChangesAsync();
116115
e.Notes = null; // clear value

src/EfCore/EfCore.AuditLogs.Tests/AdditionalAuditLogTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public async Task BuildAuditLog_Captures_Modified_Properties_Including_Nulls()
6969
await using var ctx = new TestAuditDbContext(BuildInMemoryOpts());
7070
await ctx.Database.EnsureCreatedAsync();
7171
var e = new TestAuditEntity { Name = "A", Age = 5, IsActive = true, Balance = 1m };
72-
e.SetCreatedBy("creator");
72+
e.SetCreatedOn("creator");
7373
await ctx.AddAsync(e);
7474
await ctx.SaveChangesAsync();
7575
e.Notes = "note"; // new value from null
@@ -91,7 +91,7 @@ public async Task BuildAuditLog_Deletion_Sets_NewValue_Null()
9191
await using var ctx = new TestAuditDbContext(BuildInMemoryOpts());
9292
await ctx.Database.EnsureCreatedAsync();
9393
var e = new TestAuditEntity { Name = "Del", Age = 1, IsActive = false, Balance = 0m };
94-
e.SetCreatedBy("creator");
94+
e.SetCreatedOn("creator");
9595
await ctx.AddAsync(e);
9696
await ctx.SaveChangesAsync();
9797
ctx.Remove(e);
@@ -152,7 +152,7 @@ public async Task Concurrent_Saves_Produce_All_Logs()
152152
for (var i = 0; i < 10; i++)
153153
{
154154
var e = new TestAuditEntity { Name = $"CC{i}", Age = i, IsActive = true, Balance = i };
155-
e.SetCreatedBy("seed");
155+
e.SetCreatedOn("seed");
156156
await seedCtx.AddAsync(e);
157157
}
158158

@@ -201,7 +201,7 @@ public async Task CustomPublisher_Registration_Invokes_RecordingPublisher()
201201
RecordingPublisher.Reset();
202202

203203
var e = new TestAuditEntity { Name = "C", Age = 2, IsActive = true, Balance = 3.2m };
204-
e.SetCreatedBy("creator");
204+
e.SetCreatedOn("creator");
205205
await ctx.AddAsync(e);
206206
await ctx.SaveChangesAsync();
207207

@@ -234,7 +234,7 @@ public async Task FailingPublisher_Logs_Error_But_Allows_Others()
234234

235235
RecordingPublisher.Reset();
236236
var e = new TestAuditEntity { Name = "F", Age = 1, IsActive = true, Balance = 1m };
237-
e.SetCreatedBy("creator");
237+
e.SetCreatedOn("creator");
238238
await ctx.AddAsync(e);
239239
await ctx.SaveChangesAsync();
240240
e.Age = 2;

0 commit comments

Comments
 (0)