Skip to content

Commit

Permalink
Improve the unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Ahmed-Ghanam committed Oct 3, 2024
1 parent 7cf18d6 commit 635fe89
Show file tree
Hide file tree
Showing 8 changed files with 329 additions and 293 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
namespace Altinn.Profile.Integrations.Entities;

/// <summary>
/// AutoMapper profile for configuring mappings between <see cref="Register"/> and <see cref="UserContactInfo"/>.
/// AutoMapper profile for configuring mappings between <see cref="Register"/> and a class implementing the <see cref="IUserContactInfo"/> interface.
/// </summary>
/// <remarks>
/// This profile defines the mapping rules required to transform a <see cref="Register"/> object into a <see cref="UserContactInfo"/> object.
/// This profile defines the mapping rules required to transform a <see cref="Register"/> object into a class implementing the <see cref="IUserContactInfo"/> interface.
/// It is used by AutoMapper to facilitate the conversion of data between these two models.
/// </remarks>
public class UserContactInfoProfile : AutoMapper.Profile
Expand All @@ -13,7 +13,7 @@ public class UserContactInfoProfile : AutoMapper.Profile
/// Initializes a new instance of the <see cref="UserContactInfoProfile"/> class.
/// </summary>
/// <remarks>
/// The constructor configures the mappings between the <see cref="Register"/> and <see cref="UserContactInfo"/> classes.
/// The constructor configures the mappings between the <see cref="Register"/> class and a class implementing the <see cref="IUserContactInfo"/> interface.
/// </remarks>
public UserContactInfoProfile()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@ namespace Altinn.Profile.Integrations.Repositories;
/// </summary>
public interface IRegisterRepository : IRepository<Register>
{
/// <summary>
/// Gets the contact info for a single user by the national identity number asynchronously.
/// </summary>
/// <param name="nationalIdentityNumber">The national identity number.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains the register data for the user.</returns>
Task<Register?> GetUserContactInfoAsync(string nationalIdentityNumber);

/// <summary>
/// Gets the contact info for multiple users by their national identity numbers asynchronously.
/// </summary>
Expand Down
11 changes: 0 additions & 11 deletions src/Altinn.Profile.Integrations/Repositories/RegisterRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,6 @@ public RegisterRepository(ProfileDbContext context) : base(context)
_context = context ?? throw new ArgumentNullException(nameof(context));
}

/// <summary>
/// Asynchronously retrieves the contact info for a single user based on the provided national identity number.
/// </summary>
/// <param name="nationalIdentityNumber">The national identity number to filter the user contact point.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains the user contact point, or null if not found.</returns>
/// <exception cref="ArgumentException">Thrown when the provided national identity number is null or empty.</exception>
public async Task<Register?> GetUserContactInfoAsync(string nationalIdentityNumber)
{
return await _context.Registers.SingleOrDefaultAsync(k => k.FnumberAk == nationalIdentityNumber);
}

/// <summary>
/// Asynchronously retrieves the contact info for multiple users based on the provided national identity numbers.
/// </summary>
Expand Down
23 changes: 11 additions & 12 deletions src/Altinn.Profile.Integrations/Services/RegisterService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ public class RegisterService : IRegisterService
/// <summary>
/// Initializes a new instance of the <see cref="RegisterService"/> class.
/// </summary>
/// <param name="mapper">The repository used for.</param>
/// <param name="mapper">The mapper used for object mapping.</param>
/// <param name="registerRepository">The repository used for accessing register data.</param>
/// <exception cref="ArgumentException">Thrown when the <paramref name="mapper"/> or <paramref name="registerRepository"/> object is null.</exception>
/// <exception cref="ArgumentNullException">Thrown when the <paramref name="mapper"/> or <paramref name="registerRepository"/> object is null.</exception>
public RegisterService(IMapper mapper, IRegisterRepository registerRepository)
{
_mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
Expand All @@ -40,7 +40,7 @@ public RegisterService(IMapper mapper, IRegisterRepository registerRepository)
return null;
}

var userContactInfo = await _registerRepository.GetUserContactInfoAsync(nationalIdentityNumber);
var userContactInfo = await _registerRepository.GetUserContactInfoAsync([nationalIdentityNumber]);
return _mapper.Map<IUserContactInfo>(userContactInfo);
}

