Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using AutoMapper;
using Hng.Application.Features.UserManagement.Handlers;
using Hng.Application.Features.UserManagement.Mappers;
using Hng.Application.Features.UserManagement.Queries;
using Hng.Domain.Entities;
using Hng.Infrastructure.Repository.Interface;
using Moq;
using System.Text;
using Xunit;

namespace Hng.Application.Test.Features.UserManagement
{
public class ExportUsersToCsvQueryHandlerShould
{
private readonly IMapper _mapper;

public ExportUsersToCsvQueryHandlerShould()
{
var userMappingProfile = new UserMappingProfile(); // Ensure your mapping profile is correctly configured
var configuration = new MapperConfiguration(cfg => cfg.AddProfile(userMappingProfile));
_mapper = new Mapper(configuration);
}

[Fact]
public async Task ExportUsersToCsvSuccessfully()
{
// Arrange
var expectedList = new List<User>
{
new User
{
Id = Guid.NewGuid(),
FirstName = "Jon",
LastName = "Snow",
Email = "[email protected]"
},
new User
{
Id = Guid.NewGuid(),
FirstName = "Arya",
LastName = "Stark",
Email = "[email protected]"
}
};

var userRepositoryMock = new Mock<IRepository<User>>(MockBehavior.Default);
userRepositoryMock.Setup(r => r.GetAllAsync())
.ReturnsAsync(expectedList);

var handler = new ExportUsersToCsvQueryHandler(userRepositoryMock.Object, _mapper);

// Act
var result = await handler.Handle(new ExportUsersToCsvQuery(), default);

// Assert
Assert.NotNull(result);
Assert.True(result.Length > 0); // Ensure that the result is not empty

// Verify that the CSV is correctly formatted by reading it from the byte array
using var memoryStream = new MemoryStream(result);
using var streamReader = new StreamReader(memoryStream, Encoding.UTF8);
var csvContent = await streamReader.ReadToEndAsync();

// Check that the CSV contains the expected data
foreach (var user in expectedList)
{
Assert.Contains(user.Id.ToString(), csvContent);
Assert.Contains(user.FirstName, csvContent);
Assert.Contains(user.Email, csvContent);
}
}
}
}
2 changes: 0 additions & 2 deletions src/Hng.Application.Test/Hng.Application.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@

