From fd4a60d4744153353ce0b696c87f7e11286f2beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Sat, 23 Jan 2021 22:22:45 +0300 Subject: [PATCH] List events --- .../Events/EventInListDto.cs | 24 +++++++++ .../Events/EventListFilterDto.cs | 17 ++++++ .../Events/IEventAppService.cs | 3 ++ .../Events/EventAppService.cs | 46 +++++++++++++++- .../Localization/EventHub/en.json | 3 +- .../EventHub.Web/Pages/Events/New.cshtml.cs | 2 +- eventhub/src/EventHub.Web/Pages/Index.cshtml | 28 ++++++++-- .../src/EventHub.Web/Pages/Index.cshtml.cs | 26 +++++++-- .../Events/EventAppServiceTests.cs | 43 ++++++++++++++- .../EventHub.TestBase/EventHubTestData.cs | 12 ++++- .../EventHubTestDataSeedContributor.cs | 53 +++++++++++++++---- 11 files changed, 233 insertions(+), 24 deletions(-) create mode 100644 eventhub/src/EventHub.Application.Contracts/Events/EventInListDto.cs create mode 100644 eventhub/src/EventHub.Application.Contracts/Events/EventListFilterDto.cs diff --git a/eventhub/src/EventHub.Application.Contracts/Events/EventInListDto.cs b/eventhub/src/EventHub.Application.Contracts/Events/EventInListDto.cs new file mode 100644 index 0000000..c88c7bb --- /dev/null +++ b/eventhub/src/EventHub.Application.Contracts/Events/EventInListDto.cs @@ -0,0 +1,24 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace EventHub.Events +{ + public class EventInListDto : EntityDto + { + public string OrganizationName { get; set; } + + public string OrganizationDisplayName { get; set; } + + public string Title { get; set; } + + public string Description { get; set; } + + public DateTime StartTime { get; set; } + + public DateTime EndTime { get; set; } + + public bool IsOnline { get; set; } + + public bool IsLive { get; set; } + } +} diff --git a/eventhub/src/EventHub.Application.Contracts/Events/EventListFilterDto.cs b/eventhub/src/EventHub.Application.Contracts/Events/EventListFilterDto.cs new file mode 100644 index 0000000..8c71887 --- /dev/null +++ b/eventhub/src/EventHub.Application.Contracts/Events/EventListFilterDto.cs @@ -0,0 +1,17 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace EventHub.Events +{ + public class EventListFilterDto : PagedResultRequestDto + { + public DateTime? MinDate { get; set; } + + public DateTime? MaxDate { get; set; } + + public EventListFilterDto() + { + MaxResultCount = 20; + } + } +} \ No newline at end of file diff --git a/eventhub/src/EventHub.Application.Contracts/Events/IEventAppService.cs b/eventhub/src/EventHub.Application.Contracts/Events/IEventAppService.cs index f2feaf5..7e0092b 100644 --- a/eventhub/src/EventHub.Application.Contracts/Events/IEventAppService.cs +++ b/eventhub/src/EventHub.Application.Contracts/Events/IEventAppService.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; namespace EventHub.Events @@ -6,5 +7,7 @@ namespace EventHub.Events public interface IEventAppService : IApplicationService { Task CreateAsync(CreateEventDto input); + + Task> GetListAsync(EventListFilterDto input); } } diff --git a/eventhub/src/EventHub.Application/Events/EventAppService.cs b/eventhub/src/EventHub.Application/Events/EventAppService.cs index 43ba537..bbaef58 100644 --- a/eventhub/src/EventHub.Application/Events/EventAppService.cs +++ b/eventhub/src/EventHub.Application/Events/EventAppService.cs @@ -1,8 +1,10 @@ using System; +using System.Linq; using System.Threading.Tasks; using EventHub.Organizations; using Microsoft.AspNetCore.Authorization; using Volo.Abp; +using Volo.Abp.Application.Dtos; using Volo.Abp.Domain.Repositories; using Volo.Abp.Users; @@ -10,8 +12,8 @@ namespace EventHub.Events { public class EventAppService : EventHubAppService, IEventAppService { - private readonly IRepository _organizationRepository; private readonly EventManager _eventManager; + private readonly IRepository _organizationRepository; private readonly IRepository _eventRepository; public EventAppService( @@ -50,5 +52,47 @@ namespace EventHub.Events return ObjectMapper.Map(@event); } + + public async Task> GetListAsync(EventListFilterDto input) + { + var eventQueryable = await _eventRepository.GetQueryableAsync(); + var organizationQueryable = await _organizationRepository.GetQueryableAsync(); + + var query = from @event in eventQueryable + join organization in organizationQueryable on @event.OrganizationId equals organization.Id + select new {@event, organization}; + + if (input.MinDate.HasValue) + { + query = query.Where(i => i.@event.EndTime >= input.MinDate); + } + + if (input.MaxDate.HasValue) + { + query = query.Where(i => i.@event.EndTime <= input.MaxDate); + } + + query = query.PageBy(input).OrderBy(x => x.@event.StartTime); + + var totalCount = await AsyncExecuter.CountAsync(query); + var items = await AsyncExecuter.ToListAsync(query); + var now = Clock.Now; + + var dtos = items.Select( + i => new EventInListDto + { + Id = i.@event.Id, + Title = i.@event.Title, + EndTime = i.@event.EndTime, + StartTime = i.@event.StartTime, + IsOnline = i.@event.IsOnline, + OrganizationName = i.organization.Name, + OrganizationDisplayName = i.organization.DisplayName, + IsLive = now.IsBetween(i.@event.StartTime, i.@event.EndTime) + } + ).ToList(); + + return new PagedResultDto(totalCount, dtos); + } } } diff --git a/eventhub/src/EventHub.Domain.Shared/Localization/EventHub/en.json b/eventhub/src/EventHub.Domain.Shared/Localization/EventHub/en.json index 0a6cac7..2e7a9a5 100644 --- a/eventhub/src/EventHub.Domain.Shared/Localization/EventHub/en.json +++ b/eventhub/src/EventHub.Domain.Shared/Localization/EventHub/en.json @@ -23,6 +23,7 @@ "Members": "Members", "SeeOrganization": "See Organization", "Organization": "Organization", - "Submit": "Submit" + "Submit": "Submit", + "SeeEvent": "See Event" } } diff --git a/eventhub/src/EventHub.Web/Pages/Events/New.cshtml.cs b/eventhub/src/EventHub.Web/Pages/Events/New.cshtml.cs index 94b7c89..2c7fc6a 100644 --- a/eventhub/src/EventHub.Web/Pages/Events/New.cshtml.cs +++ b/eventhub/src/EventHub.Web/Pages/Events/New.cshtml.cs @@ -17,7 +17,7 @@ namespace EventHub.Web.Pages.Events [BindProperty] public NewEventViewModel Event { get; set; } - public List Organizations { get; set; } + public List Organizations { get; private set; } private readonly IEventAppService _eventAppService; private readonly IOrganizationAppService _organizationAppService; diff --git a/eventhub/src/EventHub.Web/Pages/Index.cshtml b/eventhub/src/EventHub.Web/Pages/Index.cshtml index 3430eaf..11dc033 100644 --- a/eventhub/src/EventHub.Web/Pages/Index.cshtml +++ b/eventhub/src/EventHub.Web/Pages/Index.cshtml @@ -3,14 +3,36 @@ @using Microsoft.AspNetCore.Mvc.Localization @using EventHub.Localization @inject IHtmlLocalizer L + @section styles { - + } + @section scripts { - + } -HOME PAGE + +

Upcoming Events

+ + + @foreach (var eventItem in Model.Events) + { + + + @eventItem.Title + + @eventItem.Title + @eventItem.StartTime.ToLongDateString(), @eventItem.StartTime.ToString("hh:mm") + + @eventItem.Description.TruncateWithPostfix(100) + + @L["SeeEvent"] + + + + } + diff --git a/eventhub/src/EventHub.Web/Pages/Index.cshtml.cs b/eventhub/src/EventHub.Web/Pages/Index.cshtml.cs index ac1a797..45e2388 100644 --- a/eventhub/src/EventHub.Web/Pages/Index.cshtml.cs +++ b/eventhub/src/EventHub.Web/Pages/Index.cshtml.cs @@ -1,13 +1,31 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; +using EventHub.Events; using Microsoft.AspNetCore.Authentication; namespace EventHub.Web.Pages { public class IndexModel : EventHubPageModel { - public void OnGet() + public IReadOnlyList Events { get; private set; } + + private readonly IEventAppService _eventAppService; + + public IndexModel(IEventAppService eventAppService) + { + _eventAppService = eventAppService; + } + + public async Task OnGetAsync() { - + var result = await _eventAppService.GetListAsync( + new EventListFilterDto + { + MinDate = Clock.Now + } + ); + + Events = result.Items; } public async Task OnPostLoginAsync() @@ -15,4 +33,4 @@ namespace EventHub.Web.Pages await HttpContext.ChallengeAsync("oidc"); } } -} \ No newline at end of file +} diff --git a/eventhub/test/EventHub.Application.Tests/Events/EventAppServiceTests.cs b/eventhub/test/EventHub.Application.Tests/Events/EventAppServiceTests.cs index c18d990..96733e8 100644 --- a/eventhub/test/EventHub.Application.Tests/Events/EventAppServiceTests.cs +++ b/eventhub/test/EventHub.Application.Tests/Events/EventAppServiceTests.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Shouldly; using Volo.Abp; +using Volo.Abp.Timing; using Xunit; namespace EventHub.Events @@ -55,8 +56,48 @@ namespace EventHub.Events } ); }); - + exception.Code.ShouldBe(EventHubErrorCodes.NotAuthorizedToCreateEventInThisOrganization); } + + [Fact] + public async Task Should_Get_Upcoming_Events() + { + var now = GetRequiredService().Now; + + var result = await _eventAppService.GetListAsync( + new EventListFilterDto + { + MinDate = now + } + ); + + result.TotalCount.ShouldBeGreaterThanOrEqualTo(1); + result.Items.ShouldContain(x => + x.Id == _testData.AbpMicroservicesFutureEventId && + x.Title == _testData.AbpMicroservicesFutureEventTitle + ); + result.Items.ShouldAllBe(x => x.EndTime >= now); + } + + [Fact] + public async Task Should_Get_Past_Events() + { + var now = GetRequiredService().Now; + + var result = await _eventAppService.GetListAsync( + new EventListFilterDto + { + MaxDate = now + } + ); + + result.TotalCount.ShouldBeGreaterThanOrEqualTo(1); + result.Items.ShouldContain(x => + x.Id == _testData.AbpBlazorPastEventId && + x.Title == _testData.AbpBlazorPastEventTitle + ); + result.Items.ShouldAllBe(x => x.EndTime <= now); + } } } diff --git a/eventhub/test/EventHub.TestBase/EventHubTestData.cs b/eventhub/test/EventHub.TestBase/EventHubTestData.cs index 4bcfc0c..d20b235 100644 --- a/eventhub/test/EventHub.TestBase/EventHubTestData.cs +++ b/eventhub/test/EventHub.TestBase/EventHubTestData.cs @@ -7,10 +7,18 @@ namespace EventHub { /* ORGANIZATIONS *****************************************************/ - public Guid OrganizationVolosoftId { get; internal set; } + public Guid OrganizationVolosoftId { get; } = Guid.NewGuid(); public string OrganizationVolosoftName { get; } = "volosoft"; - public Guid OrganizationDotnetEuropeId { get; internal set; } + public Guid OrganizationDotnetEuropeId { get; } = Guid.NewGuid(); public string OrganizationDotnetEuropeName { get; } = "dotnet-europe"; + + /* EVENTS ************************************************************/ + + public Guid AbpBlazorPastEventId { get; } = Guid.NewGuid(); + public string AbpBlazorPastEventTitle { get; internal set; } = "ABP Framework Blazor UI Introduction"; + + public Guid AbpMicroservicesFutureEventId { get;} = Guid.NewGuid(); + public string AbpMicroservicesFutureEventTitle { get; internal set; } = "ABP Framework Microservice Solution Development"; } } diff --git a/eventhub/test/EventHub.TestBase/EventHubTestDataSeedContributor.cs b/eventhub/test/EventHub.TestBase/EventHubTestDataSeedContributor.cs index b7e7ff1..763bf2a 100644 --- a/eventhub/test/EventHub.TestBase/EventHubTestDataSeedContributor.cs +++ b/eventhub/test/EventHub.TestBase/EventHubTestDataSeedContributor.cs @@ -1,58 +1,89 @@ using System; using System.Threading.Tasks; +using EventHub.Events; using EventHub.Organizations; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Repositories; +using Volo.Abp.Timing; using Volo.Abp.Users; namespace EventHub { public class EventHubTestDataSeedContributor : IDataSeedContributor, ITransientDependency { - private readonly OrganizationManager _organizationManager; private readonly IRepository _organizationRepository; + private readonly IRepository _eventRepository; private readonly ICurrentUser _currentUser; private readonly EventHubTestData _eventHubTestData; + private readonly IClock _clock; public EventHubTestDataSeedContributor( EventHubTestData eventHubTestData, - OrganizationManager organizationManager, ICurrentUser currentUser, - IRepository organizationRepository) + IRepository organizationRepository, + IRepository eventRepository, + IClock clock) { _eventHubTestData = eventHubTestData; - _organizationManager = organizationManager; _currentUser = currentUser; _organizationRepository = organizationRepository; + _eventRepository = eventRepository; + _clock = clock; } public async Task SeedAsync(DataSeedContext context) { await CreateOrganizationsAsync(); + await CreateEvents(); } private async Task CreateOrganizationsAsync() { - var volosoft = await _organizationRepository.InsertAsync( - await _organizationManager.CreateAsync( + await _organizationRepository.InsertAsync( + new Organization( + _eventHubTestData.OrganizationVolosoftId, _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." ) ); - _eventHubTestData.OrganizationVolosoftId = volosoft.Id; - var dotnetEurope = await _organizationRepository.InsertAsync( - await _organizationManager.CreateAsync( - Guid.NewGuid(), //TODO: create a second user and set its id! + await _organizationRepository.InsertAsync( + new Organization( + _eventHubTestData.OrganizationDotnetEuropeId, + Guid.NewGuid(), _eventHubTestData.OrganizationDotnetEuropeName, "Dotnet Europe", "Organizing events on Microsoft's .NET Platform in European Countries." ) ); - _eventHubTestData.OrganizationDotnetEuropeId = dotnetEurope.Id; + } + + private async Task CreateEvents() + { + await _eventRepository.InsertAsync( + new Event( + _eventHubTestData.AbpBlazorPastEventId, + _eventHubTestData.OrganizationVolosoftId, + _eventHubTestData.AbpBlazorPastEventTitle, + _clock.Now.ClearTime().AddDays(-2).AddHours(15), + _clock.Now.ClearTime().AddDays(-2).AddHours(17), + "This is a past event about Blazor and the ABP Framework." + ) + ); + + await _eventRepository.InsertAsync( + new Event( + _eventHubTestData.AbpMicroservicesFutureEventId, + _eventHubTestData.OrganizationVolosoftId, + _eventHubTestData.AbpMicroservicesFutureEventTitle, + _clock.Now.ClearTime().AddDays(1).AddHours(15), + _clock.Now.ClearTime().AddDays(1).AddHours(17), + "This is a future event about the ABP Framework and Microservices that is set for tomorrow." + ) + ); } } }