Skip to content

Commit

Permalink
#131 Added Contact controller REST API
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonGeering committed Sep 1, 2020
1 parent 79eecc0 commit ba0531d
Show file tree
Hide file tree
Showing 10 changed files with 199 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
</ItemGroup>

<ItemGroup>
<Folder Include="WebAPI\v1\ContactsModule\" />
<Folder Include="WebAPI\v1\DashboardModule\" />
<Folder Include="WebAPI\v1\BillingModule\" />
<Folder Include="WebAPI\v1\MailModule\" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using AdminAssistant.DomainModel.Modules.ContactsModule;
using AdminAssistant.Framework.TypeMapping;

namespace AdminAssistant.WebAPI.v1.ContactsModule
{
public class ContactResponseDto : IMapFrom<Contact>
{
public int ContactID { get; set; }
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using AdminAssistant.DomainModel.Modules.ContactsModule.CQRS;
using AdminAssistant.Infra.Providers;
using AutoMapper;
using MediatR;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;

namespace AdminAssistant.WebAPI.v1.ContactsModule
{
[ApiController]
[Route("api/v1/core/[controller]")]
[ApiExplorerSettings(GroupName = "Contacts - Contact")]
public class ContactController : WebAPIControllerBase
{
public ContactController(IMapper mapper, IMediator mediator, ILoggingProvider loggingProvider)
: base(mapper, mediator, loggingProvider)
{
}

[HttpGet]
[SwaggerOperation("Lists all contacts", OperationId = "GetContact")]
[SwaggerResponse(StatusCodes.Status200OK, "Ok - returns a list of ContactResponseDto", type: typeof(IEnumerable<ContactResponseDto>))]
public async Task<ActionResult<IEnumerable<ContactResponseDto>>> GetContacts()
{
Log.Start();

var result = await Mediator.Send(new ContactQuery()).ConfigureAwait(false);
var response = Mapper.Map<IEnumerable<ContactResponseDto>>(result.Value);

return Log.Finish(Ok(response));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
using AdminAssistant.DomainModel.Modules.AssetRegisterModule;
using AdminAssistant.DomainModel.Modules.BudgetModule;
using AdminAssistant.DomainModel.Modules.CalendarModule;
using AdminAssistant.DomainModel.Modules.ContactsModule;
using AdminAssistant.DomainModel.Modules.CoreModule;
using AdminAssistant.DomainModel.Modules.DocumentsModule;
using AdminAssistant.DomainModel.Modules.TasksModule;
using AdminAssistant.WebAPI.v1.AccountsModule;
using AdminAssistant.WebAPI.v1.AssetRegisterModule;
using AdminAssistant.WebAPI.v1.BudgetModule;
using AdminAssistant.WebAPI.v1.CalendarModule;
using AdminAssistant.WebAPI.v1.ContactsModule;
using AdminAssistant.WebAPI.v1.CoreModule;
using AdminAssistant.WebAPI.v1.DocumentsModule;
using AdminAssistant.WebAPI.v1.TasksModule;
Expand Down Expand Up @@ -109,6 +111,21 @@ public void ShouldSupportCalendarModuleMappingFromSourceToDestination(Type sourc
result.Should().NotBeNull();
}

[Theory]
[Trait("Category", "Unit")]
[InlineData(typeof(Contact), typeof(ContactResponseDto))]
public void ShouldSupportContactsModuleMappingFromSourceToDestination(Type source, Type destination)
{
// Arrange
var instance = Activator.CreateInstance(source);

// Act
var result = _mapper.Map(instance, source, destination);

// Assert
result.Should().NotBeNull();
}

[Theory]
[Trait("Category", "Unit")]
[InlineData(typeof(Currency), typeof(CurrencyResponseDto))]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#pragma warning disable CA1707 // Identifiers should not contain underscores
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AdminAssistant.DomainModel;
using AdminAssistant.DomainModel.Modules.ContactsModule;
using AdminAssistant.DomainModel.Modules.ContactsModule.CQRS;
using Ardalis.Result;
using AutoMapper;
using FluentAssertions;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Xunit;

namespace AdminAssistant.WebAPI.v1.ContactsModule
{
public class ContactController_GetContacts
{
[Fact]
[Trait("Category", "Unit")]
public async Task Returns_Status200OK_With_AListOfContacts_Given_NoArguments()
{
// Arrange
var documents = new List<Contact>()
{
Factory.Contact.WithTestData(10).Build(),
Factory.Contact.WithTestData(20).Build()
};

var services = new ServiceCollection();
services.AddMockServerSideLogging();
services.AddAutoMapper(typeof(MappingProfile));

var mockMediator = new Mock<IMediator>();
mockMediator.Setup(x => x.Send(It.IsAny<ContactQuery>(), It.IsAny<CancellationToken>()))
.Returns(Task.FromResult(Result<IEnumerable<Contact>>.Success(documents)));

services.AddTransient((sp) => mockMediator.Object);
services.AddTransient<ContactController>();

// Act
var response = await services.BuildServiceProvider().GetRequiredService<ContactController>().GetContacts().ConfigureAwait(false);

// Assert
response.Result.Should().BeOfType<OkObjectResult>();
response.Value.Should().BeNull();

var result = (OkObjectResult)response.Result;
result.Value.Should().BeAssignableTo<IEnumerable<ContactResponseDto>>();

//var value = ((IEnumerable<CurrencyResponseDto>)result.Value).ToArray();
//value.Should().HaveCount(currencies.Count);

//var expected = currencies.ToArray();
//for (int i = 0; i < expected.Length; i++)
//{
// value[i].CurrencyID.Should().Be(expected[i].CurrencyID);
// value[i].Symbol.Should().Be(expected[i].Symbol);
// value[i].DecimalFormat.Should().Be(expected[i].DecimalFormat);
//}
}
}
}
#pragma warning restore CA1707 // Identifiers should not contain underscores
1 change: 0 additions & 1 deletion src/AdminAssistant/AdminAssistant.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@
<Folder Include="Infra\DAL\Modules\TasksModule\" />
<Folder Include="Infra\DAL\Modules\ReportsModule\" />
<Folder Include="DomainModel\Modules\BillingModule\" />
<Folder Include="DomainModel\Modules\ContactsModule\" />
<Folder Include="DomainModel\Modules\DashboardModule\" />
<Folder Include="DomainModel\Modules\MailModule\" />
<Folder Include="DomainModel\Modules\ReportsModule\" />
Expand Down
4 changes: 4 additions & 0 deletions src/AdminAssistant/DomainModel/Factory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using AdminAssistant.DomainModel.Modules.AssetRegisterModule.Builders;
using AdminAssistant.DomainModel.Modules.BudgetModule.Builders;
using AdminAssistant.DomainModel.Modules.CalendarModule.Builders;
using AdminAssistant.DomainModel.Modules.ContactsModule.Builders;
using AdminAssistant.DomainModel.Modules.CoreModule.Builders;
using AdminAssistant.DomainModel.Modules.DocumentsModule.Builders;
using AdminAssistant.DomainModel.Modules.TasksModule.Builders;
Expand All @@ -26,6 +27,9 @@ public static class Factory
// Calendar Module ...
public static IReminderBuilder Reminder => new ReminderBuilder();

// Contact Module ...
public static IContactBuilder Contact => new ContactBuilder();

// Core Module ...
public static ICurrencyBuilder Currency => new CurrencyBuilder();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
namespace AdminAssistant.DomainModel.Modules.ContactsModule.Builders
{
public interface IContactBuilder
{
Contact Build();
IContactBuilder WithTestData(int assetID = Constants.UnknownRecordID);
IContactBuilder WithFirstName(string firstName);
IContactBuilder WithLastName(string lastName);
}
internal class ContactBuilder : Contact, IContactBuilder
{
public static Contact Default(IContactBuilder builder) => builder.Build();
public static Contact Default(ContactBuilder builder) => builder.Build();

public Contact Build() => this;

public IContactBuilder WithTestData(int assetID = Constants.UnknownRecordID)
{
ContactID = assetID;
FirstName = "Fred";
LastName = "Blogs";
return this;
}

public IContactBuilder WithFirstName(string firstName)
{
FirstName = firstName;
return this;
}

public IContactBuilder WithLastName(string lastName)
{
LastName = lastName;
return this;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Collections.Generic;
using Ardalis.Result;
using MediatR;

namespace AdminAssistant.DomainModel.Modules.ContactsModule.CQRS
{
public class ContactQuery : IRequest<Result<IEnumerable<Contact>>>
{
}
}
16 changes: 16 additions & 0 deletions src/AdminAssistant/DomainModel/Modules/ContactsModule/Contact.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using AdminAssistant.Infra.DAL;

namespace AdminAssistant.DomainModel.Modules.ContactsModule
{
public class Contact : IDatabasePersistable
{
public const int ContactFirstNameMaxLength = Constants.NameMaxLength;
public const int ContactLastNameMaxLength = Constants.NameMaxLength;

public int ContactID { get; set; }
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;

public int PrimaryKey => ContactID;
}
}

0 comments on commit ba0531d

Please sign in to comment.