From 0ba8e8b4b768d2c8580d2d0de21873948139a180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Sat, 23 Jan 2021 19:57:04 +0300 Subject: [PATCH] Created initial non-functional new event page and tests. --- .../Events/CreateEventDto.cs | 27 ++++++ .../Events/IEventAppService.cs | 10 +++ .../Organizations/IOrganizationAppService.cs | 2 + .../Events/EventAppService.cs | 12 +++ .../Organizations/OrganizationAppService.cs | 13 +++ .../Events/EventConsts.cs | 11 +++ .../Localization/EventHub/en.json | 9 +- .../EventHub.Domain/EventHub.Domain.csproj | 4 + ...ventHubDbContextModelCreatingExtensions.cs | 1 + .../EventHubWebAutoMapperProfile.cs | 5 +- .../src/EventHub.Web/Pages/Events/New.cshtml | 10 +++ .../EventHub.Web/Pages/Events/New.cshtml.cs | 90 ++++++++++++++++++- .../Events/EventAppServiceTests.cs | 34 +++++++ .../EventHubTestDataSeedContributor.cs | 14 +-- 14 files changed, 230 insertions(+), 12 deletions(-) create mode 100644 eventhub/src/EventHub.Application.Contracts/Events/CreateEventDto.cs create mode 100644 eventhub/src/EventHub.Application.Contracts/Events/IEventAppService.cs create mode 100644 eventhub/src/EventHub.Application/Events/EventAppService.cs create mode 100644 eventhub/src/EventHub.Domain.Shared/Events/EventConsts.cs create mode 100644 eventhub/test/EventHub.Application.Tests/Events/EventAppServiceTests.cs diff --git a/eventhub/src/EventHub.Application.Contracts/Events/CreateEventDto.cs b/eventhub/src/EventHub.Application.Contracts/Events/CreateEventDto.cs new file mode 100644 index 0000000..46deaab --- /dev/null +++ b/eventhub/src/EventHub.Application.Contracts/Events/CreateEventDto.cs @@ -0,0 +1,27 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace EventHub.Events +{ + public class CreateEventDto + { + public Guid OrganizationId { get; set; } + + [Required] + [StringLength(EventConsts.MaxTitleLength, MinimumLength = EventConsts.MinTitleLength)] + public string Title { get; set; } + + [Required] + public DateTime StartTime { get; set; } + + [Required] + public DateTime EndTime { get; set; } + + [Required] + [StringLength(EventConsts.MaxDescriptionLength, MinimumLength = EventConsts.MinDescriptionLength)] + public string Description { get; set; } + + public bool IsOnline { get; set; } + + public int? Capacity { get; set; } + }} diff --git a/eventhub/src/EventHub.Application.Contracts/Events/IEventAppService.cs b/eventhub/src/EventHub.Application.Contracts/Events/IEventAppService.cs new file mode 100644 index 0000000..e75b435 --- /dev/null +++ b/eventhub/src/EventHub.Application.Contracts/Events/IEventAppService.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; +using Volo.Abp.Application.Services; + +namespace EventHub.Events +{ + public interface IEventAppService : IApplicationService + { + Task CreateAsync(CreateEventDto input); + } +} diff --git a/eventhub/src/EventHub.Application.Contracts/Organizations/IOrganizationAppService.cs b/eventhub/src/EventHub.Application.Contracts/Organizations/IOrganizationAppService.cs index ff89aad..b31555a 100644 --- a/eventhub/src/EventHub.Application.Contracts/Organizations/IOrganizationAppService.cs +++ b/eventhub/src/EventHub.Application.Contracts/Organizations/IOrganizationAppService.cs @@ -11,5 +11,7 @@ namespace EventHub.Organizations Task> GetListAsync(PagedResultRequestDto input); Task GetProfileAsync(string name); + + Task> GetMyOrganizationsAsync(); } } diff --git a/eventhub/src/EventHub.Application/Events/EventAppService.cs b/eventhub/src/EventHub.Application/Events/EventAppService.cs new file mode 100644 index 0000000..88ee066 --- /dev/null +++ b/eventhub/src/EventHub.Application/Events/EventAppService.cs @@ -0,0 +1,12 @@ +using System.Threading.Tasks; + +namespace EventHub.Events +{ + public class EventAppService : EventHubAppService, IEventAppService + { + public async Task CreateAsync(CreateEventDto input) + { + + } + } +} diff --git a/eventhub/src/EventHub.Application/Organizations/OrganizationAppService.cs b/eventhub/src/EventHub.Application/Organizations/OrganizationAppService.cs index 4e39672..5cd0128 100644 --- a/eventhub/src/EventHub.Application/Organizations/OrganizationAppService.cs +++ b/eventhub/src/EventHub.Application/Organizations/OrganizationAppService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Volo.Abp.Application.Dtos; @@ -52,5 +53,17 @@ namespace EventHub.Organizations var organization = await _organizationRepository.GetAsync(o => o.Name == name); return ObjectMapper.Map(organization); } + + [Authorize] + public async Task> GetMyOrganizationsAsync() + { + var currentUserId = CurrentUser.GetId(); + var query = (await _organizationRepository.GetQueryableAsync()).Where(o => o.OwnerUserId == currentUserId); + var organizations = await AsyncExecuter.ToListAsync(query); + + return new ListResultDto( + ObjectMapper.Map, List>(organizations) + ); + } } } diff --git a/eventhub/src/EventHub.Domain.Shared/Events/EventConsts.cs b/eventhub/src/EventHub.Domain.Shared/Events/EventConsts.cs new file mode 100644 index 0000000..c9861b0 --- /dev/null +++ b/eventhub/src/EventHub.Domain.Shared/Events/EventConsts.cs @@ -0,0 +1,11 @@ +namespace EventHub.Events +{ + public static class EventConsts + { + public const int MinTitleLength = 8; + public const int MaxTitleLength = 128; + + public const int MinDescriptionLength = 50; + public const int MaxDescriptionLength = 2000; + } +} diff --git a/eventhub/src/EventHub.Domain.Shared/Localization/EventHub/en.json b/eventhub/src/EventHub.Domain.Shared/Localization/EventHub/en.json index 061b952..66b088e 100644 --- a/eventhub/src/EventHub.Domain.Shared/Localization/EventHub/en.json +++ b/eventhub/src/EventHub.Domain.Shared/Localization/EventHub/en.json @@ -11,9 +11,16 @@ "DisplayName:Name": "Name", "DisplayName:DisplayName": "Display Name", "DisplayName:Description": "Description", + "DisplayName:Title": "Title", + "DisplayName:StartTime": "Start Time", + "DisplayName:EndTime": "End Time", + "DisplayName:IsOnline": "Is Online?", + "DisplayName:Capacity": "Capacity", "EventHub:OrganizationNameAlreadyExists": "The organization {Name} already exists. Please use another name.", "Events": "Events", "Members": "Members", - "SeeOrganization": "See Organization" + "SeeOrganization": "See Organization", + "Organization": "Organization", + "Submit": "Submit" } } diff --git a/eventhub/src/EventHub.Domain/EventHub.Domain.csproj b/eventhub/src/EventHub.Domain/EventHub.Domain.csproj index dc451a7..83d4ebb 100644 --- a/eventhub/src/EventHub.Domain/EventHub.Domain.csproj +++ b/eventhub/src/EventHub.Domain/EventHub.Domain.csproj @@ -22,4 +22,8 @@ + + + + diff --git a/eventhub/src/EventHub.EntityFrameworkCore/EntityFrameworkCore/EventHubDbContextModelCreatingExtensions.cs b/eventhub/src/EventHub.EntityFrameworkCore/EntityFrameworkCore/EventHubDbContextModelCreatingExtensions.cs index d616034..2b7480f 100644 --- a/eventhub/src/EventHub.EntityFrameworkCore/EntityFrameworkCore/EventHubDbContextModelCreatingExtensions.cs +++ b/eventhub/src/EventHub.EntityFrameworkCore/EntityFrameworkCore/EventHubDbContextModelCreatingExtensions.cs @@ -21,6 +21,7 @@ namespace EventHub.EntityFrameworkCore b.Property(x => x.Name).IsRequired().HasMaxLength(OrganizationConsts.MaxNameLength); b.Property(x => x.DisplayName).IsRequired().HasMaxLength(OrganizationConsts.MaxDisplayNameLength); + b.Property(x => x.Description).IsRequired().HasMaxLength(OrganizationConsts.MaxDescriptionNameLength); b.HasIndex(x => x.Name); b.HasIndex(x => x.DisplayName); diff --git a/eventhub/src/EventHub.Web/EventHubWebAutoMapperProfile.cs b/eventhub/src/EventHub.Web/EventHubWebAutoMapperProfile.cs index 9b40896..6457cef 100644 --- a/eventhub/src/EventHub.Web/EventHubWebAutoMapperProfile.cs +++ b/eventhub/src/EventHub.Web/EventHubWebAutoMapperProfile.cs @@ -1,6 +1,6 @@ using AutoMapper; +using EventHub.Events; using EventHub.Organizations; -using EventHub.Web.Pages.Organizations; namespace EventHub.Web { @@ -8,7 +8,8 @@ namespace EventHub.Web { public EventHubWebAutoMapperProfile() { - CreateMap(); + CreateMap(); + CreateMap(); } } } diff --git a/eventhub/src/EventHub.Web/Pages/Events/New.cshtml b/eventhub/src/EventHub.Web/Pages/Events/New.cshtml index 1a91392..9f7e10a 100644 --- a/eventhub/src/EventHub.Web/Pages/Events/New.cshtml +++ b/eventhub/src/EventHub.Web/Pages/Events/New.cshtml @@ -4,3 +4,13 @@ @using Microsoft.AspNetCore.Mvc.Localization @model EventHub.Web.Pages.Events.New

