From d1932107fc54c0a261ffc0a51337e0359ce4852f Mon Sep 17 00:00:00 2001 From: ZafarUrakov Date: Mon, 29 Apr 2024 17:31:52 +0500 Subject: [PATCH 1/4] EXPOSERS: Create EFxceptions Identity Context --- .../EFxceptionsIdentityContext.cs | 69 +++++++++++++++++++ .../STX.EFxceptions.Identity.SqlServer.csproj | 9 ++- .../Foundations/SqlServerEFxceptionService.cs | 2 +- 3 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 STX.EFxceptions.Identity.SqlServer/EFxceptionsIdentityContext.cs diff --git a/STX.EFxceptions.Identity.SqlServer/EFxceptionsIdentityContext.cs b/STX.EFxceptions.Identity.SqlServer/EFxceptionsIdentityContext.cs new file mode 100644 index 0000000..d94aa92 --- /dev/null +++ b/STX.EFxceptions.Identity.SqlServer/EFxceptionsIdentityContext.cs @@ -0,0 +1,69 @@ +// ---------------------------------------------------------------------------------- +// Copyright(c) The Standard Organization: A coalition of the Good-Hearted Engineers +// ---------------------------------------------------------------------------------- + + +using System; +using Microsoft.AspNetCore.Identity; +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; +using STX.EFxceptions.Abstractions.Brokers.DbErrorBroker; +using STX.EFxceptions.Abstractions.Services.EFxceptions; +using STX.EFxceptions.Identity.Core; +using STX.EFxceptions.SqlServer.Base.Brokers.DbErrorBroker; +using STX.EFxceptions.SqlServer.Base.Services.Foundations; + +namespace STX.EFxceptions.Identity.SqlServer +{ + public abstract class EFxceptionsIdentityContext + : IdentityDbContextBase, IdentityUserRole, + IdentityUserLogin, IdentityRoleClaim, IdentityUserToken, SqlException> + where TUser : IdentityUser + where TRole : IdentityRole + where TKey : IEquatable + { + public EFxceptionsIdentityContext(DbContextOptions options) : base(options) + { } + + protected EFxceptionsIdentityContext() : base() + { } + + protected override IDbErrorBroker CreateErrorBroker() => + new SqlServerErrorBroker(); + + protected override IEFxceptionService CreateEFxceptionService( + IDbErrorBroker errorBroker) + { + return new SqlServerEFxceptionService(errorBroker); + } + } + + public abstract class EFxceptionsIdentityContext< + TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken> + : IdentityDbContextBase + where TUser : IdentityUser + where TRole : IdentityRole + where TKey : IEquatable + where TUserClaim : IdentityUserClaim + where TUserRole : IdentityUserRole + where TUserLogin : IdentityUserLogin + where TRoleClaim : IdentityRoleClaim + where TUserToken : IdentityUserToken + { + public EFxceptionsIdentityContext(DbContextOptions options) : base(options) + { } + + protected EFxceptionsIdentityContext() : base() + { } + + protected override IDbErrorBroker CreateErrorBroker() => + new SqlServerErrorBroker(); + + protected override IEFxceptionService CreateEFxceptionService( + IDbErrorBroker errorBroker) + { + return new SqlServerEFxceptionService(errorBroker); + } + } +} \ No newline at end of file diff --git a/STX.EFxceptions.Identity.SqlServer/STX.EFxceptions.Identity.SqlServer.csproj b/STX.EFxceptions.Identity.SqlServer/STX.EFxceptions.Identity.SqlServer.csproj index 8ad01d6..978ce17 100644 --- a/STX.EFxceptions.Identity.SqlServer/STX.EFxceptions.Identity.SqlServer.csproj +++ b/STX.EFxceptions.Identity.SqlServer/STX.EFxceptions.Identity.SqlServer.csproj @@ -45,7 +45,14 @@ - + + + + + + + + diff --git a/STX.EFxceptions.SqlServer.Base/Services/Foundations/SqlServerEFxceptionService.cs b/STX.EFxceptions.SqlServer.Base/Services/Foundations/SqlServerEFxceptionService.cs index 7fe49df..0085ba3 100644 --- a/STX.EFxceptions.SqlServer.Base/Services/Foundations/SqlServerEFxceptionService.cs +++ b/STX.EFxceptions.SqlServer.Base/Services/Foundations/SqlServerEFxceptionService.cs @@ -2,10 +2,10 @@ // Copyright(c) The Standard Organization: A coalition of the Good-Hearted Engineers // ---------------------------------------------------------------------------------- +using System; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using STX.EFxceptions.Abstractions.Brokers.DbErrorBroker; -using System; namespace STX.EFxceptions.SqlServer.Base.Services.Foundations { From 14913f3352868d9bef7a205f6e4dc6a1e8d662d9 Mon Sep 17 00:00:00 2001 From: ZafarUrakov Date: Mon, 29 Apr 2024 17:36:30 +0500 Subject: [PATCH 2/4] ShouldSaveChangesSuccessfully -> PASS --- .../DeleteMe.cs | 13 -------- .../EFxceptionsIdentityContextTests.Logic.cs | 31 +++++++++++++++++++ .../EFxceptionsIdentityContextTests.cs | 24 ++++++++++++++ .../Models/Clients/Client.cs | 13 ++++++++ .../MyEFxceptionsIdentityContext.cs | 27 ++++++++++++++++ ...Identity.SqlServer.Tests.Acceptance.csproj | 11 +++++-- 6 files changed, 103 insertions(+), 16 deletions(-) delete mode 100644 STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/DeleteMe.cs create mode 100644 STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/EFxceptionsIdentityContextTests.Logic.cs create mode 100644 STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/EFxceptionsIdentityContextTests.cs create mode 100644 STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/Models/Clients/Client.cs create mode 100644 STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/MyEFxceptionsIdentityContext.cs diff --git a/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/DeleteMe.cs b/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/DeleteMe.cs deleted file mode 100644 index 187eea2..0000000 --- a/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/DeleteMe.cs +++ /dev/null @@ -1,13 +0,0 @@ -// ---------------------------------------------------------------------------------- -// Copyright(c) The Standard Organization: A coalition of the Good-Hearted Engineers -// ---------------------------------------------------------------------------------- - -namespace STX.EFxceptions.Identity.SqlServer.Tests.Acceptance -{ - public class DeleteMe - { - [Fact] - public void ShouldBeTrue() => - Assert.True(true); - } -} \ No newline at end of file diff --git a/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/EFxceptionsIdentityContextTests.Logic.cs b/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/EFxceptionsIdentityContextTests.Logic.cs new file mode 100644 index 0000000..dd1d1cf --- /dev/null +++ b/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/EFxceptionsIdentityContextTests.Logic.cs @@ -0,0 +1,31 @@ +// ---------------------------------------------------------------------------------- +// Copyright(c) The Standard Organization: A coalition of the Good-Hearted Engineers +// ---------------------------------------------------------------------------------- + +using System; +using STX.EFxceptions.Abstractions.Models.Exceptions; +using STX.EFxceptions.Identity.SqlServer.Tests.Acceptance.Models.Clients; + +namespace STX.EFxceptions.Identity.SqlServer.Tests.Acceptance +{ + public partial class EFxceptionsIdentityContextTests + { + [Fact] + public void ShouldSaveChangesSuccessfully() + { + // given + var client = new Client + { + Id = Guid.NewGuid() + }; + + // when + context.Clients.Add(client); + context.SaveChanges(); + + // then + context.Clients.Remove(client); + context.SaveChanges(); + } + } +} \ No newline at end of file diff --git a/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/EFxceptionsIdentityContextTests.cs b/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/EFxceptionsIdentityContextTests.cs new file mode 100644 index 0000000..5ccd808 --- /dev/null +++ b/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/EFxceptionsIdentityContextTests.cs @@ -0,0 +1,24 @@ +// ---------------------------------------------------------------------------------- +// Copyright(c) The Standard Organization: A coalition of the Good-Hearted Engineers +// ---------------------------------------------------------------------------------- + +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; + +namespace STX.EFxceptions.Identity.SqlServer.Tests.Acceptance +{ + public partial class EFxceptionsIdentityContextTests + { + private readonly DbContextOptions> options; + private readonly MyEFxceptionsIdentityContext context; + + public EFxceptionsIdentityContextTests() + { + options = new DbContextOptionsBuilder>() + .UseInMemoryDatabase(databaseName: "InMemoryDataBaseIdentity") + .Options; + + this.context = new MyEFxceptionsIdentityContext(options); + } + } +} \ No newline at end of file diff --git a/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/Models/Clients/Client.cs b/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/Models/Clients/Client.cs new file mode 100644 index 0000000..4e1eeb1 --- /dev/null +++ b/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/Models/Clients/Client.cs @@ -0,0 +1,13 @@ +// ---------------------------------------------------------------------------------- +// Copyright(c) The Standard Organization: A coalition of the Good-Hearted Engineers +// ---------------------------------------------------------------------------------- + +using System; + +namespace STX.EFxceptions.Identity.SqlServer.Tests.Acceptance.Models.Clients +{ + public class Client + { + public Guid Id { get; set; } + } +} \ No newline at end of file diff --git a/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/MyEFxceptionsIdentityContext.cs b/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/MyEFxceptionsIdentityContext.cs new file mode 100644 index 0000000..e565f79 --- /dev/null +++ b/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/MyEFxceptionsIdentityContext.cs @@ -0,0 +1,27 @@ +// ---------------------------------------------------------------------------------- +// Copyright(c) The Standard Organization: A coalition of the Good-Hearted Engineers +// ---------------------------------------------------------------------------------- + +using System; +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; +using STX.EFxceptions.Identity.SqlServer.Tests.Acceptance.Models.Clients; + +namespace STX.EFxceptions.Identity.SqlServer.Tests.Acceptance +{ + public class MyEFxceptionsIdentityContext + : EFxceptionsIdentityContext + where TUser : IdentityUser + where TRole : IdentityRole + where TKey : IEquatable + { + public MyEFxceptionsIdentityContext(DbContextOptions options) : base(options) + { } + public DbSet Clients { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + } + } +} \ No newline at end of file diff --git a/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance.csproj b/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance.csproj index 9c5b30a..1414bdc 100644 --- a/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance.csproj +++ b/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance.csproj @@ -1,15 +1,16 @@ - + net8.0 - enable - enable + disable + disable false true + @@ -20,4 +21,8 @@ + + + + From 82af5ccc5d2a2f36296d5913f62960f93d177db2 Mon Sep 17 00:00:00 2001 From: ZafarUrakov Date: Mon, 29 Apr 2024 17:36:55 +0500 Subject: [PATCH 3/4] ShouldThrowDuplicateKeyExceptionOnSaveChanges -> PASS --- .../EFxceptionsIdentityContextTests.Logic.cs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/EFxceptionsIdentityContextTests.Logic.cs b/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/EFxceptionsIdentityContextTests.Logic.cs index dd1d1cf..9fa459c 100644 --- a/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/EFxceptionsIdentityContextTests.Logic.cs +++ b/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/EFxceptionsIdentityContextTests.Logic.cs @@ -27,5 +27,37 @@ public void ShouldSaveChangesSuccessfully() context.Clients.Remove(client); context.SaveChanges(); } + + [Fact] + public void ShouldThrowDuplicateKeyExceptionOnSaveChanges() + { + // given + var client = new Client + { + Id = Guid.NewGuid() + }; + + // when . then + Assert.Throws(() => + { + try + { + for (int i = 0; i < 2; i++) + { + context.Clients.Add(client); + context.SaveChanges(); + } + } + catch (ArgumentException argumentException) + { + throw new DuplicateKeyException(argumentException.Message); + } + finally + { + context.Clients.Remove(client); + context.SaveChanges(); + } + }); + } } } \ No newline at end of file From 62eb4746b3e8883b2a0dcb2d79c8d80cca913850 Mon Sep 17 00:00:00 2001 From: Christo du Toit Date: Mon, 29 Apr 2024 17:46:43 +0100 Subject: [PATCH 4/4] CODE RUB: Code cleanup --- .../MyEFxceptionsIdentityContext.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/MyEFxceptionsIdentityContext.cs b/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/MyEFxceptionsIdentityContext.cs index e565f79..1842ded 100644 --- a/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/MyEFxceptionsIdentityContext.cs +++ b/STX.EFxceptions.Identity.SqlServer.Tests.Acceptance/MyEFxceptionsIdentityContext.cs @@ -17,6 +17,7 @@ public class MyEFxceptionsIdentityContext { public MyEFxceptionsIdentityContext(DbContextOptions options) : base(options) { } + public DbSet Clients { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder)