From bab47f91ddf588ac670b4be4b38ec6a60d81936b Mon Sep 17 00:00:00 2001 From: Francis Pion Date: Thu, 8 Feb 2024 15:19:28 -0500 Subject: [PATCH] Fixed updated events, added integration tests. (#49) Co-authored-by: Francis Pion --- .../ApiKeys/Events/ApiKeyUpdatedEvent.cs | 6 +- .../Logitar.Identity.Domain.csproj | 6 +- .../Roles/Events/RoleUpdatedEvent.cs | 4 +- .../Users/Events/UserUpdatedEvent.cs | 24 +- .../AssertRoles.cs | 30 +++ .../Repositories/ApiKeyRepositoryTests.cs | 12 +- .../OneTimePasswordRepositoryTests.cs | 7 + .../Repositories/RoleRepositoryTests.cs | 248 ++++++++++++++++++ .../Repositories/SessionRepositoryTests.cs | 4 + .../Repositories/UserRepositoryTests.cs | 15 ++ 10 files changed, 333 insertions(+), 23 deletions(-) create mode 100644 tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/AssertRoles.cs create mode 100644 tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/RoleRepositoryTests.cs diff --git a/src/Logitar.Identity.Domain/ApiKeys/Events/ApiKeyUpdatedEvent.cs b/src/Logitar.Identity.Domain/ApiKeys/Events/ApiKeyUpdatedEvent.cs index d2e2c9c..dde020e 100644 --- a/src/Logitar.Identity.Domain/ApiKeys/Events/ApiKeyUpdatedEvent.cs +++ b/src/Logitar.Identity.Domain/ApiKeys/Events/ApiKeyUpdatedEvent.cs @@ -12,15 +12,15 @@ public record ApiKeyUpdatedEvent : DomainEvent, INotification /// /// Gets or sets the display name of the API key. /// - public DisplayNameUnit? DisplayName { get; internal set; } + public DisplayNameUnit? DisplayName { get; set; } /// /// Gets or sets the description of the API key. /// - public Modification? Description { get; internal set; } + public Modification? Description { get; set; } /// /// Gets or sets the expiration date and time of the API key. /// - public DateTime? ExpiresOn { get; internal set; } + public DateTime? ExpiresOn { get; set; } /// /// Gets or sets the custom attribute modifications of the API key. diff --git a/src/Logitar.Identity.Domain/Logitar.Identity.Domain.csproj b/src/Logitar.Identity.Domain/Logitar.Identity.Domain.csproj index 141a3c3..0ceebc5 100644 --- a/src/Logitar.Identity.Domain/Logitar.Identity.Domain.csproj +++ b/src/Logitar.Identity.Domain/Logitar.Identity.Domain.csproj @@ -16,14 +16,14 @@ README.md https://github.com/Logitar/Identity git - 0.11.5.0 + 0.11.6.0 $(AssemblyVersion) LICENSE True - 0.11.5 + 0.11.6 en-CA True - Fixed LocaleUnit. + Fixed updated events. logitar;net;framework;identity;domain https://github.com/Logitar/Identity/tree/main/src/Logitar.Identity.Domain diff --git a/src/Logitar.Identity.Domain/Roles/Events/RoleUpdatedEvent.cs b/src/Logitar.Identity.Domain/Roles/Events/RoleUpdatedEvent.cs index b248668..e14201c 100644 --- a/src/Logitar.Identity.Domain/Roles/Events/RoleUpdatedEvent.cs +++ b/src/Logitar.Identity.Domain/Roles/Events/RoleUpdatedEvent.cs @@ -12,11 +12,11 @@ public record RoleUpdatedEvent : DomainEvent, INotification /// /// Gets or sets the display name of the role. /// - public Modification? DisplayName { get; internal set; } + public Modification? DisplayName { get; set; } /// /// Gets or sets the description of the role. /// - public Modification? Description { get; internal set; } + public Modification? Description { get; set; } /// /// Gets or sets the custom attribute modifications of the role. diff --git a/src/Logitar.Identity.Domain/Users/Events/UserUpdatedEvent.cs b/src/Logitar.Identity.Domain/Users/Events/UserUpdatedEvent.cs index 49d2889..7ac9c7f 100644 --- a/src/Logitar.Identity.Domain/Users/Events/UserUpdatedEvent.cs +++ b/src/Logitar.Identity.Domain/Users/Events/UserUpdatedEvent.cs @@ -12,53 +12,53 @@ public record UserUpdatedEvent : DomainEvent, INotification /// /// Gets or sets the first name of the user. /// - public Modification? FirstName { get; internal set; } + public Modification? FirstName { get; set; } /// /// Gets or sets the middle name of the user. /// - public Modification? MiddleName { get; internal set; } + public Modification? MiddleName { get; set; } /// /// Gets or sets the last name of the user. /// - public Modification? LastName { get; internal set; } + public Modification? LastName { get; set; } /// /// Gets or sets the full name of the user. /// - public Modification? FullName { get; internal set; } + public Modification? FullName { get; set; } /// /// Gets or sets the nickname of the user. /// - public Modification? Nickname { get; internal set; } + public Modification? Nickname { get; set; } /// /// Gets or sets the birthdate of the user. /// - public Modification? Birthdate { get; internal set; } + public Modification? Birthdate { get; set; } /// /// Gets or sets the gender of the user. /// - public Modification? Gender { get; internal set; } + public Modification? Gender { get; set; } /// /// Gets or sets the locale of the user. /// - public Modification? Locale { get; internal set; } + public Modification? Locale { get; set; } /// /// Gets or sets the time zone of the user. /// - public Modification? TimeZone { get; internal set; } + public Modification? TimeZone { get; set; } /// /// Gets or sets the URL to the picture of the user. /// - public Modification? Picture { get; internal set; } + public Modification? Picture { get; set; } /// /// Gets or sets the URL to the profile page of the user. /// - public Modification? Profile { get; internal set; } + public Modification? Profile { get; set; } /// /// Gets or sets the URL to the website of the user. /// - public Modification? Website { get; internal set; } + public Modification? Website { get; set; } /// /// Gets or sets the custom attribute modifications of the user. diff --git a/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/AssertRoles.cs b/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/AssertRoles.cs new file mode 100644 index 0000000..b6ebbe5 --- /dev/null +++ b/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/AssertRoles.cs @@ -0,0 +1,30 @@ +using Logitar.Identity.Domain.Roles; +using Logitar.Identity.EntityFrameworkCore.Relational.Entities; + +namespace Logitar.Identity.EntityFrameworkCore.SqlServer; + +internal static class AssertRoles +{ + public static void AreEqual(RoleAggregate? role, RoleEntity? entity) + { + if (role == null || entity == null) + { + Assert.Null(role); + Assert.Null(entity); + return; + } + + Assert.Equal(role.Version, entity.Version); + Assert.Equal(role.CreatedBy.Value, entity.CreatedBy); + Assertions.Equal(role.CreatedOn, entity.CreatedOn, TimeSpan.FromMinutes(1)); + Assert.Equal(role.UpdatedBy.Value, entity.UpdatedBy); + Assertions.Equal(role.UpdatedOn, entity.UpdatedOn, TimeSpan.FromMinutes(1)); + + Assert.Equal(role.TenantId?.Value, entity.TenantId); + Assert.Equal(role.UniqueName.Value, entity.UniqueName); + Assert.Equal(role.DisplayName?.Value, entity.DisplayName); + Assert.Equal(role.Description?.Value, entity.Description); + + Assert.Equal(role.CustomAttributes, entity.CustomAttributes); + } +} diff --git a/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/ApiKeyRepositoryTests.cs b/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/ApiKeyRepositoryTests.cs index c6c582b..7917f7a 100644 --- a/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/ApiKeyRepositoryTests.cs +++ b/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/ApiKeyRepositoryTests.cs @@ -49,7 +49,7 @@ public ApiKeyRepositoryTests() : base() Description = new DescriptionUnit("This is the default API key.") }; _apiKey.SetExpiration(DateTime.Now.AddYears(1)); - _apiKey.SetCustomAttribute("TODO", "TODO"); + _apiKey.SetCustomAttribute("OwnerId", Guid.NewGuid().ToString()); _apiKey.Update(actorId); _apiKey.AddRole(_role, actorId); @@ -153,8 +153,8 @@ public async Task LoadAsync_it_should_load_the_Api_keys_by_identifiers() [Fact(DisplayName = "SaveAsync: it should save the deleted API key.")] public async Task SaveAsync_it_should_save_the_deleted_Api_key() { - _apiKey.SetCustomAttribute("TODO", "TODO"); - _apiKey.SetCustomAttribute("TODO", "TODO"); + _apiKey.SetCustomAttribute("Confidentiality", "Private"); + _apiKey.SetCustomAttribute("SubSystem", "IntegrationTests"); _apiKey.Update(); await _apiKeyRepository.SaveAsync(_apiKey); @@ -197,6 +197,12 @@ public async Task SaveAsync_it_should_save_the_specified_Api_key() .Where(x => x.EntityType == nameof(IdentityContext.ApiKeys) && x.EntityId == entity.ApiKeyId) .ToDictionaryAsync(x => x.Key, x => x.Value); Assert.Equal(_apiKey.CustomAttributes, customAttributes); + + ApiKeyAggregate? apiKey = await _apiKeyRepository.LoadAsync(_apiKey.Id); + Assert.NotNull(apiKey); + Assert.Equal(_apiKey.Description, apiKey.Description); + Assert.Equal(_apiKey.ExpiresOn, apiKey.ExpiresOn); + Assert.Equal(_apiKey.CustomAttributes, apiKey.CustomAttributes); } [Fact(DisplayName = "SaveAsync: it should save the specified API keys.")] diff --git a/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/OneTimePasswordRepositoryTests.cs b/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/OneTimePasswordRepositoryTests.cs index 4b3bd20..c009601 100644 --- a/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/OneTimePasswordRepositoryTests.cs +++ b/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/OneTimePasswordRepositoryTests.cs @@ -36,6 +36,9 @@ public OneTimePasswordRepositoryTests() : base() _password = _passwordManager.Create(PasswordString); _oneTimePassword = new(_password, tenantId, expiresOn, maximumAttempts, actorId, id); + _oneTimePassword.SetCustomAttribute("Purpose", "MultiFactorAuthentication"); + _oneTimePassword.SetCustomAttribute("UserId", Guid.NewGuid().ToString()); + _oneTimePassword.Update(actorId); } public async Task InitializeAsync() @@ -151,6 +154,10 @@ public async Task SaveAsync_it_should_save_the_specified_One_Time_Password() .Where(x => x.EntityType == nameof(IdentityContext.OneTimePasswords) && x.EntityId == entity.OneTimePasswordId) .ToDictionaryAsync(x => x.Key, x => x.Value); Assert.Equal(_oneTimePassword.CustomAttributes, customAttributes); + + OneTimePasswordAggregate? oneTimePassword = await _oneTimePasswordRepository.LoadAsync(_oneTimePassword.Id); + Assert.NotNull(oneTimePassword); + Assert.Equal(_oneTimePassword.CustomAttributes, oneTimePassword.CustomAttributes); } [Fact(DisplayName = "SaveAsync: it should save the specified One-Time Passwords.")] diff --git a/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/RoleRepositoryTests.cs b/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/RoleRepositoryTests.cs new file mode 100644 index 0000000..63471b7 --- /dev/null +++ b/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/RoleRepositoryTests.cs @@ -0,0 +1,248 @@ +using Logitar.Data; +using Logitar.Data.SqlServer; +using Logitar.EventSourcing; +using Logitar.EventSourcing.EntityFrameworkCore.Relational; +using Logitar.Identity.Contracts.Settings; +using Logitar.Identity.Domain.ApiKeys; +using Logitar.Identity.Domain.Passwords; +using Logitar.Identity.Domain.Roles; +using Logitar.Identity.Domain.Settings; +using Logitar.Identity.Domain.Shared; +using Logitar.Identity.Domain.Users; +using Logitar.Identity.EntityFrameworkCore.Relational; +using Logitar.Identity.EntityFrameworkCore.Relational.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; + +namespace Logitar.Identity.EntityFrameworkCore.SqlServer.Repositories; + +[Trait(Traits.Category, Categories.Integration)] +public class RoleRepositoryTests : RepositoryTests, IAsyncLifetime +{ + private readonly IApiKeyRepository _apiKeyRepository; + private readonly IPasswordManager _passwordManager; + private readonly IRoleRepository _roleRepository; + private readonly IRoleSettings _roleSettings; + private readonly IUserRepository _userRepository; + private readonly IUserSettings _userSettings; + + private readonly RoleAggregate _role; + + public RoleRepositoryTests() : base() + { + _apiKeyRepository = ServiceProvider.GetRequiredService(); + _passwordManager = ServiceProvider.GetRequiredService(); + _roleRepository = ServiceProvider.GetRequiredService(); + _roleSettings = ServiceProvider.GetRequiredService().Resolve(); + _userRepository = ServiceProvider.GetRequiredService(); + _userSettings = ServiceProvider.GetRequiredService().Resolve(); + + RoleId roleId = RoleId.NewId(); + ActorId actorId = new(roleId.Value); + TenantId tenantId = new("tests"); + + UniqueNameUnit uniqueName = new(_roleSettings.UniqueName, "send_messages"); + _role = new(uniqueName, tenantId, actorId, roleId) + { + DisplayName = new DisplayNameUnit("Send Messages"), + Description = new DescriptionUnit("This role allows to send messages.") + }; + _role.SetCustomAttribute("manage_messages", bool.TrueString); + _role.Update(actorId); + } + + public async Task InitializeAsync() + { + await EventContext.Database.MigrateAsync(); + await IdentityContext.Database.MigrateAsync(); + + TableId[] tables = + [ + IdentityDb.Roles.Table, + IdentityDb.CustomAttributes.Table, + EventDb.Events.Table + ]; + foreach (TableId table in tables) + { + ICommand command = SqlServerDeleteBuilder.From(table).Build(); + await IdentityContext.Database.ExecuteSqlRawAsync(command.Text, command.Parameters.ToArray()); + } + + await _roleRepository.SaveAsync(_role); + await _roleRepository.SaveAsync(_role); + } + + [Fact(DisplayName = "LoadAsync: it should load all the roles.")] + public async Task LoadAsync_it_should_load_all_the_roles() + { + RoleAggregate deleted = new(_role.UniqueName, tenantId: null); + deleted.Delete(); + await _roleRepository.SaveAsync(deleted); + + IEnumerable roles = await _roleRepository.LoadAsync(includeDeleted: true); + Assert.Equal(2, roles.Count()); + Assert.Contains(roles, _role.Equals); + Assert.Contains(roles, deleted.Equals); + } + + [Fact(DisplayName = "LoadAsync: it should load the role by identifier.")] + public async Task LoadAsync_it_should_load_the_role_by_identifier() + { + Assert.Null(await _roleRepository.LoadAsync(RoleId.NewId())); + + _role.Delete(); + long version = _role.Version; + + UniqueNameUnit oldUniqueName = _role.UniqueName; + _role.SetUniqueName(new UniqueNameUnit(_roleSettings.UniqueName, "guest")); + await _roleRepository.SaveAsync(_role); + + Assert.Null(await _roleRepository.LoadAsync(_role.Id, version)); + + RoleAggregate? role = await _roleRepository.LoadAsync(_role.Id, version, includeDeleted: true); + Assert.NotNull(role); + Assert.Equal(oldUniqueName, role.UniqueName); + Assert.Equal(_role, role); + } + + [Fact(DisplayName = "LoadAsync: it should load the roles by tenant identifier.")] + public async Task LoadAsync_it_should_load_the_roles_by_tenant_identifier() + { + RoleAggregate role = new(_role.UniqueName, tenantId: null); + RoleAggregate deleted = new(new UniqueNameUnit(_roleSettings.UniqueName, "deleted"), _role.TenantId); + deleted.Delete(); + await _roleRepository.SaveAsync([role, deleted]); + + IEnumerable roles = await _roleRepository.LoadAsync(_role.TenantId); + Assert.Equal(_role, roles.Single()); + } + + [Fact(DisplayName = "LoadAsync: it should load the role by unique name.")] + public async Task LoadAsync_it_should_load_the_role_by_unique_name() + { + Assert.Null(await _roleRepository.LoadAsync(tenantId: null, _role.UniqueName)); + + UniqueNameUnit uniqueName = new(_roleSettings.UniqueName, $"{_role.UniqueName.Value}2"); + Assert.Null(await _roleRepository.LoadAsync(_role.TenantId, uniqueName)); + + RoleAggregate? role = await _roleRepository.LoadAsync(_role.TenantId, _role.UniqueName); + Assert.NotNull(role); + Assert.Equal(_role, role); + } + + [Fact(DisplayName = "LoadAsync: it should load the roles by identifiers.")] + public async Task LoadAsync_it_should_load_the_roles_by_identifiers() + { + RoleAggregate deleted = new(_role.UniqueName, tenantId: null); + deleted.Delete(); + await _roleRepository.SaveAsync(deleted); + + IEnumerable roles = await _roleRepository.LoadAsync([_role.Id, deleted.Id, RoleId.NewId()], includeDeleted: true); + Assert.Equal(2, roles.Count()); + Assert.Contains(roles, _role.Equals); + Assert.Contains(roles, deleted.Equals); + } + + [Fact(DisplayName = "LoadAsync: it should load the roles by API key.")] + public async Task LoadAsync_it_should_load_the_roles_by_Api_key() + { + RoleAggregate manageUsers = new(new UniqueNameUnit(_roleSettings.UniqueName, "manage_users")); + await _roleRepository.SaveAsync(manageUsers); + + Password secret = _passwordManager.GenerateBase64(32, out _); + ApiKeyAggregate apiKey = new(new DisplayNameUnit("Default"), secret); + apiKey.AddRole(manageUsers); + await _apiKeyRepository.SaveAsync(apiKey); + + RoleAggregate role = Assert.Single(await _roleRepository.LoadAsync(apiKey)); + Assert.Equal(manageUsers, role); + } + + [Fact(DisplayName = "LoadAsync: it should load the roles by user.")] + public async Task LoadAsync_it_should_load_the_roles_by_user() + { + RoleAggregate manageUsers = new(new UniqueNameUnit(_roleSettings.UniqueName, "manage_users")); + await _roleRepository.SaveAsync(manageUsers); + + UserAggregate user = new(new UniqueNameUnit(_userSettings.UniqueName, Faker.Internet.UserName())); + user.AddRole(manageUsers); + await _userRepository.SaveAsync(user); + + RoleAggregate role = Assert.Single(await _roleRepository.LoadAsync(user)); + Assert.Equal(manageUsers, role); + } + + [Fact(DisplayName = "SaveAsync: it should save the deleted role.")] + public async Task SaveAsync_it_should_save_the_deleted_role() + { + _role.SetCustomAttribute("read_messages", bool.TrueString); + _role.SetCustomAttribute("edit_messages", bool.FalseString); + _role.Update(); + await _roleRepository.SaveAsync(_role); + + RoleEntity? entity = await IdentityContext.Roles.AsNoTracking() + .SingleOrDefaultAsync(x => x.AggregateId == _role.Id.Value); + Assert.NotNull(entity); + + CustomAttributeEntity[] customAttributes = await IdentityContext.CustomAttributes.AsNoTracking() + .Where(x => x.EntityType == nameof(IdentityContext.Roles) && x.EntityId == entity.RoleId) + .ToArrayAsync(); + Assert.Equal(_role.CustomAttributes.Count, customAttributes.Length); + foreach (KeyValuePair customAttribute in _role.CustomAttributes) + { + Assert.Contains(customAttributes, c => c.Key == customAttribute.Key && c.Value == customAttribute.Value); + } + + _role.Delete(); + await _roleRepository.SaveAsync(_role); + + customAttributes = await IdentityContext.CustomAttributes.AsNoTracking() + .Where(x => x.EntityType == nameof(IdentityContext.Roles) && x.EntityId == entity.RoleId) + .ToArrayAsync(); + Assert.Empty(customAttributes); + } + + [Fact(DisplayName = "SaveAsync: it should save the specified role.")] + public async Task SaveAsync_it_should_save_the_specified_role() + { + RoleEntity? entity = await IdentityContext.Roles.AsNoTracking() + .SingleOrDefaultAsync(x => x.AggregateId == _role.Id.Value); + Assert.NotNull(entity); + AssertRoles.AreEqual(_role, entity); + + Dictionary customAttributes = await IdentityContext.CustomAttributes.AsNoTracking() + .Where(x => x.EntityType == nameof(IdentityContext.Roles) && x.EntityId == entity.RoleId) + .ToDictionaryAsync(x => x.Key, x => x.Value); + Assert.Equal(_role.CustomAttributes, customAttributes); + + RoleAggregate? role = await _roleRepository.LoadAsync(_role.Id); + Assert.NotNull(role); + Assert.Equal(_role.DisplayName, role.DisplayName); + Assert.Equal(_role.Description, role.Description); + Assert.Equal(_role.CustomAttributes, role.CustomAttributes); + } + + [Fact(DisplayName = "SaveAsync: it should save the specified roles.")] + public async Task SaveAsync_it_should_save_the_specified_roles() + { + RoleAggregate guest = new(new UniqueNameUnit(_roleSettings.UniqueName, "gwest")); + RoleAggregate deleted = new(new UniqueNameUnit(_roleSettings.UniqueName, "deleted")); + await _roleRepository.SaveAsync([guest, deleted]); + + Dictionary entities = await IdentityContext.Roles.AsNoTracking().ToDictionaryAsync(x => x.AggregateId, x => x); + Assert.True(entities.ContainsKey(guest.Id.Value)); + Assert.True(entities.ContainsKey(deleted.Id.Value)); + + guest.SetUniqueName(new UniqueNameUnit(_roleSettings.UniqueName, "guest")); + deleted.Delete(); + await _roleRepository.SaveAsync([guest, deleted]); + + entities = await IdentityContext.Roles.AsNoTracking().ToDictionaryAsync(x => x.AggregateId, x => x); + Assert.True(entities.ContainsKey(guest.Id.Value)); + Assert.False(entities.ContainsKey(deleted.Id.Value)); + + AssertRoles.AreEqual(guest, entities[guest.Id.Value]); + } + + public Task DisposeAsync() => Task.CompletedTask; +} diff --git a/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/SessionRepositoryTests.cs b/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/SessionRepositoryTests.cs index 4a644ff..7effee2 100644 --- a/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/SessionRepositoryTests.cs +++ b/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/SessionRepositoryTests.cs @@ -195,6 +195,10 @@ public async Task SaveAsync_it_should_save_the_specified_session() .Where(x => x.EntityType == nameof(IdentityContext.Sessions) && x.EntityId == entity.SessionId) .ToDictionaryAsync(x => x.Key, x => x.Value); Assert.Equal(_session.CustomAttributes, customAttributes); + + SessionAggregate? session = await _sessionRepository.LoadAsync(_session.Id); + Assert.NotNull(session); + Assert.Equal(_session.CustomAttributes, session.CustomAttributes); } [Fact(DisplayName = "SaveAsync: it should save the specified sessions.")] diff --git a/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/UserRepositoryTests.cs b/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/UserRepositoryTests.cs index 4baa25b..71e0ae2 100644 --- a/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/UserRepositoryTests.cs +++ b/tests/Logitar.Identity.EFCore.SqlServer.IntegrationTests/Repositories/UserRepositoryTests.cs @@ -274,6 +274,21 @@ public async Task SaveAsync_it_should_save_the_specified_user() .Where(x => x.EntityType == nameof(IdentityContext.Users) && x.EntityId == entity.UserId) .ToDictionaryAsync(x => x.Key, x => x.Value); Assert.Equal(_user.CustomAttributes, customAttributes); + + UserAggregate? user = await _userRepository.LoadAsync(_user.Id); + Assert.NotNull(user); + Assert.Equal(_user.FirstName, user.FirstName); + Assert.Equal(_user.MiddleName, user.MiddleName); + Assert.Equal(_user.LastName, user.LastName); + Assert.Equal(_user.Nickname, user.Nickname); + Assert.Equal(_user.Birthdate, user.Birthdate); + Assert.Equal(_user.Gender, user.Gender); + Assert.Equal(_user.Locale, user.Locale); + Assert.Equal(_user.TimeZone, user.TimeZone); + Assert.Equal(_user.Picture, user.Picture); + Assert.Equal(_user.Profile, user.Profile); + Assert.Equal(_user.Website, user.Website); + Assert.Equal(_user.CustomAttributes, user.CustomAttributes); } [Fact(DisplayName = "SaveAsync: it should save the specified users.")]