@L["NewEvent"]

+
+ + + + + + + + + diff --git a/eventhub/src/EventHub.Web/Pages/Events/New.cshtml.cs b/eventhub/src/EventHub.Web/Pages/Events/New.cshtml.cs index 8e04dc9..bdc1d1e 100644 --- a/eventhub/src/EventHub.Web/Pages/Events/New.cshtml.cs +++ b/eventhub/src/EventHub.Web/Pages/Events/New.cshtml.cs @@ -1,10 +1,96 @@ -namespace EventHub.Web.Pages.Events +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; +using EventHub.Events; +using EventHub.Organizations; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; + +namespace EventHub.Web.Pages.Events { public class New : EventHubPageModel { - public void OnGet() + [BindProperty] + public NewEventViewModel Event { get; set; } + + public List Organizations { get; set; } + + private readonly IEventAppService _eventAppService; + private readonly IOrganizationAppService _organizationAppService; + + public New( + IEventAppService eventAppService, + IOrganizationAppService organizationAppService) + { + _eventAppService = eventAppService; + _organizationAppService = organizationAppService; + } + + public async Task OnGetAsync() + { + Event = new NewEventViewModel + { + StartTime = DateTime.Now.ClearTime().AddDays(1).AddHours(19), + EndTime = DateTime.Now.ClearTime().AddDays(1).AddHours(21) + }; + + var result = await _organizationAppService.GetMyOrganizationsAsync(); + Organizations = result.Items.Select( + organization => new SelectListItem + { + Value = organization.Id.ToString(), + Text = organization.DisplayName + } + ).ToList(); + } + + public async Task OnPostAsync() { + try + { + ValidateModel(); + + var input = ObjectMapper.Map(Event); + await _eventAppService.CreateAsync(input); + + //TODO: Redirect to the event! + return RedirectToPage("/"); + } + catch (Exception exception) + { + ShowAlert(exception); + return Page(); + } + } + + public class NewEventViewModel + { + [SelectItems(nameof(Organizations))] + [DisplayName("Organization")] + public Guid OrganizationId { get; set; } + + [Required] + [StringLength(EventConsts.MaxTitleLength, MinimumLength = EventConsts.MinTitleLength)] + public string Title { get; set; } + + [Required] + public DateTime StartTime { get; set; } + + [Required] + public DateTime EndTime { get; set; } + + [Required] + [StringLength(EventConsts.MaxDescriptionLength, MinimumLength = EventConsts.MinDescriptionLength)] + [TextArea] + public string Description { get; set; } + + public bool IsOnline { get; set; } + public int? Capacity { get; set; } } } } diff --git a/eventhub/test/EventHub.Application.Tests/Events/EventAppServiceTests.cs b/eventhub/test/EventHub.Application.Tests/Events/EventAppServiceTests.cs new file mode 100644 index 0000000..91d8911 --- /dev/null +++ b/eventhub/test/EventHub.Application.Tests/Events/EventAppServiceTests.cs @@ -0,0 +1,34 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace EventHub.Events +{ + public class EventAppServiceTests : EventHubApplicationTestBase + { + private readonly IEventAppService _eventAppService; + private readonly EventHubTestData _testData; + + public EventAppServiceTests() + { + _eventAppService = GetRequiredService(); + _testData = GetRequiredService(); + } + + [Fact] + public async Task Should_Create_A_New_Valid_Event() + { + await _eventAppService.CreateAsync( + new CreateEventDto + { + OrganizationId = _testData.OrganizationVolosoftId, + Title = "Introduction to the ABP Framework", + Description = "In this event, we will introduce the ABP Framework and explore the fundamental features.", + StartTime = DateTime.Now.AddDays(1), + EndTime = DateTime.Now.AddDays(1).AddHours(3), + IsOnline = true + } + ); + } + } +} diff --git a/eventhub/test/EventHub.TestBase/EventHubTestDataSeedContributor.cs b/eventhub/test/EventHub.TestBase/EventHubTestDataSeedContributor.cs index a911781..fd7faf8 100644 --- a/eventhub/test/EventHub.TestBase/EventHubTestDataSeedContributor.cs +++ b/eventhub/test/EventHub.TestBase/EventHubTestDataSeedContributor.cs @@ -3,24 +3,24 @@ using System.Threading.Tasks; using EventHub.Organizations; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; -using Volo.Abp.Domain.Repositories; +using Volo.Abp.Users; namespace EventHub { public class EventHubTestDataSeedContributor : IDataSeedContributor, ITransientDependency { - private readonly IRepository _organizationRepository; private readonly OrganizationManager _organizationManager; + private readonly ICurrentUser _currentUser; private readonly EventHubTestData _eventHubTestData; public EventHubTestDataSeedContributor( - IRepository organizationRepository, EventHubTestData eventHubTestData, - OrganizationManager organizationManager) + OrganizationManager organizationManager, + ICurrentUser currentUser) { - _organizationRepository = organizationRepository; _eventHubTestData = eventHubTestData; _organizationManager = organizationManager; + _currentUser = currentUser; } public async Task SeedAsync(DataSeedContext context) @@ -31,7 +31,7 @@ namespace EventHub private async Task CreateOrganizationsAsync() { var volosoft = await _organizationManager.CreateAsync( - Guid.NewGuid(), + _currentUser.GetId(), _eventHubTestData.OrganizationVolosoftName, "Volosoft", "Volosoft is producing software development tools for developers. We are organizing events related to the ABP.IO platform and general software development topic." @@ -39,7 +39,7 @@ namespace EventHub _eventHubTestData.OrganizationVolosoftId = volosoft.Id; var dotnetEurope = await _organizationManager.CreateAsync( - Guid.NewGuid(), + _currentUser.GetId(), _eventHubTestData.OrganizationDotnetEuropeName, "Dotnet Europe", "Organizing events on Microsoft's .NET Platform in European Countries."