<ItemGroup>
<ProjectReference Include="..\Hng.Application\Hng.Application.csproj" />
<ProjectReference Include="..\Hng.Domain\Hng.Domain.csproj" />
<ProjectReference Include="..\Hng.Infrastructure\Hng.Infrastructure.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using AutoMapper;
using CsvHelper;
using Hng.Application.Features.UserManagement.Dtos;
using Hng.Application.Features.UserManagement.Queries;
using Hng.Domain.Entities;
using Hng.Infrastructure.Repository.Interface;
using MediatR;
using System;
using System.Collections.Generic;
using System.Formats.Asn1;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Hng.Application.Features.UserManagement.Handlers
{
public class ExportUsersToCsvQueryHandler : IRequestHandler<ExportUsersToCsvQuery, byte[]>
{
private readonly IRepository<User> _userRepository;
private readonly IMapper _mapper;

public ExportUsersToCsvQueryHandler(IRepository<User> userRepository, IMapper mapper)
{
_userRepository = userRepository;
_mapper = mapper;
}

public async Task<byte[]> Handle(ExportUsersToCsvQuery request, CancellationToken cancellationToken)
{
// Fetch all users
var users = await _userRepository.GetAllAsync();
var userDtos = _mapper.Map<IEnumerable<UserDto>>(users);

// Map to a simplified object for CSV export
var csvData = userDtos.Select(u => new
{
u.Id,
u.FullName,
u.Email
});

// Generate CSV
using var memoryStream = new MemoryStream();
using var streamWriter = new StreamWriter(memoryStream, Encoding.UTF8);
using var csvWriter = new CsvWriter(streamWriter, CultureInfo.InvariantCulture);

csvWriter.WriteRecords(userDtos);
await streamWriter.FlushAsync();

return memoryStream.ToArray();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Hng.Application.Features.UserManagement.Queries
{
public class ExportUsersToCsvQuery : IRequest<byte[]>
{
}
}
79 changes: 40 additions & 39 deletions src/Hng.Application/Hng.Application.csproj
Original file line number Diff line number Diff line change
@@ -1,48 +1,49 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Hng.Application</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Hng.Application</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
</PropertyGroup>

<ItemGroup>
<Compile Remove="Features\Waitlist\**" />
<Compile Remove="Models\**" />
<EmbeddedResource Remove="Features\Waitlist\**" />
<EmbeddedResource Remove="Models\**" />
<None Remove="Features\Waitlist\**" />
<None Remove="Models\**" />
<Compile Remove="Features\UserManagement\Commands\CreateUserCommand.cs" />
<Compile Remove="Features\UserManagement\Dtos\UserCreationDto.cs" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Features\Waitlist\**" />
<Compile Remove="Models\**" />
<EmbeddedResource Remove="Features\Waitlist\**" />
<EmbeddedResource Remove="Models\**" />
<None Remove="Features\Waitlist\**" />
<None Remove="Models\**" />
<Compile Remove="Features\UserManagement\Commands\CreateUserCommand.cs" />
<Compile Remove="Features\UserManagement\Dtos\UserCreationDto.cs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="CloudinaryDotNet" Version="1.26.2" />
<PackageReference Include="CSharpFunctionalExtensions" Version="2.42.5" />
<PackageReference Include="fluentvalidation" Version="11.9.2" />
<PackageReference Include="FluentValidation.AspNetCore" Version="11.3.0" />
<PackageReference Include="JasperFx.Core" Version="1.8.0" />
<PackageReference Include="MediatR" Version="12.4.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="8.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.13" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="CloudinaryDotNet" Version="1.26.2" />
<PackageReference Include="CSharpFunctionalExtensions" Version="2.42.5" />
<PackageReference Include="CsvHelper" Version="33.0.1" />
<PackageReference Include="fluentvalidation" Version="11.9.2" />
<PackageReference Include="FluentValidation.AspNetCore" Version="11.3.0" />
<PackageReference Include="JasperFx.Core" Version="1.8.0" />
<PackageReference Include="MediatR" Version="12.4.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="8.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.13" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Hng.Domain\Hng.Domain.csproj" />
<ProjectReference Include="..\Hng.Infrastructure\Hng.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Hng.Domain\Hng.Domain.csproj" />
<ProjectReference Include="..\Hng.Infrastructure\Hng.Infrastructure.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Features\Jobs\Queries\" />
<Folder Include="Features\SuperAdmin\Commands\" />
<Folder Include="Features\Timezones\Handlers\Queries\" />
<Folder Include="Features\Timezones\Queries\" />
</ItemGroup>
<ItemGroup>
<Folder Include="Features\Jobs\Queries\" />
<Folder Include="Features\SuperAdmin\Commands\" />
<Folder Include="Features\Timezones\Handlers\Queries\" />
<Folder Include="Features\Timezones\Queries\" />
</ItemGroup>


</Project>
46 changes: 23 additions & 23 deletions src/Hng.Domain/Hng.Domain.csproj
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Hng.Domain</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Hng.Domain</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
</PropertyGroup>

<ItemGroup>
<Compile Remove="Repository\**" />
<Compile Remove="SeedData\**" />
<EmbeddedResource Remove="Repository\**" />
<EmbeddedResource Remove="SeedData\**" />
<None Remove="Repository\**" />
<None Remove="SeedData\**" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Repository\**" />
<Compile Remove="SeedData\**" />
<EmbeddedResource Remove="Repository\**" />
<EmbeddedResource Remove="SeedData\**" />
<None Remove="Repository\**" />
<None Remove="SeedData\**" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Paystack.Net" Version="1.1.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Paystack.Net" Version="1.1.1" />
</ItemGroup>

</Project>
20 changes: 10 additions & 10 deletions src/Hng.Graphql/Hng.Graphql.csproj
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="MediatR" Version="12.4.0" />
<ItemGroup>
<PackageReference Include="MediatR" Version="12.4.0" />
<PackageReference Include="HotChocolate.AspNetCore" Version="13.9.11" />
<PackageReference Include="HotChocolate.AspNetCore.Authorization" Version="13.9.11" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Hng.Application\Hng.Application.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Hng.Application\Hng.Application.csproj" />
</ItemGroup>

</Project>
Loading
Loading