Expand All @@ -53,23 +53,22 @@ public RegisterService(IMapper mapper, IRegisterRepository registerRepository)
/// </returns>
public async Task<IEnumerable<IUserContactInfo>> GetUserContactInfoAsync(IEnumerable<string> nationalIdentityNumbers)
{
// Check if the input collection is null or empty
if (nationalIdentityNumbers == null || !nationalIdentityNumbers.Any())
{
return Enumerable.Empty<IUserContactInfo>(); // Return an empty collection
return [];
}

// Validate that all national identity numbers are valid
if (!nationalIdentityNumbers.All(IsValidNationalIdentityNumber))
// Filter out invalid national identity numbers
var validNationalIdentityNumbers = nationalIdentityNumbers.Where(IsValidNationalIdentityNumber).ToList();

if (!validNationalIdentityNumbers.Any())
{
return Enumerable.Empty<IUserContactInfo>(); // Return an empty collection for invalid numbers
return [];
}

// Retrieve user contact information from the repository
var userContactInfo = await _registerRepository.GetUserContactInfoAsync(nationalIdentityNumbers);
var userContactInfo = await _registerRepository.GetUserContactInfoAsync(validNationalIdentityNumbers);

// Map the retrieved data to the desired interface type
return _mapper.Map<IEnumerable<UserContactInfo>>(userContactInfo);
return _mapper.Map<IEnumerable<IUserContactInfo>>(userContactInfo);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using Altinn.Profile.Integrations.Entities;
using Altinn.Profile.Integrations.Persistence;
using Altinn.Profile.Integrations.Repositories;

using Microsoft.EntityFrameworkCore;

using Xunit;

namespace Altinn.Profile.Tests.Profile.Integrations;

/// <summary>
/// Contains unit tests for the <see cref="RegisterRepository"/> class.
/// </summary>
public class RegisterRepositoryTests : IDisposable
{
private readonly ProfileDbContext _context;
private readonly RegisterRepository _registerRepository;

public RegisterRepositoryTests()
{
var options = new DbContextOptionsBuilder<ProfileDbContext>().UseInMemoryDatabase(Guid.NewGuid().ToString()).Options;
_context = new ProfileDbContext(options);
_registerRepository = new RegisterRepository(_context);
}

public void Dispose()
{
_context.Database.EnsureDeleted();
_context.Dispose();
GC.SuppressFinalize(this);
}

[Fact]
public async Task GetUserContactInfoAsync_ReturnsContactInfo_WhenFound()
{
// Arrange
var register = CreateRegister("21102709516", "Test Description", "test@example.com", "Test Mailbox Address");

await AddRegisterToContext(register);

// Act
var result = await _registerRepository.GetUserContactInfoAsync(["21102709516"]);

// Assert
AssertSingleRegister(register, result.First());
}

[Fact]
public async Task GetUserContactInfoAsync_ReturnsCorrectResults_WhenValidAndInvalidNumbers()
{
// Arrange
var validRegister = CreateRegister("21102709516", "Valid Test Description", "valid@example.com", "Valid Mailbox Address");

await AddRegisterToContext(validRegister);

// Act
var result = await _registerRepository.GetUserContactInfoAsync(["21102709516", "nonexistent2"]);

// Assert valid result
AssertSingleRegister(validRegister, result.FirstOrDefault(r => r.FnumberAk == "21102709516"));

// Assert invalid result
Assert.Null(result.FirstOrDefault(r => r.FnumberAk == "nonexistent2"));
}

[Fact]
public async Task GetUserContactInfoAsync_ReturnsEmpty_WhenNoneFound()
{
// Act
var result = await _registerRepository.GetUserContactInfoAsync(["nonexistent1", "nonexistent2"]);

// Assert
Assert.Empty(result);
}

[Fact]
public async Task GetUserContactInfoAsync_ReturnsMultipleContacts_WhenFound()
{
// Arrange
var registers = new List<Register>
{
CreateRegister("03062701187", "Test Description 1", "test1@example.com", "Test Mailbox Address 1", false),
CreateRegister("02024333593", "Test Description 2", "test2@example.com", "Test Mailbox Address 2", true)
};

await _context.Registers.AddRangeAsync(registers);
await _context.SaveChangesAsync();

// Act
var result = await _registerRepository.GetUserContactInfoAsync(["03062701187", "02024333593"]);

// Assert
Assert.Equal(2, result.Count());

foreach (var register in registers)
{
var foundRegister = result.FirstOrDefault(r => r.FnumberAk == register.FnumberAk);
Assert.NotNull(foundRegister);
AssertRegisterProperties(register, foundRegister);
}
}

[Fact]
public async Task GetUserContactInfoAsync_ReturnsEmpty_WhenNotFound()
{
// Act
var result = await _registerRepository.GetUserContactInfoAsync(["nonexistent"]);

// Assert
Assert.Empty(result);
}

private async Task AddRegisterToContext(Register register)
{
await _context.Registers.AddAsync(register);
await _context.SaveChangesAsync();
}

private static void AssertSingleRegister(Register expected, Register actual)
{
Assert.NotNull(actual);
AssertRegisterProperties(expected, actual);
}

private static void AssertRegisterProperties(Register expected, Register actual)
{
Assert.Equal(expected.FnumberAk, actual.FnumberAk);
Assert.Equal(expected.Description, actual.Description);
Assert.Equal(expected.Reservation, actual.Reservation);
Assert.Equal(expected.LanguageCode, actual.LanguageCode);
Assert.Equal(expected.EmailAddress, actual.EmailAddress);
Assert.Equal(expected.MailboxAddress, actual.MailboxAddress);
Assert.Equal(expected.MobilePhoneNumber, actual.MobilePhoneNumber);
}

private static Register CreateRegister(string fnumberAk, string description, string emailAddress, string mailboxAddress, bool reservation = true)
{
return new Register
{
LanguageCode = "EN",
FnumberAk = fnumberAk,
Reservation = reservation,
Description = description,
EmailAddress = emailAddress,
MailboxAddress = mailboxAddress,
MobilePhoneNumber = "1234567890",
};
}
}
Loading

0 comments on commit 635fe89

Please sign in to comment.